sort out mess of trying to access the Pin resource instead of the pad
[pinmux.git] / src / spec / testing_stage1.py
index c0fbc8eb014ead96a710440f87ad8b3806834bd1..0ff5510d23d32a8eb0428026db047f9095cbe5a2 100644 (file)
@@ -144,7 +144,8 @@ def I2CResource(*args, scl, sda):
 
 # 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)
@@ -154,28 +155,54 @@ class Blinker(Elaboratable):
         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)
-        intermediary = Signal()
-        m.d.comb += uart.tx.eq(intermediary)
-        m.d.comb += intermediary.eq(uart.rx)
+        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)
 
         # to even be able to get at objects, you first have to make them
         # 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):
@@ -330,7 +357,7 @@ something random
 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:
@@ -378,7 +405,7 @@ if False:
 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))
@@ -387,11 +414,69 @@ def test_case0():
     print("top.gpio is a Record therefore has fields and a layout")
     print("    layout:", top.gpio.layout)
     print("    fields:", top.gpio.fields)
+    print("Fun never ends...")
+    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
-    yield top.gpio_0__gpio0__o__o.eq(0)
-    yield top.gpio_0__gpio0__o__core__o.eq(0)
-    yield top.gpio_0__gpio1__o.eq(0)
+    delayVal = 0.2e-6
+    yield top.uart.rx.eq(0)
+    yield Delay(delayVal)
+    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 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):
+        # 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()
+        # 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 Delay(delayVal)
+    yield Settle()   
 
 # Code borrowed from cesar, runs, but shouldn't actually work because of
 # self. statements and non-existent signal names.
@@ -424,6 +509,39 @@ def test_case1():
         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
 
@@ -432,8 +550,9 @@ sim.add_clock(1e-6, domain="sync")      # standard clock
 #sim.add_sync_process(wrap(jtag_sim(cdut, top.jtag))) # actual jtag tester
 #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_case1()))
+#sim.add_sync_process(wrap(test_case0()))
+sim.add_sync_process(wrap(test_gpios()))
 
 with sim.write_vcd("blinker_test.vcd"):
     sim.run()