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
, pin
):
26 if self
.type_
== IOType
.In
:
27 core_i
= getattr(dut
.test_issuer
, f
"{self.name}__core__i").value
28 pad_i
= getattr(dut
.test_issuer
, f
"{self.name}__pad__i").value
29 dut
._log
.info(f
"{self.name}: core.i={core_i}, pad.i={pad_i}")
30 elif self
.type_
== IOType
.Out
:
31 core_o
= getattr(dut
.test_issuer
, f
"{self.name}__core__o").value
32 pad_o
= getattr(dut
.test_issuer
, f
"{self.name}__pad__o").value
33 dut
._log
.info(f
"{self.name}: core.o={core_o}, pad.o={pad_o}")
34 elif self
.type_
== IOType
.TriOut
:
35 core_o
= getattr(dut
.test_issuer
, f
"{self.name}__core__o").value
36 core_oe
= getattr(dut
.test_issuer
, f
"{self.name}__core__oe").value
37 pad_o
= getattr(dut
.test_issuer
, f
"{self.name}__pad__o").value
38 pad_oe
= getattr(dut
.test_issuer
, f
"{self.name}__pad__oe").value
39 dut
._log
.info(f
"{self.name}: core.(o={core_o}, oe={core_oe}), pad.(o={pad_o}, oe={pad_oe})")
40 elif self
.type_
== IOType
.InTriOut
:
41 core_i
= getattr(dut
.test_issuer
, f
"{self.name}__core__i").value
42 core_o
= getattr(dut
.test_issuer
, f
"{self.name}__core__o").value
43 core_oe
= getattr(dut
.test_issuer
, f
"{self.name}__core__oe").value
44 pad_i
= getattr(dut
.test_issuer
, f
"{self.name}__pad__i").value
45 pad_o
= getattr(dut
.test_issuer
, f
"{self.name}__pad__o").value
46 pad_oe
= getattr(dut
.test_issuer
, f
"{self.name}__pad__oe").value
47 dut
._log
.info(f
"{self.name}: core.(i={core_i}, o={core_o}, oe={core_oe}), pad.(i={core_i}, o={pad_o}, oe={pad_oe})")
49 raise ValueError(f
"Unsupported pin type {self.type_}")
52 if self
.type_
in (IOType
.In
, IOType
.Out
):
54 elif self
.type_
== IOType
.TriOut
:
56 elif self
.type_
== IOType
.InTriOut
:
59 raise ValueError(f
"Unsupported pin type {self.type_}")
61 def check(self
, dut
, val
):
62 if self
.type_
== IOType
.In
:
63 assert getattr(dut
.test_issuer
, f
"{self.name}__core__i").value
== val
64 elif self
.type_
== IOType
.Out
:
65 assert getattr(dut
.test_issuer
, f
"{self.name}__pad__o").value
== val
66 elif self
.type_
== IOType
.TriOut
:
67 assert getattr(dut
.test_issuer
, f
"{self.name}__core__o").value
== val
68 assert getattr(dut
.test_issuer
, f
"{self.name}__core__oe").value
== 1
69 elif self
.type_
== IOType
.InTriOut
:
70 assert getattr(dut
.test_issuer
, f
"{self.name}__core__i").value
== val
71 assert getattr(dut
.test_issuer
, f
"{self.name}__pad__o").value
== val
72 assert getattr(dut
.test_issuer
, f
"{self.name}__pad__oe").value
== val
74 raise ValueError(f
"Unsupported pin type {self.type_}")
76 def log_pins(dut
, pins
):
81 def get_jtag_boundary():
82 """gets the list of information for jtag boundary scan
84 # currently only a subset of pins is enabled. nuisance
87 'eint', 'gpio', 'mspi0',
88 # 'mspi1', - disabled for now
89 # 'pwm', 'sd0', - disabled for now
91 pins
= tuple(JTAGPin(pin
) for pin
in Pins(get_pinspecs(subset
=subset
)))
95 def setup_sim(dut
, *, clk_period
, run
):
96 """Initialize CPU and setup clock"""
98 clk_steps
= get_sim_steps(clk_period
, "ns")
99 cocotb
.fork(Clock(dut
.sys_clk
, clk_steps
).start())
104 yield Timer(int(10.5*clk_steps
))
106 yield Timer(int(5*clk_steps
))
108 def setup_jtag(dut
, *, tck_period
):
109 # Make this a generator
112 return JTAG_Master(dut
.jtag_tck
, dut
.jtag_tms
,
113 dut
.jtag_tdi
, dut
.jtag_tdo
,
114 clk_period
=tck_period
,
117 def execute_svf(dut
, *, jtag
, svf_filename
):
120 jtag_svf
= SVF_Executor(jtag
)
121 with
open(svf_filename
, "r") as f
:
123 yield jtag_svf
.run(svf_deck
, p
=dut
._log
.info
)
126 # IDCODE using JTAG_master
129 def idcode(dut
, *, jtag
):
131 result1
= jtag
.result
132 dut
._log
.info("IDCODE1: {}".format(result1
))
133 assert(result1
== BinaryValue("00000000000000000001100011111111"))
136 result2
= jtag
.result
137 dut
._log
.info("IDCODE2: {}".format(result2
))
139 assert(result1
== result2
)
142 def idcode_reset(dut
):
143 dut
._log
.info("Running IDCODE test; cpu in reset...")
145 clk_period
= 100 # 10MHz
146 tck_period
= 300 # 3MHz
148 yield from setup_sim(dut
, clk_period
=clk_period
, run
=False)
149 jtag
= yield from setup_jtag(dut
, tck_period
= tck_period
)
151 yield from idcode(dut
, jtag
=jtag
)
153 dut
._log
.info("IDCODE test completed")
157 dut
._log
.info("Running IDCODE test; cpu running...")
159 clk_period
= 100 # 10MHz
160 tck_period
= 300 # 3MHz
162 yield from setup_sim(dut
, clk_period
=clk_period
, run
=True)
163 jtag
= yield from setup_jtag(dut
, tck_period
= tck_period
)
165 yield from idcode(dut
, jtag
=jtag
)
167 dut
._log
.info("IDCODE test completed")
170 # Read IDCODE from SVF file
174 def idcodesvf_reset(dut
):
175 dut
._log
.info("Running IDCODE through SVF test; cpu in reset...")
177 clk_period
= 100 # 10MHz
178 tck_period
= 300 # 3MHz
180 yield from setup_sim(dut
, clk_period
=clk_period
, run
=False)
181 jtag
= yield from setup_jtag(dut
, tck_period
= tck_period
)
183 yield from execute_svf(dut
, jtag
=jtag
, svf_filename
="idcode.svf")
185 dut
._log
.info("IDCODE test completed")
188 def idcodesvf_run(dut
):
189 dut
._log
.info("Running IDCODE through SVF test; cpu running...")
191 clk_period
= 100 # 10MHz
192 tck_period
= 300 # 3MHz
194 yield from setup_sim(dut
, clk_period
=clk_period
, run
=True)
195 jtag
= yield from setup_jtag(dut
, tck_period
= tck_period
)
197 yield from execute_svf(dut
, jtag
=jtag
, svf_filename
="idcode.svf")
199 dut
._log
.info("IDCODE test completed")
205 def boundary_scan(dut
, *, jtag
):
206 pins
= get_jtag_boundary()
211 dut
._log
.info("Before scan")
214 yield jtag
.load_ir([0, 0, 0, 0])
215 data
= chain(*(pin
.data(i
%2) for i
, pin
in enumerate(pins
)))
216 yield jtag
.shift_data(data
)
219 dut
._log
.info("After scan")
225 dut
._log
.info("After reset")
230 def boundary_scan_reset(dut
):
231 dut
._log
.info("Running boundary scan test; cpu in reset...")
233 clk_period
= 100 # 10MHz
234 tck_period
= 300 # 3MHz
236 yield from setup_sim(dut
, clk_period
=clk_period
, run
=False)
237 jtag
= yield from setup_jtag(dut
, tck_period
= tck_period
)
239 yield from boundary_scan(dut
, jtag
=jtag
)
241 dut
._log
.info("IDCODE test completed")
244 def boundary_scan_run(dut
):
245 dut
._log
.info("Running boundary scan test; cpu running...")
247 clk_period
= 100 # 10MHz
248 tck_period
= 300 # 3MHz
250 yield from setup_sim(dut
, clk_period
=clk_period
, run
=True)
251 jtag
= yield from setup_jtag(dut
, tck_period
= tck_period
)
253 yield from boundary_scan(dut
, jtag
=jtag
)
255 dut
._log
.info("IDCODE test completed")
258 # demo / debug how to get boundary scan names. run "python3 test.py"
259 if __name__
== '__main__':
260 pinouts
= get_jtag_boundary()
262 # example: ('eint', '2', <IOType.In: 1>, 'eint_2', 125)