add ldst PortInterface misalign unit test (underway)
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 26 May 2021 13:22:45 +0000 (14:22 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 26 May 2021 13:22:49 +0000 (14:22 +0100)
src/soc/experiment/test/test_ldst_pi_misalign.py [new file with mode: 0644]
src/soc/litex/florent

diff --git a/src/soc/experiment/test/test_ldst_pi_misalign.py b/src/soc/experiment/test/test_ldst_pi_misalign.py
new file mode 100644 (file)
index 0000000..df67997
--- /dev/null
@@ -0,0 +1,164 @@
+"""MMU PortInterface Test
+
+quite basic, goes directly to the MMU to assert signals (does not
+yet use PortInterface)
+"""
+
+from nmigen import (C, Module, Signal, Elaboratable, Mux, Cat, Repl, Signal)
+from nmigen.cli import main
+from nmigen.cli import rtlil
+from nmutil.mask import Mask, masked
+from nmutil.util import Display
+
+if True:
+    from nmigen.back.pysim import Simulator, Delay, Settle
+else:
+    from nmigen.sim.cxxsim import Simulator, Delay, Settle
+from nmutil.util import wrap
+
+from soc.config.test.test_pi2ls import pi_ld, pi_st, pi_ldst
+from soc.config.test.test_loadstore import TestMemPspec
+from soc.config.loadstore import ConfigMemoryPortInterface
+
+from soc.fu.ldst.loadstore import LoadStore1
+from soc.experiment.mmu import MMU
+
+from nmigen.compat.sim import run_simulation
+
+
+stop = False
+
+def b(x): # byte-reverse function
+    return int.from_bytes(x.to_bytes(8, byteorder='little'),
+                          byteorder='big', signed=False)
+
+def wb_get(wb, mem):
+    """simulator process for getting memory load requests
+    """
+
+    global stop
+
+    while not stop:
+        while True: # wait for dc_valid
+            if stop:
+                return
+            cyc = yield (wb.cyc)
+            stb = yield (wb.stb)
+            if cyc and stb:
+                break
+            yield
+        addr = (yield wb.adr) << 3
+        if addr not in mem:
+            print ("    WB LOOKUP NO entry @ %x, returning zero" % (addr))
+
+        # read or write?
+        we = (yield wb.we)
+        if we:
+            store = (yield wb.dat_w)
+            sel = (yield wb.sel)
+            data = mem.get(addr, 0)
+            # note we assume 8-bit sel, here
+            res = 0
+            for i in range(8):
+                mask = 0xff << (i*8)
+                if sel & (1<<i):
+                    res |= store & mask
+                else:
+                    res |= data & mask
+            mem[addr] = res
+            print ("    DCACHE set %x mask %x data %x" % (addr, sel, res))
+        else:
+            data = mem.get(addr, 0)
+            yield wb.dat_r.eq(data)
+            print ("    DCACHE get %x data %x" % (addr, data))
+
+        yield wb.ack.eq(1)
+        yield
+        yield wb.ack.eq(0)
+        yield
+
+
+def setup_mmu():
+
+    pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
+                         imem_ifacetype='',
+                         addr_wid=48,
+                         #disable_cache=True, # hmmm...
+                         mask_wid=8,
+                         reg_wid=64)
+
+    m = Module()
+    comb = m.d.comb
+    cmpi = ConfigMemoryPortInterface(pspec)
+    m.submodules.ldst = ldst = cmpi.pi
+    m.submodules.mmu = mmu = MMU()
+    dcache = ldst.dcache
+
+    l_in, l_out = mmu.l_in, mmu.l_out
+    d_in, d_out = dcache.d_in, dcache.d_out
+    wb_out, wb_in = dcache.wb_out, dcache.wb_in
+
+    # link mmu and dcache together
+    m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
+    m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
+
+    # link ldst and MMU together
+    comb += l_in.eq(ldst.m_out)
+    comb += ldst.m_in.eq(l_out)
+
+    return m, cmpi
+
+
+
+def ldst_sim_misalign(dut):
+    mmu = dut.submodules.mmu
+    global stop
+    stop = False
+
+    yield mmu.rin.prtbl.eq(0x1000000) # set process table
+    yield
+
+    data = yield from pi_ld(dut.submodules.ldst.pi, 0x1000, 4, msr_pr=1)
+
+
+def test_misalign_mmu():
+
+    m, cmpi = setup_mmu()
+
+    # virtual "memory" to use for this test
+
+    mem = {0x10000:    # PARTITION_TABLE_2
+                       # PATB_GR=1 PRTB=0x1000 PRTS=0xb
+           b(0x800000000100000b),
+
+           0x30000:     # RADIX_ROOT_PTE
+                        # V = 1 L = 0 NLB = 0x400 NLS = 9
+           b(0x8000000000040009),
+
+           0x40000:     # RADIX_SECOND_LEVEL
+                        #         V = 1 L = 1 SW = 0 RPN = 0
+                           # R = 1 C = 1 ATT = 0 EAA 0x7
+           b(0xc000000000000183),
+
+          0x1000000:   # PROCESS_TABLE_3
+                       # RTS1 = 0x2 RPDB = 0x300 RTS2 = 0x5 RPDS = 13
+           b(0x40000000000300ad),
+
+         # data to return
+          0x1000: 0xdeadbeef01234567,
+          0x1008: 0xfeedf00ff001a5a5
+          }
+
+
+    # nmigen Simulation
+    sim = Simulator(m)
+    sim.add_clock(1e-6)
+
+    sim.add_sync_process(wrap(ldst_sim_misalign(m)))
+    sim.add_sync_process(wrap(wb_get(cmpi.wb_bus(), mem)))
+    with sim.write_vcd('test_ldst_pi_misalign.vcd'):
+        sim.run()
+
+
+if __name__ == '__main__':
+    test_misalign_mmu()
index 670638591d786b042f85f3839c59eb92e34ba1e6..b7ed023c21f58bd69da634df258dbca0ece1f4a1 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 670638591d786b042f85f3839c59eb92e34ba1e6
+Subproject commit b7ed023c21f58bd69da634df258dbca0ece1f4a1