9e6b77c7c5ff344b4f91a4019979ece2da58b958
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
)
41 def __init__(self
, pin
):
46 if self
.type_
== IOType
.In
:
47 core_i
= getattr(wrap
.ti
, f
"{self.name}__core__i").value
48 pad_i
= getattr(wrap
.ti
, f
"{self.name}__pad__i").value
49 wrap
.info(f
"{self.name}: core.i={core_i}, pad.i={pad_i}")
50 elif self
.type_
== IOType
.Out
:
51 core_o
= getattr(wrap
.ti
, f
"{self.name}__core__o").value
52 pad_o
= getattr(wrap
.ti
, f
"{self.name}__pad__o").value
53 wrap
.info(f
"{self.name}: core.o={core_o}, pad.o={pad_o}")
54 elif self
.type_
== IOType
.TriOut
:
55 core_o
= getattr(wrap
.ti
, f
"{self.name}__core__o").value
56 core_oe
= getattr(wrap
.ti
, f
"{self.name}__core__oe").value
57 pad_o
= getattr(wrap
.ti
, f
"{self.name}__pad__o").value
58 pad_oe
= getattr(wrap
.ti
, f
"{self.name}__pad__oe").value
59 wrap
.info(f
"{self.name}: core.(o={core_o}, oe={core_oe}), " \
60 "pad.(o={pad_o}, oe={pad_oe})")
61 elif self
.type_
== IOType
.InTriOut
:
62 core_i
= getattr(wrap
.ti
, f
"{self.name}__core__i").value
63 core_o
= getattr(wrap
.ti
, f
"{self.name}__core__o").value
64 core_oe
= getattr(wrap
.ti
, f
"{self.name}__core__oe").value
65 pad_i
= getattr(wrap
.ti
, f
"{self.name}__pad__i").value
66 pad_o
= getattr(wrap
.ti
, f
"{self.name}__pad__o").value
67 pad_oe
= getattr(wrap
.ti
, f
"{self.name}__pad__oe").value
68 wrap
.info(f
"{self.name}: core.(i={core_i}, o={core_o}, " \
69 "oe={core_oe}), pad.(i={core_i}, o={pad_o}, " \
72 raise ValueError(f
"Unsupported pin type {self.type_}")
74 def data(self
, *, i
=None, o
=None, oe
=None):
75 if self
.type_
== IOType
.In
:
78 elif self
.type_
== IOType
.Out
:
81 elif self
.type_
== IOType
.TriOut
:
82 assert (o
is not None) and (oe
is not None)
84 elif self
.type_
== IOType
.InTriOut
:
85 assert (i
is not None) and(o
is not None) and (oe
is not None)
88 raise ValueError(f
"Unsupported pin type {self.type_}")
90 def check(self
, *, wrap
, i
=None, o
=None, oe
=None):
91 if self
.type_
in (IOType
.In
, IOType
.InTriOut
):
92 sig
= f
"{self.name}__core__i"
93 val
= getattr(wrap
.ti
, sig
).value
95 raise ValueError(f
"'{sig}' should be {i}, not {val}")
96 if self
.type_
in (IOType
.Out
, IOType
.TriOut
, IOType
.InTriOut
):
97 sig
= f
"{self.name}__pad__o"
98 val
= getattr(wrap
.ti
, sig
).value
100 raise ValueError(f
"'{sig}' should be {o}, not {val}")
101 if self
.type_
in (IOType
.TriOut
, IOType
.InTriOut
):
102 sig
= f
"{self.name}__pad__oe"
103 val
= getattr(wrap
.ti
, sig
).value
105 raise ValueError(f
"'{sig}' should be {oe}, not {val}")
108 def log_pins(wrap
, pins
):
113 def get_jtag_boundary():
114 """gets the list of information for jtag boundary scan
116 # currently only a subset of pins is enabled. nuisance
119 'eint', 'gpio', 'mspi0',
120 # 'mspi1', - disabled for now
121 # 'pwm', 'sd0', - disabled for now
123 pins
= tuple(JTAGPin(pin
) for pin
in Pins(get_pinspecs(subset
=subset
)))
127 def setup_sim(dut
, *, info
, clk_period
, run
):
128 """Initialize CPU and setup clock"""
130 wrap
= DUTWrapper(dut
)
133 clk_steps
= get_sim_steps(clk_period
, "ns")
134 cocotb
.fork(Clock(wrap
.clk
, clk_steps
).start())
139 yield Timer(int(10.5*clk_steps
))
141 yield Timer(int(5*clk_steps
))
146 def setup_jtag(wrap
, *, tck_period
):
147 # TODO: Make this a generator
150 return JTAG_Master(wrap
.tck
, wrap
.tms
, wrap
.tdi
, wrap
.tdo
,
151 clk_period
=tck_period
,
154 def execute_svf(wrap
, *, jtag
, svf_filename
):
157 jtag_svf
= SVF_Executor(jtag
)
158 with
open(svf_filename
, "r") as f
:
160 yield jtag_svf
.run(svf_deck
, p
=wrap
.info
)
163 # IDCODE using JTAG_master
166 def idcode(wrap
, *, jtag
):
168 result1
= jtag
.result
169 wrap
.info("IDCODE1: {}".format(result1
))
170 assert(result1
== BinaryValue("00000000000000000001100011111111"))
173 result2
= jtag
.result
174 wrap
.info("IDCODE2: {}".format(result2
))
176 assert(result1
== result2
)
180 def idcode_reset(dut
):
181 clk_period
= 100 # 10MHz
182 tck_period
= 300 # 3MHz
184 info
= "Running IDCODE test; cpu in reset..."
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")
196 clk_period
= 100 # 10MHz
197 tck_period
= 300 # 3MHz
199 info
= "Running IDCODE test; cpu running..."
200 wrap
= yield from setup_sim(dut
, info
=info
, clk_period
=clk_period
,
202 jtag
= yield from setup_jtag(wrap
, tck_period
= tck_period
)
204 yield from idcode(wrap
, jtag
=jtag
)
206 wrap
.info("IDCODE test completed")
209 # Read IDCODE from SVF file
213 def idcodesvf_reset(dut
):
214 clk_period
= 100 # 10MHz
215 tck_period
= 300 # 3MHz
217 info
= "Running IDCODE through SVF test; cpu in reset..."
218 wrap
= yield from setup_sim(dut
, info
=info
, clk_period
=clk_period
,
220 jtag
= yield from setup_jtag(wrap
, tck_period
= tck_period
)
222 yield from execute_svf(wrap
, jtag
=jtag
, svf_filename
="idcode.svf")
224 wrap
.info("IDCODE test completed")
228 def idcodesvf_run(dut
):
229 clk_period
= 100 # 10MHz
230 tck_period
= 300 # 3MHz
232 info
= "Running IDCODE through SVF test; cpu running..."
233 wrap
= yield from setup_sim(dut
, info
=info
, clk_period
=clk_period
,
235 jtag
= yield from setup_jtag(wrap
, tck_period
= tck_period
)
237 yield from execute_svf(wrap
, jtag
=jtag
, svf_filename
="idcode.svf")
239 wrap
.info("IDCODE test completed")
245 def boundary_scan(wrap
, *, jtag
):
246 pins
= get_jtag_boundary()
251 wrap
.info("Before scan")
254 yield jtag
.load_ir([0, 0, 0, 0])
255 pinsdata
= tuple(pin
.data(i
=i
%2, o
=((i
%3)%2), oe
=((i
%5)%2))
256 for i
, pin
in enumerate(pins
))
257 yield jtag
.shift_data(chain(*pinsdata
))
260 wrap
.info("After scan")
262 for i
, pin
in enumerate(pins
):
263 pin
.check(wrap
=wrap
, i
=i
%2, o
=((i
%3)%2), oe
=((i
%5)%2))
268 wrap
.info("After reset")
273 def boundary_scan_reset(dut
):
274 clk_period
= 100 # 10MHz
275 tck_period
= 300 # 3MHz
277 info
= "Running boundary scan test; cpu in reset..."
278 wrap
= yield from setup_sim(dut
, info
=info
, clk_period
=clk_period
,
280 jtag
= yield from setup_jtag(wrap
, tck_period
= tck_period
)
282 yield from boundary_scan(wrap
, jtag
=jtag
)
284 wrap
.info("IDCODE test completed")
288 def boundary_scan_run(dut
):
289 clk_period
= 100 # 10MHz
290 tck_period
= 300 # 3MHz
292 info
= "Running boundary scan test; cpu running..."
293 wrap
= yield from setup_sim(dut
, info
=info
, clk_period
=clk_period
,
295 jtag
= yield from setup_jtag(wrap
, tck_period
= tck_period
)
297 yield from boundary_scan(wrap
, jtag
=jtag
)
299 wrap
.info("IDCODE test completed")
302 # demo / debug how to get boundary scan names. run "python3 test.py"
303 if __name__
== '__main__':
304 pinouts
= get_jtag_boundary()
306 # example: ('eint', '2', <IOType.In: 1>, 'eint_2', 125)