add ghdl wishbone basic test
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 10 Apr 2021 14:01:40 +0000 (15:01 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 10 Apr 2021 14:01:40 +0000 (15:01 +0100)
ls180/post_pnr/cocotb/Makefile
ls180/post_pnr/cocotb/run_ghdl_wb.sh [new file with mode: 0755]
ls180/post_pnr/cocotb/test.py

index 1255036a575644b2c41a4e7169cbba125392bf2d..006c168beb8555df515f24a90fb29848f48e8c2a 100644 (file)
@@ -15,7 +15,7 @@ VHDL_SOURCES = \
   $(wildcard $(VSTDIR)/*.vst) \
   $(wildcard $(NSXLIBDIR)/*.vhd) \
   $(wildcard $(NIOLIBDIR)/*.vhd)
-TOPLEVEL=corona
+TOPLEVEL=ls180
 TOPLEVEL_LANG=vhdl
 MODULE=test
 SIM=ghdl
diff --git a/ls180/post_pnr/cocotb/run_ghdl_wb.sh b/ls180/post_pnr/cocotb/run_ghdl_wb.sh
new file mode 100755 (executable)
index 0000000..3d76ec1
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# Only run test in reset state as running CPU takes too much time to simulate
+make \
+  SIM=ghdl \
+  COCOTB_RESULTS_FILE=results_iverilog.xml \
+  COCOTB_HDL_TIMEUNIT=100ps \
+  TESTCASE="wishbone_basic" \
+  SIM_BUILD=sim_build_iverilog
+
+
index 68057e3a273b4cff4efb35c2509263431991d986..4a8658020c8d61f96b3b3b54f2bbc7045898897e 100644 (file)
@@ -15,21 +15,21 @@ def setup_sim(dut, *, clk_period, run):
     """Initialize CPU and setup clock"""
 
     clk_steps = get_sim_steps(clk_period, "ns")
-    cocotb.fork(Clock(dut.clk_from_pad, clk_steps).start())
+    cocotb.fork(Clock(dut.sys_clk, clk_steps).start())
 
-    dut.rst_from_pad <= 1
-    dut.clk_from_pad <= 0
+    dut.sys_rst <= 1
+    dut.sys_clk <= 0
     if run:
         yield Timer(int(10.5*clk_steps))
-        dut.rst_from_pad <= 0
+        dut.sys_rst <= 0
         yield Timer(int(5*clk_steps))
 
 def setup_jtag(dut, *, tck_period):
     # Make this a generator
     if False:
         yield Timer(0)
-    return JTAG_Master(dut.tck_from_pad, dut.tms_from_pad,
-                       dut.tdi_from_pad, dut.tdo_to_pad,
+    return JTAG_Master(dut.jtag_tck, dut.jtag_tms,
+                       dut.jtag_tdi, dut.jtag_tdo,
                        clk_period=tck_period,
                        ir_width=4)
 
@@ -116,3 +116,145 @@ def idcode_run(dut):
 
     dut._log.info("IDCODE test completed")
 
+from itertools import chain
+
+import cocotb
+from cocotb.clock import Clock
+from cocotb.triggers import Timer
+from cocotb.utils import get_sim_steps
+from cocotb.binary import BinaryValue
+
+from c4m.nmigen.jtag.tap import IOType
+from c4m.cocotb.jtag.c4m_jtag import JTAG_Master
+from c4m.cocotb.jtag.c4m_jtag_svfcocotb import SVF_Executor
+
+from soc.config.pinouts import get_pinspecs
+from soc.debug.jtag import Pins
+
+
+@cocotb.test()
+def wishbone_basic(dut):
+    """
+    Test of an added Wishbone interface
+    """
+    clk_period = 100 # 10MHz
+    tck_period = 3000 # 0.3MHz
+
+    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
+
+    info = "Running Wishbone basic test"
+    yield from setup_sim(dut, clk_period=clk_period, run=True)
+    master = yield from setup_jtag(wrap, tck_period = tck_period)
+
+    # Load the memory address
+    yield master.load_ir(cmd_MEMADDRESS)
+    dut._log.info("Loading address")
+
+    data_in.binstr = "000000000000000000000000000001"
+    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" * 8
+    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" * 8
+    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 = "000000000000000000000000000001"
+    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 == "000000000000000000000000000000"
+
+    # Do read and write
+    yield master.load_ir(cmd_MEMREADWRITE)
+    dut._log.info("Reading and writing memory")
+
+    data_in.binstr = "10101010" * 4
+    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" * 4
+
+    data_in.binstr = "01010101" * 4
+    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" * 4
+
+    # Load the memory address
+    yield master.load_ir(cmd_MEMADDRESS)
+    dut._log.info("Loading address")
+
+    data_in.binstr = "000000000000000000000000000001"
+    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 == "000000000000000000000000000010"
+
+    # Do read
+    yield master.load_ir(cmd_MEMREAD)
+    dut._log.info("Reading memory")
+    data_in.binstr = "00000000" * 4
+
+    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" * 4
+
+    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" * 4
+
+    # Load the memory address
+    yield master.load_ir(cmd_MEMADDRESS) # MEMADDR
+    dut._log.info("Loading address")
+
+    data_in.binstr = "0000000000000000000000000000001"
+    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 == "000000000000000000000000000010"
+
+    # Do read
+    yield master.load_ir(cmd_MEMREAD) # MEMREAD
+    dut._log.info("Reading memory")
+    data_in.binstr = "00000000" * 4
+
+    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" * 4
+
+    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" * 4
+
+    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()
+    for pin in pinouts:
+        # example: ('eint', '2', <IOType.In: 1>, 'eint_2', 125)
+        print (pin)