upd: TB done

This commit is contained in:
Zer0Nu11
2026-07-31 19:18:59 +03:00
parent 7c7cd451b8
commit e354cb2742
2 changed files with 163 additions and 47 deletions
+153 -39
View File
@@ -1,9 +1,8 @@
`timescale 1ns / 1ps
`include "interfaces.svh"
// start push
`define DEBUG
// `define DEBUG
`define MEASURE_CLK(clk, period) \
begin \
@@ -15,6 +14,13 @@ begin \
period = t2 - t1; \
end
`define ERR_CHECK \
total_tests++; \
if (result_flag) begin \
total_failed_tests++; \
$error("Test #%0d failed. Err code: %0d", total_tests, result_flag); \
end \
module reflectometer_tb;
//------------------------------------------------------------
// Параметры
@@ -30,6 +36,10 @@ module reflectometer_tb;
localparam PACKET_SIZE = 1024; // bytes per UDP packet
localparam int REQUEST_TIMEOUT = 3 * PACKET_SIZE; // timeout for packet receiving from accumulator
localparam int TEST_NUM = 100; // number of random tests
localparam real PEARSON_THRESHOLD = 0.99;
localparam real NRMSE_THRESHOLD = 0.1;
localparam ZERO_LEVEL = LOGIC_ZERO_LEVEL; // "logic" VS "voltage"
@@ -326,6 +336,8 @@ module reflectometer_tb;
$finish;
end
wait(processing_done == 0);
endtask
//------------------------------------------------------------
@@ -425,32 +437,22 @@ module reflectometer_tb;
return sum / a.size();
endfunction
// NRMSE двух выборок (нормирование MSE)
// NRMSE двух выборок (нормирование RMSE)
function automatic real calc_nrmse(
input real a[],
input real b[]
);
real mse;
real min_val;
real max_val;
const real EPS = 1e-12;
real mse, ms = 0;
mse = calc_mse(a, b);
min_val = a[0];
max_val = a[0];
foreach (a[i]) begin
if (a[i] < min_val)
min_val = a[i];
if (a[i] > max_val)
max_val = a[i];
ms += a[i] * a[i];
end
ms /= a.size();
if (max_val == min_val)
return 0.0;
return $sqrt(mse) / (max_val - min_val);
return $sqrt(mse / (ms + EPS));
endfunction
// Функция модуля
@@ -521,6 +523,14 @@ module reflectometer_tb;
$write("\n");
endfunction
// Вспомогательная функция для вывода массива
function automatic void display_array(input int a[]);
$write("\t");
foreach(a[i])
$write("%0d ", a[i]);
$write("\n");
endfunction
// Основная таска типового теста
task automatic run_test_case(
virtual axis_if#(8).tb ctrl_vif,
@@ -533,7 +543,7 @@ module reflectometer_tb;
input int window_size,
input bit rand_recv_delays,
input bit use_reset,
output bit result
output int result
);
int output_data[]; // raw accum values
real output_signal_v[]; // accum values after voltage conversion
@@ -567,6 +577,11 @@ module reflectometer_tb;
);
// actual size of payload is pulse_period_adc / window_size
output_signal_v = new[pulse_period_adc / window_size];
`ifdef DEBUG
$display("[TB] Output data stream");
display_array(output_data);
`endif
// voltage conversion
begin
@@ -605,17 +620,21 @@ module reflectometer_tb;
`endif
// check metrics
result = 1;
if (pearson < 0.99)
result = 0;
if (nrmse > 0.1)
result = 0;
result = 0;
// if (pearson < PEARSON_THRESHOLD)
// result += 1;
if (nrmse > NRMSE_THRESHOLD)
result += 2;
/*
Max error not used in evaluation because of fast pulse edge falling
resulting in plain difference between active signal level and zero level
For ex.: zero_level = 0x00 = -5V. pulse_height = 2^14-1 = 0x3fff = 5V
In some cases like jitter this may cause max error = 5 - (-5) = 10(V)
This cases are hardly traceble, thus max error not used in eval.
Pearson not used in evaluation because it only shows correlation of changing signals. Tests broke on static signals.
Pearson and max err remain in test for info.
*/
endtask
@@ -623,7 +642,7 @@ module reflectometer_tb;
// ОСНОВНОЙ ПРОЦЕСС ТЕСТИРОВАНИЯ
//------------------------------------------------------------
initial begin
bit result_flag;
int result_flag;
int total_failed_tests = 0, total_tests = 0;
automatic virtual axis_if.tb control_vif = axis_control_if.tb;
@@ -646,35 +665,130 @@ module reflectometer_tb;
join
$info("[TB] ADC & DAC clock periods measured: ADC_period = %0.3f, DAC_period = %0.3f", CLK_ADC_PERIOD, CLK_DAC_PERIOD);
dut_soft_reset(control_vif);
#100;
// Тесты
$info("[TB] Tests start");
$info("[TB] Simple test run");
run_test_case(
.ctrl_vif(control_vif),
.accum_vif(accumulator_vif),
.pulse_width(400),
.pulse_width(4000),
.pulse_period(10000),
.pulse_num(5),
.pulse_height(12000),
.pulse_period_adc(6000),
.window_size(10),
.rand_recv_delays(1),
.use_reset(1),
.result(result_flag)
);
`ERR_CHECK
$info("[TB] Random test run");
for (int i = 0; i < TEST_NUM; i++) begin
int pulse_width, pulse_period, pulse_num, pulse_height, pulse_period_adc, window_size;
bit rand_recv_delays, use_reset;
// Генерируемые параметры
pulse_period = $urandom_range(500, 5000);
pulse_width = $urandom_range(50, pulse_period);
pulse_num = $urandom_range(1, 10);
pulse_height = $urandom_range(0, 2**DAC_DATA_WIDTH-1);
window_size = $urandom_range(1, 11);
pulse_period_adc = $urandom_range(50, N_MAX-1) * window_size;
rand_recv_delays = 1;
use_reset = 1; // ($urandom_range(0, 10) >= 9);
`ifdef DEBUG
$display("Test #%0d", total_tests);
$display("Parameters:\n\tpulse_width=%0d\n\tpulse_period=%0d\n\tpulse_num=%0d\n\tpulse_height=%0d\n\tpulse_period_adc=%0d\n\twindow_size=%0d\n\trand_recv_delays=%0d\n\tuse_reset=%0d",
pulse_width, pulse_period, pulse_num, pulse_height, pulse_period_adc, window_size, rand_recv_delays, use_reset);
`endif
run_test_case(
.ctrl_vif(control_vif),
.accum_vif(accumulator_vif),
.pulse_width(pulse_width),
.pulse_period(pulse_period),
.pulse_num(pulse_num),
.pulse_height(pulse_height),
.pulse_period_adc(pulse_period_adc),
.window_size(window_size),
.rand_recv_delays(rand_recv_delays),
.use_reset(use_reset),
.result(result_flag)
);
`ERR_CHECK
if (result_flag) begin
$display("Parameters:\n\tpulse_width=%0d\n\tpulse_period=%0d\n\tpulse_num=%0d\n\tpulse_height=%0d\n\tpulse_period_adc=%0d\n\twindow_size=%0d\n\trand_recv_delays=%0d\n\tuse_reset=%0d",
pulse_width, pulse_period, pulse_num, pulse_height, pulse_period_adc, window_size, rand_recv_delays, use_reset);
end
end
$info("[TB] Corner case test run");
run_test_case(
.ctrl_vif(control_vif),
.accum_vif(accumulator_vif),
.pulse_width(0),
.pulse_period(1000),
.pulse_num(5),
.pulse_height(12000),
.pulse_period_adc(600),
.window_size(10),
.rand_recv_delays(0),
.use_reset(0),
.use_reset(1),
.result(result_flag)
);
`ERR_CHECK
$info("[TB] Random test run");
$info("[TB] Corner case test run");
run_test_case(
.ctrl_vif(control_vif),
.accum_vif(accumulator_vif),
.pulse_width(1000),
.pulse_period(1000),
.pulse_num(5),
.pulse_height(12000),
.pulse_period_adc(600),
.window_size(10),
.rand_recv_delays(0),
.use_reset(1),
.result(result_flag)
);
`ERR_CHECK
// if (!failed)
$info("[TB] ALL PASSED");
run_test_case(
.ctrl_vif(control_vif),
.accum_vif(accumulator_vif),
.pulse_width(500),
.pulse_period(1000),
.pulse_num(5),
.pulse_height(2**(DAC_DATA_WIDTH-1)),
.pulse_period_adc(600),
.window_size(10),
.rand_recv_delays(0),
.use_reset(1),
.result(result_flag)
);
`ERR_CHECK
run_test_case(
.ctrl_vif(control_vif),
.accum_vif(accumulator_vif),
.pulse_width(500),
.pulse_period(1000),
.pulse_num(5),
.pulse_height(15000),
.pulse_period_adc(10),
.window_size(1),
.rand_recv_delays(0),
.use_reset(1),
.result(result_flag)
);
`ERR_CHECK
$display("[TB] Tests done. [%0d/%0d] tests passed, %0d failed", total_tests - total_failed_tests, total_tests, total_failed_tests);
if (!total_failed_tests)
$display("[TB] ALL PASSED");
$finish;
end
endmodule