# top-level demo module.
class Blinker(Elaboratable):
- def __init__(self, pinset, resources):
+ def __init__(self, pinset, resources, no_jtag_connect=False):
+ self.no_jtag_connect = no_jtag_connect
self.jtag = JTAG({}, "sync", resources=resources)
#memory = Memory(width=32, depth=16)
#self.sram = SRAM(memory=memory, bus=self.jtag.wb)
m = Module()
m.submodules.jtag = self.jtag
#m.submodules.sram = self.sram
-
- count = Signal(5)
- m.d.sync += count.eq(count+1)
+
+ #count = Signal(5)
+ #m.d.sync += count.eq(count+1)
print ("resources", platform, jtag_resources.items())
gpio = self.jtag.request('gpio')
print (gpio, gpio.layout, gpio.fields)
# get the GPIO bank, mess about with some of the pins
- m.d.comb += gpio.gpio0.o.eq(1)
- m.d.comb += gpio.gpio1.o.eq(gpio.gpio2.i)
- m.d.comb += gpio.gpio1.oe.eq(count[4])
- m.d.sync += count[0].eq(gpio.gpio1.i)
+ #m.d.comb += gpio.gpio0.o.eq(1)
+ #m.d.comb += gpio.gpio1.o.eq(gpio.gpio2.i)
+ #m.d.comb += gpio.gpio1.oe.eq(count[4])
+ #m.d.sync += count[0].eq(gpio.gpio1.i)
+
+ num_gpios = 4
+ gpio_o_test = Signal(num_gpios)
+ gpio_oe_test = Signal(num_gpios)
+ # Wire up the output signal of each gpio by XOR'ing each bit of
+ # gpio_o_test with gpio's input
+ # Wire up each bit of gpio_oe_test signal to oe signal of each gpio.
+ # Turn into a loop at some point, probably a way without
+ # using get_attr()
+ m.d.comb += gpio.gpio0.o.eq(gpio_o_test[0] ^ gpio.gpio0.i)
+ m.d.comb += gpio.gpio1.o.eq(gpio_o_test[1] ^ gpio.gpio1.i)
+ m.d.comb += gpio.gpio2.o.eq(gpio_o_test[2] ^ gpio.gpio2.i)
+ m.d.comb += gpio.gpio3.o.eq(gpio_o_test[3] ^ gpio.gpio3.i)
+
+ m.d.comb += gpio.gpio0.oe.eq(gpio_oe_test[0])
+ m.d.comb += gpio.gpio1.oe.eq(gpio_oe_test[1])
+ m.d.comb += gpio.gpio2.oe.eq(gpio_oe_test[2])
+ m.d.comb += gpio.gpio3.oe.eq(gpio_oe_test[3])
+
# get the UART resource, mess with the output tx
uart = self.jtag.request('uart')
- print (uart, uart.fields)
+ print ("uart fields", uart, uart.fields)
self.intermediary = Signal()
m.d.comb += uart.tx.eq(self.intermediary)
m.d.comb += self.intermediary.eq(uart.rx)
# available - i.e. not as local variables
self.gpio = gpio
self.uart = uart
+ self.gpio_o_test = gpio_o_test
+ self.gpio_oe_test = gpio_oe_test
+ # sigh these wire up to the pads so you cannot set Signals
+ # that are already wired
+ if self.no_jtag_connect: # bypass jtag pad connect for testing purposes
+ return m
return self.jtag.boundary_elaborate(m, platform)
def ports(self):
pinset = dummy_pinset()
print(pinset)
resources = create_resources(pinset)
-top = Blinker(pinset, resources)
+top = Blinker(pinset, resources, no_jtag_connect=False)#True)
vl = rtlil.convert(top, ports=top.ports())
with open("test_jtag_blinker.il", "w") as f:
def test_case0():
print("Starting sanity test case!")
print("printing out list of stuff in top")
- print(dir(top))
+ print ("JTAG IOs", top.jtag.ios)
# ok top now has a variable named "gpio", let's enumerate that too
print("printing out list of stuff in top.gpio and its type")
print(top.gpio.__class__.__name__, dir(top.gpio))
print(" layout, gpio2:", top.gpio.layout['gpio2'])
print(" fields, gpio2:", top.gpio.fields['gpio2'])
print(top.jtag.__class__.__name__, dir(top.jtag))
+ print("Pads:")
+ print(top.jtag.resource_table_pads[('gpio', 0)])
# etc etc. you get the general idea
delayVal = 0.2e-6
yield Settle()
yield top.gpio.gpio2.o.eq(0)
yield top.gpio.gpio3.o.eq(1)
+ yield
+ yield top.gpio.gpio3.oe.eq(1)
+ yield
+ yield top.gpio.gpio3.oe.eq(0)
+ # grab the JTAG resource pad
+ gpios_pad = top.jtag.resource_table_pads[('gpio', 0)]
+ yield gpios_pad.gpio3.i.eq(1)
yield Delay(delayVal)
yield Settle()
yield top.gpio.gpio2.oe.eq(1)
yield top.gpio.gpio3.oe.eq(1)
- #yield top.jtag.gpio.gpio2.i.eq(1)
+ yield gpios_pad.gpio3.i.eq(0)
+ yield top.jtag.gpio.gpio2.i.eq(1)
yield Delay(delayVal)
yield Settle()
+ gpio_o2 = 0
for _ in range(20):
- yield top.gpio.gpio2.o.eq(~top.gpio.gpio2.o)
- yield top.gpio.gpio3.o.eq(~top.gpio.gpio3.o)
+ # get a value first (as an integer). you were trying to set
+ # it to the actual Signal. this is not going to work. or if
+ # it does, it's very scary.
+ gpio_o2 = not gpio_o2
+ yield top.gpio.gpio2.o.eq(gpio_o2)
+
+ # ditto: here you are trying to set to an AST expression
+ # which is inadviseable (likely to fail)
+ gpio_o3 = not gpio_o2
+ yield top.gpio.gpio3.o.eq(gpio_o3)
yield Delay(delayVal)
yield Settle()
- yield top.uart.rx.eq(~top.intermediary)
+ # grab the JTAG resource pad
+ uart_pad = top.jtag.resource_table_pads[('uart', 0)]
+ yield uart_pad.rx.i.eq(gpio_o2)
yield Delay(delayVal)
yield Settle()
+ yield # one clock cycle
+ tx_val = yield uart_pad.tx.o
+ print ("xmit uart", tx_val, gpio_o2)
+ print ("jtag pad table keys")
+ print (top.jtag.resource_table_pads.keys())
+ uart_pad = top.jtag.resource_table_pads[('uart', 0)]
+ print ("uart pad", uart_pad)
+ print ("uart pad", uart_pad.layout)
+
yield top.gpio.gpio2.oe.eq(0)
yield top.gpio.gpio3.oe.eq(0)
- #yield top.jtag.gpio.gpio2.i.eq(0)
+ yield top.jtag.gpio.gpio2.i.eq(0)
yield Delay(delayVal)
- yield Settle()
+ yield Settle()
# Code borrowed from cesar, runs, but shouldn't actually work because of
# self. statements and non-existent signal names.
yield self.go_i.eq(0)
yield self.port.eq(0)
+def test_gpios():
+ print("Starting GPIO test case!")
+ # Grab GPIO pad resource from JTAG BS
+ print (top.jtag.boundary_scan_pads.keys())
+ gpio0_o = top.jtag.boundary_scan_pads['gpio_0__gpio0__o']['o']
+ gpio1_o = top.jtag.boundary_scan_pads['gpio_0__gpio1__o']['o']
+
+ # Have the sim run through a for-loop where the gpio_o_test is
+ # incremented like a counter (0000, 0001...)
+ # At each iteration of the for-loop, assert:
+ # + output set at core matches output seen at pad
+ # TODO + input set at pad matches input seen at core
+ # TODO + if gpio_o_test bit is cleared, output seen at pad matches
+ # input seen at pad
+ num_gpio_o_states = top.gpio_o_test.width**2
+ print("Num of permutations of gpio_o_test record: ", num_gpio_o_states)
+ for gpio_o_val in range(0, num_gpio_o_states):
+ yield top.gpio_o_test.eq(gpio_o_val)
+ yield Settle()
+ yield # Move to the next clk cycle
+
+ # yield the pad output
+ pad0_out = yield gpio0_o
+ pad1_out = yield gpio1_o
+ print("gpio0", gpio0_o, bin(gpio_o_val), pad0_out, pad1_out)
+ # gpio_o_val is a 4-bit binary number setting each pad (single-bit)
+ assert ((gpio_o_val & 0b0001) != 0) == pad0_out
+ assert ((gpio_o_val & 0b0010) != 0) == pad1_out
+
+ # Another for loop to run through gpio_oe_test. Assert:
+ # + oe set at core matches oe seen at pad.
+ # TODO
+
sim = Simulator(top)
sim.add_clock(1e-6, domain="sync") # standard clock
#sim.add_sync_process(wrap(dmi_sim(top.jtag))) # handles (pretends to be) DMI
#sim.add_sync_process(wrap(test_case1()))
-sim.add_sync_process(wrap(test_case0()))
+#sim.add_sync_process(wrap(test_case0()))
+sim.add_sync_process(wrap(test_gpios()))
with sim.write_vcd("blinker_test.vcd"):
sim.run()