code-morph which redirects lsmem unit test through new ConfigLoadStoreUnit
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 26 Jun 2020 12:14:47 +0000 (13:14 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 26 Jun 2020 12:14:47 +0000 (13:14 +0100)
this to allow wishbone-SRAM test version to be tested with the same
unit test

src/soc/bus/test/test_minerva.py
src/soc/config/loadstore.py
src/soc/config/test/test_loadstore.py [new file with mode: 0644]
src/soc/experiment/lsmem.py
src/soc/minerva/units/loadstore.py
src/soc/minerva/wishbone.py

index e009c62ad07880df76dbc022b99832d818db2eeb..93ed702c070909110b0ab972d644005a177d4a64 100644 (file)
@@ -1,6 +1,6 @@
 from nmigen_soc.wishbone.sram import SRAM
 from nmigen import Memory, Signal, Module
-from soc.minerva.units.loadstore import BareLoadStoreUnit, CacheLoadStoreUnit
+from soc.minerva.units.loadstore import BareLoadStoreUnit, CachedLoadStoreUnit
 
 
 class TestSRAMBareLoadStoreUnit(BareLoadStoreUnit):
index 37e2bf38f08d18b869fcb4d8295974a00c0df06b..e7d52ff0ebb84bf73ec96bbe98d0c719b50405f0 100644 (file)
@@ -3,14 +3,14 @@
 allows the type of LoadStoreUnit to be run-time selectable
 
 """
-from soc.experiment.pimem import TestMemoryLoadStoreUnit
+from soc.experiment.lsmem import TestMemLoadStoreUnit
 from soc.bus.test.test_minerva import TestSRAMBareLoadStoreUnit
 
 
-class ConfigureableLoadStoreUnit:
+class ConfigLoadStoreUnit:
     def __init__(self, pspec):
-        lsidict = {'testmem': TestMemoryLoadStoreUnit,
-                   'test_bare_wb': TestBareLoadStoreUnit,
+        lsidict = {'testmem': TestMemLoadStoreUnit,
+                   'test_bare_wb': TestSRAMBareLoadStoreUnit,
                    #'test_cache_wb': TestCacheLoadStoreUnit
                   }
         lsikls = lsidict[pspec.ldst_ifacetype]
diff --git a/src/soc/config/test/test_loadstore.py b/src/soc/config/test/test_loadstore.py
new file mode 100644 (file)
index 0000000..b0add59
--- /dev/null
@@ -0,0 +1,103 @@
+from soc.minerva.units.loadstore import LoadStoreUnitInterface
+from nmigen import Signal, Module, Elaboratable, Mux
+from nmigen.utils import log2_int
+import random
+from nmigen.back.pysim import Simulator, Settle
+from soc.config.loadstore import ConfigLoadStoreUnit
+from collections import namedtuple
+
+
+def write_to_addr(dut, addr, value):
+    yield dut.x_addr_i.eq(addr)
+    yield dut.x_st_data_i.eq(value)
+    yield dut.x_st_i.eq(1)
+    yield dut.x_mask_i.eq(-1)
+    yield dut.x_valid_i.eq(1)
+    yield dut.x_stall_i.eq(1)
+    yield
+    yield
+    
+    yield dut.x_stall_i.eq(0)
+    yield
+    yield dut.x_st_i.eq(0)
+    while (yield dut.x_stall_i):
+        yield
+
+
+def read_from_addr(dut, addr):
+    yield dut.x_addr_i.eq(addr)
+    yield dut.x_ld_i.eq(1)
+    yield dut.x_valid_i.eq(1)
+    yield dut.x_stall_i.eq(1)
+    yield
+    yield dut.x_stall_i.eq(0)
+    yield
+    yield dut.x_ld_i.eq(0)
+    yield Settle()
+    while (yield dut.x_stall_i):
+        yield
+    assert (yield dut.x_valid_i)
+    return (yield dut.m_ld_data_o)
+
+
+def write_byte(dut, addr, val):
+    offset = addr & 0x3
+    yield dut.x_addr_i.eq(addr)
+    yield dut.x_st_i.eq(1)
+    yield dut.x_st_data_i.eq(val << (offset * 8))
+    yield dut.x_mask_i.eq(1 << offset)
+    yield dut.x_valid_i.eq(1)
+
+    yield
+    yield dut.x_st_i.eq(0)
+    while (yield dut.x_stall_i):
+        yield
+
+
+def read_byte(dut, addr):
+    offset = addr & 0x3
+    yield dut.x_addr_i.eq(addr)
+    yield dut.x_ld_i.eq(1)
+    yield dut.x_valid_i.eq(1)
+    yield
+    yield dut.x_ld_i.eq(0)
+    yield Settle()
+    while (yield dut.x_stall_i):
+        yield
+    assert (yield dut.x_valid_i)
+    val = (yield dut.m_ld_data_o)
+    return (val >> (offset * 8)) & 0xff
+
+
+if __name__ == '__main__':
+    m = Module()
+    Pspec = namedtuple('Pspec', ['ldst_ifacetype',
+                                 'addr_wid', 'mask_wid', 'reg_wid'])
+    pspec = Pspec(ldst_ifacetype='testmem', addr_wid=64, mask_wid=3, reg_wid=64)
+    dut = ConfigLoadStoreUnit(pspec).lsi
+    m.submodules.dut = dut
+
+    sim = Simulator(m)
+    sim.add_clock(1e-6)
+
+    def process():
+
+        values = [random.randint(0, (1<<32)-1) for x in range(16)]
+
+        for addr, val in enumerate(values):
+            yield from write_to_addr(dut, addr << 2, val)
+        for addr, val in enumerate(values):
+            x = yield from read_from_addr(dut, addr << 2)
+            assert x == val
+
+        values = [random.randint(0, 255) for x in range(16*4)]
+        for addr, val in enumerate(values):
+            yield from write_byte(dut, addr, val)
+        for addr, val in enumerate(values):
+            x = yield from read_byte(dut, addr)
+            assert x == val
+
+    sim.add_sync_process(process)
+    with sim.write_vcd("test_loadstore_tm.vcd", traces=[]):
+        sim.run()
+
index 68b4d0fc77e5de406f968e8482c0ec90a981c33b..e926017646bca872e940e584b37337c766f991f8 100644 (file)
@@ -2,24 +2,23 @@ from soc.minerva.units.loadstore import LoadStoreUnitInterface
 from nmigen import Signal, Module, Elaboratable, Mux
 from nmigen.utils import log2_int
 from soc.experiment.testmem import TestMemory # TODO: replace with TMLSUI
-import random
-
-from nmigen.back.pysim import Simulator, Settle
+from nmigen.cli import rtlil
 
 
 class TestMemLoadStoreUnit(LoadStoreUnitInterface, Elaboratable):
-    def __init__(self, regwid, addrwid, mask_wid=4):
+    def __init__(self, addr_wid=32, mask_wid=4, data_wid=32):
         super().__init__()
-        self.regwid = regwid
-        self.addrwid = addrwid
+        self.regwid = data_wid
+        self.addrwid = addr_wid
         self.mask_wid = mask_wid
 
     def elaborate(self, platform):
         m = Module()
         regwid, addrwid, mask_wid = self.regwid, self.addrwid, self.mask_wid
-        adr_lsb = log2_int(mask_wid)
+        adr_lsb = self.adr_lsbs
 
-        m.submodules.mem = mem = TestMemory(regwid, addrwid, granularity=8)
+        # limit TestMemory to 2^6 entries of regwid size
+        m.submodules.mem = mem = TestMemory(regwid, 6, granularity=8)
 
         do_load = Signal()  # set when doing a load while valid and not stalled
         do_store = Signal() # set when doing a store while valid and not stalled
@@ -42,93 +41,9 @@ class TestMemLoadStoreUnit(LoadStoreUnitInterface, Elaboratable):
         return m
 
 
-def write_to_addr(dut, addr, value):
-    yield dut.x_addr_i.eq(addr)
-    yield dut.x_st_data_i.eq(value)
-    yield dut.x_st_i.eq(1)
-    yield dut.x_mask_i.eq(-1)
-    yield dut.x_valid_i.eq(1)
-    yield dut.x_stall_i.eq(1)
-    yield
-    yield
-    
-    yield dut.x_stall_i.eq(0)
-    yield
-    yield dut.x_st_i.eq(0)
-    while (yield dut.x_stall_i):
-        yield
-
-
-def read_from_addr(dut, addr):
-    yield dut.x_addr_i.eq(addr)
-    yield dut.x_ld_i.eq(1)
-    yield dut.x_valid_i.eq(1)
-    yield dut.x_stall_i.eq(1)
-    yield
-    yield dut.x_stall_i.eq(0)
-    yield
-    yield dut.x_ld_i.eq(0)
-    yield Settle()
-    while (yield dut.x_stall_i):
-        yield
-    assert (yield dut.x_valid_i)
-    return (yield dut.m_ld_data_o)
-
-
-def write_byte(dut, addr, val):
-    offset = addr & 0x3
-    yield dut.x_addr_i.eq(addr)
-    yield dut.x_st_i.eq(1)
-    yield dut.x_st_data_i.eq(val << (offset * 8))
-    yield dut.x_mask_i.eq(1 << offset)
-    yield dut.x_valid_i.eq(1)
-
-    yield
-    yield dut.x_st_i.eq(0)
-    while (yield dut.x_stall_i):
-        yield
-
-
-def read_byte(dut, addr):
-    offset = addr & 0x3
-    yield dut.x_addr_i.eq(addr)
-    yield dut.x_ld_i.eq(1)
-    yield dut.x_valid_i.eq(1)
-    yield
-    yield dut.x_ld_i.eq(0)
-    yield Settle()
-    while (yield dut.x_stall_i):
-        yield
-    assert (yield dut.x_valid_i)
-    val = (yield dut.m_ld_data_o)
-    return (val >> (offset * 8)) & 0xff
-
-
 if __name__ == '__main__':
-    m = Module()
     dut = TestMemLoadStoreUnit(regwid=32, addrwid=4)
-    m.submodules.dut = dut
-
-    sim = Simulator(m)
-    sim.add_clock(1e-6)
-
-    def process():
-
-        values = [random.randint(0, (1<<32)-1) for x in range(16)]
-
-        for addr, val in enumerate(values):
-            yield from write_to_addr(dut, addr << 2, val)
-        for addr, val in enumerate(values):
-            x = yield from read_from_addr(dut, addr << 2)
-            assert x == val
-
-        values = [random.randint(0, 255) for x in range(16*4)]
-        for addr, val in enumerate(values):
-            yield from write_byte(dut, addr, val)
-        for addr, val in enumerate(values):
-            x = yield from read_byte(dut, addr)
-            assert x == val
+    vl = rtlil.convert(dut, ports=[]) # TODOdut.ports())
+    with open("test_lsmem.il", "w") as f:
+        f.write(vl)
 
-    sim.add_sync_process(process)
-    with sim.write_vcd("lsmem.vcd", "lsmem.gtkw", traces=[]):
-        sim.run()
index c74f6042d17fe4a022fa604b342f3627974380a0..c91769c9586a04747b751b456c3331528cd45d7a 100644 (file)
@@ -3,7 +3,7 @@ from nmigen.utils import log2_int
 from nmigen.lib.fifo import SyncFIFO
 
 from soc.minerva.cache import L1Cache
-from soc.minerva.wishbone import wishbone_layout, WishboneArbiter, Cycle
+from soc.minerva.wishbone import make_wb_layout, WishboneArbiter, Cycle
 
 
 __all__ = ["LoadStoreUnitInterface", "BareLoadStoreUnit",
@@ -12,12 +12,12 @@ __all__ = ["LoadStoreUnitInterface", "BareLoadStoreUnit",
 
 class LoadStoreUnitInterface:
     def __init__(self, addr_wid=32, mask_wid=4, data_wid=32):
-        self.dbus = Record(mk_wb_layout(addr_wid, mask_wid, data_wid))
+        self.dbus = Record(make_wb_layout(addr_wid, mask_wid, data_wid))
         self.mask_wid = mask_wid
         self.addr_wid = addr_wid
         self.data_wid = data_wid
-        self.adr_lsbs = log2_int_mask_wid) # LSBs of addr covered by mask
-        badwid = addr_wid-log2_int(self.adr_lsbs) # TODO: is this correct?
+        self.adr_lsbs = log2_int(mask_wid) # LSBs of addr covered by mask
+        badwid = addr_wid-self.adr_lsbs    # TODO: is this correct?
 
         # INPUTS
         self.x_addr_i = Signal(addr_wid)    # address used for loads/stores
index fa6bca3e871c32e2199b9b8b98cca8e83f562782..1f56619fac4659a7b7c16417968079fde746470c 100644 (file)
@@ -15,8 +15,8 @@ class Cycle:
 
 
 def make_wb_layout(addr_wid, mask_wid, data_wid):
-    adr_lsbs = log2_int_mask_wid)        # LSBs of addr covered by mask
-    badwid = addr_wid-log2_int(adr_lsbs) # MSBs (not covered by mask)
+    adr_lsbs = log2_int(mask_wid) # LSBs of addr covered by mask
+    badwid = addr_wid-adr_lsbs    # MSBs (not covered by mask)
 
     return [
     ("adr",   badwid  , DIR_FANOUT),