Support running tb on test_issuer subblock.
authorStaf Verhaegen <staf@stafverhaegen.be>
Sat, 3 Apr 2021 18:57:50 +0000 (20:57 +0200)
committerStaf Verhaegen <staf@stafverhaegen.be>
Sat, 3 Apr 2021 18:57:50 +0000 (20:57 +0200)
Use wrapper class around dut that select proper signals depending on
top cell used. Should be able to be used later to extend to post_pnr
netlist.

ls180/pre_pnr/Makefile
ls180/pre_pnr/run_iverilog.sh [deleted file]
ls180/pre_pnr/run_iverilog_ls180.sh [new file with mode: 0755]
ls180/pre_pnr/run_iverilog_ti.sh [new file with mode: 0755]
ls180/pre_pnr/test.py

index 663ece6e75a191366cff8bb96adbe45a32ae3452..4fbc60f119e0df5a3bff4b559bc82469c4c3962f 100644 (file)
@@ -11,7 +11,6 @@ VERILOG_SOURCES := \
   ../../../litex/florent/ls180.v \
 # END VERILOG_SOURCES
 
-TOPLEVEL := ls180
 MODULE := test
 
 include $(shell cocotb-config --makefiles)/Makefile.sim
diff --git a/ls180/pre_pnr/run_iverilog.sh b/ls180/pre_pnr/run_iverilog.sh
deleted file mode 100755 (executable)
index 2866883..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-touch mem.init mem_1.init mem_2.init mem_3.init mem_4.init
-# Only run test in reset state as running CPU takes too much time to simulate
-make \
-  SIM=icarus \
-  COCOTB_RESULTS_FILE=results_iverilog.xml \
-  COCOTB_HDL_TIMEUNIT=100ps \
-  TESTCASE="idcode_reset,idcodesvf_reset,boundary_scan_reset" \
-  SIM_BUILD=sim_build_iverilog
-
-
diff --git a/ls180/pre_pnr/run_iverilog_ls180.sh b/ls180/pre_pnr/run_iverilog_ls180.sh
new file mode 100755 (executable)
index 0000000..eae0986
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+touch mem.init mem_1.init mem_2.init mem_3.init mem_4.init
+# Only run test in reset state as running CPU takes too much time to simulate
+make \
+  SIM=icarus \
+  TOPLEVEL=ls180 \
+  COCOTB_RESULTS_FILE=results_iverilog_ls180.xml \
+  COCOTB_HDL_TIMEUNIT=100ps \
+  TESTCASE="idcode_reset,idcodesvf_reset,boundary_scan_reset" \
+  SIM_BUILD=sim_build_iverilog_ls180
+
+
diff --git a/ls180/pre_pnr/run_iverilog_ti.sh b/ls180/pre_pnr/run_iverilog_ti.sh
new file mode 100755 (executable)
index 0000000..e01138a
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+touch mem.init mem_1.init mem_2.init mem_3.init mem_4.init
+# Only run test in reset state as running CPU takes too much time to simulate
+make \
+  SIM=icarus \
+  TOPLEVEL=test_issuer \
+  COCOTB_RESULTS_FILE=results_iverilog_ti.xml \
+  COCOTB_HDL_TIMEUNIT=100ps \
+  TESTCASE="idcode_reset,idcodesvf_reset,boundary_scan_reset" \
+  SIM_BUILD=sim_build_iverilog_ti
+
+
index 87520430894100b8819b1150439a8f2b1a8d4520..25e8caff1d71989be8f24f4ec01289e891f9194d 100644 (file)
@@ -17,34 +17,53 @@ from soc.debug.jtag import Pins
 # Helper functions
 #
 
+class DUTWrapper:
+    def __init__(self, dut):
+        self.dut = dut
+        try:
+            ti = dut.test_issuer
+        except AttributeError:
+            ti = dut
+        ti._discover_all()
+        self.ti = ti
+        self.clk = ti.clk
+        self.rst = ti.rst
+        self.tck = ti.TAP_bus__tck
+        self.tms = ti.TAP_bus__tms
+        self.tdi = ti.TAP_bus__tdi
+        self.tdo = ti.TAP_bus__tdo
+
+    def info(self, *args, **kwargs):
+        return self.dut._log.info(*args, **kwargs)
+
 class JTAGPin:
     def __init__(self, pin):
         self.type_ = pin[2]
         self.name = pin[3]
 
-    def log(self, dut):
+    def log(self, wrap):
         if self.type_ == IOType.In:
-            core_i = getattr(dut.test_issuer, f"{self.name}__core__i").value
-            pad_i = getattr(dut.test_issuer, f"{self.name}__pad__i").value
-            dut._log.info(f"{self.name}: core.i={core_i}, pad.i={pad_i}")
+            core_i = getattr(wrap.ti, f"{self.name}__core__i").value
+            pad_i = getattr(wrap.ti, f"{self.name}__pad__i").value
+            wrap.info(f"{self.name}: core.i={core_i}, pad.i={pad_i}")
         elif self.type_ == IOType.Out:
-            core_o = getattr(dut.test_issuer, f"{self.name}__core__o").value
-            pad_o = getattr(dut.test_issuer, f"{self.name}__pad__o").value
-            dut._log.info(f"{self.name}: core.o={core_o}, pad.o={pad_o}")
+            core_o = getattr(wrap.ti, f"{self.name}__core__o").value
+            pad_o = getattr(wrap.ti, f"{self.name}__pad__o").value
+            wrap.info(f"{self.name}: core.o={core_o}, pad.o={pad_o}")
         elif self.type_ == IOType.TriOut:
-            core_o = getattr(dut.test_issuer, f"{self.name}__core__o").value
-            core_oe = getattr(dut.test_issuer, f"{self.name}__core__oe").value
-            pad_o = getattr(dut.test_issuer, f"{self.name}__pad__o").value
-            pad_oe = getattr(dut.test_issuer, f"{self.name}__pad__oe").value
-            dut._log.info(f"{self.name}: core.(o={core_o}, oe={core_oe}), pad.(o={pad_o}, oe={pad_oe})")
+            core_o = getattr(wrap.ti, f"{self.name}__core__o").value
+            core_oe = getattr(wrap.ti, f"{self.name}__core__oe").value
+            pad_o = getattr(wrap.ti, f"{self.name}__pad__o").value
+            pad_oe = getattr(wrap.ti, f"{self.name}__pad__oe").value
+            wrap.info(f"{self.name}: core.(o={core_o}, oe={core_oe}), pad.(o={pad_o}, oe={pad_oe})")
         elif self.type_ == IOType.InTriOut:
-            core_i = getattr(dut.test_issuer, f"{self.name}__core__i").value
-            core_o = getattr(dut.test_issuer, f"{self.name}__core__o").value
-            core_oe = getattr(dut.test_issuer, f"{self.name}__core__oe").value
-            pad_i = getattr(dut.test_issuer, f"{self.name}__pad__i").value
-            pad_o = getattr(dut.test_issuer, f"{self.name}__pad__o").value
-            pad_oe = getattr(dut.test_issuer, f"{self.name}__pad__oe").value
-            dut._log.info(f"{self.name}: core.(i={core_i}, o={core_o}, oe={core_oe}), pad.(i={core_i}, o={pad_o}, oe={pad_oe})")
+            core_i = getattr(wrap.ti, f"{self.name}__core__i").value
+            core_o = getattr(wrap.ti, f"{self.name}__core__o").value
+            core_oe = getattr(wrap.ti, f"{self.name}__core__oe").value
+            pad_i = getattr(wrap.ti, f"{self.name}__pad__i").value
+            pad_o = getattr(wrap.ti, f"{self.name}__pad__o").value
+            pad_oe = getattr(wrap.ti, f"{self.name}__pad__oe").value
+            wrap.info(f"{self.name}: core.(i={core_i}, o={core_o}, oe={core_oe}), pad.(i={core_i}, o={pad_o}, oe={pad_oe})")
         else:
             raise ValueError(f"Unsupported pin type {self.type_}")
 
@@ -54,28 +73,29 @@ class JTAGPin:
         elif self.type_ == IOType.TriOut:
             return [1, val]
         elif self.type_ == IOType.InTriOut:
-            return [val, 1, val]
+            return [val, val, 1]
         else:
             raise ValueError(f"Unsupported pin type {self.type_}")
 
-    def check(self, dut, val):
+    def check(self, wrap, val):
         if self.type_ == IOType.In:
-            assert getattr(dut.test_issuer, f"{self.name}__core__i").value == val
+            assert getattr(wrap.ti, f"{self.name}__core__i").value == val
         elif self.type_ == IOType.Out:
-            assert getattr(dut.test_issuer, f"{self.name}__pad__o").value == val
+            assert getattr(wrap.ti, f"{self.name}__pad__o").value == val
         elif self.type_ == IOType.TriOut:
-            assert getattr(dut.test_issuer, f"{self.name}__core__o").value == val
-            assert getattr(dut.test_issuer, f"{self.name}__core__oe").value == 1
+            assert getattr(wrap.ti, f"{self.name}__core__o").value == val
+            assert getattr(wrap.ti, f"{self.name}__core__oe").value == 1
         elif self.type_ == IOType.InTriOut:
-            assert getattr(dut.test_issuer, f"{self.name}__core__i").value == val
-            assert getattr(dut.test_issuer, f"{self.name}__pad__o").value == val
-            assert getattr(dut.test_issuer, f"{self.name}__pad__oe").value == val
+            assert getattr(wrap.ti, f"{self.name}__core__i").value == val
+            assert getattr(wrap.ti, f"{self.name}__pad__o").value == val
+            assert getattr(wrap.ti, f"{self.name}__pad__oe").value == val
         else:
             raise ValueError(f"Unsupported pin type {self.type_}")
 
-def log_pins(dut, pins):
+
+def log_pins(wrap, pins):
     for pin in pins:
-        pin.log(dut)
+        pin.log(wrap)
 
 
 def get_jtag_boundary():
@@ -92,79 +112,83 @@ def get_jtag_boundary():
     return pins
 
 
-def setup_sim(dut, *, clk_period, run):
+def setup_sim(dut, *, info, clk_period, run):
     """Initialize CPU and setup clock"""
 
+    wrap = DUTWrapper(dut)
+    wrap.info(info)
+
     clk_steps = get_sim_steps(clk_period, "ns")
-    cocotb.fork(Clock(dut.sys_clk, clk_steps).start())
+    cocotb.fork(Clock(wrap.clk, clk_steps).start())
 
-    dut.sys_rst <= 1
-    dut.sys_clk <= 0
+    wrap.rst <= 1
+    wrap.clk <= 0
     if run:
         yield Timer(int(10.5*clk_steps))
-        dut.sys_rst <= 0
+        wrap.rst <= 0
         yield Timer(int(5*clk_steps))
 
-def setup_jtag(dut, *, tck_period):
+    return wrap
+
+def setup_jtag(wrap, *, tck_period):
     # Make this a generator
     if False:
         yield Timer(0)
-    return JTAG_Master(dut.jtag_tck, dut.jtag_tms,
-                       dut.jtag_tdi, dut.jtag_tdo,
+    return JTAG_Master(wrap.tck, wrap.tms, wrap.tdi, wrap.tdo,
                        clk_period=tck_period,
                        ir_width=4)
 
-def execute_svf(dut, *, jtag, svf_filename):
+def execute_svf(wrap, *, jtag, svf_filename):
     yield jtag.reset()
 
     jtag_svf = SVF_Executor(jtag)
     with open(svf_filename, "r") as f:
         svf_deck = f.read()
-    yield jtag_svf.run(svf_deck, p=dut._log.info)
+    yield jtag_svf.run(svf_deck, p=wrap.info)
     
 #
 # IDCODE using JTAG_master
 #
 
-def idcode(dut, *, jtag):
+def idcode(wrap, *, jtag):
     yield jtag.idcode()
     result1 = jtag.result
-    dut._log.info("IDCODE1: {}".format(result1))
+    wrap.info("IDCODE1: {}".format(result1))
     assert(result1 == BinaryValue("00000000000000000001100011111111"))
 
     yield jtag.idcode()
     result2 = jtag.result
-    dut._log.info("IDCODE2: {}".format(result2))
+    wrap.info("IDCODE2: {}".format(result2))
 
     assert(result1 == result2)
 
 @cocotb.test()
 def idcode_reset(dut):
-    dut._log.info("Running IDCODE test; cpu in reset...")
-
     clk_period = 100 # 10MHz
     tck_period = 300 # 3MHz
 
-    yield from setup_sim(dut, clk_period=clk_period, run=False)
-    jtag = yield from setup_jtag(dut, tck_period = tck_period)
+    info = "Running IDCODE test; cpu in reset..."
+    wrap = yield from setup_sim(dut, info=info, clk_period=clk_period,
+                                run=False)
+    jtag = yield from setup_jtag(wrap, tck_period = tck_period)
 
-    yield from idcode(dut, jtag=jtag)
+    yield from idcode(wrap, jtag=jtag)
 
-    dut._log.info("IDCODE test completed")
+    wrap.info("IDCODE test completed")
 
 @cocotb.test()
 def idcode_run(dut):
-    dut._log.info("Running IDCODE test; cpu running...")
-
     clk_period = 100 # 10MHz
     tck_period = 300 # 3MHz
 
-    yield from setup_sim(dut, clk_period=clk_period, run=True)
-    jtag = yield from setup_jtag(dut, tck_period = tck_period)
+    info = "Running IDCODE test; cpu running..."
+    wrap = yield from setup_sim(dut, info=info, clk_period=clk_period,
+                         run=True)
+    jtag = yield from setup_jtag(wrap, tck_period = tck_period)
 
-    yield from idcode(dut, jtag=jtag)
+    yield from idcode(wrap, jtag=jtag)
 
-    dut._log.info("IDCODE test completed")
+    wrap.info("IDCODE test completed")
 
 #
 # Read IDCODE from SVF file
@@ -172,87 +196,89 @@ def idcode_run(dut):
 
 @cocotb.test()
 def idcodesvf_reset(dut):
-    dut._log.info("Running IDCODE through SVF test; cpu in reset...")
-
     clk_period = 100 # 10MHz
     tck_period = 300 # 3MHz
 
-    yield from setup_sim(dut, clk_period=clk_period, run=False)
-    jtag = yield from setup_jtag(dut, tck_period = tck_period)
+    info = "Running IDCODE through SVF test; cpu in reset..."
+    wrap = yield from setup_sim(dut, info=info, clk_period=clk_period,
+                                run=False)
+    jtag = yield from setup_jtag(wrap, tck_period = tck_period)
 
-    yield from execute_svf(dut, jtag=jtag, svf_filename="idcode.svf")
+    yield from execute_svf(wrap, jtag=jtag, svf_filename="idcode.svf")
 
-    dut._log.info("IDCODE test completed")
+    wrap.info("IDCODE test completed")
 
 @cocotb.test()
 def idcodesvf_run(dut):
-    dut._log.info("Running IDCODE through SVF test; cpu running...")
-
     clk_period = 100 # 10MHz
     tck_period = 300 # 3MHz
 
-    yield from setup_sim(dut, clk_period=clk_period, run=True)
-    jtag = yield from setup_jtag(dut, tck_period = tck_period)
+    info = "Running IDCODE through SVF test; cpu running..."
+    wrap = yield from setup_sim(dut, info=info, clk_period=clk_period,
+                                run=True)
+    jtag = yield from setup_jtag(wrap, tck_period = tck_period)
 
-    yield from execute_svf(dut, jtag=jtag, svf_filename="idcode.svf")
+    yield from execute_svf(wrap, jtag=jtag, svf_filename="idcode.svf")
 
-    dut._log.info("IDCODE test completed")
+    wrap.info("IDCODE test completed")
 
 #
 # Boundary scan
 #
 
-def boundary_scan(dut, *, jtag):
+def boundary_scan(wrap, *, jtag):
     pins = get_jtag_boundary()
 
     yield jtag.reset()
 
-    dut._log.info("")
-    dut._log.info("Before scan")
-    log_pins(dut, pins)
+    wrap.info("")
+    wrap.info("Before scan")
+    log_pins(wrap, pins)
 
     yield jtag.load_ir([0, 0, 0, 0])
     data = chain(*(pin.data(i%2) for i, pin in enumerate(pins)))
     yield jtag.shift_data(data)
 
-    dut._log.info("")
-    dut._log.info("After scan")
-    log_pins(dut, pins)
+    wrap.info("")
+    wrap.info("After scan")
+    log_pins(wrap, pins)
+#    pins[0].check(dut, 1)
 
     yield jtag.reset()
 
-    dut._log.info("")
-    dut._log.info("After reset")
-    log_pins(dut, pins)
+    wrap.info("")
+    wrap.info("After reset")
+    log_pins(wrap, pins)
+#    pins[0].check(dut, 0)
 
 
 @cocotb.test()
 def boundary_scan_reset(dut):
-    dut._log.info("Running boundary scan test; cpu in reset...")
-
     clk_period = 100 # 10MHz
     tck_period = 300 # 3MHz
 
-    yield from setup_sim(dut, clk_period=clk_period, run=False)
-    jtag = yield from setup_jtag(dut, tck_period = tck_period)
+    info = "Running boundary scan test; cpu in reset..."
+    wrap = yield from setup_sim(dut, info=info, clk_period=clk_period,
+                                run=False)
+    jtag = yield from setup_jtag(wrap, tck_period = tck_period)
 
-    yield from boundary_scan(dut, jtag=jtag)
+    yield from boundary_scan(wrap, jtag=jtag)
 
-    dut._log.info("IDCODE test completed")
+    wrap.info("IDCODE test completed")
 
 @cocotb.test()
 def boundary_scan_run(dut):
-    dut._log.info("Running boundary scan test; cpu running...")
-
     clk_period = 100 # 10MHz
     tck_period = 300 # 3MHz
 
-    yield from setup_sim(dut, clk_period=clk_period, run=True)
-    jtag = yield from setup_jtag(dut, tck_period = tck_period)
+    info = "Running boundary scan test; cpu running..."
+    wrap = yield from setup_sim(dut, info=info, clk_period=clk_period,
+                                run=True)
+    jtag = yield from setup_jtag(wrap, tck_period = tck_period)
 
-    yield from boundary_scan(dut, jtag=jtag)
+    yield from boundary_scan(wrap, jtag=jtag)
 
-    dut._log.info("IDCODE test completed")
+    wrap.info("IDCODE test completed")
 
 
 # demo / debug how to get boundary scan names. run "python3 test.py"