dut.i.b.eq(b),
a.eq(AnyConst(64)),
b.eq(AnyConst(64))]
-
comb += dut.i.ctx.op.eq(rec)
-
# Assert that op gets copied from the input to output
for p in rec.ports():
name = p.name
dut_sig = getattr(dut.o.ctx.op, name)
comb += Assert(dut_sig == rec_sig)
- with m.If(rec.insn_type != InternalOp.OP_CMP):
- with m.If(rec.invert_a):
- comb += Assert(dut.o.a == ~a)
- with m.Else():
- comb += Assert(dut.o.a == a)
-
- comb += Assert(dut.o.b == b)
+ with m.If(rec.invert_a):
+ comb += Assert(dut.o.a == ~a)
with m.Else():
- with m.If(rec.invert_a):
- comb += Assert(dut.o.a == ~b)
- with m.Else():
- comb += Assert(dut.o.a == b)
-
- comb += Assert(dut.o.b == a)
-
-
-
-
+ comb += Assert(dut.o.a == a)
+ comb += Assert(dut.o.b == b)
return m
+
class GTCombinerTestCase(FHDLTestCase):
def test_formal(self):
module = Driver()
# operand a to be as-is or inverted
a = Signal.like(self.i.a)
- with m.If(self.i.ctx.op.insn_type != InternalOp.OP_CMP):
- with m.If(self.i.ctx.op.invert_a):
- comb += a.eq(~self.i.a)
- with m.Else():
- comb += a.eq(self.i.a)
-
- comb += self.o.a.eq(a)
- comb += self.o.b.eq(self.i.b)
+ with m.If(self.i.ctx.op.invert_a):
+ comb += a.eq(~self.i.a)
with m.Else():
- with m.If(self.i.ctx.op.invert_a):
- comb += self.o.a.eq(~self.i.b)
- with m.Else():
- comb += self.o.a.eq(self.i.b)
-
- comb += self.o.b.eq(self.i.a)
+ comb += a.eq(self.i.a)
+ comb += self.o.a.eq(a)
+ comb += self.o.b.eq(self.i.b)
##### carry-in #####
comb += is_32bit.eq(self.i.ctx.op.is_32bit)
comb += sign_bit.eq(Mux(is_32bit, self.i.a[31], self.i.a[63]))
-
-
# little trick: do the add using only one add (not 2)
add_a = Signal(self.i.a.width + 2, reset_less=True)
add_b = Signal(self.i.a.width + 2, reset_less=True)
is_positive = Signal(reset_less=True)
is_negative = Signal(reset_less=True)
msb_test = Signal(reset_less=True) # set equal to MSB, invert if OP=CMP
+ is_cmp = Signal(reset_less=True) # true if OP=CMP
so = Signal(reset_less=True)
# TODO: if o[63] is XORed with "operand == OP_CMP"
# that can be used as a test
# see https://bugs.libre-soc.org/show_bug.cgi?id=305#c60
+ comb += is_cmp.eq(self.i.ctx.op.insn_type == InternalOp.OP_CMP)
+ comb += msb_test.eq(o[-1] ^ is_cmp)
comb += is_zero.eq(o == 0)
- comb += is_positive.eq(~is_zero & ~o[63])
- comb += is_negative.eq(~is_zero & o[63])
+ comb += is_positive.eq(~is_zero & ~msb_test)
+ comb += is_negative.eq(~is_zero & msb_test)
comb += so.eq(self.i.so | self.i.ov)
comb += self.o.o.eq(o)
print(f"expected {expected:x}, actual: {alu_out:x}")
self.assertEqual(expected, alu_out)
yield from self.check_extra_alu_outputs(alu, pdecode2,
- simulator)
+ simulator, code)
sim.add_sync_process(process)
with sim.write_vcd("simulator.vcd", "simulator.gtkw",
traces=[]):
sim.run()
- def check_extra_alu_outputs(self, alu, dec2, sim):
+
+ def check_extra_alu_outputs(self, alu, dec2, sim, code):
rc = yield dec2.e.rc.data
if rc:
cr_expected = sim.crl[0].get_range().value
cr_actual = yield alu.n.data_o.cr0
- self.assertEqual(cr_expected, cr_actual)
+ self.assertEqual(cr_expected, cr_actual, code)
op = yield dec2.e.insn_type
if op == InternalOp.OP_CMP.value:
bf = yield dec2.dec.BF
cr_actual = yield alu.n.data_o.cr0
cr_expected = sim.crl[bf].get_range().value
- self.assertEqual(cr_expected, cr_actual)
+ self.assertEqual(cr_expected, cr_actual, code)