add first cut at wishbone jtag unit test
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 6 Apr 2021 14:38:31 +0000 (15:38 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 6 Apr 2021 14:38:31 +0000 (15:38 +0100)
ls180/pre_pnr/README.md
ls180/pre_pnr/test.py

index 0f06209536d1dae3eb17a3b48c2161e6fd7cd8fb..142f8955e789851c17fb83ecaf50b0793c88947c 100644 (file)
@@ -9,6 +9,9 @@ simulators, run scripts are provided that call the Makefile:
 # Dependency
 
 * cocotb: `pip install cocotb`
+* cocotb-bus: git clone https://github.com/cocotb/cocotb-bus/
+  then "python3 setup.py develop"
+* cocotbext
 * c4m-jtag: install according to HDL workflow
 * iverilog: `apt install iverilog`
 * `../libresoc.v`, `../ls180.v`: run `make ls180_verilog` in soc directory,
index 9e6b77c7c5ff344b4f91a4019979ece2da58b958..4c4d722893c44634e10ca0d6be7f975c3270fbcf 100644 (file)
@@ -13,6 +13,7 @@ from c4m.cocotb.jtag.c4m_jtag_svfcocotb import SVF_Executor
 from soc.config.pinouts import get_pinspecs
 from soc.debug.jtag import Pins
 
+
 #
 # Helper functions
 #
@@ -158,7 +159,7 @@ def execute_svf(wrap, *, jtag, svf_filename):
     with open(svf_filename, "r") as f:
         svf_deck = f.read()
     yield jtag_svf.run(svf_deck, p=wrap.info)
-    
+
 #
 # IDCODE using JTAG_master
 #
@@ -299,6 +300,126 @@ def boundary_scan_run(dut):
     wrap.info("IDCODE test completed")
 
 
+@cocotb.test()
+def test05_wishbone(dut):
+    """
+    Test of an added Wishbone interface
+    """
+    data_in = BinaryValue()
+    # these have to match with soc.debug.jtag.JTAG ircodes
+    cmd_MEMADDRESS = BinaryValue("0101")    # 5
+    cmd_MEMREAD = BinaryValue("0110")       # 6
+    cmd_MEMREADWRITE = BinaryValue("0111")  # 7
+
+    # Run JTAG @ 1MHz
+    jtagclk_period = get_sim_steps(1, "us")
+    master = JTAG_Master(
+        dut.tap_bus__tck, dut.tap_bus__tms, dut.tap_bus__tdi, dut.tap_bus__tdo,
+        clk_period=jtagclk_period, ir_width=3,
+    )
+    # Run main chip @ 10MHz; need to be clocked for WB interface to function
+    cocotb.fork(Clock(dut.clk, 100, "ns").start())
+
+    # Load the memory address
+    yield master.load_ir(cmd_MEMADDRESS)
+    dut._log.info("Loading address")
+
+    data_in.binstr = "00000000000000000000000000001"
+    dut._log.info("  input: {}".format(data_in.binstr))
+    yield master.shift_data(data_in)
+    dut._log.info("  output: {}".format(master.result.binstr))
+
+    # Do write
+    yield master.load_ir(cmd_MEMREADWRITE)
+    dut._log.info("Writing memory")
+
+    data_in.binstr = "01010101"
+    dut._log.info("  input: {}".format(data_in.binstr))
+    yield master.shift_data(data_in)
+    dut._log.info("  output: {}".format(master.result.binstr))
+
+    data_in.binstr = "10101010"
+    dut._log.info("  input: {}".format(data_in.binstr))
+    yield master.shift_data(data_in)
+    dut._log.info("  output: {}".format(master.result.binstr))
+
+    # Load the memory address
+    yield master.load_ir(cmd_MEMADDRESS)
+    dut._log.info("Loading address")
+
+    data_in.binstr = "00000000000000000000000000001"
+    dut._log.info("  input: {}".format(data_in.binstr))
+    yield master.shift_data(data_in)
+    dut._log.info("  output: {}".format(master.result.binstr))
+    assert master.result.binstr == "1100000000000010"
+
+    # Do read and write
+    yield master.load_ir(cmd_MEMREADWRITE)
+    dut._log.info("Reading and writing memory")
+
+    data_in.binstr = "10101010" * 8
+    dut._log.info("  input: {}".format(data_in.binstr))
+    yield master.shift_data(data_in)
+    dut._log.info("  output: {}".format(master.result.binstr))
+    assert master.result.binstr == "01010101" * 8
+
+    data_in.binstr = "01010101" * 8
+    dut._log.info("  input: {}".format(data_in.binstr))
+    yield master.shift_data(data_in)
+    dut._log.info("  output: {}".format(master.result.binstr))
+    assert master.result.binstr == "10101010" * 8
+
+    # Load the memory address
+    yield master.load_ir(cmd_MEMADDRESS)
+    dut._log.info("Loading address")
+
+    data_in.binstr = "00000000000000000000000000001"
+    dut._log.info("  input: {}".format(data_in.binstr))
+    yield master.shift_data(data_in)
+    dut._log.info("  output: {}".format(master.result.binstr))
+    assert master.result.binstr == "1100000000000010"
+
+    # Do read
+    yield master.load_ir(cmd_MEMREAD)
+    dut._log.info("Reading memory")
+    data_in.binstr = "00000000" * 8
+
+    dut._log.info("  input: {}".format(data_in.binstr))
+    yield master.shift_data(data_in)
+    dut._log.info("  output: {}".format(master.result.binstr))
+    assert master.result.binstr == "10101010" * 8
+
+    dut._log.info("  input: {}".format(data_in.binstr))
+    yield master.shift_data(data_in)
+    dut._log.info("  output: {}".format(master.result.binstr))
+    assert master.result.binstr == "01010101" * 8
+
+    # Load the memory address
+    yield master.load_ir(cmd_MEMADDRESS) # MEMADDR
+    dut._log.info("Loading address")
+
+    data_in.binstr = "00000000000000000000000000001"
+    dut._log.info("  input: {}".format(data_in.binstr))
+    yield master.shift_data(data_in)
+    dut._log.info("  output: {}".format(master.result.binstr))
+    assert master.result.binstr == "1100000000000010"
+
+    # Do read
+    yield master.load_ir(cmd_MEMREAD) # MEMREAD
+    dut._log.info("Reading memory")
+    data_in.binstr = "00000000" * 8
+
+    dut._log.info("  input: {}".format(data_in.binstr))
+    yield master.shift_data(data_in)
+    dut._log.info("  output: {}".format(master.result.binstr))
+    assert master.result.binstr == "10101010" * 8
+
+    dut._log.info("  input: {}".format(data_in.binstr))
+    yield master.shift_data(data_in)
+    dut._log.info("  output: {}".format(master.result.binstr))
+    assert master.result.binstr == "01010101" * 8
+
+    dut._log.info("{!r}".format(wbmem))
 # demo / debug how to get boundary scan names. run "python3 test.py"
 if __name__ == '__main__':
     pinouts = get_jtag_boundary()