Move tests for pimem to new file, add ability to test pi2ls.py
authorMichael Nolan <mtnolan2640@gmail.com>
Fri, 26 Jun 2020 18:58:54 +0000 (14:58 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Fri, 26 Jun 2020 18:59:25 +0000 (14:59 -0400)
src/soc/experiment/pi2ls.py
src/soc/experiment/pimem.py
src/soc/experiment/test/test_pi2ls.py [new file with mode: 0644]

index b1c888d12c08ba499faaff39d29f2e040309b392..79b2f2677b0db6033dcfa5a8f5c421d63606e761 100644 (file)
@@ -34,9 +34,9 @@ class Pi2LSUI(Elaboratable):
     def __init__(self, name, pi=None, lsui=None, regwid=64, addrwid=48):
         self.addrbits = 4
         if pi is None:
-            pi = PortInterface(name="%s_pi", regwidaddrwid)
+            pi = PortInterface(name="%s_pi", regwid=regwid, addrwid=addrwid)
         self.pi = pi
-        if lsui = None:
+        if lsui is None:
             lsui = LoadStoreUnitInterface(addrwid, self.addrbits, regwid)
         self.lsui = lsui
 
@@ -70,3 +70,4 @@ class Pi2LSUI(Elaboratable):
             m.d.comb += lsui.x_st_data_i.eq(pi.st.data)
 
         return m
+
index 4bb6aafdd94a2b50de15237cf9f3155d2a5a4b0e..0d2e77843c3f23495dd6d0747555e92ff4b216c7 100644 (file)
@@ -346,117 +346,4 @@ class TestMemoryPortInterface(Elaboratable):
             yield from p.ports()
 
 
-def wait_busy(port, no=False):
-    while True:
-        busy = yield port.pi.busy_o
-        print("busy", no, busy)
-        if bool(busy) == no:
-            break
-        yield
-
-
-def wait_addr(port):
-    while True:
-        addr_ok = yield port.pi.addr_ok_o
-        print("addrok", addr_ok)
-        if not addr_ok:
-            break
-        yield
-
-
-def wait_ldok(port):
-    while True:
-        ldok = yield port.pi.ld.ok
-        print("ldok", ldok)
-        if ldok:
-            break
-        yield
-
-
-def l0_cache_st(dut, addr, data, datalen):
-    mem = dut.mem
-    port1 = dut.pi
-
-    # have to wait until not busy
-    yield from wait_busy(port1, no=False)    # wait until not busy
-
-    # set up a ST on the port.  address first:
-    yield port1.pi.is_st_i.eq(1)  # indicate ST
-    yield port1.pi.data_len.eq(datalen)  # ST length (1/2/4/8)
-
-    yield port1.pi.addr.data.eq(addr)  # set address
-    yield port1.pi.addr.ok.eq(1)  # set ok
-    yield from wait_addr(port1)             # wait until addr ok
-    # yield # not needed, just for checking
-    # yield # not needed, just for checking
-    # assert "ST" for one cycle (required by the API)
-    yield port1.pi.st.data.eq(data)
-    yield port1.pi.st.ok.eq(1)
-    yield
-    yield port1.pi.st.ok.eq(0)
-
-    # can go straight to reset.
-    yield port1.pi.is_st_i.eq(0)  # end
-    yield port1.pi.addr.ok.eq(0)  # set !ok
-    # yield from wait_busy(port1, False)    # wait until not busy
-
-
-def l0_cache_ld(dut, addr, datalen, expected):
-
-    mem = dut.mem
-    port1 = dut.pi
-
-    # have to wait until not busy
-    yield from wait_busy(port1, no=False)    # wait until not busy
-
-    # set up a LD on the port.  address first:
-    yield port1.pi.is_ld_i.eq(1)  # indicate LD
-    yield port1.pi.data_len.eq(datalen)  # LD length (1/2/4/8)
-
-    yield port1.pi.addr.data.eq(addr)  # set address
-    yield port1.pi.addr.ok.eq(1)  # set ok
-    yield from wait_addr(port1)             # wait until addr ok
-
-    yield from wait_ldok(port1)             # wait until ld ok
-    data = yield port1.pi.ld.data
-
-    # cleanup
-    yield port1.pi.is_ld_i.eq(0)  # end
-    yield port1.pi.addr.ok.eq(0)  # set !ok
-    # yield from wait_busy(port1, no=False)    # wait until not busy
-
-    return data
-
-
-def l0_cache_ldst(arg, dut):
-    yield
-    addr = 0x2
-    data = 0xbeef
-    data2 = 0xf00f
-    #data = 0x4
-    yield from l0_cache_st(dut, 0x2, data, 2)
-    yield from l0_cache_st(dut, 0x4, data2, 2)
-    result = yield from l0_cache_ld(dut, 0x2, 2, data)
-    result2 = yield from l0_cache_ld(dut, 0x4, 2, data2)
-    yield
-    arg.assertEqual(data, result, "data %x != %x" % (result, data))
-    arg.assertEqual(data2, result2, "data2 %x != %x" % (result2, data2))
-
-
-
-class TestPIMem(unittest.TestCase):
-
-    def test_pi_mem(self):
-
-        dut = TestMemoryPortInterface(regwid=64)
-        #vl = rtlil.convert(dut, ports=dut.ports())
-        #with open("test_basic_l0_cache.il", "w") as f:
-        #    f.write(vl)
-
-        run_simulation(dut, l0_cache_ldst(self, dut),
-                       vcd_name='test_pi_mem_basic.vcd')
-
-
-if __name__ == '__main__':
-    unittest.main(exit=False)
 
diff --git a/src/soc/experiment/test/test_pi2ls.py b/src/soc/experiment/test/test_pi2ls.py
new file mode 100644 (file)
index 0000000..0e04d37
--- /dev/null
@@ -0,0 +1,156 @@
+from nmigen import Signal, Module, Record
+from nmigen.back.pysim import Simulator, Delay
+from nmigen.compat.sim import run_simulation, Settle
+from nmutil.formaltest import FHDLTestCase
+from nmigen.cli import rtlil
+import unittest
+from soc.experiment.pi2ls import Pi2LSUI
+from soc.experiment.lsmem import TestMemLoadStoreUnit
+from soc.experiment.pimem import TestMemoryPortInterface
+
+def wait_busy(port, no=False):
+    while True:
+        busy = yield port.pi.busy_o
+        print("busy", no, busy)
+        if bool(busy) == no:
+            break
+        yield
+
+
+def wait_addr(port):
+    while True:
+        addr_ok = yield port.pi.addr_ok_o
+        print("addrok", addr_ok)
+        if not addr_ok:
+            break
+        yield
+
+
+def wait_ldok(port):
+    while True:
+        ldok = yield port.pi.ld.ok
+        print("ldok", ldok)
+        if ldok:
+            break
+        yield
+
+
+def l0_cache_st(dut, addr, data, datalen):
+    if isinstance(dut.pi, Record):
+        port1 = dut
+    else:
+        port1 = dut.pi
+
+    # have to wait until not busy
+    yield from wait_busy(port1, no=False)    # wait until not busy
+
+    # set up a ST on the port.  address first:
+    yield port1.pi.is_st_i.eq(1)  # indicate ST
+    yield port1.pi.data_len.eq(datalen)  # ST length (1/2/4/8)
+
+    yield port1.pi.addr.data.eq(addr)  # set address
+    yield port1.pi.addr.ok.eq(1)  # set ok
+    yield from wait_addr(port1)             # wait until addr ok
+    # yield # not needed, just for checking
+    # yield # not needed, just for checking
+    # assert "ST" for one cycle (required by the API)
+    yield port1.pi.st.data.eq(data)
+    yield port1.pi.st.ok.eq(1)
+    yield
+    yield port1.pi.st.ok.eq(0)
+
+    # can go straight to reset.
+    yield port1.pi.is_st_i.eq(0)  # end
+    yield port1.pi.addr.ok.eq(0)  # set !ok
+    # yield from wait_busy(port1, False)    # wait until not busy
+
+
+def l0_cache_ld(dut, addr, datalen, expected):
+
+    if isinstance(dut.pi, Record):
+        port1 = dut
+    else:
+        port1 = dut.pi
+
+    # have to wait until not busy
+    yield from wait_busy(port1, no=False)    # wait until not busy
+
+    # set up a LD on the port.  address first:
+    yield port1.pi.is_ld_i.eq(1)  # indicate LD
+    yield port1.pi.data_len.eq(datalen)  # LD length (1/2/4/8)
+
+    yield port1.pi.addr.data.eq(addr)  # set address
+    yield port1.pi.addr.ok.eq(1)  # set ok
+    yield from wait_addr(port1)             # wait until addr ok
+
+    yield from wait_ldok(port1)             # wait until ld ok
+    data = yield port1.pi.ld.data
+
+    # cleanup
+    yield port1.pi.is_ld_i.eq(0)  # end
+    yield port1.pi.addr.ok.eq(0)  # set !ok
+    # yield from wait_busy(port1, no=False)    # wait until not busy
+
+    return data
+
+
+def l0_cache_ldst(arg, dut):
+    yield
+    addr = 0x2
+    data = 0xbeef
+    data2 = 0xf00f
+    #data = 0x4
+    yield from l0_cache_st(dut, 0x2, data, 2)
+    yield from l0_cache_st(dut, 0x4, data2, 2)
+    result = yield from l0_cache_ld(dut, 0x2, 2, data)
+    result2 = yield from l0_cache_ld(dut, 0x4, 2, data2)
+    yield
+    arg.assertEqual(data, result, "data %x != %x" % (result, data))
+    arg.assertEqual(data2, result2, "data2 %x != %x" % (result2, data2))
+
+
+
+class TestPIMem(unittest.TestCase):
+
+    def test_pi_mem(self):
+
+        dut = TestMemoryPortInterface(regwid=64)
+        #vl = rtlil.convert(dut, ports=dut.ports())
+        #with open("test_basic_l0_cache.il", "w") as f:
+        #    f.write(vl)
+
+        run_simulation(dut, {"sync": l0_cache_ldst(self, dut)},
+                       vcd_name='test_pi_mem_basic.vcd')
+
+    @unittest.skip("broken")
+    def test_pi2ls(self):
+        m = Module()
+        regwid = 32
+        addrwid = 32
+        m.submodules.dut = dut = Pi2LSUI("mem", regwid=regwid, addrwid=addrwid)
+        m.submodules.lsmem = lsmem = TestMemLoadStoreUnit(addr_wid=addrwid,
+                                                          data_wid=regwid)
+
+        # Connect inputs
+        m.d.comb += [lsmem.x_addr_i.eq(dut.lsui.x_addr_i),
+                     lsmem.x_mask_i.eq(dut.lsui.x_mask_i),
+                     lsmem.x_ld_i.eq(dut.lsui.x_ld_i),
+                     lsmem.x_st_i.eq(dut.lsui.x_st_i),
+                     lsmem.x_st_data_i.eq(dut.lsui.x_st_data_i),
+                     lsmem.x_stall_i.eq(dut.lsui.x_stall_i),
+                     lsmem.x_valid_i.eq(dut.lsui.x_valid_i),
+                     lsmem.m_stall_i.eq(dut.lsui.m_stall_i),
+                     lsmem.m_valid_i.eq(dut.lsui.m_valid_i)]
+
+        m.d.comb += [dut.lsui.x_busy_o.eq(lsmem.x_busy_o),
+                     dut.lsui.m_busy_o.eq(lsmem.m_busy_o),
+                     dut.lsui.m_ld_data_o.eq(lsmem.m_ld_data_o),
+                     dut.lsui.m_load_err_o.eq(lsmem.m_load_err_o),
+                     dut.lsui.m_store_err_o.eq(lsmem.m_store_err_o),
+                     dut.lsui.m_badaddr_o.eq(lsmem.m_badaddr_o)]
+
+        run_simulation(m, {"sync": l0_cache_ldst(self, dut)},
+                       vcd_name='test_pi2ls.vcd')
+
+if __name__ == '__main__':
+    unittest.main(exit=False)