增加测试串行线路采样数据的代码, 可以回答晶体容限\漂移\滤波器效果等问题
This commit is contained in:
250
tb/shinTest/test_filter.py
Executable file
250
tb/shinTest/test_filter.py
Executable file
@@ -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<<i)) != (multi_clk_prev_val & (1<<i))):
|
||||
if (multi_clk_val & (1<<i)) != 0:
|
||||
writer.change(sample[i], timestamp, data_bit)
|
||||
writer.change(noise_sample[i], timestamp, noise_data_bit)
|
||||
|
||||
sample_filter_data = sample_filter_data[1:] + [data_bit, ]
|
||||
noise_sample_filter_data = noise_sample_filter_data[1:] + [noise_data_bit, ]
|
||||
if i == 0:
|
||||
writer.change(sample_out, timestamp, filter_1(sample_filter_data))
|
||||
b1 = filter_1(noise_sample_filter_data)
|
||||
writer.change(noise_sample_out, timestamp, b1)
|
||||
if timestamp > 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<<i)
|
||||
else:
|
||||
multi_clk_prev_val = multi_clk_prev_val ^ (1<<i)
|
||||
|
||||
|
||||
if t == 0:
|
||||
multi_clk_val = ((multi_clk_val << 1) & (2 ** multi_clk_num - 1)) + ((multi_clk_val >> (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")
|
||||
Reference in New Issue
Block a user