diff --git a/Makefile b/Makefile index 8ba879b..7125c4a 100644 --- a/Makefile +++ b/Makefile @@ -53,9 +53,14 @@ testShin: vvp -N ./tb/build/shinTest.iverilog -lxt2 || true ./tb/shinTest/check_testcase.py +testFilter: + ./tb/shinTest/test_filter.py + +vcdFilter: + gtkwave ./tb/build/test_filter.vcd 1>/dev/null 2>&1 & vcdShin: - gtkwave ./tb/build/wave.vcd & + gtkwave ./tb/build/wave.vcd 1>/dev/null 2>&1 & ef: sbt "test:runMain test.testModule" diff --git a/tb/shinTest/test_filter.py b/tb/shinTest/test_filter.py new file mode 100755 index 0000000..77a6bd7 --- /dev/null +++ b/tb/shinTest/test_filter.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python +#encoding=utf-8 +import sys +from vcd import VCDWriter +import time +import random + + +def convert_4b_2_5b(data): + conv_table = [0b11110, 0b01001, 0b10100, 0b10101, + 0b01010, 0b01011, 0b01110, 0b01111, + 0b10010, 0b10011, 0b10110, 0b10111, + 0b11010, 0b11011, 0b11100, 0b11101] + + high = conv_table[(data >> 4) & 0xf] + low = conv_table[data & 0xf] + cv = (high << 5 | low) & 0x3ff + return cv + +def data_map_bit(bit_order, use_code = True): + #rom = [0xa5, 0x5a, 0x5a, 0xa5] + rom = list(range(0, 255)) + + if use_code: + byte_order = int(bit_order / 10) + bit_order_in_byte = 9 - int(bit_order % 10) + + if byte_order >= len(rom): + return 0 + else: + data = convert_4b_2_5b(rom[byte_order]) + if (data & (1 << bit_order_in_byte)) != 0: + return 1 + else: + return 0 + else: + byte_order = int(bit_order / 8) + bit_order_in_byte = 7 - int(bit_order % 8) + + if byte_order >= len(rom): + return 0 + else: + data = rom[byte_order] + if (data & (1 << bit_order_in_byte)) != 0: + return 1 + else: + return 0 + +max_noise = 0 +def get_noise(s): + global max_noise + #d = random.randint(-s, s) + d = random.randint(-1, 1) * s + + ''' + if d < 0: + if max_noise < -d: + max_noise = -d + else: + if max_noise < d: + max_noise = d + #print(f"{d}ns") + ''' + return d + +def filter_1(data, num = 9): + #''' + one_ctr = 0 + zero_ctr = 0 + for i in range(num): + if data[i] == 0: + zero_ctr = zero_ctr + 1 + else: + one_ctr = one_ctr + 1 + if zero_ctr > one_ctr: + return 0 + else: + return 1 + + ''' + r = data[0]+data[1]*2 +data[2]*8+data[3]*8+data[4]*8+data[5]*8+data[6]*2+data[7] + if r >= 16: + return 1 + else: + return 0 + #''' + + +if __name__ == '__main__': + f = open("./tb/build/test_filter.vcd", "wt+", encoding="utf-8", newline="\n") + + ratio = 100 + multi_clk_num = 16 #(4, 8, 16) + + sys_clk_val = 1 + + tx_ratio = ratio + + sim_stop_time = 525000 * multi_clk_num #ns + #噪声强度 + phrase_noise_strength = int(multi_clk_num * ratio * 2 * 0.374) + + + reset_delay=100 #ns + ref_dout_delay = reset_delay + 100 #ns + ref_tx_dout_delay = reset_delay + 100 #ns + tx_dout_delay = ref_tx_dout_delay #ns + + + random.seed(int(time.time() * 1000)) + + + multi_clk_val = (2 ** int(multi_clk_num / 2) - 1) << int(multi_clk_num / 2) + multi_clk_val = ((multi_clk_val << 1) & (2 ** multi_clk_num - 1)) + ((multi_clk_val >> (multi_clk_num - 1)) & 0x1) + multi_clk_prev_val = multi_clk_val + + + filter_result_check_delay = 375 * multi_clk_num + + + ref_clk_val = 1 + with VCDWriter(f, timescale='1 ns', date='today') as writer: + sys_clk = writer.register_var('ebus.clock', 'sys_clk', 'wire', size=1, init=0) + multi_clk = writer.register_var('ebus.clock', 'multi_clk', 'reg', size=multi_clk_num, init=0) + ref_clk = writer.register_var('ebus.clock', 'ref_clk', 'wire', size=1, init=0) + + #接收时钟 + rx_clk = writer.register_var('ebus', 'rx_clk', 'wire', size=1, init=0) + rx_clk_val = 0 + rx_clk_prev_val = 0 + + #发送时钟 + tx_clk = writer.register_var('ebus', 'tx_clk', 'wire', size=1, init=0) + tx_clk_val = 0 + tx_clk_prev_val = 0 + + data_out = writer.register_var('ebus', 'data_out', 'wire', size=1, init=0) + data_index = 0 + + ref_data_out = writer.register_var('ebus', 'ref_data_out', 'wire', size=1, init=0) + ref_data_index = 0 + + nosie_data_out = writer.register_var('ebus', 'nosie_data_out', 'wire', size=1, init=0) + nosie_data_index = 0 + + sample = list() + noise_sample = list() + for i in range(multi_clk_num): + sample.append(writer.register_var('ebus.sample', f'sample_{i}', 'wire', size=1, init=0)) + noise_sample.append(writer.register_var('ebus.sample', f'noise_sample_{i}', 'wire', size=1, init=0)) + sample_out = writer.register_var('ebus.sample', f'sample_out', 'wire', size=1, init=0) + noise_sample_out = writer.register_var('ebus.sample', f'noise_sample_out', 'wire', size=1, init=0) + + + ref_sample_out = writer.register_var('ebus.sample', f'ref_sample_out', 'wire', size=1, init=0) + ref_sample_out_index = 0 + + filter_result_check = writer.register_var('ebus.sample', f'filter_result_check', 'wire', size=1, init=0) + + data_bit = 0 + noise_data_bit = 0 + noise_dout_time = int((tx_dout_delay + tx_ratio * multi_clk_num * 2 - 1) / (tx_ratio * multi_clk_num * 2)) * (tx_ratio * multi_clk_num * 2) + noise_time = get_noise(phrase_noise_strength) + #noise_dout_time_next = int((tx_dout_delay + tx_ratio * multi_clk_num * 2 - 1) / (tx_ratio * multi_clk_num * 2)) * (tx_ratio * multi_clk_num * 2) + (tx_ratio * multi_clk_num * 2) + get_noise(phrase_noise_strength) + sample_filter_data = [0, ] * multi_clk_num + noise_sample_filter_data = [0, ] * multi_clk_num + + for timestamp in range(sim_stop_time): + if timestamp >= reset_delay: + writer.change(sys_clk, timestamp, sys_clk_val) + + t = timestamp % (2 * ratio) + + if t == 0: + writer.change(multi_clk, timestamp, multi_clk_val) + + if t == 0: + rx_clk_val = multi_clk_val & 0x1 + if rx_clk_val != rx_clk_prev_val: + writer.change(rx_clk, timestamp, rx_clk_val) + rx_clk_prev_val = rx_clk_val + + + #这里输出数据,主要做参考使用 + if (rx_clk_val == 1) and (timestamp >= ref_dout_delay): + ref_data_bit = data_map_bit(ref_data_index)#, True) + writer.change(ref_data_out, timestamp, ref_data_bit) + ref_data_index = ref_data_index + 1 + + #发送数据 + t2 = timestamp % (tx_ratio * multi_clk_num) + if (t2 == 0) and (timestamp >= ref_tx_dout_delay): + #if tx_clk_val != tx_clk_prev_val: + writer.change(tx_clk, timestamp, tx_clk_val) + if tx_clk_val == 1: + data_bit = data_map_bit(data_index)#, True) + writer.change(data_out, timestamp, data_bit) + data_index = data_index + 1 + + tx_clk_prev_val = tx_clk_val + tx_clk_val = 1 - tx_clk_val + + #发送带噪声的数据 + if timestamp >= (noise_dout_time + noise_time): + noise_data_bit = data_map_bit(nosie_data_index) + writer.change(nosie_data_out, timestamp, noise_data_bit) + nosie_data_index = nosie_data_index + 1 + noise_dout_time = noise_dout_time + (tx_ratio * multi_clk_num * 2) + noise_time = get_noise(phrase_noise_strength) + + #采样数据 + if t == 0: + #空间采样时钟发生沿跳变 + for i in range(multi_clk_num): + if ((multi_clk_val & (1< filter_result_check_delay: + b2 = data_map_bit(ref_sample_out_index) + writer.change(ref_sample_out, timestamp, b2) + writer.change(filter_result_check, timestamp, b1 ^ b2) + + ref_sample_out_index = ref_sample_out_index + 1 + + + multi_clk_prev_val = multi_clk_prev_val | (1<> (multi_clk_num - 1)) & 0x1) + + if timestamp % (ratio) == 0: + writer.change(ref_clk, timestamp, ref_clk_val) + ref_clk_val = 1 - ref_clk_val + + #更新sys时钟 + sys_clk_val = 1 - sys_clk_val + + f.close() + print(f"max_noise={max_noise}ns") \ No newline at end of file