bc0faff7d111089ef10334b74a35b2e406ddc7bf
[soc-cocotb-sim.git] / ls180 / pre_pnr / test.py
1 from itertools import product
2
3 import cocotb
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
8
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
12
13 from soc.config.pinouts import get_pinspecs
14 from soc.debug.jtag import Pins
15
16 #
17 # Helper functions
18 #
19
20 class JTAGPin:
21 def __init__(self, pin):
22 self.type_ = pin[2]
23 self.name = pin[3]
24
25 def log(self, dut):
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})")
48 else:
49 raise ValueError(f"Unsupported pin type {self.type_}")
50
51 def check(self, dut, val):
52 if self.type_ == IOType.In:
53 assert getattr(dut.test_issuer, f"{self.name}__core__i").value == val
54 elif self.type_ == IOType.Out:
55 assert getattr(dut.test_issuer, f"{self.name}__pad__o").value == val
56 elif self.type_ == IOType.TriOut:
57 assert getattr(dut.test_issuer, f"{self.name}__core__o").value == val
58 assert getattr(dut.test_issuer, f"{self.name}__core__oe").value == 1
59 elif self.type_ == IOType.InTriOut:
60 assert getattr(dut.test_issuer, f"{self.name}__core__i").value == val
61 assert getattr(dut.test_issuer, f"{self.name}__pad__o").value == val
62 assert getattr(dut.test_issuer, f"{self.name}__pad__oe").value == val
63 else:
64 raise ValueError(f"Unsupported pin type {self.type_}")
65
66 def log_pins(dut, pins):
67 for pin in pins:
68 pin.log(dut)
69
70
71 def get_jtag_boundary():
72 """gets the list of information for jtag boundary scan
73 """
74 # currently only a subset of pins is enabled. nuisance
75 subset = ['uart',
76 'mtwi',
77 'eint', 'gpio', 'mspi0',
78 # 'mspi1', - disabled for now
79 # 'pwm', 'sd0', - disabled for now
80 'sdr']
81 pins = tuple(JTAGPin(pin) for pin in Pins(get_pinspecs(subset=subset)))
82 return pins
83
84
85 def setup_sim(dut, *, clk_period, run):
86 """Initialize CPU and setup clock"""
87
88 clk_steps = get_sim_steps(clk_period, "ns")
89 cocotb.fork(Clock(dut.sys_clk, clk_steps).start())
90
91 dut.sys_rst <= 1
92 dut.sys_clk <= 0
93 if run:
94 yield Timer(int(10.5*clk_steps))
95 dut.sys_rst <= 0
96 yield Timer(int(5*clk_steps))
97
98 def setup_jtag(dut, *, tck_period):
99 # Make this a generator
100 if False:
101 yield Timer(0)
102 return JTAG_Master(dut.jtag_tck, dut.jtag_tms,
103 dut.jtag_tdi, dut.jtag_tdo,
104 clk_period=tck_period,
105 ir_width=4)
106
107 def execute_svf(dut, *, jtag, svf_filename):
108 yield jtag.reset()
109
110 jtag_svf = SVF_Executor(jtag)
111 with open(svf_filename, "r") as f:
112 svf_deck = f.read()
113 yield jtag_svf.run(svf_deck, p=dut._log.info)
114
115 #
116 # IDCODE using JTAG_master
117 #
118
119 def idcode(dut, *, jtag):
120 yield jtag.idcode()
121 result1 = jtag.result
122 dut._log.info("IDCODE1: {}".format(result1))
123 assert(result1 == BinaryValue("00000000000000000001100011111111"))
124
125 yield jtag.idcode()
126 result2 = jtag.result
127 dut._log.info("IDCODE2: {}".format(result2))
128
129 assert(result1 == result2)
130
131 @cocotb.test()
132 def idcode_reset(dut):
133 dut._log.info("Running IDCODE test; cpu in reset...")
134
135 clk_period = 100 # 10MHz
136 tck_period = 300 # 3MHz
137
138 yield from setup_sim(dut, clk_period=clk_period, run=False)
139 jtag = yield from setup_jtag(dut, tck_period = tck_period)
140
141 yield from idcode(dut, jtag=jtag)
142
143 dut._log.info("IDCODE test completed")
144
145 @cocotb.test()
146 def idcode_run(dut):
147 dut._log.info("Running IDCODE test; cpu running...")
148
149 clk_period = 100 # 10MHz
150 tck_period = 300 # 3MHz
151
152 yield from setup_sim(dut, clk_period=clk_period, run=True)
153 jtag = yield from setup_jtag(dut, tck_period = tck_period)
154
155 yield from idcode(dut, jtag=jtag)
156
157 dut._log.info("IDCODE test completed")
158
159 #
160 # Read IDCODE from SVF file
161 #
162
163 @cocotb.test()
164 def idcodesvf_reset(dut):
165 dut._log.info("Running IDCODE through SVF test; cpu in reset...")
166
167 clk_period = 100 # 10MHz
168 tck_period = 300 # 3MHz
169
170 yield from setup_sim(dut, clk_period=clk_period, run=False)
171 jtag = yield from setup_jtag(dut, tck_period = tck_period)
172
173 yield from execute_svf(dut, jtag=jtag, svf_filename="idcode.svf")
174
175 dut._log.info("IDCODE test completed")
176
177 @cocotb.test()
178 def idcodesvf_run(dut):
179 dut._log.info("Running IDCODE through SVF test; cpu running...")
180
181 clk_period = 100 # 10MHz
182 tck_period = 300 # 3MHz
183
184 yield from setup_sim(dut, clk_period=clk_period, run=True)
185 jtag = yield from setup_jtag(dut, tck_period = tck_period)
186
187 yield from execute_svf(dut, jtag=jtag, svf_filename="idcode.svf")
188
189 dut._log.info("IDCODE test completed")
190
191 #
192 # Boundary scan
193 #
194
195 def boundary_scan(dut, *, jtag):
196 pins = get_jtag_boundary()
197
198 yield jtag.reset()
199
200 dut._log.info("Before scan")
201 log_pins(dut, pins)
202
203 yield jtag.load_ir([0, 0, 0, 0])
204 yield jtag.shift_data([1])
205
206 dut._log.info("After scan")
207 log_pins(dut, pins)
208 pins[0].check(dut, 1)
209
210 yield jtag.reset()
211
212 dut._log.info("After reset")
213 log_pins(dut, pins)
214 pins[0].check(dut, 0)
215
216
217 @cocotb.test()
218 def boundary_scan_reset(dut):
219 dut._log.info("Running boundary scan test; cpu in reset...")
220
221 clk_period = 100 # 10MHz
222 tck_period = 300 # 3MHz
223
224 yield from setup_sim(dut, clk_period=clk_period, run=False)
225 jtag = yield from setup_jtag(dut, tck_period = tck_period)
226
227 yield from boundary_scan(dut, jtag=jtag)
228
229 dut._log.info("IDCODE test completed")
230
231 @cocotb.test()
232 def boundary_scan_run(dut):
233 dut._log.info("Running boundary scan test; cpu running...")
234
235 clk_period = 100 # 10MHz
236 tck_period = 300 # 3MHz
237
238 yield from setup_sim(dut, clk_period=clk_period, run=True)
239 jtag = yield from setup_jtag(dut, tck_period = tck_period)
240
241 yield from boundary_scan(dut, jtag=jtag)
242
243 dut._log.info("IDCODE test completed")
244
245
246 # demo / debug how to get boundary scan names. run "python3 test.py"
247 if __name__ == '__main__':
248 pinouts = get_jtag_boundary()
249 for pin in pinouts:
250 # example: ('eint', '2', <IOType.In: 1>, 'eint_2', 125)
251 print (pin)