remove code trying to treat Pins/Resources as Signals/Records (again)
[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_o_test = Signal(num_gpios)
172 gpio_oe_test = Signal(num_gpios)
173 # Wire up the output signal of each gpio by XOR'ing each bit of
174 # gpio_o_test with gpio's input
175 # Wire up each bit of gpio_oe_test signal to oe signal of each gpio.
176 # Turn into a loop at some point, probably a way without
177 # using get_attr()
178 m.d.comb += gpio.gpio0.o.eq(gpio_o_test[0] ^ gpio.gpio0.i)
179 m.d.comb += gpio.gpio1.o.eq(gpio_o_test[1] ^ gpio.gpio1.i)
180 m.d.comb += gpio.gpio2.o.eq(gpio_o_test[2] ^ gpio.gpio2.i)
181 m.d.comb += gpio.gpio3.o.eq(gpio_o_test[3] ^ gpio.gpio3.i)
182
183 m.d.comb += gpio.gpio0.oe.eq(gpio_oe_test[0])
184 m.d.comb += gpio.gpio1.oe.eq(gpio_oe_test[1])
185 m.d.comb += gpio.gpio2.oe.eq(gpio_oe_test[2])
186 m.d.comb += gpio.gpio3.oe.eq(gpio_oe_test[3])
187
188 # get the UART resource, mess with the output tx
189 uart = self.jtag.request('uart')
190 print ("uart fields", uart, uart.fields)
191 self.intermediary = Signal()
192 m.d.comb += uart.tx.eq(self.intermediary)
193 m.d.comb += self.intermediary.eq(uart.rx)
194
195 # to even be able to get at objects, you first have to make them
196 # available - i.e. not as local variables
197 self.gpio = gpio
198 self.uart = uart
199 self.gpio_o_test = gpio_o_test
200 self.gpio_oe_test = gpio_oe_test
201
202 # sigh these wire up to the pads so you cannot set Signals
203 # that are already wired
204 if self.no_jtag_connect: # bypass jtag pad connect for testing purposes
205 return m
206 return self.jtag.boundary_elaborate(m, platform)
207
208 def ports(self):
209 return list(self)
210
211 def __iter__(self):
212 yield from self.jtag.iter_ports()
213
214 '''
215 _trellis_command_templates = [
216 r"""
217 {{invoke_tool("yosys")}}
218 {{quiet("-q")}}
219 {{get_override("yosys_opts")|options}}
220 -l {{name}}.rpt
221 {{name}}.ys
222 """,
223 ]
224 '''
225
226 # sigh, have to create a dummy platform for now.
227 # TODO: investigate how the heck to get it to output ilang. or verilog.
228 # or, anything, really. but at least it doesn't barf
229 class ASICPlatform(TemplatedPlatform):
230 connectors = []
231 resources = OrderedDict()
232 required_tools = []
233 command_templates = ['/bin/true'] # no command needed: stops barfing
234 file_templates = {
235 **TemplatedPlatform.build_script_templates,
236 "{{name}}.il": r"""
237 # {{autogenerated}}
238 {{emit_rtlil()}}
239 """,
240 "{{name}}.debug.v": r"""
241 /* {{autogenerated}} */
242 {{emit_debug_verilog()}}
243 """,
244 }
245 toolchain = None
246 default_clk = "clk" # should be picked up / overridden by platform sys.clk
247 default_rst = "rst" # should be picked up / overridden by platform sys.rst
248
249 def __init__(self, resources, jtag):
250 self.jtag = jtag
251 super().__init__()
252
253 # create set of pin resources based on the pinset, this is for the core
254 #jtag_resources = self.jtag.pad_mgr.resources
255 self.add_resources(resources)
256
257 # add JTAG without scan
258 self.add_resources([JTAGResource('jtag', 0)], no_boundary_scan=True)
259
260 def add_resources(self, resources, no_boundary_scan=False):
261 print ("ASICPlatform add_resources", resources)
262 return super().add_resources(resources)
263
264 #def iter_ports(self):
265 # yield from super().iter_ports()
266 # for io in self.jtag.ios.values():
267 # print ("iter ports", io.layout, io)
268 # for field in io.core.fields:
269 # yield getattr(io.core, field)
270 # for field in io.pad.fields:
271 # yield getattr(io.pad, field)
272
273 # XXX these aren't strictly necessary right now but the next
274 # phase is to add JTAG Boundary Scan so it maaay be worth adding?
275 # at least for the print statements
276 def get_input(self, pin, port, attrs, invert):
277 self._check_feature("single-ended input", pin, attrs,
278 valid_xdrs=(0,), valid_attrs=None)
279
280 m = Module()
281 print (" get_input", pin, "port", port, port.layout)
282 m.d.comb += pin.i.eq(self._invert_if(invert, port))
283 return m
284
285 def get_output(self, pin, port, attrs, invert):
286 self._check_feature("single-ended output", pin, attrs,
287 valid_xdrs=(0,), valid_attrs=None)
288
289 m = Module()
290 print (" get_output", pin, "port", port, port.layout)
291 m.d.comb += port.eq(self._invert_if(invert, pin.o))
292 return m
293
294 def get_tristate(self, pin, port, attrs, invert):
295 self._check_feature("single-ended tristate", pin, attrs,
296 valid_xdrs=(0,), valid_attrs=None)
297
298 print (" get_tristate", pin, "port", port, port.layout)
299 m = Module()
300 print (" pad", pin, port, attrs)
301 print (" pin", pin.layout)
302 return m
303 # m.submodules += Instance("$tribuf",
304 # p_WIDTH=pin.width,
305 # i_EN=pin.oe,
306 # i_A=self._invert_if(invert, pin.o),
307 # o_Y=port,
308 # )
309 m.d.comb += io.core.o.eq(pin.o)
310 m.d.comb += io.core.oe.eq(pin.oe)
311 m.d.comb += pin.i.eq(io.core.i)
312 m.d.comb += io.pad.i.eq(port.i)
313 m.d.comb += port.o.eq(io.pad.o)
314 m.d.comb += port.oe.eq(io.pad.oe)
315 return m
316
317 def get_input_output(self, pin, port, attrs, invert):
318 self._check_feature("single-ended input/output", pin, attrs,
319 valid_xdrs=(0,), valid_attrs=None)
320
321 print (" get_input_output", pin, "port", port, port.layout)
322 m = Module()
323 print (" port layout", port.layout)
324 print (" pin", pin)
325 print (" layout", pin.layout)
326 #m.submodules += Instance("$tribuf",
327 # p_WIDTH=pin.width,
328 # i_EN=io.pad.oe,
329 # i_A=self._invert_if(invert, io.pad.o),
330 # o_Y=port,
331 #)
332 # Create aliases for the port sub-signals
333 port_i = port.io[0]
334 port_o = port.io[1]
335 port_oe = port.io[2]
336
337 m.d.comb += pin.i.eq(self._invert_if(invert, port_i))
338 m.d.comb += port_o.eq(self._invert_if(invert, pin.o))
339 m.d.comb += port_oe.eq(pin.oe)
340
341 return m
342
343 def toolchain_prepare(self, fragment, name, **kwargs):
344 """override toolchain_prepare in order to grab the fragment
345 """
346 self.fragment = fragment
347 return super().toolchain_prepare(fragment, name, **kwargs)
348
349
350
351 def test_case0():
352 print("Starting sanity test case!")
353 print("printing out list of stuff in top")
354 print ("JTAG IOs", top.jtag.ios)
355 # ok top now has a variable named "gpio", let's enumerate that too
356 print("printing out list of stuff in top.gpio and its type")
357 print(top.gpio.__class__.__name__, dir(top.gpio))
358 # ok, it's a nmigen Record, therefore it has a layout. let's print
359 # that too
360 print("top.gpio is a Record therefore has fields and a layout")
361 print(" layout:", top.gpio.layout)
362 print(" fields:", top.gpio.fields)
363 print("Fun never ends...")
364 print(" layout, gpio2:", top.gpio.layout['gpio2'])
365 print(" fields, gpio2:", top.gpio.fields['gpio2'])
366 print(top.jtag.__class__.__name__, dir(top.jtag))
367 print("Pads:")
368 print(top.jtag.resource_table_pads[('gpio', 0)])
369
370 # etc etc. you get the general idea
371 delayVal = 0.2e-6
372 yield top.uart.rx.eq(0)
373 yield Delay(delayVal)
374 yield Settle()
375 yield top.gpio.gpio2.o.eq(0)
376 yield top.gpio.gpio3.o.eq(1)
377 yield
378 yield top.gpio.gpio3.oe.eq(1)
379 yield
380 yield top.gpio.gpio3.oe.eq(0)
381 # grab the JTAG resource pad
382 gpios_pad = top.jtag.resource_table_pads[('gpio', 0)]
383 yield gpios_pad.gpio3.i.eq(1)
384 yield Delay(delayVal)
385 yield Settle()
386 yield top.gpio.gpio2.oe.eq(1)
387 yield top.gpio.gpio3.oe.eq(1)
388 yield gpios_pad.gpio3.i.eq(0)
389 yield top.jtag.gpio.gpio2.i.eq(1)
390 yield Delay(delayVal)
391 yield Settle()
392 gpio_o2 = 0
393 for _ in range(20):
394 # get a value first (as an integer). you were trying to set
395 # it to the actual Signal. this is not going to work. or if
396 # it does, it's very scary.
397 gpio_o2 = not gpio_o2
398 yield top.gpio.gpio2.o.eq(gpio_o2)
399
400 # ditto: here you are trying to set to an AST expression
401 # which is inadviseable (likely to fail)
402 gpio_o3 = not gpio_o2
403 yield top.gpio.gpio3.o.eq(gpio_o3)
404 yield Delay(delayVal)
405 yield Settle()
406 # grab the JTAG resource pad
407 uart_pad = top.jtag.resource_table_pads[('uart', 0)]
408 yield uart_pad.rx.i.eq(gpio_o2)
409 yield Delay(delayVal)
410 yield Settle()
411 yield # one clock cycle
412 tx_val = yield uart_pad.tx.o
413 print ("xmit uart", tx_val, gpio_o2)
414
415 print ("jtag pad table keys")
416 print (top.jtag.resource_table_pads.keys())
417 uart_pad = top.jtag.resource_table_pads[('uart', 0)]
418 print ("uart pad", uart_pad)
419 print ("uart pad", uart_pad.layout)
420
421 yield top.gpio.gpio2.oe.eq(0)
422 yield top.gpio.gpio3.oe.eq(0)
423 yield top.jtag.gpio.gpio2.i.eq(0)
424 yield Delay(delayVal)
425 yield Settle()
426
427 # Code borrowed from cesar, runs, but shouldn't actually work because of
428 # self. statements and non-existent signal names.
429 def test_case1():
430 print("Example test case")
431 yield Passive()
432 while True:
433 # Settle() is needed to give a quick response to
434 # the zero delay case
435 yield Settle()
436 # wait for rel_o to become active
437 while not (yield self.rel_o):
438 yield
439 yield Settle()
440 # read the transaction parameters
441 assert self.expecting, "an unexpected result was produced"
442 delay = (yield self.delay)
443 expected = (yield self.expected)
444 # wait for `delay` cycles
445 for _ in range(delay):
446 yield
447 # activate go_i for one cycle
448 yield self.go_i.eq(1)
449 yield self.count.eq(self.count + 1)
450 yield
451 # check received data against the expected value
452 result = (yield self.port)
453 assert result == expected,\
454 f"expected {expected}, received {result}"
455 yield self.go_i.eq(0)
456 yield self.port.eq(0)
457
458 def test_gpios():
459 print("Starting GPIO test case!")
460
461 num_gpios = top.gpio_o_test.width
462 # Grab GPIO outpud pad resource from JTAG BS - end of chain
463 print (top.jtag.boundary_scan_pads.keys())
464 gpio0_o = top.jtag.boundary_scan_pads['gpio_0__gpio0__o']['o']
465 gpio1_o = top.jtag.boundary_scan_pads['gpio_0__gpio1__o']['o']
466 gpio2_o = top.jtag.boundary_scan_pads['gpio_0__gpio2__o']['o']
467 gpio3_o = top.jtag.boundary_scan_pads['gpio_0__gpio3__o']['o']
468
469 # Grab GPIO input pad resource from JTAG BS - start of chain
470 gpio0_pad_in = top.jtag.boundary_scan_pads['gpio_0__gpio0__i']['i']
471 gpio1_pad_in = top.jtag.boundary_scan_pads['gpio_0__gpio1__i']['i']
472 gpio2_pad_in = top.jtag.boundary_scan_pads['gpio_0__gpio2__i']['i']
473 gpio3_pad_in = top.jtag.boundary_scan_pads['gpio_0__gpio3__i']['i']
474 #pad_in = [gpio0_pad_in gpio1_pad_in gpio2_pad_in gpio3_pad_in]
475
476 # temp test
477 # no: already told you, these are never going to work
478 print ("printing out info about the resource gpio0")
479 print (top.gpio['gpio0']['i'])
480 print ("this is a PIN resource", type(top.gpio['gpio0']['i']))
481 # yield can only be done on SIGNALS or RECORDS,
482 # NOT Pins/Resources gpio0_core_in = yield top.gpio['gpio0']['i']
483 #print("Test gpio0 core in: ", gpio0_core_in)
484
485 #print("JTAG")
486 #print(top.jtag.__class__.__name__, dir(top.jtag))
487 #print("TOP")
488 #print(top.__class__.__name__, dir(top))
489 #print("PORT")
490 #print(top.ports.__class__.__name__, dir(top.ports))
491 #print("GPIO")
492 #print(top.gpio.__class__.__name__, dir(top.gpio))
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 print("Num of permutations of gpio_o_test record: ", num_gpio_o_states)
503 for gpio_o_val in range(0, num_gpio_o_states):
504 yield top.gpio_o_test.eq(gpio_o_val)
505 yield Settle()
506 yield # Move to the next clk cycle
507
508 # yield the pad output
509 pad0_out = yield gpio0_o
510 pad1_out = yield gpio1_o
511 pad2_out = yield gpio2_o
512 pad3_out = yield gpio3_o
513 print("Applied values:", bin(gpio_o_val), "Seeing",
514 pad3_out, pad2_out, pad1_out, pad0_out)
515 # Test without asserting input
516 # gpio_o_val is a 4-bit binary number setting each pad (single-bit)
517 assert ((gpio_o_val & 0b0001) != 0) == pad0_out
518 assert ((gpio_o_val & 0b0010) != 0) == pad1_out
519 assert ((gpio_o_val & 0b0100) != 0) == pad2_out
520 assert ((gpio_o_val & 0b1000) != 0) == pad3_out
521 # Test with input asserted
522 test_in = 1
523 yield gpio0_pad_in.eq(test_in)
524 # don't need this *and* a yield of 1 clock cycle yield Settle()
525 yield
526
527 # after changing the gpio0 input, the output is also going to
528 # change. *therefore it must be read again* to get the
529 # snapshot (as a python value)
530 pad0_out = yield gpio0_o
531 pad1_out = yield gpio1_o
532 pad2_out = yield gpio2_o
533 pad3_out = yield gpio3_o
534 print("Applied test_in=1 with values:", bin(gpio_o_val), "Seeing",
535 pad3_out, pad2_out, pad1_out, pad0_out)
536 # Trying to read input from core side, looks like might be a pin...
537 # XXX don't "look like" - don't guess - *print it out*
538 print ("don't guess, CHECK", type(top.gpio.gpio0.i))
539 #temp_in = yield top.gpio.gpio0.i
540 #print("Core input ", temp_in, temp_in==test_in)
541 #print((gpio_o_val & 0b0001) == 1)
542 #print(((gpio_o_val & 0b0001) == 1) ^ test_in)
543 assert (((gpio_o_val & 0b0001) != 0) ^ test_in) == pad0_out
544 test_in = 0
545 yield gpio0_pad_in.eq(test_in)
546 print () # extra print to divide the output
547
548 # Another for loop to run through gpio_oe_test. Assert:
549 # + oe set at core matches oe seen at pad.
550 # TODO
551
552 if __name__ == '__main__':
553 """
554 and to create a Platform instance with that list, and build
555 something random
556
557 p=Platform()
558 p.resources=listofstuff
559 p.build(Blinker())
560 """
561 pinset = dummy_pinset()
562 print(pinset)
563 resources = create_resources(pinset)
564 top = Blinker(pinset, resources, no_jtag_connect=False)#True)
565
566 vl = rtlil.convert(top, ports=top.ports())
567 with open("test_jtag_blinker.il", "w") as f:
568 f.write(vl)
569
570 if False:
571 # XXX these modules are all being added *AFTER* the build process links
572 # everything together. the expectation that this would work is...
573 # unrealistic. ordering, clearly, is important.
574
575 # dut = JTAG(test_pinset(), wb_data_wid=64, domain="sync")
576 top.jtag.stop = False
577 # rather than the client access the JTAG bus directly
578 # create an alternative that the client sets
579 class Dummy: pass
580 cdut = Dummy()
581 cdut.cbus = JTAGInterface()
582
583 # set up client-server on port 44843-something
584 top.jtag.s = JTAGServer()
585 cdut.c = JTAGClient()
586 top.jtag.s.get_connection()
587 #else:
588 # print ("running server only as requested,
589 # use openocd remote to test")
590 # sys.stdout.flush()
591 # top.jtag.s.get_connection(None) # block waiting for connection
592
593 # take copy of ir_width and scan_len
594 cdut._ir_width = top.jtag._ir_width
595 cdut.scan_len = top.jtag.scan_len
596
597 p = ASICPlatform (resources, top.jtag)
598 p.build(top)
599 # this is what needs to gets treated as "top", after "main module" top
600 # is augmented with IO pads with JTAG tacked on. the expectation that
601 # the get_input() etc functions will be called magically by some other
602 # function is unrealistic.
603 top_fragment = p.fragment
604
605 # XXX simulating top (the module that does not itself contain IO pads
606 # because that's covered by build) cannot possibly be expected to work
607 # particularly when modules have been added *after* the platform build()
608 # function has been called.
609
610 sim = Simulator(top)
611 sim.add_clock(1e-6, domain="sync") # standard clock
612
613 #sim.add_sync_process(wrap(jtag_srv(top))) #? jtag server
614 #if len(sys.argv) != 2 or sys.argv[1] != 'server':
615 # actual jtag tester
616 #sim.add_sync_process(wrap(jtag_sim(cdut, top.jtag)))
617 # handles (pretends to be) DMI
618 #sim.add_sync_process(wrap(dmi_sim(top.jtag)))
619
620 #sim.add_sync_process(wrap(test_case1()))
621 #sim.add_sync_process(wrap(test_case0()))
622 sim.add_sync_process(wrap(test_gpios()))
623
624 with sim.write_vcd("blinker_test.vcd"):
625 sim.run()