fix Bug 607 - unnecessary code added related to MMU in PowerDecoder2
[soc.git] / src / soc / decoder / power_decoder2.py
index 71aa57aa8c3c1a5c4c2da6cf5277bf3964940011..4cee7ab7c903faeef3416db3f530ed2a10faed98 100644 (file)
@@ -751,6 +751,12 @@ class DecodeCROut(Elaboratable):
         comb += self.whole_reg.ok.eq(0)
         comb += self.sv_override.eq(0)
 
+        # please note these MUST match (setting of cr_bitfield.ok) exactly
+        # with write_cr0 below in PowerDecoder2.  the reason it's separated
+        # is to avoid having duplicate copies of DecodeCROut in multiple
+        # PowerDecoderSubsets.  register decoding should be a one-off in
+        # PowerDecoder2.  see https://bugs.libre-soc.org/show_bug.cgi?id=606
+
         with m.Switch(self.sel_in):
             with m.Case(CROutSel.NONE):
                 pass  # No bitfield activated
@@ -894,24 +900,16 @@ class PowerDecodeSubset(Elaboratable):
 
         # set up submodule decoders
         m.submodules.dec = self.dec
-        m.submodules.dec_rc = dec_rc = DecodeRC(self.dec)
+        m.submodules.dec_rc = self.dec_rc = dec_rc = DecodeRC(self.dec)
         m.submodules.dec_oe = dec_oe = DecodeOE(self.dec)
-        m.submodules.dec_cr_in = self.dec_cr_in = DecodeCRIn(self.dec)
-        m.submodules.dec_cr_out = self.dec_cr_out = DecodeCROut(self.dec)
-        rc_out = dec_rc.rc_out.data
 
         # copy instruction through...
-        for i in [do.insn,
-                  dec_rc.insn_in, dec_oe.insn_in,
-                  self.dec_cr_in.insn_in, self.dec_cr_out.insn_in]:
+        for i in [do.insn, dec_rc.insn_in, dec_oe.insn_in, ]:
             comb += i.eq(self.dec.opcode_in)
 
         # ...and subdecoders' input fields
         comb += dec_rc.sel_in.eq(op.rc_sel)
         comb += dec_oe.sel_in.eq(op.rc_sel)  # XXX should be OE sel
-        comb += self.dec_cr_in.sel_in.eq(op.cr_in)
-        comb += self.dec_cr_out.sel_in.eq(op.cr_out)
-        comb += self.dec_cr_out.rc_in.eq(rc_out)
 
         # copy "state" over
         comb += self.do_copy("msr", msr)
@@ -919,16 +917,8 @@ class PowerDecodeSubset(Elaboratable):
 
         # set up instruction type
         # no op: defaults to OP_ILLEGAL
-        if self.fn_name=="MMU":
-            # mmu is special case: needs SPR opcode as well
-            mmu0 = self.mmu0_spr_dec
-            with m.If(((mmu0.dec.op.internal_op == MicrOp.OP_MTSPR) |
-                       (mmu0.dec.op.internal_op == MicrOp.OP_MFSPR))):
-                comb += self.do_copy("insn_type", mmu0.op_get("internal_op"))
-            with m.Else():
-                comb += self.do_copy("insn_type", self.op_get("internal_op"))
-        else:
-            comb += self.do_copy("insn_type", self.op_get("internal_op"))
+        # FIX https://bugs.libre-soc.org/show_bug.cgi?id=607
+        comb += self.do_copy("insn_type", self.op_get("internal_op"))
 
         # function unit for decoded instruction: requires minor redirect
         # for SPR set/get
@@ -936,18 +926,12 @@ class PowerDecodeSubset(Elaboratable):
         spr = Signal(10, reset_less=True)
         comb += spr.eq(decode_spr_num(self.dec.SPR)) # from XFX
 
-        # XXX BUG - don't use hardcoded magic constants.
-        # also use ".value" otherwise the test fails.  bit of a pain
-        # https://bugs.libre-soc.org/show_bug.cgi?id=603
-
-        SPR_PID   = 48  # TODO read docs for POWER9
         # Microwatt doesn't implement the partition table
-        # instead has PRTBL register (SPR) to point to process table
-        SPR_PRTBL = 720 # see common.vhdl in microwatt, not in POWER9
+        # instead has PRTBL(SVSRR0) register (SPR) to point to process table
         with m.If(((self.dec.op.internal_op == MicrOp.OP_MTSPR) |
                    (self.dec.op.internal_op == MicrOp.OP_MFSPR)) &
-                  ((spr == SPR.DSISR) | (spr == SPR.DAR)
-                   | (spr==SPR_PRTBL) | (spr==SPR_PID))):
+                   ((spr == SPR.DSISR.value) | (spr == SPR.DAR.value) |
+                     (spr==SPR.SVSRR0.value) | (spr==SPR.PIDR.value))):
             comb += self.do_copy("fn_unit", Function.MMU)
         with m.Else():
             comb += self.do_copy("fn_unit",fn)
@@ -966,9 +950,9 @@ class PowerDecodeSubset(Elaboratable):
         comb += self.do_copy("rc", dec_rc.rc_out)
         comb += self.do_copy("oe", dec_oe.oe_out)
 
-        # CR in/out
-        comb += self.do_copy("read_cr_whole", self.dec_cr_in.whole_reg)
-        comb += self.do_copy("write_cr_whole", self.dec_cr_out.whole_reg)
+        # CR in/out - note: these MUST match with what happens in
+        # DecodeCROut!
+        rc_out = self.dec_rc.rc_out.data
         with m.Switch(op.cr_out):
             with m.Case(CROutSel.CR0, CROutSel.CR1):
                 comb += self.do_copy("write_cr0", rc_out) # only when RC=1
@@ -1070,6 +1054,7 @@ class PowerDecode2(PowerDecodeSubset):
         state = self.state
         e_out, op, do_out = self.e, self.dec.op, self.e.do
         dec_spr, msr, cia, ext_irq = state.dec, state.msr, state.pc, state.eint
+        rc_out = self.dec_rc.rc_out.data
         e = self.e_tmp
         do = e.do
 
@@ -1082,6 +1067,8 @@ class PowerDecode2(PowerDecodeSubset):
         m.submodules.dec_c = dec_c = DecodeC(self.dec)
         m.submodules.dec_o = dec_o = DecodeOut(self.dec)
         m.submodules.dec_o2 = dec_o2 = DecodeOut2(self.dec)
+        m.submodules.dec_cr_in = self.dec_cr_in = DecodeCRIn(self.dec)
+        m.submodules.dec_cr_out = self.dec_cr_out = DecodeCROut(self.dec)
 
         # and SVP64 Extra decoders
         m.submodules.crout_svdec = crout_svdec = SVP64CRExtra()
@@ -1102,9 +1089,19 @@ class PowerDecode2(PowerDecodeSubset):
 
         # copy instruction through...
         for i in [do.insn, dec_a.insn_in, dec_b.insn_in,
+                  self.dec_cr_in.insn_in, self.dec_cr_out.insn_in,
                   dec_c.insn_in, dec_o.insn_in, dec_o2.insn_in]:
             comb += i.eq(self.dec.opcode_in)
 
+        # CR setup
+        comb += self.dec_cr_in.sel_in.eq(op.cr_in)
+        comb += self.dec_cr_out.sel_in.eq(op.cr_out)
+        comb += self.dec_cr_out.rc_in.eq(rc_out)
+
+        # CR register info
+        comb += self.do_copy("read_cr_whole", self.dec_cr_in.whole_reg)
+        comb += self.do_copy("write_cr_whole", self.dec_cr_out.whole_reg)
+
         # now do the SVP64 munging.  op.SV_Etype and op.sv_in1 comes from
         # PowerDecoder which in turn comes from LDST-RM*.csv and RM-*.csv
         # which in turn were auto-generated by sv_analysis.py