set separate "iside" signal in LoadStore1 to not confuse it
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 7 Dec 2021 15:51:34 +0000 (15:51 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 7 Dec 2021 15:51:34 +0000 (15:51 +0000)
with instr_fault (exception flag).  starting to experiment getting
instruction-side MMU requests to trigger

src/soc/experiment/test/test_loadstore1.py
src/soc/fu/ldst/loadstore.py

index 8ddfe1308f19f3fe5102dd3d52ce51c329e1930a..e133e437aaabf048234ef170aa2ce790dc740de7 100644 (file)
@@ -65,7 +65,8 @@ test_random = True
 
 def _test_loadstore1_ifetch(dut, mem):
     mmu = dut.submodules.mmu
-    pi = dut.submodules.ldst.pi
+    ldst = dut.submodules.ldst
+    pi = ldst.pi
     icache = dut.submodules.ldst.icache
     wbget.stop = False
 
@@ -75,7 +76,11 @@ def _test_loadstore1_ifetch(dut, mem):
     i_out  = icache.i_out
     i_m_in = icache.m_in
 
-    # first basic test
+    # first virtual memory test
+
+    print ("set process table")
+    yield mmu.rin.prtbl.eq(0x1000000) # set process table
+    yield
 
     # set address to zero, update mem[0] to 01234
     addr = 8
@@ -117,14 +122,15 @@ def _test_loadstore1_ifetch(dut, mem):
     # look up i-cache expecting it to fail
 
     # set address to zero, update mem[0] to 01234
-    addr = 16
+    virt_addr = 0x10200
+    real_addr = virt_addr
     expected_insn = 0x5678
-    mem[addr] = expected_insn
+    mem[real_addr] = expected_insn
 
     yield i_in.priv_mode.eq(1)
     yield i_in.virt_mode.eq(1)
     yield i_in.req.eq(0)
-    yield i_in.nia.eq(addr)
+    yield i_in.nia.eq(virt_addr)
     yield i_in.stop_mark.eq(0)
     yield i_m_in.tlbld.eq(0)
     yield i_m_in.tlbie.eq(0)
@@ -136,7 +142,7 @@ def _test_loadstore1_ifetch(dut, mem):
 
     # miss, stalls for a bit
     yield i_in.req.eq(1)
-    yield i_in.nia.eq(addr)
+    yield i_in.nia.eq(virt_addr)
     yield
     valid = yield i_out.valid
     failed = yield i_out.fetch_failed
@@ -151,6 +157,29 @@ def _test_loadstore1_ifetch(dut, mem):
     yield
     yield
 
+    print("=== test loadstore instruction (instruction fault) ===")
+
+    virt_addr = 0x10200
+
+    yield mmu.l_in.iside.eq(1)
+    yield mmu.l_in.load.eq(1)
+    yield mmu.l_in.valid.eq(1)
+    yield mmu.l_in.priv.eq(1)
+    yield mmu.l_in.addr.eq(virt_addr)
+    #ld_data, exctype, exc = yield from pi_ld(pi, virt_addr, 8, msr_pr=1)
+    #yield ldst.iside.eq(0)
+    yield
+    l_done = yield (mmu.l_out.done)
+    l_err = yield (mmu.l_out.err)
+    while not l_done and not l_err:
+        yield
+        l_done = yield (mmu.l_out.done)
+        l_err = yield (mmu.l_out.err)
+    yield mmu.l_in.valid.eq(0)
+    yield
+    yield
+    yield
+
     wbget.stop = True
 
 
index fdf18292a3d245ad722d52b328cb1503d8ad79c6..a3bff180f290a5b1b384b0027b3de952a24ce731 100644 (file)
@@ -111,6 +111,7 @@ class LoadStore1(PortInterfaceBase):
         self.virt_mode     = Signal()
         self.priv_mode     = Signal()
         self.state        = Signal(State)
+        self.iside         = Signal() # request instruction-side load
         self.instr_fault   = Signal()
         self.align_intr    = Signal()
         self.busy          = Signal()
@@ -380,7 +381,7 @@ class LoadStore1(PortInterfaceBase):
 
         # Update outputs to MMU
         m.d.comb += m_out.valid.eq(mmureq)
-        m.d.comb += m_out.iside.eq(self.instr_fault)
+        m.d.comb += m_out.iside.eq(self.iside)
         m.d.comb += m_out.load.eq(ldst_r.load)
         # m_out.priv <= r.priv_mode; TODO
         m.d.comb += m_out.tlbie.eq(self.tlbie)