add a TestSRAM variant of LoadStore1, for being able to run unit MMU unit tests
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 30 Apr 2021 14:23:34 +0000 (15:23 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 30 Apr 2021 14:23:34 +0000 (15:23 +0100)
src/soc/config/loadstore.py
src/soc/fu/compunits/compunits.py
src/soc/fu/compunits/test/test_compunit.py
src/soc/fu/mmu/fsm.py
src/soc/fu/mmu/test/test_pipe_caller.py
src/soc/simple/core.py
src/soc/simple/test/test_runner.py

index 3e42e13478a97bbb18142de4b96d8716f109204c..52973f87696decfdc3cac0cf73e205d00cba95d8 100644 (file)
@@ -11,14 +11,15 @@ from soc.bus.test.test_minerva import TestSRAMBareLoadStoreUnit
 from soc.experiment.pi2ls import Pi2LSUI
 from soc.experiment.pimem import TestMemoryPortInterface
 from soc.minerva.units.loadstore import BareLoadStoreUnit
-from soc.fu.mmu.fsm import LoadStore1 # MMU and DCache
+from soc.fu.mmu.fsm import TestSRAMLoadStore1, LoadStore1 # MMU and DCache
 
 class ConfigLoadStoreUnit:
     def __init__(self, pspec):
         lsidict = {'testmem': TestMemLoadStoreUnit,
-                   'test_bare_wb': TestSRAMBareLoadStoreUnit,
+                   'test_bare_wb': TestSRAMBareLoadStoreUnit, # SRAM added
                    'bare_wb': BareLoadStoreUnit,
-                   'mmu_cache_wb': LoadStore1
+                   'mmu_cache_wb': LoadStore1,
+                   'test_mmu_cache_wb': TestSRAMLoadStore1, # SRAM added
                   }
         lsikls = lsidict[pspec.ldst_ifacetype]
         self.lsi = lsikls(pspec)
@@ -32,8 +33,8 @@ class ConfigMemoryPortInterface:
                                               regwid=pspec.reg_wid) # data bus
             return
         self.lsmem = ConfigLoadStoreUnit(pspec)
-        if self.pspec.ldst_ifacetype == 'mmu_cache_wb':
-            self.pi = self.lsmem.lsi.pi # LoadStore1 already is a PortInterface
+        if self.pspec.ldst_ifacetype in ['mmu_cache_wb', 'test_mmu_cache_wb']:
+            self.pi = self.lsmem.lsi # LoadStore1 already is a PortInterface
             return
         self.pi = Pi2LSUI("mem", lsui=self.lsmem.lsi,
                           addr_wid=pspec.addr_wid, # address range
@@ -41,7 +42,7 @@ class ConfigMemoryPortInterface:
                           data_wid=pspec.reg_wid)  # data bus width
 
     def wb_bus(self):
-        if self.pspec.ldst_ifacetype == 'mmu_cache_wb':
+        if self.pspec.ldst_ifacetype in ['mmu_cache_wb', 'test_mmu_cache_wb']:
             return self.lsmem.lsi.dbus
         return self.lsmem.lsi.slavebus
 
index cd3bf716c33a124b58733fa5bb1ddbc87a0cb9df..e628c0820bbe52e5f9e1aa24afe5d779748ed76d 100644 (file)
@@ -275,14 +275,18 @@ class AllFunctionUnits(Elaboratable):
             print("cut here ==============================")
             alu = self.fus["mmu0"].alu
             print("alu", alu)
-            pi = alu.pi
-            print("pi", pi)
-            pilist = [pi]
+            #pi = alu.pi
+            #print("pi", pi)
+            #pilist = [pi]
         if pilist is None:
             return
+        print ("pilist", pilist)
         for i, pi in enumerate(pilist):
             self.fus["ldst%d" % (i)] = LDSTFunctionUnit(pi, addrwid, i)
 
+    def get_fu(self, name):
+        return self.fus.get(name)
+
     def elaborate(self, platform):
         m = Module()
         for (name, fu) in self.fus.items():
index 2031b20ed236c3e27c0e8299dd67982c01db72de..11eb8b3c7f84e81ed1dc5f038e305d12d2c7c3e6 100644 (file)
@@ -1,4 +1,4 @@
-from nmigen import Module, Signal, ResetSignal
+from nmigen import Module, Signal, ResetSignal, Memory
 
 # NOTE: to use cxxsim, export NMIGEN_SIM_MODE=cxxsim from the shell
 # Also, check out the cxxsim nmigen branch, and latest yosys from git
@@ -128,10 +128,13 @@ def get_inp_indexed(cu, inp):
     return res
 
 
-def get_l0_mem(l0):  # BLECH!
+def get_l0_mem(l0):  # BLECH! this is awful! hunting around through structures
     if hasattr(l0.pimem, 'lsui'):
         return l0.pimem.lsui.mem
-    return l0.pimem.mem.mem
+    mem = l0.pimem.mem
+    if isinstance(mem, Memory): # euuurg this one is for TestSRAMLoadStore1
+        return mem
+    return mem.mem
 
 
 def setup_test_memory(l0, sim):
index 400063e0d94c8c816012b125ba8684f1ec61e077..a21b73da0921200ddc243c909da9412f0dec504e 100644 (file)
@@ -1,5 +1,5 @@
 from nmigen import Elaboratable, Module, Signal, Shape, unsigned, Cat, Mux
-from nmigen import Record
+from nmigen import Record, Memory
 from nmigen import Const
 from soc.fu.mmu.pipe_data import MMUInputData, MMUOutputData, MMUPipeSpec
 from nmutil.singlepipe import ControlBase
@@ -21,11 +21,13 @@ from soc.experiment.mem_types import LoadStore1ToDCacheType, LoadStore1ToMMUType
 from soc.experiment.mem_types import DCacheToLoadStore1Type, MMUToLoadStore1Type
 
 from soc.minerva.wishbone import make_wb_layout
+from soc.bus.sram import SRAM
 
 
 # glue logic for microwatt mmu and dcache
 class LoadStore1(PortInterfaceBase):
     def __init__(self, pspec):
+        self.pspec = pspec
         regwid = pspec.reg_wid
         addrwid = pspec.addr_wid
 
@@ -163,6 +165,44 @@ class LoadStore1(PortInterfaceBase):
         # TODO: memory ports
 
 
+class TestSRAMLoadStore1(LoadStore1):
+    def __init__(self, pspec):
+        super().__init__(pspec)
+        pspec = self.pspec
+        # small 32-entry Memory
+        if (hasattr(pspec, "dmem_test_depth") and
+                isinstance(pspec.dmem_test_depth, int)):
+            depth = pspec.dmem_test_depth
+        else:
+            depth = 32
+        print("TestSRAMBareLoadStoreUnit depth", depth)
+
+        self.mem = Memory(width=pspec.reg_wid, depth=depth)
+
+    def elaborate(self, platform):
+        m = super().elaborate(platform)
+        comb = m.d.comb
+        m.submodules.sram = sram = SRAM(memory=self.mem, granularity=8,
+                                        features={'cti', 'bte', 'err'})
+        dbus = self.dbus
+
+        # directly connect the wishbone bus of LoadStoreUnitInterface to SRAM
+        # note: SRAM is a target (slave), dbus is initiator (master)
+        fanouts = ['dat_w', 'sel', 'cyc', 'stb', 'we', 'cti', 'bte']
+        fanins = ['dat_r', 'ack', 'err']
+        for fanout in fanouts:
+            print("fanout", fanout, getattr(sram.bus, fanout).shape(),
+                  getattr(dbus, fanout).shape())
+            comb += getattr(sram.bus, fanout).eq(getattr(dbus, fanout))
+            comb += getattr(sram.bus, fanout).eq(getattr(dbus, fanout))
+        for fanin in fanins:
+            comb += getattr(dbus, fanin).eq(getattr(sram.bus, fanin))
+        # connect address
+        comb += sram.bus.adr.eq(dbus.adr)
+
+        return m
+
+
 class FSMMMUStage(ControlBase):
     """FSM MMU
 
@@ -221,7 +261,7 @@ class FSMMMUStage(ControlBase):
 
         # link mmu and dcache together
         m.submodules.mmu = mmu = self.mmu
-        m.submodules.ldst = ldst = self.ldst
+        ldst = self.ldst # managed externally: do not add here
         m.d.comb += dcache.m_in.eq(mmu.d_out)
         m.d.comb += mmu.d_in.eq(dcache.m_out)
 
index 1c05e8810d26efa1fb66a8444fa17226536b9f1c..175347b7a57f7dc9c07f5932800d3d2aeea2f5ae 100644 (file)
@@ -218,6 +218,7 @@ class TestRunner(unittest.TestCase):
         fsm = FSMMMUStage(pipe_spec)
         fsm.set_ldst_interface(ldst)
         m.submodules.fsm = fsm
+        m.submodules.ldst = ldst
 
         #FIXME connect fsm inputs
 
index 5c1dc13f48a82940bc04d2d07c323473c0e47043..b5fbbebe559b08843967fc22175288424835c7a0 100644 (file)
@@ -87,8 +87,12 @@ class NonProductionCore(Elaboratable):
         self.fus = AllFunctionUnits(pspec, pilist=[pi])
 
         # link LoadStore1 into MMU
-        if hasattr(self.fus, 'mmu') and hasattr(l0.cmpi, "ldst"):
-            self.fus.mmu.set_ldst_interface(l0.cmpi.ldst)
+        mmu = self.fus.get_fu('mmu0')
+        print ("core pspec", pspec.ldst_ifacetype)
+        print ("core mmu", mmu)
+        print ("core lsmem.lsi", l0.cmpi.lsmem.lsi)
+        if mmu is not None:
+            mmu.alu.set_ldst_interface(l0.cmpi.lsmem.lsi)
 
         # register files (yes plural)
         self.regs = RegFiles(pspec)
index e111d8b460bf5893b91a2689a7716f43fc0e30e6..5d039a360e10f3db5a404c04c811d1e5a0ac968e 100644 (file)
@@ -136,7 +136,7 @@ class TestRunner(FHDLTestCase):
         svstate_i = Signal(32)
 
         if self.microwatt_mmu:
-            ldst_ifacetype = 'mmu_cache_wb'
+            ldst_ifacetype = 'test_mmu_cache_wb'
         else:
             ldst_ifacetype = 'test_bare_wb'
         imem_ifacetype = 'test_bare_wb'