Merge branch 'master' of ssh://git.libre-riscv.org:922/soc
[soc.git] / src / soc / experiment / pimem.py
index 89ba7714dc85a0d816d2e338a1cfffc18b4520ab..f8a05992b2b49ae29fdcbf7b704d179a9224c6db 100644 (file)
@@ -25,12 +25,12 @@ from nmutil.latch import SRLatch, latchregister
 from nmutil.util import rising_edge
 from soc.decoder.power_decoder2 import Data
 from soc.scoreboard.addr_match import LenExpand
+from soc.experiment.mem_types import LDSTException
 
 # for testing purposes
 from soc.experiment.testmem import TestMemory
 #from soc.scoreboard.addr_split import LDSTSplitter
 
-
 import unittest
 
 
@@ -59,13 +59,13 @@ class PortInterface(RecordObject):
       for the L0 Cache/Buffer to have an additional address latch
       (because the LDSTCompUnit already has it)
 
-    * addr_ok_o (or addr_exc_o) must be waited for.  these will
+    * addr_ok_o (or exception.happened) must be waited for.  these will
       be asserted *only* for one cycle and one cycle only.
 
-    * addr_exc_o will be asserted if there is no chance that the
+    * exception.happened will be asserted if there is no chance that the
       memory request may be fulfilled.
 
-      busy_o is deasserted on the same cycle as addr_exc_o is asserted.
+      busy_o is deasserted on the same cycle as exception.happened is asserted.
 
     * conversely: addr_ok_o must *ONLY* be asserted if there is a
       HUNDRED PERCENT guarantee that the memory request will be
@@ -107,7 +107,7 @@ class PortInterface(RecordObject):
         self.addr = Data(addrwid, "addr_i")            # addr/addr-ok
         # addr is valid (TLB, L1 etc.)
         self.addr_ok_o = Signal(reset_less=True)
-        self.addr_exc_o = Signal(reset_less=True)  # TODO, "type" of exception
+        self.exception_o = LDSTException("exc")
 
         # LD/ST
         self.ld = Data(regwid, "ld_data_o")  # ok to be set by L0 Cache/Buf
@@ -119,6 +119,14 @@ class PortInterface(RecordObject):
         self.virt_mode     = Signal()  # virtual mode
         self.priv_mode     = Signal()  # privileged mode
 
+        # mmu
+        self.mmu_done          = Signal() # keep for now
+       
+        # dcache
+        self.ldst_error        = Signal()
+        ## Signalling ld/st error - NC cache hit, TLB miss, prot/RC failure
+        self.cache_paradox     = Signal()
+
     def connect_port(self, inport):
         print("connect_port", self, inport)
         return [self.is_ld_i.eq(inport.is_ld_i),
@@ -131,7 +139,10 @@ class PortInterface(RecordObject):
                 inport.ld.eq(self.ld),
                 inport.busy_o.eq(self.busy_o),
                 inport.addr_ok_o.eq(self.addr_ok_o),
-                inport.addr_exc_o.eq(self.addr_exc_o),
+                inport.exception_o.eq(self.exception_o),
+                inport.mmu_done.eq(self.mmu_done),
+                inport.ldst_error.eq(self.ldst_error),
+                inport.cache_paradox.eq(self.cache_paradox)
                 ]
 
 
@@ -280,7 +291,7 @@ class PortInterfaceBase(Elaboratable):
             comb += st_done.r.eq(1)     # store done reset
 
         # monitor for an exception or the completion of LD.
-        with m.If(self.pi.addr_exc_o):
+        with m.If(self.pi.exception_o.happened):
             comb += busy_l.r.eq(1)
 
         # however ST needs one cycle before busy is reset