diff --git a/power_fv/checks/insn/_cr.py b/power_fv/checks/insn/_cr.py index d604cd6..77dbea3 100644 --- a/power_fv/checks/insn/_cr.py +++ b/power_fv/checks/insn/_cr.py @@ -33,12 +33,11 @@ class CRSpec(Elaboratable): # CR - spec_cr_r_stb = Signal( 8) - spec_cr_w_stb = Signal( 8) + spec_cr_r_stb = Signal(8) + spec_cr_w_stb = Signal(8) spec_cr_w_data = Signal(32) - if isinstance(spec_insn, (Instruction_XL_crl)): - + if isinstance(spec_insn, Instruction_XL_crl): ba_r_field = Signal(4) bb_r_field = Signal(4) bt_r_field = Signal(4) @@ -89,6 +88,18 @@ class CRSpec(Elaboratable): spec_cr_w_stb[::-1].bit_select(spec_insn.bt[2:], width=1).eq(1), spec_cr_w_data[::-1].eq(Repl(spec_bt_w_field, 8)) ] + + elif isinstance(spec_insn, MCRF): + bfa_r_field = Signal(4) + + m.d.comb += [ + bfa_r_field.eq(self.pfv.cr.r_data[::-1].word_select(spec_insn.bfa, width=4)), + + spec_cr_r_stb[::-1].bit_select(spec_insn.bfa, width=1).eq(1), + spec_cr_w_stb[::-1].bit_select(spec_insn.bf, width=1).eq(1), + spec_cr_w_data[::-1].eq(Repl(bfa_r_field, 8)), + ] + else: assert False diff --git a/power_fv/checks/insn/_fmt.py b/power_fv/checks/insn/_fmt.py index 14a1322..548daca 100644 --- a/power_fv/checks/insn/_fmt.py +++ b/power_fv/checks/insn/_fmt.py @@ -3,7 +3,11 @@ from amaranth.asserts import AnyConst from amaranth.hdl.ast import ValueCastable -__all__ = ["Instruction_I", "Instruction_B", "Instruction_XL_bc", "Instruction_XL_crl"] +__all__ = [ + "Instruction_I", + "Instruction_B", + "Instruction_XL_bc", "Instruction_XL_crl", "Instruction_XL_crf", +] class Instruction_I(ValueCastable): @@ -94,3 +98,30 @@ class Instruction_XL_crl(ValueCastable): @ValueCastable.lowermethod def as_value(self): return Cat(self._0, self.xo, self.bb, self.ba, self.bt, self.po) + + +class Instruction_XL_crf(ValueCastable): + po = None + bf = None + _0 = None + bfa = None + _1 = None + _2 = None + xo = None + _3 = None + + def __init_subclass__(cls, *, po, xo): + cls.po = Const(po, unsigned( 6)) + cls.xo = Const(xo, unsigned(10)) + + def __init__(self): + self.bf = AnyConst(unsigned(3)) + self._0 = AnyConst(unsigned(2)) + self.bfa = AnyConst(unsigned(3)) + self._1 = AnyConst(unsigned(2)) + self._2 = AnyConst(unsigned(5)) + self._3 = AnyConst(unsigned(1)) + + @ValueCastable.lowermethod + def as_value(self): + return Cat(self._3, self.xo, self._2, self._1, self.bfa, self._0, self.bf, self.po) diff --git a/power_fv/checks/insn/_insn.py b/power_fv/checks/insn/_insn.py index 7799bc5..7ac9218 100644 --- a/power_fv/checks/insn/_insn.py +++ b/power_fv/checks/insn/_insn.py @@ -29,3 +29,5 @@ class CRNOR (_fmt.Instruction_XL_crl, po=19, xo= 33): pass class CRANDC (_fmt.Instruction_XL_crl, po=19, xo=129): pass class CREQV (_fmt.Instruction_XL_crl, po=19, xo=289): pass class CRORC (_fmt.Instruction_XL_crl, po=19, xo=417): pass + +class MCRF (_fmt.Instruction_XL_crf, po=19, xo=0): pass diff --git a/power_fv/checks/insn/all.py b/power_fv/checks/insn/all.py index 4ee9080..200a14c 100644 --- a/power_fv/checks/insn/all.py +++ b/power_fv/checks/insn/all.py @@ -31,3 +31,5 @@ class CRNOR (CRCheck, name="insn_crnor", insn_cls=_insn.CRNOR ): pass class CRANDC (CRCheck, name="insn_crandc", insn_cls=_insn.CRANDC): pass class CREQV (CRCheck, name="insn_creqv", insn_cls=_insn.CREQV ): pass class CRORC (CRCheck, name="insn_crorc", insn_cls=_insn.CRORC ): pass + +class MCRF (CRCheck, name="insn_mcrf", insn_cls=_insn.MCRF ): pass