From cb78905d856fce9fda85fd074b9abd3415c3268f Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Fri, 30 Apr 2021 15:23:34 +0100 Subject: [PATCH] add a TestSRAM variant of LoadStore1, for being able to run unit MMU unit tests --- src/soc/config/loadstore.py | 13 ++++--- src/soc/fu/compunits/compunits.py | 10 +++-- src/soc/fu/compunits/test/test_compunit.py | 9 +++-- src/soc/fu/mmu/fsm.py | 44 +++++++++++++++++++++- src/soc/fu/mmu/test/test_pipe_caller.py | 1 + src/soc/simple/core.py | 8 +++- src/soc/simple/test/test_runner.py | 2 +- 7 files changed, 70 insertions(+), 17 deletions(-) diff --git a/src/soc/config/loadstore.py b/src/soc/config/loadstore.py index 3e42e134..52973f87 100644 --- a/src/soc/config/loadstore.py +++ b/src/soc/config/loadstore.py @@ -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 diff --git a/src/soc/fu/compunits/compunits.py b/src/soc/fu/compunits/compunits.py index cd3bf716..e628c082 100644 --- a/src/soc/fu/compunits/compunits.py +++ b/src/soc/fu/compunits/compunits.py @@ -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(): diff --git a/src/soc/fu/compunits/test/test_compunit.py b/src/soc/fu/compunits/test/test_compunit.py index 2031b20e..11eb8b3c 100644 --- a/src/soc/fu/compunits/test/test_compunit.py +++ b/src/soc/fu/compunits/test/test_compunit.py @@ -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): diff --git a/src/soc/fu/mmu/fsm.py b/src/soc/fu/mmu/fsm.py index 400063e0..a21b73da 100644 --- a/src/soc/fu/mmu/fsm.py +++ b/src/soc/fu/mmu/fsm.py @@ -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) diff --git a/src/soc/fu/mmu/test/test_pipe_caller.py b/src/soc/fu/mmu/test/test_pipe_caller.py index 1c05e881..175347b7 100644 --- a/src/soc/fu/mmu/test/test_pipe_caller.py +++ b/src/soc/fu/mmu/test/test_pipe_caller.py @@ -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 diff --git a/src/soc/simple/core.py b/src/soc/simple/core.py index 5c1dc13f..b5fbbebe 100644 --- a/src/soc/simple/core.py +++ b/src/soc/simple/core.py @@ -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) diff --git a/src/soc/simple/test/test_runner.py b/src/soc/simple/test/test_runner.py index e111d8b4..5d039a36 100644 --- a/src/soc/simple/test/test_runner.py +++ b/src/soc/simple/test/test_runner.py @@ -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' -- 2.30.2