def test_comparison(op, reference, width): for _ in range(NTESTS): I0, I1 = SIntVector.random(width), SIntVector.random(width) if op is operator.floordiv and I1 == 0: # Skip divide by zero continue expected = Bit(reference(int(I0), int(I1))) assert expected == bool(op(I0, I1))
def signed(value): return SIntVector(value._value, value.num_bits)
#print("ln", bfbin2float(test_vector[0]), bfbin2float(test_vector[1]), # golden_res, actual_res, delta, max_error) assert delta <= max_error def test_add32_targeted(): add32 = Add32() assert Data32(10) == add32(Data32(2), Data32(8)) assert Data32(100000) == add32(Data32(20000), Data32(80000)) assert Data32(2**17 - 2) == add32(Data32(2**16 - 1), Data32(2**16 - 1)) assert Data32(2**31 - 2) == add32(Data32(2**30 - 1), Data32(2**30 - 1)) op = namedtuple("op", ["complex", "func"]) @pytest.mark.parametrize("op", [ op(Add32, lambda x, y: x + y), op(Sub32, lambda x, y: x - y), ]) @pytest.mark.parametrize("args", [(SIntVector.random(32), SIntVector.random(32)) for _ in range(NTESTS)]) def test_addsub(op, args): cop = op.complex() in0 = args[0] in1 = args[1] res = cop(in0, in1) assert res == op.func(in0, in1)
#Generate random bfloat def random_bfloat(): return fpdata(BitVector.random(1), BitVector.random(8), BitVector.random(7)) @pytest.mark.parametrize("fpdata", [ random_bfloat() for _ in range(NTESTS) ]) def test_bfloat_construct(fpdata): fp = BFloat(fpdata) assert fp[-1] == fpdata.sign assert fp[7:-1] == fpdata.exp assert fp[:7] == fpdata.frac @pytest.mark.parametrize("args", [ (random_bfloat(), SIntVector.random(DATAWIDTH)) for _ in range(NTESTS) ]) def test_get_mant(args): #output = input.mantissa (7 bit) fp0 = args[0] in0 = BFloat(fp0) in1 = args[1] inst = asm.fgetmant() res, res_p, _ = pe(inst, in0, in1) assert res == Data(fp0.frac) rtl_tester(inst, in0, in1, res=Data(fp0.frac)) def test_add_exp_imm_targeted(): inst = asm.faddiexp() data0 = Data(0x7F8A)
def alu(alu: ALU, signed: Signed, a: Data, b: Data, d: Bit): if signed: a = SIntVector(a) b = SIntVector(b) mula, mulb = a.sext(16), b.sext(16) else: mula, mulb = a.zext(16), b.zext(16) mul = mula * mulb C = Bit(0) V = Bit(0) if alu == ALU.Add: res, C = a.adc(b, Bit(0)) V = overflow(a, b, res) res_p = C elif alu == ALU.Sub: b_not = ~b res, C = a.adc(b_not, Bit(1)) V = overflow(a, b_not, res) res_p = C elif alu == ALU.Mult0: res, C, V = mul[:16], Bit(0), Bit(0) # wrong C, V res_p = C elif alu == ALU.Mult1: res, C, V = mul[8:24], Bit(0), Bit(0) # wrong C, V res_p = C elif alu == ALU.Mult2: res, C, V = mul[16:32], Bit(0), Bit(0) # wrong C, V res_p = C elif alu == ALU.GTE_Max: # C, V = a-b? pred = a >= b res, res_p = pred.ite(a, b), a >= b elif alu == ALU.LTE_Min: # C, V = a-b? pred = a <= b res, res_p = pred.ite(a, b), a >= b elif alu == ALU.Abs: pred = a >= 0 res, res_p = pred.ite(a, -a), Bit(a[-1]) elif alu == ALU.Sel: res, res_p = d.ite(a, b), Bit(0) elif alu == ALU.And: res, res_p = a & b, Bit(0) elif alu == ALU.Or: res, res_p = a | b, Bit(0) elif alu == ALU.XOr: res, res_p = a ^ b, Bit(0) elif alu == ALU.SHR: res, res_p = a >> Data(b[:4]), Bit(0) elif alu == ALU.SHL: res, res_p = a << Data(b[:4]), Bit(0) elif alu == ALU.Neg: if signed: res, res_p = ~a + Bit(1), Bit(0) else: res, res_p = ~a, Bit(0) else: raise NotImplementedError(alu) Z = res == Bit(0) N = Bit(res[-1]) return res, res_p, Z, N, C, V
def test_operator_by_0(op, reference): I0, I1 = SIntVector.random(5), 0 expected = signed(reference(int(I0), int(I1)), 5) assert expected == int(op(I0, I1))
def test_operator_int_shift(op, reference, width): for _ in range(NTESTS): I0, I1 = SIntVector.random(width), UIntVector.random(width) expected = signed(reference(int(I0), int(I1)), width) assert expected == int(op(I0, I1))
def test_operator_int1(op, reference, width): for _ in range(NTESTS): I = SIntVector.random(width) expected = signed(reference(int(I)), width) assert expected == int(op(I))
for _ in range(NTESTS)]) def test_unsigned_binary(op, args): x, y = args res, _, _ = pe(op.inst, Data(x), Data(y)) assert res == op.func(x, y) rtl_tester(op, x, y, res=res) @pytest.mark.parametrize("op", [ op(asm.lsl(), lambda x, y: x << y), op(asm.asr(), lambda x, y: x >> y), op(asm.smin(), lambda x, y: (x < y).ite(x, y)), op(asm.smax(), lambda x, y: (x > y).ite(x, y)), ]) @pytest.mark.parametrize( "args", [(SIntVector.random(DATAWIDTH), SIntVector.random(DATAWIDTH)) for _ in range(NTESTS)]) def test_signed_binary(op, args): x, y = args res, _, _ = pe(op.inst, Data(x), Data(y)) assert res == op.func(x, y) rtl_tester(op, x, y, res=res) @pytest.mark.parametrize("op", [ op(asm.abs(), lambda x: x if x > 0 else -x), ]) @pytest.mark.parametrize("args", [SIntVector.random(DATAWIDTH) for _ in range(NTESTS)]) def test_signed_unary(op, args): x = args
def __int__(self): if not self.const(): raise Exception("Can't call __int__ on a non-constant") return SIntVector(self.bits()).as_sint()