sort out LoadStore1 misalignment FSM, also required test function pi_ld
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 14 May 2021 11:09:55 +0000 (12:09 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 14 May 2021 11:09:55 +0000 (12:09 +0100)
to be modified to understand exceptions.  pi_st TODO

src/soc/config/test/test_pi2ls.py
src/soc/experiment/test/test_ldst_pi.py
src/soc/fu/ldst/loadstore.py

index f1807ccf3e7d53ec7d4b7ebe29569e4e10fced13..bb363a382d65e18e112b62123b1d5f8b6bb38e35 100644 (file)
@@ -29,8 +29,9 @@ def wait_addr(port):
 def wait_ldok(port):
     while True:
         ldok = yield port.ld.ok
-        print("ldok", ldok)
-        if ldok:
+        exc_happened = yield port.exc_o.happened
+        print("ldok", ldok, "exception", exc_happened)
+        if ldok or exc_happened:
             break
         yield
 
@@ -80,10 +81,14 @@ def pi_ld(port1, addr, datalen, msr_pr=0):
     yield
     yield from wait_ldok(port1)             # wait until ld ok
     data = yield port1.ld.data
+    exc_happened = yield port1.exc_o.happened
 
     # cleanup
     yield port1.is_ld_i.eq(0)  # end
     yield port1.addr.ok.eq(0)  # set !ok
+    if exc_happened:
+        return 0
+
     yield from wait_busy(port1, no=False)    # wait while not busy
 
     return data
index 7ae1c2c74f0659118e5009368c05aca06228f772..c052b1414628580d816fce21ba262e474876d381 100644 (file)
@@ -276,5 +276,5 @@ def test_misalign_mmu():
 
 
 if __name__ == '__main__':
-    #test_mmu()
+    test_mmu()
     test_misalign_mmu()
index 57404747d1ff058cf8e579b60987519dbae7dc0b..e20a77966432cfce911cf56b9282782b4fde0277 100644 (file)
@@ -132,7 +132,6 @@ class LoadStore1(PortInterfaceBase):
         return None
 
     def set_rd_addr(self, m, addr, mask, misalign, msr_pr):
-        m.d.comb += self.d_out.valid.eq(self.d_validblip)
         m.d.comb += self.d_valid.eq(1)
         m.d.comb += self.req.load.eq(1) # load operation
         m.d.comb += self.req.byte_sel.eq(mask)
@@ -151,7 +150,6 @@ class LoadStore1(PortInterfaceBase):
 
     def set_wr_data(self, m, data, wen):
         # do the "blip" on write data
-        m.d.comb += self.d_out.valid.eq(self.d_validblip)
         m.d.comb += self.d_valid.eq(1)
         # put data into comb which is picked up in main elaborate()
         m.d.comb += self.d_w_valid.eq(1)
@@ -188,19 +186,20 @@ class LoadStore1(PortInterfaceBase):
         # a request when MMU_LOOKUP completes.
         m.d.comb += self.d_validblip.eq(rising_edge(m, self.d_valid))
         ldst_r = LDSTRequest("ldst_r")
-        with m.If(self.d_validblip):
-            sync += ldst_r.eq(self.req) # copy of LDSTRequest on "blip"
 
         # fsm skeleton
         with m.Switch(self.state):
             with m.Case(State.IDLE):
-                with m.If(self.d_validblip):
+                with m.If(self.d_validblip & ~exc.happened):
                     comb += self.busy.eq(1)
                     sync += self.state.eq(State.ACK_WAIT)
+                    sync += ldst_r.eq(self.req) # copy of LDSTRequest on "blip"
+                with m.Else():
+                    sync += ldst_r.eq(0)
 
             # waiting for completion
             with m.Case(State.ACK_WAIT):
-                comb += self.busy.eq(1)
+                comb += self.busy.eq(~exc.happened)
 
                 with m.If(d_in.error):
                     # cache error is not necessarily "final", it could
@@ -299,12 +298,14 @@ class LoadStore1(PortInterfaceBase):
         # task 2: if dcache fails, look up in MMU.
         # do **NOT** confuse the two.
         with m.If(self.d_validblip):
+            m.d.comb += self.d_out.valid.eq(~exc.happened)
             m.d.comb += d_out.load.eq(self.req.load)
             m.d.comb += d_out.byte_sel.eq(self.req.byte_sel)
             m.d.comb += self.addr.eq(self.req.addr)
             m.d.comb += d_out.nc.eq(self.req.nc)
             m.d.comb += d_out.priv_mode.eq(self.req.priv_mode)
             m.d.comb += d_out.virt_mode.eq(self.req.virt_mode)
+            m.d.comb += self.align_intr.eq(self.req.align_intr)
         with m.Else():
             m.d.comb += d_out.load.eq(ldst_r.load)
             m.d.comb += d_out.byte_sel.eq(ldst_r.byte_sel)
@@ -312,6 +313,7 @@ class LoadStore1(PortInterfaceBase):
             m.d.comb += d_out.nc.eq(ldst_r.nc)
             m.d.comb += d_out.priv_mode.eq(ldst_r.priv_mode)
             m.d.comb += d_out.virt_mode.eq(ldst_r.virt_mode)
+            m.d.comb += self.align_intr.eq(ldst_r.align_intr)
 
         # XXX these should be possible to remove but for some reason
         # cannot be... yet. TODO, investigate