Example #1
0
def test_fp_mul():
    # Regression test for https://github.com/StanfordAHA/lassen/issues/111
    inst = asm.fp_mul()
    data0 = Data(0x4040)
    data1 = Data(0x4049)
    res, res_p, _ = pe(inst, data0, data1)
    if CAD_ENV:
        rtl_tester(inst, data0, data1, res=res)
    else:
        pytest.skip("Skipping since DW not available")
Example #2
0
 def __call__(self, in0: Data, in1: Data) -> Data:
     inst1 = asm.fgetmant()
     inst2 = asm.fsubexp()
     inst3 = asm.fp_mul()
     rom_instr = mem_asm.rom([TLUT.div_lut(i) for i in range(0, 128)] +
                             [0x0000] * (depth - 128))
     op_a = in0
     op_b = in1
     mant, _, _ = self.pe_get_mant(inst1, op_b, Data(0))
     lookup_result = self.rom(rom_instr, mant, Data(0))
     scaled_result, _, _ = self.pe_scale_res(inst2, lookup_result, op_b)
     result, _, _ = self.pe_mult(inst3, scaled_result, op_a)
     return result
Example #3
0
 def __call__(self, in0: Data) -> Data:
     inst1 = asm.fgetmant()
     inst2 = asm.fcnvexp2f()
     inst3 = asm.fp_mul()
     inst4 = asm.fp_add()
     rom_instr = mem_asm.rom([TLUT.ln_lut(i) for i in range(0, 128)] +
                             [0x0000] * (depth - 128))
     op_a = in0
     ln2 = math.log(2)
     ln2_bf = int(float2bfbin(ln2), 2)
     const_ln2 = Data(ln2_bf)
     mant, _, _ = self.pe_get_mant(inst1, op_a, Data(0))
     fexp, _, _ = self.pe_get_exp(inst2, op_a, Data(0))
     lookup_result = self.rom(rom_instr, mant, Data(0))
     mult, _, _ = self.pe_mult(inst3, fexp, const_ln2)
     result, _, _ = self.pe_mult(inst4, lookup_result, mult)
     return result
Example #4
0
 def __call__(self, in0: Data) -> Data:
     # Perform op_a/ln(2)
     inst1 = asm.fp_mul()
     # Compute 2**op_a
     inst2 = asm.fgetfint()
     inst3 = asm.fgetffrac()
     inst4 = asm.and_()
     inst5 = asm.faddiexp()
     rom_instr = mem_asm.rom([TLUT.exp_lut(i) for i in range(0, 128)] +
                             [TLUT.exp_lut(i) for i in range(-128, 0)] +
                             [0x0000] * (depth - 256))
     op_a = in0
     ln2_inv = 1.0 / math.log(2)
     ln2_inv_bf = int(float2bfbin(ln2_inv), 2)
     const_ln2_inv = Data(ln2_inv_bf)
     div_res, _, _ = self.pe_div_mult(inst1, const_ln2_inv, op_a)
     fint, _, _ = self.pe_get_int(inst2, div_res, Data(0))
     ffrac, _, _ = self.pe_get_frac(inst3, div_res, Data(0))
     idx, _, _ = self.pe_rom_idx(inst4, ffrac, Data(0xFF))
     lookup_result = self.rom(rom_instr, idx, Data(0))
     result, _, _ = self.pe_incr_exp(inst5, lookup_result, fint)
     return result
Example #5
0
def _make_random(cls):
    if issubclass(cls, hwtypes.BitVector):
        return cls.random(len(cls))
    if issubclass(cls, hwtypes.FPVector):
        while True:
            val = cls.random()
            if val.fp_is_normal():
                return val.reinterpret_as_bv()
    return NotImplemented


_CAD_DIR = "/cad/synopsys/syn/P-2019.03/dw/sim_ver/"
_EXPENSIVE = {
    "bits32.mul": ((umult0(),), "magma_Bits_32_mul_inst0", hwtypes.UIntVector[16]),  # noqa
    "bfloat16.mul": ((fp_mul(),), "magma_BFloat_16_mul_inst0", BFloat16_fc(PyFamily())),  # noqa
    "bfloat16.add": ((fp_add(),), "magma_BFloat_16_add_inst0", BFloat16_fc(PyFamily())),  # noqa
}


@pytest.mark.parametrize("op", list(_EXPENSIVE.keys()))
def test_pe_data_gate(op, dw_files):
    instrs, fu, BV = _EXPENSIVE[op]

    is_float = issubclass(BV, hwtypes.FPVector)
    if not irun_available() and is_float:
        pytest.skip("Need irun to test fp ops")

    core = PeakCore(PE_fc)
    core.name = lambda: "PECore"
    circuit = core.circuit()
Example #6
0
def _make_random(cls):
    if issubclass(cls, hwtypes.BitVector):
        return cls.random(len(cls))
    if issubclass(cls, hwtypes.FPVector):
        while True:
            val = cls.random()
            if val.fp_is_normal():
                return val.reinterpret_as_bv()
    return NotImplemented


_EXPENSIVE = {
    "bits32.mul":
    ((umult0(), ), "magma_Bits_32_mul_inst0", hwtypes.UIntVector[16]),  # noqa
    "bfloat16.mul": ((fp_mul(), ), "magma_BFloat_16_mul_inst0",
                     BFloat16_fc(PyFamily())),  # noqa
    "bfloat16.add": ((fp_add(), ), "magma_BFloat_16_add_inst0",
                     BFloat16_fc(PyFamily())),  # noqa
}


@pytest.mark.parametrize("op", list(_EXPENSIVE.keys()))
def test_pe_data_gate(op, run_tb):
    instrs, fu, BV = _EXPENSIVE[op]

    is_float = issubclass(BV, hwtypes.FPVector)
    if not irun_available() and is_float:
        pytest.skip("Need irun to test fp ops")

    # note to skip mul since CW BFloat is faulty
Example #7
0
#


def BV(val):
    return BFloat16(val)


fp_sign_vec = [BV(2.0), BV(-2.0), BV(3.0), BV(-3.0)]
fp_zero_vec = [BV(0.0), BV('-0.0')]
fp_inf_vec = [BV('inf'), BV('-inf')]


@pytest.mark.parametrize("op", [
    op(asm.fp_add(), lambda x, y: x + y),
    op(asm.fp_sub(), lambda x, y: x - y),
    op(asm.fp_mul(), lambda x, y: x * y)
])
@pytest.mark.parametrize(
    "args", [(BFloat16.random(), BFloat16.random()) for _ in range(NTESTS)] +
    list(product(fp_sign_vec + fp_zero_vec, fp_sign_vec + fp_zero_vec)))
def test_fp_binary_op(op, args):
    inst = op.inst
    in0 = args[0]
    in1 = args[1]
    out = op.func(in0, in1)
    data0 = BFloat16.reinterpret_as_bv(in0)
    data1 = BFloat16.reinterpret_as_bv(in1)
    res, res_p, _ = pe(inst, data0, data1)
    assert res == BFloat16.reinterpret_as_bv(out)
    if CAD_ENV:
        rtl_tester(op, data0, data1, res=res)