+
+ ###############
+ # TDI/TWI/TD/TW. v3.0B p90-91
+ ###############
+ with m.Case(MicrOp.OP_TRAP):
+ to = Signal(len(d_fields.TO))
+ comb += to.eq(d_fields.TO[0:-1])
+
+ a_i = Signal(64)
+ b_i = Signal(64)
+ comb += a_i.eq(dut.i.a)
+ comb += b_i.eq(dut.i.b)
+
+ a_s = Signal(signed(64), reset_less=True)
+ b_s = Signal(signed(64), reset_less=True)
+ a = Signal(64, reset_less=True)
+ b = Signal(64, reset_less=True)
+
+ with m.If(op.is_32bit):
+ comb += a_s.eq(exts(a_i, 32, 64))
+ comb += b_s.eq(exts(b_i, 32, 64))
+ comb += a.eq(a_i[0:32])
+ comb += b.eq(b_i[0:32])
+ with m.Else():
+ comb += a_s.eq(a_i)
+ comb += b_s.eq(b_i)
+ comb += a.eq(a_i)
+ comb += b.eq(b_i)
+
+ lt_s = Signal(reset_less=True)
+ gt_s = Signal(reset_less=True)
+ lt_u = Signal(reset_less=True)
+ gt_u = Signal(reset_less=True)
+ equal = Signal(reset_less=True)
+
+ comb += lt_s.eq(a_s < b_s)
+ comb += gt_s.eq(a_s > b_s)
+ comb += lt_u.eq(a < b)
+ comb += gt_u.eq(a > b)
+ comb += equal.eq(a == b)
+
+ trapbits = Signal(5, reset_less=True)
+ comb += trapbits.eq(Cat(gt_u, lt_u, equal, gt_s, lt_s))
+
+ take_trap = Signal()
+ traptype = op.traptype
+ comb += take_trap.eq(traptype.any() | (trapbits & to).any())
+
+ with m.If(take_trap):
+ expected_msr = Signal(len(msr_o.data))
+ comb += expected_msr.eq(op.msr)
+
+ comb += field(expected_msr, MSRb.IR).eq(0)
+ comb += field(expected_msr, MSRb.DR).eq(0)
+ comb += field(expected_msr, MSRb.FE0).eq(0)
+ comb += field(expected_msr, MSRb.FE1).eq(0)
+ comb += field(expected_msr, MSRb.EE).eq(0)
+ comb += field(expected_msr, MSRb.RI).eq(0)
+ comb += field(expected_msr, MSRb.SF).eq(1)
+ comb += field(expected_msr, MSRb.TM).eq(0)
+ comb += field(expected_msr, MSRb.VEC).eq(0)
+ comb += field(expected_msr, MSRb.VSX).eq(0)
+ comb += field(expected_msr, MSRb.PR).eq(0)
+ comb += field(expected_msr, MSRb.FP).eq(0)
+ comb += field(expected_msr, MSRb.PMM).eq(0)
+
+ # still wrong.
+ # see https://bugs.libre-soc.org/show_bug.cgi?id=325#c120
+ #
+ # saf2: no it's not. Proof by substitution:
+ #
+ # field(R,MSRb.TEs,MSRb.TEe).eq(0)
+ # == field(R,53,54).eq(0)
+ # == R[field_slice(53,54)].eq(0)
+ # == R[slice(63-54, (63-53)+1)].eq(0)
+ # == R[slice(9, 11)].eq(0)
+ # == R[9:11].eq(0)
+ #
+ # Also put proof in py-doc for field().
+
+ comb += field(expected_msr, MSRb.TEs, MSRb.TEe).eq(0)
+
+ comb += field(expected_msr, MSRb.UND).eq(0)
+ comb += field(expected_msr, MSRb.LE).eq(1)
+
+ expected_srr1 = Signal(len(srr1_o.data))
+ comb += expected_srr1.eq(op.msr)
+
+ # Per V3.0B, page 1075
+ comb += field(expected_srr1, 33, 36).eq(0)
+ comb += field(expected_srr1, 42).eq(0) # TM_BAD_THING
+ comb += field(expected_srr1, 43).eq(traptype[0]) # FP
+ comb += field(expected_srr1, 44).eq(traptype[4]) # ILLEG
+ comb += field(expected_srr1, 45).eq(traptype[1]) # PRIV
+ comb += field(expected_srr1, 46).eq(traptype == 0) # TRAP
+ comb += field(expected_srr1, 47).eq(traptype[3]) # ADDR
+
+ comb += [
+ Assert(msr_o.ok),
+ Assert(msr_o.data == expected_msr),
+ Assert(srr0_o.ok),
+ Assert(srr0_o.data == op.cia),
+ Assert(srr1_o.ok),
+ Assert(srr1_o.data == expected_srr1),
+ Assert(nia_o.ok),
+ Assert(nia_o.data == op.trapaddr << 4),
+ ]
+
+ #################
+ # SC. v3.0B p952
+ #################