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")
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
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
# 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)
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
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)
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)
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)
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):