25e8caff1d71989be8f24f4ec01289e891f9194d
1 from itertools
import chain
4 from cocotb
.clock
import Clock
5 from cocotb
.triggers
import Timer
6 from cocotb
.utils
import get_sim_steps
7 from cocotb
.binary
import BinaryValue
9 from c4m
.nmigen
.jtag
.tap
import IOType
10 from c4m
.cocotb
.jtag
.c4m_jtag
import JTAG_Master
11 from c4m
.cocotb
.jtag
.c4m_jtag_svfcocotb
import SVF_Executor
13 from soc
.config
.pinouts
import get_pinspecs
14 from soc
.debug
.jtag
import Pins
21 def __init__(self
, dut
):
25 except AttributeError:
31 self
.tck
= ti
.TAP_bus__tck
32 self
.tms
= ti
.TAP_bus__tms
33 self
.tdi
= ti
.TAP_bus__tdi
34 self
.tdo
= ti
.TAP_bus__tdo
36 def info(self
, *args
, **kwargs
):
37 return self
.dut
._log
.info(*args
, **kwargs
)
40 def __init__(self
, pin
):
45 if self
.type_
== IOType
.In
:
46 core_i
= getattr(wrap
.ti
, f
"{self.name}__core__i").value
47 pad_i
= getattr(wrap
.ti
, f
"{self.name}__pad__i").value
48 wrap
.info(f
"{self.name}: core.i={core_i}, pad.i={pad_i}")
49 elif self
.type_
== IOType
.Out
:
50 core_o
= getattr(wrap
.ti
, f
"{self.name}__core__o").value
51 pad_o
= getattr(wrap
.ti
, f
"{self.name}__pad__o").value
52 wrap
.info(f
"{self.name}: core.o={core_o}, pad.o={pad_o}")
53 elif self
.type_
== IOType
.TriOut
:
54 core_o
= getattr(wrap
.ti
, f
"{self.name}__core__o").value
55 core_oe
= getattr(wrap
.ti
, f
"{self.name}__core__oe").value
56 pad_o
= getattr(wrap
.ti
, f
"{self.name}__pad__o").value
57 pad_oe
= getattr(wrap
.ti
, f
"{self.name}__pad__oe").value
58 wrap
.info(f
"{self.name}: core.(o={core_o}, oe={core_oe}), pad.(o={pad_o}, oe={pad_oe})")
59 elif self
.type_
== IOType
.InTriOut
:
60 core_i
= getattr(wrap
.ti
, f
"{self.name}__core__i").value
61 core_o
= getattr(wrap
.ti
, f
"{self.name}__core__o").value
62 core_oe
= getattr(wrap
.ti
, f
"{self.name}__core__oe").value
63 pad_i
= getattr(wrap
.ti
, f
"{self.name}__pad__i").value
64 pad_o
= getattr(wrap
.ti
, f
"{self.name}__pad__o").value
65 pad_oe
= getattr(wrap
.ti
, f
"{self.name}__pad__oe").value
66 wrap
.info(f
"{self.name}: core.(i={core_i}, o={core_o}, oe={core_oe}), pad.(i={core_i}, o={pad_o}, oe={pad_oe})")
68 raise ValueError(f
"Unsupported pin type {self.type_}")
71 if self
.type_
in (IOType
.In
, IOType
.Out
):
73 elif self
.type_
== IOType
.TriOut
:
75 elif self
.type_
== IOType
.InTriOut
:
78 raise ValueError(f
"Unsupported pin type {self.type_}")
80 def check(self
, wrap
, val
):
81 if self
.type_
== IOType
.In
:
82 assert getattr(wrap
.ti
, f
"{self.name}__core__i").value
== val
83 elif self
.type_
== IOType
.Out
:
84 assert getattr(wrap
.ti
, f
"{self.name}__pad__o").value
== val
85 elif self
.type_
== IOType
.TriOut
:
86 assert getattr(wrap
.ti
, f
"{self.name}__core__o").value
== val
87 assert getattr(wrap
.ti
, f
"{self.name}__core__oe").value
== 1
88 elif self
.type_
== IOType
.InTriOut
:
89 assert getattr(wrap
.ti
, f
"{self.name}__core__i").value
== val
90 assert getattr(wrap
.ti
, f
"{self.name}__pad__o").value
== val
91 assert getattr(wrap
.ti
, f
"{self.name}__pad__oe").value
== val
93 raise ValueError(f
"Unsupported pin type {self.type_}")
96 def log_pins(wrap
, pins
):
101 def get_jtag_boundary():
102 """gets the list of information for jtag boundary scan
104 # currently only a subset of pins is enabled. nuisance
107 'eint', 'gpio', 'mspi0',
108 # 'mspi1', - disabled for now
109 # 'pwm', 'sd0', - disabled for now
111 pins
= tuple(JTAGPin(pin
) for pin
in Pins(get_pinspecs(subset
=subset
)))
115 def setup_sim(dut
, *, info
, clk_period
, run
):
116 """Initialize CPU and setup clock"""
118 wrap
= DUTWrapper(dut
)
121 clk_steps
= get_sim_steps(clk_period
, "ns")
122 cocotb
.fork(Clock(wrap
.clk
, clk_steps
).start())
127 yield Timer(int(10.5*clk_steps
))
129 yield Timer(int(5*clk_steps
))
133 def setup_jtag(wrap
, *, tck_period
):
134 # Make this a generator
137 return JTAG_Master(wrap
.tck
, wrap
.tms
, wrap
.tdi
, wrap
.tdo
,
138 clk_period
=tck_period
,
141 def execute_svf(wrap
, *, jtag
, svf_filename
):
144 jtag_svf
= SVF_Executor(jtag
)
145 with
open(svf_filename
, "r") as f
:
147 yield jtag_svf
.run(svf_deck
, p
=wrap
.info
)
150 # IDCODE using JTAG_master
153 def idcode(wrap
, *, jtag
):
155 result1
= jtag
.result
156 wrap
.info("IDCODE1: {}".format(result1
))
157 assert(result1
== BinaryValue("00000000000000000001100011111111"))
160 result2
= jtag
.result
161 wrap
.info("IDCODE2: {}".format(result2
))
163 assert(result1
== result2
)
166 def idcode_reset(dut
):
167 clk_period
= 100 # 10MHz
168 tck_period
= 300 # 3MHz
170 info
= "Running IDCODE test; cpu in reset..."
171 wrap
= yield from setup_sim(dut
, info
=info
, clk_period
=clk_period
,
173 jtag
= yield from setup_jtag(wrap
, tck_period
= tck_period
)
175 yield from idcode(wrap
, jtag
=jtag
)
177 wrap
.info("IDCODE test completed")
181 clk_period
= 100 # 10MHz
182 tck_period
= 300 # 3MHz
184 info
= "Running IDCODE test; cpu running..."
185 wrap
= yield from setup_sim(dut
, info
=info
, clk_period
=clk_period
,
187 jtag
= yield from setup_jtag(wrap
, tck_period
= tck_period
)
189 yield from idcode(wrap
, jtag
=jtag
)
191 wrap
.info("IDCODE test completed")
194 # Read IDCODE from SVF file
198 def idcodesvf_reset(dut
):
199 clk_period
= 100 # 10MHz
200 tck_period
= 300 # 3MHz
202 info
= "Running IDCODE through SVF test; cpu in reset..."
203 wrap
= yield from setup_sim(dut
, info
=info
, clk_period
=clk_period
,
205 jtag
= yield from setup_jtag(wrap
, tck_period
= tck_period
)
207 yield from execute_svf(wrap
, jtag
=jtag
, svf_filename
="idcode.svf")
209 wrap
.info("IDCODE test completed")
212 def idcodesvf_run(dut
):
213 clk_period
= 100 # 10MHz
214 tck_period
= 300 # 3MHz
216 info
= "Running IDCODE through SVF test; cpu running..."
217 wrap
= yield from setup_sim(dut
, info
=info
, clk_period
=clk_period
,
219 jtag
= yield from setup_jtag(wrap
, tck_period
= tck_period
)
221 yield from execute_svf(wrap
, jtag
=jtag
, svf_filename
="idcode.svf")
223 wrap
.info("IDCODE test completed")
229 def boundary_scan(wrap
, *, jtag
):
230 pins
= get_jtag_boundary()
235 wrap
.info("Before scan")
238 yield jtag
.load_ir([0, 0, 0, 0])
239 data
= chain(*(pin
.data(i
%2) for i
, pin
in enumerate(pins
)))
240 yield jtag
.shift_data(data
)
243 wrap
.info("After scan")
245 # pins[0].check(dut, 1)
250 wrap
.info("After reset")
252 # pins[0].check(dut, 0)
256 def boundary_scan_reset(dut
):
257 clk_period
= 100 # 10MHz
258 tck_period
= 300 # 3MHz
260 info
= "Running boundary scan test; cpu in reset..."
261 wrap
= yield from setup_sim(dut
, info
=info
, clk_period
=clk_period
,
263 jtag
= yield from setup_jtag(wrap
, tck_period
= tck_period
)
265 yield from boundary_scan(wrap
, jtag
=jtag
)
267 wrap
.info("IDCODE test completed")
270 def boundary_scan_run(dut
):
271 clk_period
= 100 # 10MHz
272 tck_period
= 300 # 3MHz
274 info
= "Running boundary scan test; cpu running..."
275 wrap
= yield from setup_sim(dut
, info
=info
, clk_period
=clk_period
,
277 jtag
= yield from setup_jtag(wrap
, tck_period
= tck_period
)
279 yield from boundary_scan(wrap
, jtag
=jtag
)
281 wrap
.info("IDCODE test completed")
284 # demo / debug how to get boundary scan names. run "python3 test.py"
285 if __name__
== '__main__':
286 pinouts
= get_jtag_boundary()
288 # example: ('eint', '2', <IOType.In: 1>, 'eint_2', 125)