Allow the formal engine to perform a same-cycle result in the ALU
[soc.git] / src / soc / fu / mmu / fsm.py
index ae71f97b80fac3090629117e6b92dbe4e4c31a4a..24be3f5402710bed1fb3a016e672ef12cc13671b 100644 (file)
@@ -45,6 +45,7 @@ class FSMMMUStage(ControlBase):
         # set up p/n data
         self.p.i_data = MMUInputData(pspec)
         self.n.o_data = MMUOutputData(pspec)
+        self.exc_o = self.n.o_data.exception # AllFunctionUnits needs this
 
         self.mmu = MMU()
 
@@ -65,19 +66,21 @@ class FSMMMUStage(ControlBase):
         # incoming PortInterface
         self.ldst = ldst
         self.dcache = self.ldst.dcache
+        self.icache = self.ldst.icache
         self.pi = self.ldst.pi
 
     def elaborate(self, platform):
         assert hasattr(self, "dcache"), "remember to call set_ldst_interface"
         m = super().elaborate(platform)
         comb, sync = m.d.comb, m.d.sync
-        dcache = self.dcache
+        dcache, icache = self.dcache, self.icache
+        ldst = self.ldst # managed externally: do not add here
 
-        # link mmu and dcache together
+        # link mmu, dcache and icache together
         m.submodules.mmu = mmu = self.mmu
-        ldst = self.ldst # managed externally: do not add here
         m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
         m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
+        m.d.comb += icache.m_in.eq(mmu.i_out) # MMUToICacheType
 
         l_in, l_out = mmu.l_in, mmu.l_out
         d_in, d_out = dcache.d_in, dcache.d_out
@@ -88,13 +91,14 @@ class FSMMMUStage(ControlBase):
 
         i_data, o_data = self.p.i_data, self.n.o_data
         op = i_data.ctx.op
-        nia_i = op.nia
+        cia_i = op.cia
+        msr_i = op.msr
         a_i, b_i, spr1_i = i_data.ra, i_data.rb, i_data.spr1
-        o, spr1_o = o_data.o, o_data.spr1
+        o, exc_o, spr1_o = o_data.o, o_data.exception, o_data.spr1
 
         # busy/done signals
-        busy = Signal()
-        done = Signal()
+        busy = Signal(name="mmu_fsm_busy")
+        done = Signal(name="mmu_fsm_done")
         m.d.comb += self.n.o_valid.eq(busy & done)
         m.d.comb += self.p.o_ready.eq(~busy)
 
@@ -212,7 +216,7 @@ class FSMMMUStage(ControlBase):
                 ##########
 
                 with m.Case(MicrOp.OP_FETCH_FAILED):
-                    comb += Display("MMUTEST: OP_FETCH_FAILED: @%x", nia_i)
+                    comb += Display("MMUTEST: OP_FETCH_FAILED: @%x", cia_i)
                     # trigger an instruction fetch failed MMU event.
                     # PowerDecoder2 drops svstate.pc into NIA for us
                     # really, this should be direct communication with the
@@ -221,9 +225,14 @@ class FSMMMUStage(ControlBase):
                     # from accepting any other LD/ST requests.
                     comb += valid.eq(1)   # start "pulse"
                     comb += ldst.instr_fault.eq(blip)
-                    comb += ldst.maddr.eq(nia_i)
-                    comb += done.eq(ldst.done) # zzzz
+                    comb += ldst.priv_mode.eq(~msr_i[MSR.PR])
+                    comb += ldst.maddr.eq(cia_i)
+                    # XXX should not access this!
+                    comb += done.eq(ldst.done)
                     comb += self.debug0.eq(3)
+                    # LDST unit contains exception data, which (messily)
+                    # is copied over, here.  not ideal but it will do for now
+                    comb += exc_o.eq(ldst.pi.exc_o)
 
                 ############
                 # OP_ILLEGAL