get access to jtag boundary scan pads for uart_0_tx/rx
[pinmux.git] / src / spec / testing_stage1.py
index efc8335050283baebcd1255bceab83bf7ae0a82a..fe5143179b3139b50e199b76b980116486ca3408 100644 (file)
@@ -168,8 +168,17 @@ class Blinker(Elaboratable):
         #m.d.sync += count[0].eq(gpio.gpio1.i)
        
         num_gpios = 4
+        gpio_i_ro = Signal(num_gpios)
         gpio_o_test = Signal(num_gpios)
         gpio_oe_test = Signal(num_gpios)
+
+        # Create a read-only copy of core-side GPIO input signals 
+        # for Simulation asserts
+        m.d.comb += gpio_i_ro[0].eq(gpio.gpio0.i)
+        m.d.comb += gpio_i_ro[1].eq(gpio.gpio1.i)
+        m.d.comb += gpio_i_ro[2].eq(gpio.gpio2.i)
+        m.d.comb += gpio_i_ro[3].eq(gpio.gpio3.i)
+
         # 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. 
@@ -192,10 +201,28 @@ class Blinker(Elaboratable):
         m.d.comb += uart.tx.eq(self.intermediary)
         m.d.comb += self.intermediary.eq(uart.rx)
 
+        # I2C
+        num_i2c = 1
+        i2c_sda_oe_test = Signal(num_i2c)
+        i2c_scl_oe_test = Signal(num_i2c)
+        i2c = self.jtag.request('i2c')
+        print ("i2c fields", i2c, i2c.fields)
+        # Connect in loopback
+        m.d.comb += i2c.scl.o.eq(i2c.scl.i)
+        m.d.comb += i2c.sda.o.eq(i2c.sda.i)
+        # Connect output enable to test port for sim
+        m.d.comb += i2c.sda.oe.eq(i2c_sda_oe_test)
+        m.d.comb += i2c.scl.oe.eq(i2c_scl_oe_test)
+
         # to even be able to get at objects, you first have to make them
         # available - i.e. not as local variables
+        # Public attributes are equivalent to input/output ports in hdl's
         self.gpio = gpio
         self.uart = uart
+        self.i2c = i2c
+        self.i2c_sda_oe_test = i2c_sda_oe_test
+        self.i2c_scl_oe_test = i2c_scl_oe_test
+        self.gpio_i_ro = gpio_i_ro
         self.gpio_o_test = gpio_o_test
         self.gpio_oe_test = gpio_oe_test
 
@@ -465,13 +492,21 @@ def test_gpios():
     gpio1_o = top.jtag.boundary_scan_pads['gpio_0__gpio1__o']['o']
     gpio2_o = top.jtag.boundary_scan_pads['gpio_0__gpio2__o']['o']
     gpio3_o = top.jtag.boundary_scan_pads['gpio_0__gpio3__o']['o']
+    gpio_pad_out = [ gpio0_o, gpio1_o, gpio2_o, gpio3_o]
+
+    # Grab GPIO output enable pad resource from JTAG BS - end of chain
+    gpio0_oe = top.jtag.boundary_scan_pads['gpio_0__gpio0__oe']['o']
+    gpio1_oe = top.jtag.boundary_scan_pads['gpio_0__gpio1__oe']['o']
+    gpio2_oe = top.jtag.boundary_scan_pads['gpio_0__gpio2__oe']['o']
+    gpio3_oe = top.jtag.boundary_scan_pads['gpio_0__gpio3__oe']['o']
+    gpio_pad_oe = [gpio0_oe, gpio1_oe, gpio2_oe, gpio3_oe]
 
     # Grab GPIO input pad resource from JTAG BS - start of chain
     gpio0_pad_in = top.jtag.boundary_scan_pads['gpio_0__gpio0__i']['i']
     gpio1_pad_in = top.jtag.boundary_scan_pads['gpio_0__gpio1__i']['i']
     gpio2_pad_in = top.jtag.boundary_scan_pads['gpio_0__gpio2__i']['i']
     gpio3_pad_in = top.jtag.boundary_scan_pads['gpio_0__gpio3__i']['i']
-    #pad_in = [gpio0_pad_in gpio1_pad_in gpio2_pad_in gpio3_pad_in]
+    gpio_pad_in = [gpio0_pad_in, gpio1_pad_in, gpio2_pad_in, gpio3_pad_in]
     
     # Have the sim run through a for-loop where the gpio_o_test is 
     # incremented like a counter (0000, 0001...)
@@ -481,41 +516,171 @@ def test_gpios():
     # TODO + if gpio_o_test bit is cleared, output seen at pad matches 
     # input seen at pad
     num_gpio_o_states = num_gpios**2
-    print("Num of permutations of gpio_o_test record: ", num_gpio_o_states)
+    pad_out = [0] * num_gpios
+    pad_oe = [0] * num_gpios
+    #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 Settle()
         yield # Move to the next clk cycle
-
-        # yield the pad output
-        pad0_out = yield gpio0_o
-        pad1_out = yield gpio1_o
-        pad2_out = yield gpio2_o
-        pad3_out = yield gpio3_o
-        print("Applied values:", bin(gpio_o_val), "Seeing", 
-              pad3_out, pad2_out, pad1_out, pad0_out)
-        # Test without asserting input
-        # 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
-        assert ((gpio_o_val & 0b0100) != 0) == pad2_out
-        assert ((gpio_o_val & 0b1000) != 0) == pad3_out
-        # Test with input asserted
-        test_in = 1
-        yield gpio0_pad_in.eq(test_in)
+        
+        # Cycle through all input combinations
+        for gpio_i_val in range(0, num_gpio_o_states):
+            # Set each gpio input at pad to test value
+            for gpio_bit in range(0, num_gpios):
+                yield gpio_pad_in[gpio_bit].eq((gpio_i_val >> gpio_bit) & 0x1)
+            yield
+            # After changing the gpio0/1/2/3 inputs,
+            # the output is also going to change.
+            # *therefore it must be read again* to get the
+            # snapshot (as a python value)
+            for gpio_bit in range(0, num_gpios):
+                pad_out[gpio_bit] = yield gpio_pad_out[gpio_bit]
+            yield
+            for gpio_bit in range(0, num_gpios):
+                # check core and pad in
+                gpio_i_ro = yield top.gpio_i_ro[gpio_bit]
+                out_test_bit = ((gpio_o_val & (1 << gpio_bit)) != 0)
+                in_bit = ((gpio_i_val & (1 << gpio_bit)) != 0)
+                # Check that the core end input matches pad 
+                assert in_bit == gpio_i_ro
+                # Test that the output at pad matches:
+                # Pad output == given test output XOR test input
+                assert (out_test_bit ^ in_bit) == pad_out[gpio_bit]
+            
+            # For debugging - VERY verbose
+            #print("---------------------")
+            #print("Test Out: ", bin(gpio_o_val))
+            #print("Test Input: ", bin(gpio_i_val)) 
+            # Print MSB first
+            #print("Pad Output: ", list(reversed(pad_out)))
+            #print("---------------------")
+        
+    # For-loop for testing output enable signals
+    for gpio_o_val in range(0, num_gpio_o_states):
+        yield top.gpio_oe_test.eq(gpio_o_val) 
+        yield # Move to the next clk cycle
+        
+        for gpio_bit in range(0, num_gpios):
+            pad_oe[gpio_bit] = yield gpio_pad_oe[gpio_bit]
+        yield 
+
+        for gpio_bit in range(0, num_gpios):
+            oe_test_bit = ((gpio_o_val & (1 << gpio_bit)) != 0)
+            # oe set at core matches oe seen at pad:
+            assert oe_test_bit == pad_oe[gpio_bit]
+        # For debugging - VERY verbose
+        #print("---------------------")
+        #print("Test Output Enable: ", bin(gpio_o_val))
+        # Print MSB first
+        #print("Pad Output Enable: ", list(reversed(pad_oe)))
+        #print("---------------------") 
+    print("GPIO Test PASSED!")
+
+def test_uart():
+    # grab the JTAG resource pad
+    print ()
+    print ("bs pad keys", top.jtag.boundary_scan_pads.keys())
+    print ()
+    uart_rx_pad = top.jtag.boundary_scan_pads['uart_0__rx']['i']
+    uart_tx_pad = top.jtag.boundary_scan_pads['uart_0__tx']['o']
+
+    print ("uart rx pad", uart_rx_pad)
+    print ("uart tx pad", uart_tx_pad)
+
+    # Test UART by writing 0 and 1 to RX
+    # Internally TX connected to RX,
+    # so match pad TX with RX
+    for i in range(0, 2):
+        yield uart_rx_pad.eq(i)
+        #yield uart_rx_pad.eq(i)
         yield Settle()
-        yield
-        temp_in = yield top.gpio.gpio0.i
-        print("Core input ", temp_in, temp_in==test_in) 
-        print((gpio_o_val & 0b0001) == 1) 
-        #print(((gpio_o_val & 0b0001) == 1) ^ test_in) 
-        #assert (((gpio_o_val & 0b0001) != 0) ^ test_in) == pad0_out
-        test_in = 0
-        yield gpio0_pad_in.eq(test_in)
-
-    # Another for loop to run through gpio_oe_test. Assert:
-    # + oe set at core matches oe seen at pad.
-    # TODO
+        yield # one clock cycle
+        tx_val = yield uart_tx_pad
+        print ("xmit uart", tx_val, 1)
+        assert tx_val == i
+
+    print("UART Test PASSED!")
+
+def test_i2c():
+    i2c_sda_i_pad = top.jtag.boundary_scan_pads['i2c_0__sda__i']['i']
+    i2c_sda_o_pad = top.jtag.boundary_scan_pads['i2c_0__sda__o']['o']
+    i2c_sda_oe_pad = top.jtag.boundary_scan_pads['i2c_0__sda__oe']['o']
+
+    i2c_scl_i_pad = top.jtag.boundary_scan_pads['i2c_0__scl__i']['i']
+    i2c_scl_o_pad = top.jtag.boundary_scan_pads['i2c_0__scl__o']['o']
+    i2c_scl_oe_pad = top.jtag.boundary_scan_pads['i2c_0__scl__oe']['o']
+
+    #i2c_pad = top.jtag.resource_table_pads[('i2c', 0)]
+    #print ("i2c pad", i2c_pad)
+    #print ("i2c pad", i2c_pad.layout)
+
+    for i in range(0, 2):
+        yield i2c_sda_i_pad.eq(i) #i2c_pad.sda.i.eq(i)
+        yield i2c_scl_i_pad.eq(i) #i2c_pad.scl.i.eq(i)
+        yield top.i2c_sda_oe_test.eq(i)
+        yield top.i2c_scl_oe_test.eq(i)
+        yield Settle()
+        yield # one clock cycle
+        sda_o_val = yield i2c_sda_o_pad
+        scl_o_val = yield i2c_scl_o_pad
+        sda_oe_val = yield i2c_sda_oe_pad
+        scl_oe_val = yield i2c_scl_oe_pad
+        print ("Test input: ", i, " SDA/SCL out: ", sda_o_val, scl_o_val,
+               " SDA/SCL oe: ", sda_oe_val, scl_oe_val)
+        assert sda_o_val == i
+        assert scl_o_val == i
+        assert sda_oe_val == i
+        assert scl_oe_val == i
+
+    print("I2C Test PASSED!")
+
+
+
+def test_debug_print():
+    print("Test used for getting object methods/information")
+    print("Moved here to clear clutter of gpio test")
+    
+    print ("printing out info about the resource gpio0")
+    print (top.gpio['gpio0']['i'])
+    print ("this is a PIN resource", type(top.gpio['gpio0']['i']))
+    # yield can only be done on SIGNALS or RECORDS,
+    # NOT Pins/Resources gpio0_core_in = yield top.gpio['gpio0']['i']
+    #print("Test gpio0 core in: ", gpio0_core_in)
+    
+    print("JTAG")
+    print(top.jtag.__class__.__name__, dir(top.jtag))
+    print("TOP")
+    print(top.__class__.__name__, dir(top))
+    print("PORT")
+    print(top.ports.__class__.__name__, dir(top.ports))
+    print("GPIO")
+    print(top.gpio.__class__.__name__, dir(top.gpio))
+   
+    print("UART")
+    print(dir(top.jtag.boundary_scan_pads['uart_0__rx__pad__i']))
+    print(top.jtag.boundary_scan_pads['uart_0__rx__pad__i'].keys())
+    print(top.jtag.boundary_scan_pads['uart_0__tx__pad__o'])
+    #print(type(top.jtag.boundary_scan_pads['uart_0__rx__pad__i']['rx']))
+    print ("jtag pad table keys")
+    print (top.jtag.resource_table_pads.keys())
+    print(type(top.jtag.resource_table_pads[('uart', 0)].rx.i))
+    print(top.jtag.boundary_scan_pads['uart_0__rx__i'])
+
+    print("I2C")
+    print(top.jtag.boundary_scan_pads['i2c_0__sda__i'])
+    print(type(top.jtag.boundary_scan_pads['i2c_0__sda__i']['i']))
+
+    print(top.jtag.resource_table_pads)
+    print(top.jtag.boundary_scan_pads)
+
+
+    # Trying to read input from core side, looks like might be a pin...
+    # XXX don't "look like" - don't guess - *print it out*
+    #print ("don't guess, CHECK", type(top.gpio.gpio0.i))
+    
+    print () # extra print to divide the output
+    yield
 
 if __name__ == '__main__':
     """
@@ -587,7 +752,11 @@ if __name__ == '__main__':
     
     #sim.add_sync_process(wrap(test_case1()))
     #sim.add_sync_process(wrap(test_case0()))
-    sim.add_sync_process(wrap(test_gpios()))
+    
+    #sim.add_sync_process(wrap(test_gpios()))
+    sim.add_sync_process(wrap(test_uart()))
+    sim.add_sync_process(wrap(test_i2c()))
+    #sim.add_sync_process(wrap(test_debug_print()))
 
     with sim.write_vcd("blinker_test.vcd"):
         sim.run()