reconfigureable PortInterface testing now possible
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 27 Jun 2020 12:34:57 +0000 (13:34 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 27 Jun 2020 12:34:57 +0000 (13:34 +0100)
src/soc/config/loadstore.py
src/soc/config/test/test_loadstore.py
src/soc/experiment/pi2ls.py
src/soc/experiment/test/test_pi2ls.py

index e7d52ff0ebb84bf73ec96bbe98d0c719b50405f0..104483d19f6010e674e0c08f556cdf3846cfd4bc 100644 (file)
@@ -1,11 +1,15 @@
-"""ConfigureableLoadStoreUnit
+"""ConfigureableLoadStoreUnit and ConfigMemoryPortInterface
 
 allows the type of LoadStoreUnit to be run-time selectable
 
+this allows the same code to be used for both small unit tests
+as well as larger ones and so on, without needing large amounts
+of unnecessarily-duplicated code
 """
 from soc.experiment.lsmem import TestMemLoadStoreUnit
 from soc.bus.test.test_minerva import TestSRAMBareLoadStoreUnit
-
+from soc.experiment.pi2ls import Pi2LSUI
+from soc.experiment.pimem import TestMemoryPortInterface
 
 class ConfigLoadStoreUnit:
     def __init__(self, pspec):
@@ -18,3 +22,15 @@ class ConfigLoadStoreUnit:
                           mask_wid=pspec.mask_wid, # cache line range
                           data_wid=pspec.reg_wid)  # data bus width
 
+
+class ConfigMemoryPortInterface:
+    def __init__(self, pspec):
+        if pspec.ldst_ifacetype == 'testpi':
+            self.pi = TestMemoryPortInterface(addrwid=pspec.addr_wid, # adr bus
+                                              regwid=pspec.reg_wid) # data bus
+            return
+        self.lsmem = ConfigLoadStoreUnit(pspec)
+        self.pi = Pi2LSUI("mem", lsui=self.lsmem.lsi,
+                          addr_wid=pspec.addr_wid, # address range
+                          mask_wid=pspec.mask_wid, # cache line range
+                          data_wid=pspec.reg_wid)  # data bus width
index 0cbb81fc627f0cff6370d6e13bdc2ec900090752..2e337e92f7ba0ac72d3a4b8ee00a5bf03c2b0ebf 100644 (file)
@@ -7,6 +7,8 @@ from soc.config.loadstore import ConfigLoadStoreUnit
 from collections import namedtuple
 from nmigen.cli import rtlil
 
+TestMemPspec = namedtuple('TestMemPspec', ['ldst_ifacetype',
+                             'addr_wid', 'mask_wid', 'reg_wid'])
 
 def write_to_addr(dut, addr, value):
     yield dut.x_addr_i.eq(addr)
@@ -76,9 +78,9 @@ def read_byte(dut, addr):
 
 def tst_lsmemtype(ifacetype):
     m = Module()
-    Pspec = namedtuple('Pspec', ['ldst_ifacetype',
-                                 'addr_wid', 'mask_wid', 'reg_wid'])
-    pspec = Pspec(ldst_ifacetype=ifacetype, addr_wid=64, mask_wid=4, reg_wid=32)
+    pspec = TestMemPspec(ldst_ifacetype=ifacetype, addr_wid=64,
+                                                   mask_wid=4,
+                                                   reg_wid=32)
     dut = ConfigLoadStoreUnit(pspec).lsi
     vl = rtlil.convert(dut, ports=[]) # TODOdut.ports())
     with open("test_loadstore_%s.il" % ifacetype, "w") as f:
index 7e4f59c6efc0a1668e7aba68558bf3d37520c1b4..e51d41e7e43039bfe51ad45969f5ab402d9338c4 100644 (file)
@@ -33,15 +33,15 @@ from nmigen import Elaboratable, Module, Signal
 class Pi2LSUI(Elaboratable):
 
     def __init__(self, name, pi=None, lsui=None,
-                             regwid=64, mask_wid=8, addrwid=48):
-        print ("pi2lsui reg mask addr", regwid, mask_wid, addrwid)
+                             data_wid=64, mask_wid=8, addr_wid=48):
+        print ("pi2lsui reg mask addr", data_wid, mask_wid, addr_wid)
         self.addrbits = mask_wid
         if pi is None:
             piname = "%s_pi" % name
-            pi = PortInterface(piname, regwid=regwid, addrwid=addrwid)
+            pi = PortInterface(piname, regwid=data_wid, addrwid=addr_wid)
         self.pi = pi
         if lsui is None:
-            lsui = LoadStoreUnitInterface(addrwid, self.addrbits, regwid)
+            lsui = LoadStoreUnitInterface(addr_wid, self.addrbits, data_wid)
         self.lsui = lsui
 
     def splitaddr(self, addr):
index 076746218b17f7f320a5f44ae8469841fe24cf3e..ed1c0a8baef5a56ad4448f2d2ab7604e9a32ee37 100644 (file)
@@ -4,9 +4,9 @@ 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
+from soc.config.test.test_loadstore import TestMemPspec
+from soc.config.loadstore import ConfigMemoryPortInterface
+
 
 def wait_busy(port, no=False):
     while True:
@@ -97,7 +97,8 @@ def l0_cache_ld(dut, addr, datalen):
 
 
 def l0_cache_ldst(arg, dut):
-    yield
+
+    # do two half-word stores at consecutive addresses, then two loads
     addr1 = 0x04
     addr2 = addr1 + 0x2
     data = 0xbeef
@@ -110,56 +111,41 @@ def l0_cache_ldst(arg, dut):
     arg.assertEqual(data, result, "data %x != %x" % (result, data))
     arg.assertEqual(data2, result2, "data2 %x != %x" % (result2, data2))
 
-    # now load both
+    # now load both in a 32-bit load to make sure they're really consecutive
     data3 = data | (data2 << 16)
     result3 = yield from l0_cache_ld(dut, addr1, 4)
     arg.assertEqual(data3, result3, "data3 %x != %x" % (result3, data3))
 
 
-class TestPIMem(unittest.TestCase):
+def tst_config_pi(testcls, ifacetype):
+    """set up a configureable memory test of type ifacetype
+    """
+    dut = Module()
+    pspec = TestMemPspec(ldst_ifacetype=ifacetype,
+                         addr_wid=48,
+                         mask_wid=8,
+                         reg_wid=64)
+    cmpi = ConfigMemoryPortInterface(pspec)
+    dut.submodules.pi = cmpi.pi
+    if hasattr(cmpi, 'lsmem'): # hmmm not happy about this
+        dut.submodules.lsmem = cmpi.lsmem.lsi
+    vl = rtlil.convert(dut, ports=[])#dut.ports())
+    with open("test_pi_%s.il" % ifacetype, "w") as f:
+        f.write(vl)
 
-    def test_pi_mem(self):
+    run_simulation(dut, {"sync": l0_cache_ldst(testcls, cmpi.pi)},
+                   vcd_name='test_pi_%s.vcd' % ifacetype)
 
-        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')
+class TestPIMem(unittest.TestCase):
+
+    def test_pi_mem(self):
+        tst_config_pi(self, 'testpi')
 
     def test_pi2ls(self):
-        m = Module()
-        regwid = 64
-        addrwid = 48
-        m.submodules.lsmem = lsmem = TestMemLoadStoreUnit(addr_wid=addrwid,
-                                                          mask_wid=8,
-                                                          data_wid=regwid)
-        m.submodules.dut = dut = Pi2LSUI("mem", lsui=lsmem,
-                                         regwid=regwid, addrwid=addrwid)
-
-        """ passing in lsmem to Pi2LSUI means this isn't needed
-        # 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)]
-
-        # connect outputs
-        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')
+        tst_config_pi(self, 'testmem')
+
 
 if __name__ == '__main__':
     unittest.main(exit=False)
+