async def check_core(dut): width_in = len(dut.input) width_gain = len(dut.gain) width_out = len(dut.output) max_gain = 10 gain_required_bits = int(ceil(log2(max_gain + 1))) gain_decimal_bits = width_gain - gain_required_bits gain_shift = gain_decimal_bits shift = width_in - width_out limits = (-2**(width_out - 1), +2**(width_out - 1) - 1) test_size = 1000 dut.input <= 0 dut.gain <= 0 for i in range(test_size): pix = random.getrandbits(width_in) pig = random.getrandbits(width_gain) pix_signed = int_from_twos_comp(pix, width_in) dut.input <= pix dut.gain <= pig gain = saturate(pig / 2**gain_decimal_bits, (0, 10)) expected = saturate(round_convergent(pix_signed * gain), limits) await Timer(1, units='ns') result = dut.output.value.signed_integer # print(f'pix={pix_signed:15} (0b {twos_comp_from_int(pix_signed, 12):>012b})') # print(f'pig={pig:15} (0b {twos_comp_from_int(pig, 11):>010b})') # print(f'expected={expected:15} (0b {twos_comp_from_int(expected, 14):>014b})') # print(f'result={result:15} (0b {twos_comp_from_int(result, 14):>014b})') assert result == expected, f'{result} != {expected}'
async def trunc(dut): width_in = len(dut.input) width_out = len(dut.output) shift = width_in - width_out dut.input <= 0 for i in range(2**width_in): dut.input <= i di_signed = int_from_twos_comp(i, width_in) expected = floor(di_signed / 2**shift) # or: di_signed >> shift await Timer(1, units='ns') result = dut.output.value.signed_integer assert result == expected, f'{result} != {expected}'
async def check_core(dut): width_in = len(dut.input) width_out = len(dut.output) shift = width_in - width_out limits = (-2**(width_out - 1), +2**(width_out - 1) - 1) dut.input <= 0 for i in range(2**width_in): dut.input <= i di_signed = int_from_twos_comp(i, width_in) expected = saturate(round_convergent(di_signed / 2**shift), limits) await Timer(1, units='ns') result = dut.output.value.signed_integer print(f' in={bin(i)}, out={bin(result)}, exp={bin(expected)}') print(f' input={di_signed}, output={bin(result)}, exp={bin(expected)}') assert result == expected, f'{result} != {expected}'
async def check_core(dut): n_inputs = 8 width_in = len(dut.input_0) width_out = len(dut.output) shift = width_in - width_out limits = (-2**(width_out - 1), +2**(width_out - 1) - 1) test_size = 1000 set_inputs(dut, [0] * n_inputs) for i in range(test_size): inputs = get_random_inputs(width_in, n_inputs) inputs_signed = [int_from_twos_comp(di, width_in) for di in inputs] set_inputs(dut, inputs) expected = saturate( round_convergent(np.mean(inputs_signed) / 2**shift), limits) await Timer(1, units='ns') result = dut.output.value.signed_integer assert result == expected, f'{result} != {expected}'
async def check_core(dut): width_in = len(dut.PiX0) width_weight = len(dut.PiW0) width_out = len(dut.PoZ) test_size = 1000 dec_data = (4, 0, 5) dec_weig = (3, 2, 1) partial_shifts = [a + b for a, b in zip(dec_data, dec_weig)] total_shift = max(partial_shifts) dut.PiX0 <= 0 dut.PiX1 <= 0 dut.PiX2 <= 0 dut.PiW0 <= 0 dut.PiW1 <= 0 dut.PiW2 <= 0 for i in range(test_size): pix0 = random.getrandbits(width_in) pix1 = random.getrandbits(width_in) pix2 = random.getrandbits(width_in) piw0 = random.getrandbits(width_weight) piw1 = random.getrandbits(width_weight) piw2 = random.getrandbits(width_weight) pix0_value = int_from_twos_comp(pix0, width_in) / 2**dec_data[0] pix1_value = int_from_twos_comp(pix1, width_in) / 2**dec_data[1] pix2_value = int_from_twos_comp(pix2, width_in) / 2**dec_data[2] piw0_value = int_from_twos_comp(piw0, width_weight) / 2**dec_weig[0] piw1_value = int_from_twos_comp(piw1, width_weight) / 2**dec_weig[1] piw2_value = int_from_twos_comp(piw2, width_weight) / 2**dec_weig[2] dut.PiX0 <= pix0 dut.PiX1 <= pix1 dut.PiX2 <= pix2 dut.PiW0 <= piw0 dut.PiW1 <= piw1 dut.PiW2 <= piw2 expected = (pix0_value * piw0_value + \ pix1_value * piw1_value + \ pix2_value * piw2_value) * 2**total_shift await Timer(1, units='ns') result = dut.PoZ.value.signed_integer assert result == expected, f'{result} != {expected}'