slowly morphing towards using an XER bit-field selector in decoder
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 29 Aug 2020 19:42:35 +0000 (20:42 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 29 Aug 2020 19:42:43 +0000 (20:42 +0100)
src/soc/decoder/decode2execute1.py
src/soc/decoder/power_decoder2.py
src/soc/decoder/power_regspec_map.py
src/soc/fu/test/common.py

index 00a225ed3d2b5f5e459f13abf8aadd36177282f1..98ed32f67790453cefb03a0f793fd539d6514bcb 100644 (file)
@@ -79,7 +79,7 @@ class Decode2ToExecute1Type(RecordObject):
         self.read_spr1 = Data(SPR, name="spr1")
         #self.read_spr2 = Data(SPR, name="spr2") # only one needed
 
-        self.xer_in = Signal(reset_less=True)   # xer might be read
+        self.xer_in = Signal(3, reset_less=True)   # xer might be read
         self.xer_out = Signal(reset_less=True)  # xer might be written
 
         self.read_fast1 = Data(3, name="fast1")
index f838a7426e6d838ecb28f52f02dfc50dd1a67874..b0142c15c670b2623fa5a5a6ad99d53ba090b808 100644 (file)
@@ -8,6 +8,7 @@ over-riding the internal opcode when an exception is needed.
 
 from nmigen import Module, Elaboratable, Signal, Mux, Const, Cat, Repl, Record
 from nmigen.cli import rtlil
+from soc.regfile.regfiles import XERRegs
 
 from nmutil.picker import PriorityPicker
 from nmutil.iocontrol import RecordObject
@@ -457,6 +458,7 @@ class DecodeOE(Elaboratable):
             with m.Case(MicrOp.OP_MUL_H64, MicrOp.OP_MUL_H32,
                         MicrOp.OP_EXTS, MicrOp.OP_CNTZ,
                         MicrOp.OP_SHL, MicrOp.OP_SHR, MicrOp.OP_RLC,
+                        MicrOp.OP_LOAD, MicrOp.OP_STORE,
                         MicrOp.OP_RLCL, MicrOp.OP_RLCR,
                         MicrOp.OP_EXTSWSLI):
                 pass
@@ -727,7 +729,9 @@ class PowerDecode2(Elaboratable):
         # decoder is designed to not need.  MTSPR, MFSPR and others need
         # access to the XER bits.  however setting e.oe is not appropriate
         with m.If(op.internal_op == MicrOp.OP_MFSPR):
-            comb += e.xer_in.eq(1)
+            comb += e.xer_in.eq(0b111) # SO, CA, OV
+        with m.If(op.internal_op == MicrOp.OP_CMP):
+            comb += e.xer_in.eq(1<<XERRegs.SO) # SO
         with m.If(op.internal_op == MicrOp.OP_MTSPR):
             comb += e.xer_out.eq(1)
 
index 97f62ee614326a06fe4029a733eaa35dca9ba168..65caf014946696c9c8c523a87c0d24ab300b42a7 100644 (file)
@@ -77,12 +77,14 @@ def regspec_decode_read(e, regfile, name):
         if name == 'xer_so':
             # SO needs to be read for overflow *and* for creation
             # of CR0 and also for MFSPR
-            return ((e.do.oe.oe[0] & e.do.oe.oe_ok) | e.xer_in |
+            return ((e.do.oe.oe[0] & e.do.oe.oe_ok) | (e.xer_in & SO == SO)|
                      (e.do.rc.rc & e.do.rc.ok)), SO
         if name == 'xer_ov':
-            return (e.do.oe.oe[0] & e.do.oe.oe_ok) | e.xer_in, OV
+            return ((e.do.oe.oe[0] & e.do.oe.oe_ok) |
+                    (e.xer_in & CA == CA)), OV
         if name == 'xer_ca':
-            return (e.do.input_carry == CryIn.CA.value) | e.xer_in, CA
+            return ((e.do.input_carry == CryIn.CA.value) |
+                    (e.xer_in & OV == OV)), CA
 
     # STATE regfile
 
index 63f1b67789d04508d30dc7358820847c456b3a9b..1631747cbbfb67e019af4712ffc071a6990ea0b3 100644 (file)
@@ -8,7 +8,7 @@ import functools
 import types
 from soc.decoder.power_enums import XER_bits, CryIn, spr_dict
 from soc.regfile.util import fast_reg_to_spr  # HACK!
-from soc.regfile.regfiles import FastRegs
+from soc.regfile.regfiles import XERRegs, FastRegs
 
 
 # TODO: make this a util routine (somewhere)
@@ -203,7 +203,7 @@ class ALUHelpers:
     def get_rd_sim_xer_ca(res, sim, dec2):
         cry_in = yield dec2.e.do.input_carry
         xer_in = yield dec2.e.xer_in
-        if xer_in or cry_in == CryIn.CA.value:
+        if (xer_in & (1<<XERRegs.CA)) or cry_in == CryIn.CA.value:
             expected_carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
             expected_carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0
             res['xer_ca'] = expected_carry | (expected_carry32 << 1)
@@ -445,7 +445,7 @@ class ALUHelpers:
         oe_ok = yield dec2.e.do.oe.ok
         xer_in = yield dec2.e.xer_in
         print("get_sim_xer_ov", xer_in)
-        if xer_in or (oe and oe_ok):
+        if (xer_in & (1<<XERRegs.OV)) or (oe and oe_ok):
             expected_ov = 1 if sim.spr['XER'][XER_bits['OV']] else 0
             expected_ov32 = 1 if sim.spr['XER'][XER_bits['OV32']] else 0
             res['xer_ov'] = expected_ov | (expected_ov32 << 1)
@@ -457,7 +457,7 @@ class ALUHelpers:
         xer_in = yield dec2.e.xer_in
         rc = yield dec2.e.do.rc.rc
         rc_ok = yield dec2.e.do.rc.ok
-        if xer_in or (oe and oe_ok) or (rc and rc_ok):
+        if (xer_in & (1<<XERRegs.SO)) or (oe and oe_ok) or (rc and rc_ok):
             res['xer_so'] = 1 if sim.spr['XER'][XER_bits['SO']] else 0
 
     def check_slow_spr1(dut, res, sim_o, msg):