Starting to write UART test
[pinmux.git] / src / spec / testing_stage1.py
1 #!/usr/bin/env python3
2 """
3 pinmux documented here https://libre-soc.org/docs/pinmux/
4 """
5 from nmigen.build.dsl import Resource, Subsignal, Pins
6 from nmigen.build.plat import TemplatedPlatform
7 from nmigen.build.res import ResourceManager, ResourceError
8 from nmigen.hdl.rec import Layout
9 from nmigen import Elaboratable, Signal, Module, Instance
10 from collections import OrderedDict
11 from jtag import JTAG, resiotypes
12 from copy import deepcopy
13 from nmigen.cli import rtlil
14 import sys
15
16 # extra dependencies for jtag testing (?)
17 #from soc.bus.sram import SRAM
18
19 #from nmigen import Memory
20 from nmigen.sim import Simulator, Delay, Settle, Tick, Passive
21
22 from nmutil.util import wrap
23
24 #from soc.debug.jtagutils import (jtag_read_write_reg,
25 # jtag_srv, jtag_set_reset,
26 # jtag_set_ir, jtag_set_get_dr)
27
28 from c4m.nmigen.jtag.tap import TAP, IOType
29 from c4m.nmigen.jtag.bus import Interface as JTAGInterface
30 #from soc.debug.dmi import DMIInterface, DBGCore
31 #from soc.debug.test.dmi_sim import dmi_sim
32 #from soc.debug.test.jtagremote import JTAGServer, JTAGClient
33 from nmigen.build.res import ResourceError
34
35 # Was thinking of using these functions, but skipped for simplicity for now
36 # XXX nope. the output from JSON file.
37 #from pinfunctions import (i2s, lpc, emmc, sdmmc, mspi, mquadspi, spi,
38 # quadspi, i2c, mi2c, jtag, uart, uartfull, rgbttl, ulpi, rgmii, flexbus1,
39 # flexbus2, sdram1, sdram2, sdram3, vss, vdd, sys, eint, pwm, gpio)
40
41 # File for stage 1 pinmux tested proposed by Luke,
42 # https://bugs.libre-soc.org/show_bug.cgi?id=50#c10
43
44
45 def dummy_pinset():
46 # sigh this needs to come from pinmux.
47 gpios = []
48 for i in range(4):
49 gpios.append("%d*" % i)
50 return {'uart': ['tx+', 'rx-'],
51 'gpio': gpios,
52 #'jtag': ['tms-', 'tdi-', 'tdo+', 'tck+'],
53 'i2c': ['sda*', 'scl+']}
54
55 """
56 a function is needed which turns the results of dummy_pinset()
57 into:
58
59 [UARTResource("uart", 0, tx=..., rx=..),
60 I2CResource("i2c", 0, scl=..., sda=...),
61 Resource("gpio", 0, Subsignal("i"...), Subsignal("o"...)
62 Resource("gpio", 1, Subsignal("i"...), Subsignal("o"...)
63 ...
64 ]
65 """
66
67
68 def create_resources(pinset):
69 resources = []
70 for periph, pins in pinset.items():
71 print(periph, pins)
72 if periph == 'i2c':
73 #print("I2C required!")
74 resources.append(I2CResource('i2c', 0, sda='sda', scl='scl'))
75 elif periph == 'uart':
76 #print("UART required!")
77 resources.append(UARTResource('uart', 0, tx='tx', rx='rx'))
78 elif periph == 'gpio':
79 #print("GPIO required!")
80 print ("GPIO is defined as '*' type, meaning i, o and oe needed")
81 ios = []
82 for pin in pins:
83 pname = "gpio"+pin[:-1] # strip "*" on end
84 # urrrr... tristsate and io assume a single pin which is
85 # of course exactly what we don't want in an ASIC: we want
86 # *all three* pins but the damn port is not outputted
87 # as a triplet, it's a single Record named "io". sigh.
88 # therefore the only way to get a triplet of i/o/oe
89 # is to *actually* create explicit triple pins
90 # XXX ARRRGH, doesn't work
91 #pad = Subsignal("io",
92 # Pins("%s_i %s_o %s_oe" % (pname, pname, pname),
93 # dir="io", assert_width=3))
94 #ios.append(Resource(pname, 0, pad))
95 pads = []
96 pads.append(Subsignal("i",
97 Pins(pname+"_i", dir="i", assert_width=1)))
98 pads.append(Subsignal("o",
99 Pins(pname+"_o", dir="o", assert_width=1)))
100 pads.append(Subsignal("oe",
101 Pins(pname+"_oe", dir="o", assert_width=1)))
102 ios.append(Resource.family(pname, 0, default_name=pname,
103 ios=pads))
104 resources.append(Resource.family(periph, 0, default_name="gpio",
105 ios=ios))
106
107 # add clock and reset
108 clk = Resource("clk", 0, Pins("sys_clk", dir="i"))
109 rst = Resource("rst", 0, Pins("sys_rst", dir="i"))
110 resources.append(clk)
111 resources.append(rst)
112 return resources
113
114
115 def JTAGResource(*args):
116 io = []
117 io.append(Subsignal("tms", Pins("tms", dir="i", assert_width=1)))
118 io.append(Subsignal("tdi", Pins("tdi", dir="i", assert_width=1)))
119 io.append(Subsignal("tck", Pins("tck", dir="i", assert_width=1)))
120 io.append(Subsignal("tdo", Pins("tdo", dir="o", assert_width=1)))
121 return Resource.family(*args, default_name="jtag", ios=io)
122
123 def UARTResource(*args, rx, tx):
124 io = []
125 io.append(Subsignal("rx", Pins(rx, dir="i", assert_width=1)))
126 io.append(Subsignal("tx", Pins(tx, dir="o", assert_width=1)))
127 return Resource.family(*args, default_name="uart", ios=io)
128
129
130 def I2CResource(*args, scl, sda):
131 ios = []
132 pads = []
133 pads.append(Subsignal("i", Pins(sda+"_i", dir="i", assert_width=1)))
134 pads.append(Subsignal("o", Pins(sda+"_o", dir="o", assert_width=1)))
135 pads.append(Subsignal("oe", Pins(sda+"_oe", dir="o", assert_width=1)))
136 ios.append(Resource.family(sda, 0, default_name=sda, ios=pads))
137 pads = []
138 pads.append(Subsignal("i", Pins(scl+"_i", dir="i", assert_width=1)))
139 pads.append(Subsignal("o", Pins(scl+"_o", dir="o", assert_width=1)))
140 pads.append(Subsignal("oe", Pins(scl+"_oe", dir="o", assert_width=1)))
141 ios.append(Resource.family(scl, 0, default_name=scl, ios=pads))
142 return Resource.family(*args, default_name="i2c", ios=ios)
143
144
145 # top-level demo module.
146 class Blinker(Elaboratable):
147 def __init__(self, pinset, resources, no_jtag_connect=False):
148 self.no_jtag_connect = no_jtag_connect
149 self.jtag = JTAG({}, "sync", resources=resources)
150 #memory = Memory(width=32, depth=16)
151 #self.sram = SRAM(memory=memory, bus=self.jtag.wb)
152
153 def elaborate(self, platform):
154 jtag_resources = self.jtag.pad_mgr.resources
155 m = Module()
156 m.submodules.jtag = self.jtag
157 #m.submodules.sram = self.sram
158
159 #count = Signal(5)
160 #m.d.sync += count.eq(count+1)
161 print ("resources", platform, jtag_resources.items())
162 gpio = self.jtag.request('gpio')
163 print (gpio, gpio.layout, gpio.fields)
164 # get the GPIO bank, mess about with some of the pins
165 #m.d.comb += gpio.gpio0.o.eq(1)
166 #m.d.comb += gpio.gpio1.o.eq(gpio.gpio2.i)
167 #m.d.comb += gpio.gpio1.oe.eq(count[4])
168 #m.d.sync += count[0].eq(gpio.gpio1.i)
169
170 num_gpios = 4
171 gpio_i_ro = Signal(num_gpios)
172 gpio_o_test = Signal(num_gpios)
173 gpio_oe_test = Signal(num_gpios)
174
175 # Create a read-only copy of core-side GPIO input signals
176 # for Simulation asserts
177 m.d.comb += gpio_i_ro[0].eq(gpio.gpio0.i)
178 m.d.comb += gpio_i_ro[1].eq(gpio.gpio1.i)
179 m.d.comb += gpio_i_ro[2].eq(gpio.gpio2.i)
180 m.d.comb += gpio_i_ro[3].eq(gpio.gpio3.i)
181
182 # Wire up the output signal of each gpio by XOR'ing each bit of
183 # gpio_o_test with gpio's input
184 # Wire up each bit of gpio_oe_test signal to oe signal of each gpio.
185 # Turn into a loop at some point, probably a way without
186 # using get_attr()
187 m.d.comb += gpio.gpio0.o.eq(gpio_o_test[0] ^ gpio.gpio0.i)
188 m.d.comb += gpio.gpio1.o.eq(gpio_o_test[1] ^ gpio.gpio1.i)
189 m.d.comb += gpio.gpio2.o.eq(gpio_o_test[2] ^ gpio.gpio2.i)
190 m.d.comb += gpio.gpio3.o.eq(gpio_o_test[3] ^ gpio.gpio3.i)
191
192 m.d.comb += gpio.gpio0.oe.eq(gpio_oe_test[0])
193 m.d.comb += gpio.gpio1.oe.eq(gpio_oe_test[1])
194 m.d.comb += gpio.gpio2.oe.eq(gpio_oe_test[2])
195 m.d.comb += gpio.gpio3.oe.eq(gpio_oe_test[3])
196
197 # get the UART resource, mess with the output tx
198 uart = self.jtag.request('uart')
199 print ("uart fields", uart, uart.fields)
200 self.intermediary = Signal()
201 m.d.comb += uart.tx.eq(self.intermediary)
202 m.d.comb += self.intermediary.eq(uart.rx)
203
204 # to even be able to get at objects, you first have to make them
205 # available - i.e. not as local variables
206 self.gpio = gpio
207 self.uart = uart
208 self.gpio_i_ro = gpio_i_ro
209 self.gpio_o_test = gpio_o_test
210 self.gpio_oe_test = gpio_oe_test
211
212 # sigh these wire up to the pads so you cannot set Signals
213 # that are already wired
214 if self.no_jtag_connect: # bypass jtag pad connect for testing purposes
215 return m
216 return self.jtag.boundary_elaborate(m, platform)
217
218 def ports(self):
219 return list(self)
220
221 def __iter__(self):
222 yield from self.jtag.iter_ports()
223
224 '''
225 _trellis_command_templates = [
226 r"""
227 {{invoke_tool("yosys")}}
228 {{quiet("-q")}}
229 {{get_override("yosys_opts")|options}}
230 -l {{name}}.rpt
231 {{name}}.ys
232 """,
233 ]
234 '''
235
236 # sigh, have to create a dummy platform for now.
237 # TODO: investigate how the heck to get it to output ilang. or verilog.
238 # or, anything, really. but at least it doesn't barf
239 class ASICPlatform(TemplatedPlatform):
240 connectors = []
241 resources = OrderedDict()
242 required_tools = []
243 command_templates = ['/bin/true'] # no command needed: stops barfing
244 file_templates = {
245 **TemplatedPlatform.build_script_templates,
246 "{{name}}.il": r"""
247 # {{autogenerated}}
248 {{emit_rtlil()}}
249 """,
250 "{{name}}.debug.v": r"""
251 /* {{autogenerated}} */
252 {{emit_debug_verilog()}}
253 """,
254 }
255 toolchain = None
256 default_clk = "clk" # should be picked up / overridden by platform sys.clk
257 default_rst = "rst" # should be picked up / overridden by platform sys.rst
258
259 def __init__(self, resources, jtag):
260 self.jtag = jtag
261 super().__init__()
262
263 # create set of pin resources based on the pinset, this is for the core
264 #jtag_resources = self.jtag.pad_mgr.resources
265 self.add_resources(resources)
266
267 # add JTAG without scan
268 self.add_resources([JTAGResource('jtag', 0)], no_boundary_scan=True)
269
270 def add_resources(self, resources, no_boundary_scan=False):
271 print ("ASICPlatform add_resources", resources)
272 return super().add_resources(resources)
273
274 #def iter_ports(self):
275 # yield from super().iter_ports()
276 # for io in self.jtag.ios.values():
277 # print ("iter ports", io.layout, io)
278 # for field in io.core.fields:
279 # yield getattr(io.core, field)
280 # for field in io.pad.fields:
281 # yield getattr(io.pad, field)
282
283 # XXX these aren't strictly necessary right now but the next
284 # phase is to add JTAG Boundary Scan so it maaay be worth adding?
285 # at least for the print statements
286 def get_input(self, pin, port, attrs, invert):
287 self._check_feature("single-ended input", pin, attrs,
288 valid_xdrs=(0,), valid_attrs=None)
289
290 m = Module()
291 print (" get_input", pin, "port", port, port.layout)
292 m.d.comb += pin.i.eq(self._invert_if(invert, port))
293 return m
294
295 def get_output(self, pin, port, attrs, invert):
296 self._check_feature("single-ended output", pin, attrs,
297 valid_xdrs=(0,), valid_attrs=None)
298
299 m = Module()
300 print (" get_output", pin, "port", port, port.layout)
301 m.d.comb += port.eq(self._invert_if(invert, pin.o))
302 return m
303
304 def get_tristate(self, pin, port, attrs, invert):
305 self._check_feature("single-ended tristate", pin, attrs,
306 valid_xdrs=(0,), valid_attrs=None)
307
308 print (" get_tristate", pin, "port", port, port.layout)
309 m = Module()
310 print (" pad", pin, port, attrs)
311 print (" pin", pin.layout)
312 return m
313 # m.submodules += Instance("$tribuf",
314 # p_WIDTH=pin.width,
315 # i_EN=pin.oe,
316 # i_A=self._invert_if(invert, pin.o),
317 # o_Y=port,
318 # )
319 m.d.comb += io.core.o.eq(pin.o)
320 m.d.comb += io.core.oe.eq(pin.oe)
321 m.d.comb += pin.i.eq(io.core.i)
322 m.d.comb += io.pad.i.eq(port.i)
323 m.d.comb += port.o.eq(io.pad.o)
324 m.d.comb += port.oe.eq(io.pad.oe)
325 return m
326
327 def get_input_output(self, pin, port, attrs, invert):
328 self._check_feature("single-ended input/output", pin, attrs,
329 valid_xdrs=(0,), valid_attrs=None)
330
331 print (" get_input_output", pin, "port", port, port.layout)
332 m = Module()
333 print (" port layout", port.layout)
334 print (" pin", pin)
335 print (" layout", pin.layout)
336 #m.submodules += Instance("$tribuf",
337 # p_WIDTH=pin.width,
338 # i_EN=io.pad.oe,
339 # i_A=self._invert_if(invert, io.pad.o),
340 # o_Y=port,
341 #)
342 # Create aliases for the port sub-signals
343 port_i = port.io[0]
344 port_o = port.io[1]
345 port_oe = port.io[2]
346
347 m.d.comb += pin.i.eq(self._invert_if(invert, port_i))
348 m.d.comb += port_o.eq(self._invert_if(invert, pin.o))
349 m.d.comb += port_oe.eq(pin.oe)
350
351 return m
352
353 def toolchain_prepare(self, fragment, name, **kwargs):
354 """override toolchain_prepare in order to grab the fragment
355 """
356 self.fragment = fragment
357 return super().toolchain_prepare(fragment, name, **kwargs)
358
359
360
361 def test_case0():
362 print("Starting sanity test case!")
363 print("printing out list of stuff in top")
364 print ("JTAG IOs", top.jtag.ios)
365 # ok top now has a variable named "gpio", let's enumerate that too
366 print("printing out list of stuff in top.gpio and its type")
367 print(top.gpio.__class__.__name__, dir(top.gpio))
368 # ok, it's a nmigen Record, therefore it has a layout. let's print
369 # that too
370 print("top.gpio is a Record therefore has fields and a layout")
371 print(" layout:", top.gpio.layout)
372 print(" fields:", top.gpio.fields)
373 print("Fun never ends...")
374 print(" layout, gpio2:", top.gpio.layout['gpio2'])
375 print(" fields, gpio2:", top.gpio.fields['gpio2'])
376 print(top.jtag.__class__.__name__, dir(top.jtag))
377 print("Pads:")
378 print(top.jtag.resource_table_pads[('gpio', 0)])
379
380 # etc etc. you get the general idea
381 delayVal = 0.2e-6
382 yield top.uart.rx.eq(0)
383 yield Delay(delayVal)
384 yield Settle()
385 yield top.gpio.gpio2.o.eq(0)
386 yield top.gpio.gpio3.o.eq(1)
387 yield
388 yield top.gpio.gpio3.oe.eq(1)
389 yield
390 yield top.gpio.gpio3.oe.eq(0)
391 # grab the JTAG resource pad
392 gpios_pad = top.jtag.resource_table_pads[('gpio', 0)]
393 yield gpios_pad.gpio3.i.eq(1)
394 yield Delay(delayVal)
395 yield Settle()
396 yield top.gpio.gpio2.oe.eq(1)
397 yield top.gpio.gpio3.oe.eq(1)
398 yield gpios_pad.gpio3.i.eq(0)
399 yield top.jtag.gpio.gpio2.i.eq(1)
400 yield Delay(delayVal)
401 yield Settle()
402 gpio_o2 = 0
403 for _ in range(20):
404 # get a value first (as an integer). you were trying to set
405 # it to the actual Signal. this is not going to work. or if
406 # it does, it's very scary.
407 gpio_o2 = not gpio_o2
408 yield top.gpio.gpio2.o.eq(gpio_o2)
409
410 # ditto: here you are trying to set to an AST expression
411 # which is inadviseable (likely to fail)
412 gpio_o3 = not gpio_o2
413 yield top.gpio.gpio3.o.eq(gpio_o3)
414 yield Delay(delayVal)
415 yield Settle()
416 # grab the JTAG resource pad
417 uart_pad = top.jtag.resource_table_pads[('uart', 0)]
418 yield uart_pad.rx.i.eq(gpio_o2)
419 yield Delay(delayVal)
420 yield Settle()
421 yield # one clock cycle
422 tx_val = yield uart_pad.tx.o
423 print ("xmit uart", tx_val, gpio_o2)
424
425 print ("jtag pad table keys")
426 print (top.jtag.resource_table_pads.keys())
427 uart_pad = top.jtag.resource_table_pads[('uart', 0)]
428 print ("uart pad", uart_pad)
429 print ("uart pad", uart_pad.layout)
430
431 yield top.gpio.gpio2.oe.eq(0)
432 yield top.gpio.gpio3.oe.eq(0)
433 yield top.jtag.gpio.gpio2.i.eq(0)
434 yield Delay(delayVal)
435 yield Settle()
436
437 # Code borrowed from cesar, runs, but shouldn't actually work because of
438 # self. statements and non-existent signal names.
439 def test_case1():
440 print("Example test case")
441 yield Passive()
442 while True:
443 # Settle() is needed to give a quick response to
444 # the zero delay case
445 yield Settle()
446 # wait for rel_o to become active
447 while not (yield self.rel_o):
448 yield
449 yield Settle()
450 # read the transaction parameters
451 assert self.expecting, "an unexpected result was produced"
452 delay = (yield self.delay)
453 expected = (yield self.expected)
454 # wait for `delay` cycles
455 for _ in range(delay):
456 yield
457 # activate go_i for one cycle
458 yield self.go_i.eq(1)
459 yield self.count.eq(self.count + 1)
460 yield
461 # check received data against the expected value
462 result = (yield self.port)
463 assert result == expected,\
464 f"expected {expected}, received {result}"
465 yield self.go_i.eq(0)
466 yield self.port.eq(0)
467
468 def test_gpios():
469 print("Starting GPIO test case!")
470
471 num_gpios = top.gpio_o_test.width
472 # Grab GPIO outpud pad resource from JTAG BS - end of chain
473 print (top.jtag.boundary_scan_pads.keys())
474 gpio0_o = top.jtag.boundary_scan_pads['gpio_0__gpio0__o']['o']
475 gpio1_o = top.jtag.boundary_scan_pads['gpio_0__gpio1__o']['o']
476 gpio2_o = top.jtag.boundary_scan_pads['gpio_0__gpio2__o']['o']
477 gpio3_o = top.jtag.boundary_scan_pads['gpio_0__gpio3__o']['o']
478 gpio_pad_out = [ gpio0_o, gpio1_o, gpio2_o, gpio3_o]
479
480 # Grab GPIO output enable pad resource from JTAG BS - end of chain
481 gpio0_oe = top.jtag.boundary_scan_pads['gpio_0__gpio0__oe']['o']
482 gpio1_oe = top.jtag.boundary_scan_pads['gpio_0__gpio1__oe']['o']
483 gpio2_oe = top.jtag.boundary_scan_pads['gpio_0__gpio2__oe']['o']
484 gpio3_oe = top.jtag.boundary_scan_pads['gpio_0__gpio3__oe']['o']
485 gpio_pad_oe = [gpio0_oe, gpio1_oe, gpio2_oe, gpio3_oe]
486
487 # Grab GPIO input pad resource from JTAG BS - start of chain
488 gpio0_pad_in = top.jtag.boundary_scan_pads['gpio_0__gpio0__i']['i']
489 gpio1_pad_in = top.jtag.boundary_scan_pads['gpio_0__gpio1__i']['i']
490 gpio2_pad_in = top.jtag.boundary_scan_pads['gpio_0__gpio2__i']['i']
491 gpio3_pad_in = top.jtag.boundary_scan_pads['gpio_0__gpio3__i']['i']
492 gpio_pad_in = [gpio0_pad_in, gpio1_pad_in, gpio2_pad_in, gpio3_pad_in]
493
494 # Have the sim run through a for-loop where the gpio_o_test is
495 # incremented like a counter (0000, 0001...)
496 # At each iteration of the for-loop, assert:
497 # + output set at core matches output seen at pad
498 # TODO + input set at pad matches input seen at core
499 # TODO + if gpio_o_test bit is cleared, output seen at pad matches
500 # input seen at pad
501 num_gpio_o_states = num_gpios**2
502 pad_out = [0] * num_gpios
503 pad_oe = [0] * num_gpios
504 #print("Num of permutations of gpio_o_test record: ", num_gpio_o_states)
505 for gpio_o_val in range(0, num_gpio_o_states):
506 yield top.gpio_o_test.eq(gpio_o_val)
507 #yield Settle()
508 yield # Move to the next clk cycle
509
510 # Cycle through all input combinations
511 for gpio_i_val in range(0, num_gpio_o_states):
512 # Set each gpio input at pad to test value
513 for gpio_bit in range(0, num_gpios):
514 yield gpio_pad_in[gpio_bit].eq((gpio_i_val >> gpio_bit) & 0x1)
515 yield
516 # After changing the gpio0/1/2/3 inputs,
517 # the output is also going to change.
518 # *therefore it must be read again* to get the
519 # snapshot (as a python value)
520 for gpio_bit in range(0, num_gpios):
521 pad_out[gpio_bit] = yield gpio_pad_out[gpio_bit]
522 yield
523 for gpio_bit in range(0, num_gpios):
524 # check core and pad in
525 gpio_i_ro = yield top.gpio_i_ro[gpio_bit]
526 out_test_bit = ((gpio_o_val & (1 << gpio_bit)) != 0)
527 in_bit = ((gpio_i_val & (1 << gpio_bit)) != 0)
528 # Check that the core end input matches pad
529 assert in_bit == gpio_i_ro
530 # Test that the output at pad matches:
531 # Pad output == given test output XOR test input
532 assert (out_test_bit ^ in_bit) == pad_out[gpio_bit]
533
534 # For debugging - VERY verbose
535 #print("---------------------")
536 #print("Test Out: ", bin(gpio_o_val))
537 #print("Test Input: ", bin(gpio_i_val))
538 # Print MSB first
539 #print("Pad Output: ", list(reversed(pad_out)))
540 #print("---------------------")
541
542 # For-loop for testing output enable signals
543 for gpio_o_val in range(0, num_gpio_o_states):
544 yield top.gpio_oe_test.eq(gpio_o_val)
545 yield # Move to the next clk cycle
546
547 for gpio_bit in range(0, num_gpios):
548 pad_oe[gpio_bit] = yield gpio_pad_oe[gpio_bit]
549 yield
550
551 for gpio_bit in range(0, num_gpios):
552 oe_test_bit = ((gpio_o_val & (1 << gpio_bit)) != 0)
553 # oe set at core matches oe seen at pad:
554 assert oe_test_bit == pad_oe[gpio_bit]
555 # For debugging - VERY verbose
556 #print("---------------------")
557 #print("Test Output Enable: ", bin(gpio_o_val))
558 # Print MSB first
559 #print("Pad Output Enable: ", list(reversed(pad_oe)))
560 #print("---------------------")
561 print("GPIO Test PASSED!")
562
563 def test_uart():
564 # write a zero
565 # read rx
566 # match rx==tx
567 # write a one
568 # read rx
569 # match rx==tx
570
571 # grab the JTAG resource pad
572 uart_pad = top.jtag.resource_table_pads[('uart', 0)]
573 yield uart_pad.rx.i.eq(1)
574 yield Settle()
575 yield # one clock cycle
576
577 tx_val = yield uart_pad.tx.o
578 print ("xmit uart", tx_val, 1)
579 # check core matches pad
580 assert tx_val == 1
581
582 print ("jtag pad table keys")
583 print (top.jtag.resource_table_pads.keys())
584 uart_pad = top.jtag.resource_table_pads[('uart', 0)]
585 print ("uart pad", uart_pad)
586 print ("uart pad", uart_pad.layout)
587
588
589 #uart_pad_rx = yield top.jtag.boundary_scan_pads['uart_0__tx__pad__i']['i']
590 #yield uart_pad_rx.eq(0)
591 #yield Settle()
592 #yield
593 print(top.jtag.boundary_scan_pads['uart_0__tx__pad__o'])
594 #uart_pad_tx = yield top.jtag.boundary_scan_pads['uart_0__tx__pad__o']['o']
595 #assert uart_pad_tx == 0
596 #yield top.intermediary.eq(1)
597 #yield Settle()
598 #yield
599
600
601 def test_debug_print():
602 print("Test used for getting object methods/information")
603 print("Moved here to clear clutter of gpio test")
604
605 print ("printing out info about the resource gpio0")
606 print (top.gpio['gpio0']['i'])
607 print ("this is a PIN resource", type(top.gpio['gpio0']['i']))
608 # yield can only be done on SIGNALS or RECORDS,
609 # NOT Pins/Resources gpio0_core_in = yield top.gpio['gpio0']['i']
610 #print("Test gpio0 core in: ", gpio0_core_in)
611
612 print("JTAG")
613 print(top.jtag.__class__.__name__, dir(top.jtag))
614 print("TOP")
615 print(top.__class__.__name__, dir(top))
616 print("PORT")
617 print(top.ports.__class__.__name__, dir(top.ports))
618 print("GPIO")
619 print(top.gpio.__class__.__name__, dir(top.gpio))
620
621 print("UART")
622 print(dir(top.jtag.boundary_scan_pads['uart_0__rx__pad__i']))
623 print(top.jtag.boundary_scan_pads['uart_0__rx__pad__i'].keys())
624 #print(type(top.jtag.boundary_scan_pads['uart_0__rx__pad__i']['rx']))
625
626 # Trying to read input from core side, looks like might be a pin...
627 # XXX don't "look like" - don't guess - *print it out*
628 #print ("don't guess, CHECK", type(top.gpio.gpio0.i))
629
630 print () # extra print to divide the output
631 yield
632
633 if __name__ == '__main__':
634 """
635 and to create a Platform instance with that list, and build
636 something random
637
638 p=Platform()
639 p.resources=listofstuff
640 p.build(Blinker())
641 """
642 pinset = dummy_pinset()
643 print(pinset)
644 resources = create_resources(pinset)
645 top = Blinker(pinset, resources, no_jtag_connect=False)#True)
646
647 vl = rtlil.convert(top, ports=top.ports())
648 with open("test_jtag_blinker.il", "w") as f:
649 f.write(vl)
650
651 if False:
652 # XXX these modules are all being added *AFTER* the build process links
653 # everything together. the expectation that this would work is...
654 # unrealistic. ordering, clearly, is important.
655
656 # dut = JTAG(test_pinset(), wb_data_wid=64, domain="sync")
657 top.jtag.stop = False
658 # rather than the client access the JTAG bus directly
659 # create an alternative that the client sets
660 class Dummy: pass
661 cdut = Dummy()
662 cdut.cbus = JTAGInterface()
663
664 # set up client-server on port 44843-something
665 top.jtag.s = JTAGServer()
666 cdut.c = JTAGClient()
667 top.jtag.s.get_connection()
668 #else:
669 # print ("running server only as requested,
670 # use openocd remote to test")
671 # sys.stdout.flush()
672 # top.jtag.s.get_connection(None) # block waiting for connection
673
674 # take copy of ir_width and scan_len
675 cdut._ir_width = top.jtag._ir_width
676 cdut.scan_len = top.jtag.scan_len
677
678 p = ASICPlatform (resources, top.jtag)
679 p.build(top)
680 # this is what needs to gets treated as "top", after "main module" top
681 # is augmented with IO pads with JTAG tacked on. the expectation that
682 # the get_input() etc functions will be called magically by some other
683 # function is unrealistic.
684 top_fragment = p.fragment
685
686 # XXX simulating top (the module that does not itself contain IO pads
687 # because that's covered by build) cannot possibly be expected to work
688 # particularly when modules have been added *after* the platform build()
689 # function has been called.
690
691 sim = Simulator(top)
692 sim.add_clock(1e-6, domain="sync") # standard clock
693
694 #sim.add_sync_process(wrap(jtag_srv(top))) #? jtag server
695 #if len(sys.argv) != 2 or sys.argv[1] != 'server':
696 # actual jtag tester
697 #sim.add_sync_process(wrap(jtag_sim(cdut, top.jtag)))
698 # handles (pretends to be) DMI
699 #sim.add_sync_process(wrap(dmi_sim(top.jtag)))
700
701 #sim.add_sync_process(wrap(test_case1()))
702 #sim.add_sync_process(wrap(test_case0()))
703
704 sim.add_sync_process(wrap(test_gpios()))
705 sim.add_sync_process(wrap(test_uart()))
706 #sim.add_sync_process(wrap(test_debug_print()))
707
708 with sim.write_vcd("blinker_test.vcd"):
709 sim.run()