pass SPR MicroOp to MMU function unit
[soc.git] / src / soc / simple / core.py
index 8ec18ce968b792fa9645bda671b35e69e0ec40f8..d3a66bb1e9916c50277b1d5b1dc2a859707fc90b 100644 (file)
@@ -32,6 +32,7 @@ from nmutil.util import treereduce
 from soc.fu.compunits.compunits import AllFunctionUnits
 from soc.regfile.regfiles import RegFiles
 from soc.decoder.decode2execute1 import Decode2ToExecute1Type
+from soc.decoder.decode2execute1 import IssuerDecode2ToOperand
 from soc.decoder.power_decoder2 import get_rdflags
 from soc.decoder.decode2execute1 import Data
 from soc.experiment.l0_cache import TstL0CacheBuffer  # test only
@@ -68,19 +69,22 @@ def sort_fuspecs(fuspecs):
 
 class NonProductionCore(Elaboratable):
     def __init__(self, pspec):
+        self.pspec = pspec
 
         # single LD/ST funnel for memory access
         self.l0 = TstL0CacheBuffer(pspec, n_units=1)
         pi = self.l0.l0.dports[0]
 
         # function units (only one each)
+        # only include mmu if enabled in pspec
         self.fus = AllFunctionUnits(pspec, pilist=[pi])
 
         # register files (yes plural)
         self.regs = RegFiles()
 
-        # instruction decoder
-        self.e = Decode2ToExecute1Type() # decoded instruction
+        # instruction decoder - needs a Trap-capable Record (captures EINT etc.)
+        self.e = Decode2ToExecute1Type("core", opkls=IssuerDecode2ToOperand)
+
         self.state = CoreState("core")
         self.raw_insn_i = Signal(32) # raw instruction
         self.bigendian_i = Signal() # bigendian
@@ -92,12 +96,11 @@ class NonProductionCore(Elaboratable):
 
         # start/stop and terminated signalling
         self.core_stopped_i = Signal(reset_less=True)
-        self.core_reset_i = Signal()
         self.core_terminate_o = Signal(reset=0)  # indicates stopped
 
         # create per-FU instruction decoders (subsetted)
         self.decoders = {}
-        self.ees = {}
+        self.des = {}
 
         for funame, fu in self.fus.fus.items():
             f_name = fu.fnunit.name
@@ -109,10 +112,18 @@ class NonProductionCore(Elaboratable):
             self.decoders[funame] = PowerDecodeSubset(None, opkls, f_name,
                                                       final=True,
                                                       state=self.state)
-            self.ees[funame] = self.decoders[funame].e
+            self.des[funame] = self.decoders[funame].do
+
+        if "mmu0" in self.decoders:
+            self.decoders["mmu0"].mmu0_spr_dec = self.decoders["spr0"]
 
     def elaborate(self, platform):
         m = Module()
+        # for testing purposes, to cut down on build time in coriolis2
+        if hasattr(self.pspec, "nocore") and self.pspec.nocore == True:
+            x = Signal() # dummy signal
+            m.d.sync += x.eq(~x)
+            return m
         comb = m.d.comb
 
         m.submodules.fus = self.fus
@@ -128,16 +139,13 @@ class NonProductionCore(Elaboratable):
             comb += v.dec.bigendian.eq(self.bigendian_i)
 
         # ssh, cheat: trap uses the main decoder because of the rewriting
-        self.ees[self.trapunit] = self.e
+        self.des[self.trapunit] = self.e.do
 
         # connect up Function Units, then read/write ports
         fu_bitdict = self.connect_instruction(m)
         self.connect_rdports(m, fu_bitdict)
         self.connect_wrports(m, fu_bitdict)
 
-        # connect up reset
-        m.d.comb += ResetSignal().eq(self.core_reset_i)
-
         return m
 
     def connect_instruction(self, m):
@@ -189,14 +197,14 @@ class NonProductionCore(Elaboratable):
                 with m.Default():
                     # connect up instructions.  only one enabled at a time
                     for funame, fu in fus.items():
-                        e = self.ees[funame]
+                        do = self.des[funame]
                         enable = fu_bitdict[funame]
 
                         # run this FunctionUnit if enabled
                         # route op, issue, busy, read flags and mask to FU
                         with m.If(enable):
                             # operand comes from the *local*  decoder
-                            comb += fu.oper_i.eq_from(e.do)
+                            comb += fu.oper_i.eq_from(do)
                             #comb += fu.oper_i.eq_from_execute1(e)
                             comb += fu.issue_i.eq(self.issue_i)
                             comb += self.busy_o.eq(fu.busy_o)