Update the unit tests.
[c4m-jtag.git] / test / nmigen / cocotb / controller / test.py
1 import cocotb
2 from cocotb.utils import get_sim_steps
3 from cocotb.binary import BinaryValue
4 from cocotb.triggers import Timer, RisingEdge, ReadOnly
5 from cocotb.clock import Clock
6
7 from c4m.cocotb.jtag.c4m_jtag import JTAG_Master
8
9 from cocotbext.wishbone import WishboneBus
10
11
12 class WishboneMemory(object):
13 def __init__(self, bus):
14 self.bus = bus
15 self._mem = {}
16 self._adr_width = len(self.bus.adr)
17 self._dat_width = len(self.bus.datrd)
18 self._dat_x = BinaryValue(self._dat_width * "X")
19
20 @cocotb.coroutine
21 def start(self):
22 while True:
23 yield self.bus.clock_event
24 if self.bus.cyc.value and self.bus.stb.value:
25 adr = self.bus.adr.value.integer
26 # Immediately ack a cycle
27 self.bus.ack <= 1
28 if self.bus.we.value:
29 # Write
30 self._mem[adr] = self.bus.datwr.value
31 self.bus.datrd <= self._dat_x
32 else:
33 # Read
34 if adr in self._mem:
35 self.bus.datrd <= self._mem[adr]
36 else:
37 self.bus.datrd <= self._dat_x
38 else:
39 self.bus.ack <= 0
40 self.bus.datrd <= self._dat_x
41
42 def __repr__(self):
43 return "WishboneMemory: {!r}".format(self._mem)
44
45 @cocotb.test()
46 def test01_idcode(dut):
47 """
48 Test the IDCODE command
49 """
50
51 # Run @ 1MHz
52 clk_period = get_sim_steps(1, "us")
53 master = JTAG_Master(
54 dut.tap_bus__tck, dut.tap_bus__tms, dut.tap_bus__tdi, dut.tap_bus__tdo,
55 clk_period=clk_period, ir_width=3,
56 )
57
58 dut._log.info("Trying to get IDCODE...")
59
60 yield master.idcode()
61 result1 = master.result
62 dut._log.info("IDCODE1: {}".format(result1))
63
64 yield master.idcode()
65 result2 = master.result
66 dut._log.info("IDCODE2: {}".format(result2))
67
68 assert(result1 == result2)
69
70
71 @cocotb.test()
72 def test02_bypass(dut):
73 """
74 Test of BYPASS mode
75 """
76
77 # Run @ 1MHz
78 clk_period = get_sim_steps(1, "us")
79 master = JTAG_Master(
80 dut.tap_bus__tck, dut.tap_bus__tms, dut.tap_bus__tdi, dut.tap_bus__tdo,
81 clk_period=clk_period, ir_width=3,
82 )
83
84 dut._log.info("Loading BYPASS command")
85 yield master.load_ir(master.BYPASS)
86
87 data_in = BinaryValue()
88 data_in.binstr = "01001101"
89 dut._log.info(" Sending data: {}".format(data_in.binstr))
90 yield master.shift_data(data_in)
91
92 dut._log.info(" bypass out: {}".format(master.result.binstr))
93 assert(master.result.binstr[:-1] == data_in.binstr[1:])
94
95
96 @cocotb.test()
97 def test03_sample(dut):
98 """
99 Test of SAMPLEPRELOAD and EXTEST
100 """
101 data_in = BinaryValue()
102
103 dut.rst = 1
104 yield Timer(100, "ns")
105 dut.rst = 0
106
107 # Run @ 1MHz
108 clk_period = get_sim_steps(1, "us")
109 master = JTAG_Master(
110 dut.tap_bus__tck, dut.tap_bus__tms, dut.tap_bus__tdi, dut.tap_bus__tdo,
111 clk_period=clk_period, ir_width=3,
112 )
113
114
115 dut._log.info("Load SAMPLEPRELOAD command")
116 yield master.load_ir(master.SAMPLEPRELOAD)
117
118 data_in.binstr = "0100110"
119 dut._log.info(" preloading data {}".format(data_in.binstr))
120
121 # Set the ios pins
122 dut.ioconn0__pad__i = 1
123 dut.ioconn1__core__o = 0
124 dut.ioconn2__core__o = 1
125 dut.ioconn2__core__oe = 1
126 dut.ioconn3__pad__i = 0
127 dut.ioconn3__core__o = 0
128 dut.ioconn3__core__oe = 1
129 yield master.shift_data(data_in)
130 dut._log.info(" output: {}".format(master.result.binstr))
131 assert(master.result.binstr == "1011001")
132
133 assert dut.ioconn0__core__i == 1
134 assert dut.ioconn1__pad__o == 0
135 assert dut.ioconn2__pad__o == 1
136 assert dut.ioconn2__pad__oe == 1
137 assert dut.ioconn3__core__i == 0
138 assert dut.ioconn3__pad__o == 0
139 assert dut.ioconn3__pad__oe == 1
140
141 dut._log.info("Load EXTEST command")
142 yield master.load_ir(master.EXTEST)
143
144 assert dut.ioconn0__core__i == 0
145 assert dut.ioconn1__pad__o == 1
146 assert dut.ioconn2__pad__o == 0
147 assert dut.ioconn2__pad__oe == 0
148 assert dut.ioconn3__core__i == 1
149 assert dut.ioconn3__pad__o == 1
150 assert dut.ioconn3__pad__oe == 0
151
152 data_in.binstr = "1011001"
153 dut._log.info(" input data {}".format(data_in.binstr))
154
155 # Set the ios pins
156 dut.ioconn0__pad__i = 0
157 dut.ioconn1__core__o = 1
158 dut.ioconn2__core__o = 0
159 dut.ioconn2__core__oe = 0
160 dut.ioconn3__pad__i = 1
161 dut.ioconn3__core__o = 1
162 dut.ioconn3__core__oe = 0
163 yield master.shift_data(data_in)
164 dut._log.info(" output: {}".format(master.result.binstr))
165 assert(master.result.binstr == "0100110")
166
167 assert dut.ioconn0__core__i == 1
168 assert dut.ioconn1__pad__o == 0
169 assert dut.ioconn2__pad__o == 1
170 assert dut.ioconn2__pad__oe == 1
171 assert dut.ioconn3__core__i == 0
172 assert dut.ioconn3__pad__o == 0
173 assert dut.ioconn3__pad__oe == 1
174
175 yield master.reset()
176
177 assert dut.ioconn0__core__i == 0
178 assert dut.ioconn1__pad__o == 1
179 assert dut.ioconn2__pad__o == 0
180 assert dut.ioconn2__pad__oe == 0
181 assert dut.ioconn3__core__i == 1
182 assert dut.ioconn3__pad__o == 1
183 assert dut.ioconn3__pad__oe == 0
184
185
186 @cocotb.test()
187 def test04_shiftreg(dut):
188 """
189 Test of custom shiftreg
190 """
191 data_in = BinaryValue()
192 cmd_SR = BinaryValue("011")
193
194 # Run @ 1MHz
195 clk_period = get_sim_steps(1, "us")
196 master = JTAG_Master(
197 dut.tap_bus__tck, dut.tap_bus__tms, dut.tap_bus__tdi, dut.tap_bus__tdo,
198 clk_period=clk_period, ir_width=3,
199 )
200
201
202 dut._log.info("Load custom shiftreg command")
203 yield master.load_ir(cmd_SR)
204
205 data_in.binstr = "010"
206 dut._log.info(" input: {}".format(data_in.binstr))
207 yield master.shift_data(data_in)
208 dut._log.info(" output: {}".format(master.result.binstr))
209
210 data_in.binstr = "101"
211 dut._log.info(" input: {}".format(data_in.binstr))
212 yield master.shift_data(data_in)
213 dut._log.info(" output: {}".format(master.result.binstr))
214 assert master.result.binstr == "010"
215
216 @cocotb.test()
217 def test05_wishbone(dut):
218 """
219 Test of an added Wishbone interface
220 """
221 data_in = BinaryValue()
222 cmd_MEMADDRESS = BinaryValue("100")
223 cmd_MEMREAD = BinaryValue("101")
224 cmd_MEMREADWRITE = BinaryValue("110")
225
226 # Run JTAG @ 1MHz
227 jtagclk_period = get_sim_steps(1, "us")
228 master = JTAG_Master(
229 dut.tap_bus__tck, dut.tap_bus__tms, dut.tap_bus__tdi, dut.tap_bus__tdo,
230 clk_period=jtagclk_period, ir_width=3,
231 )
232 # Run main chip @ 10MHz; need to be clocked for Wishbone interface to function
233 cocotb.fork(Clock(dut.clk, 100, "ns").start())
234
235 # Add Wishbone memory on the bus
236 bus = WishboneBus(
237 entity=dut.tap, name="wb0", bus_separator="__", clock=dut.clk, reset=dut.rst,
238 signals={"datwr": "dat_w", "datrd": "dat_r"},
239 )
240 wbmem = WishboneMemory(bus)
241 cocotb.fork(wbmem.start())
242
243 # Load the memory address
244 yield master.load_ir(cmd_MEMADDRESS)
245 dut._log.info("Loading address")
246
247 data_in.binstr = "1100000000000000"
248 dut._log.info(" input: {}".format(data_in.binstr))
249 yield master.shift_data(data_in)
250 dut._log.info(" output: {}".format(master.result.binstr))
251
252 # Do write
253 yield master.load_ir(cmd_MEMREADWRITE)
254 dut._log.info("Writing memory")
255
256 data_in.binstr = "01010101"
257 dut._log.info(" input: {}".format(data_in.binstr))
258 yield master.shift_data(data_in)
259 dut._log.info(" output: {}".format(master.result.binstr))
260
261 data_in.binstr = "10101010"
262 dut._log.info(" input: {}".format(data_in.binstr))
263 yield master.shift_data(data_in)
264 dut._log.info(" output: {}".format(master.result.binstr))
265
266 # Load the memory address
267 yield master.load_ir(cmd_MEMADDRESS)
268 dut._log.info("Loading address")
269
270 data_in.binstr = "1100000000000000"
271 dut._log.info(" input: {}".format(data_in.binstr))
272 yield master.shift_data(data_in)
273 dut._log.info(" output: {}".format(master.result.binstr))
274 assert master.result.binstr == "1100000000000010"
275
276 # Do read and write
277 yield master.load_ir(cmd_MEMREADWRITE)
278 dut._log.info("Reading and writing memory")
279
280 data_in.binstr = "10101010"
281 dut._log.info(" input: {}".format(data_in.binstr))
282 yield master.shift_data(data_in)
283 dut._log.info(" output: {}".format(master.result.binstr))
284 assert master.result.binstr == "01010101"
285
286 data_in.binstr = "01010101"
287 dut._log.info(" input: {}".format(data_in.binstr))
288 yield master.shift_data(data_in)
289 dut._log.info(" output: {}".format(master.result.binstr))
290 assert master.result.binstr == "10101010"
291
292 # Load the memory address
293 yield master.load_ir(cmd_MEMADDRESS)
294 dut._log.info("Loading address")
295
296 data_in.binstr = "1100000000000000"
297 dut._log.info(" input: {}".format(data_in.binstr))
298 yield master.shift_data(data_in)
299 dut._log.info(" output: {}".format(master.result.binstr))
300 assert master.result.binstr == "1100000000000010"
301
302 # Do read
303 yield master.load_ir(cmd_MEMREAD)
304 dut._log.info("Reading memory")
305 data_in.binstr = "00000000"
306
307 dut._log.info(" input: {}".format(data_in.binstr))
308 yield master.shift_data(data_in)
309 dut._log.info(" output: {}".format(master.result.binstr))
310 assert master.result.binstr == "10101010"
311
312 dut._log.info(" input: {}".format(data_in.binstr))
313 yield master.shift_data(data_in)
314 dut._log.info(" output: {}".format(master.result.binstr))
315 assert master.result.binstr == "01010101"
316
317 # Load the memory address
318 yield master.load_ir(cmd_MEMADDRESS) # MEMADDR
319 dut._log.info("Loading address")
320
321 data_in.binstr = "1100000000000000"
322 dut._log.info(" input: {}".format(data_in.binstr))
323 yield master.shift_data(data_in)
324 dut._log.info(" output: {}".format(master.result.binstr))
325 assert master.result.binstr == "1100000000000010"
326
327 # Do read
328 yield master.load_ir(cmd_MEMREAD) # MEMREAD
329 dut._log.info("Reading memory")
330 data_in.binstr = "00000000"
331
332 dut._log.info(" input: {}".format(data_in.binstr))
333 yield master.shift_data(data_in)
334 dut._log.info(" output: {}".format(master.result.binstr))
335 assert master.result.binstr == "10101010"
336
337 dut._log.info(" input: {}".format(data_in.binstr))
338 yield master.shift_data(data_in)
339 dut._log.info(" output: {}".format(master.result.binstr))
340 assert master.result.binstr == "01010101"
341
342 dut._log.info("{!r}".format(wbmem))