Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
735bc6518d | ||
|
|
e354cb2742 | ||
|
|
7c7cd451b8 |
@@ -86,15 +86,15 @@
|
||||
|
||||
Система работает в нескольких тактовых доменах:
|
||||
|
||||
- Ethernet RX (`gmii_rx_clk`)
|
||||
- Ethernet TX (`gmii_tx_clk`)
|
||||
- DAC (`dac_clk`)
|
||||
- ADC (`adc_clk`)
|
||||
- Ethernet RX (`clk_axis_control`)
|
||||
- Ethernet TX (`clk_axis_accumulator`)
|
||||
- DAC (`clk_generator`)
|
||||
- ADC (`clk_sampler`)
|
||||
|
||||
Для корректной синхронизации между DAC и ADC используются специальные CDC-регистры для сигналов:
|
||||
|
||||
- `sample_req`
|
||||
- `sample_done`
|
||||
- `done`
|
||||
- `request`
|
||||
|
||||
Это обеспечивает безопасную передачу handshake-сигналов между тактовыми доменами.
|
||||
|
||||
@@ -110,8 +110,8 @@
|
||||
|
||||
Типовые значения:
|
||||
|
||||
- `8192` — середина диапазона ЦАП
|
||||
- `0` — нулевой уровень
|
||||
- `8192` — середина диапазона ЦАП (0V)
|
||||
- `0` — нулевой уровень (-5V)
|
||||
|
||||
### ADC_DATA_WIDTH
|
||||
Ширина входных данных, получаемых с АЦП.
|
||||
@@ -143,3 +143,5 @@
|
||||
```make all``` - собрать все до битстрима
|
||||
|
||||
```make vivado``` - открыть проект в Vivado
|
||||
|
||||
```make sim``` - симуляция и верификация проекта
|
||||
|
||||
@@ -2,6 +2,25 @@
|
||||
|
||||
`include "interfaces.svh"
|
||||
|
||||
// `define DEBUG
|
||||
|
||||
`define MEASURE_CLK(clk, period) \
|
||||
begin \
|
||||
realtime t1, t2; \
|
||||
@(posedge clk); \
|
||||
t1 = $realtime; \
|
||||
@(posedge clk); \
|
||||
t2 = $realtime; \
|
||||
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;
|
||||
//------------------------------------------------------------
|
||||
// Параметры
|
||||
@@ -17,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"
|
||||
|
||||
@@ -26,7 +49,8 @@ module reflectometer_tb;
|
||||
//------------------------------------------------------------
|
||||
// Глобальные перменные
|
||||
//------------------------------------------------------------
|
||||
int unsigned WINDOW_SIZE = 65; // fixed subwindow size to average by time
|
||||
realtime CLK_ADC_PERIOD;
|
||||
realtime CLK_DAC_PERIOD;
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Тактовые сигналы и сброс
|
||||
@@ -38,7 +62,7 @@ module reflectometer_tb;
|
||||
//------------------------------------------------------------
|
||||
// Управление и конфиг DUT
|
||||
//------------------------------------------------------------
|
||||
logic [31:0] window_size;
|
||||
logic [31:0] window_size_port;
|
||||
// AXI-S интерфейс для управления
|
||||
axis_if axis_control_if (
|
||||
.clk(clk_eth_phy),
|
||||
@@ -139,7 +163,7 @@ module reflectometer_tb;
|
||||
// Control AXI-S bus
|
||||
.clk_axis_control(clk_eth_phy), // GMII PHY TX clock
|
||||
.axis_control(axis_control_if.slave),
|
||||
.window_size(window_size), // direct signal crutch (old controller)
|
||||
.window_size(window_size_port), // direct signal crutch (old controller)
|
||||
|
||||
// RTL-MAC handshake
|
||||
.request_ready(request_ready),
|
||||
@@ -155,7 +179,6 @@ module reflectometer_tb;
|
||||
.adc_data(adc_data),
|
||||
.adc_otr(adc_otr)
|
||||
);
|
||||
assign window_size = WINDOW_SIZE;
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Тактовые сигналы
|
||||
@@ -197,7 +220,7 @@ module reflectometer_tb;
|
||||
|
||||
// Ахтунг, 14-битный ЦАП захардкожен
|
||||
if (DAC_DATA_WIDTH != 14)
|
||||
$display("[WARNING] -dut_send_system_config- Default pulse height (DAC bitwidth) is equal to 14. Be aware, controller packet structure is coded for 14 bits");
|
||||
$warning("[WARNING] -dut_send_system_config- Default pulse height (DAC bitwidth) is equal to 14. Be aware, controller packet structure is coded for 14 bits");
|
||||
|
||||
tx_packet = '{
|
||||
8'h88, // Команда
|
||||
@@ -210,25 +233,26 @@ module reflectometer_tb;
|
||||
vif.master_send(tx_packet);
|
||||
|
||||
// TODO remove for new controller
|
||||
WINDOW_SIZE = window_size;
|
||||
window_size_port = window_size;
|
||||
endtask
|
||||
|
||||
// Таски сбора статистики
|
||||
task automatic dut_read_output(
|
||||
virtual axis_if#(8).tb vif,
|
||||
input int sample_num,
|
||||
input int window_size,
|
||||
input bit randomize_recv_delays,
|
||||
output int output_data[]
|
||||
);
|
||||
logic [7:0] rx_packet[];
|
||||
logic [ACCUM_WIDTH-1:0] data_packet[];
|
||||
int numbers_per_packet = PACKET_SIZE/(ACCUM_WIDTH/8);
|
||||
int packet_num = $ceil(real'(sample_num / WINDOW_SIZE) / real'(numbers_per_packet));
|
||||
int packet_num = $ceil(real'(sample_num / window_size) / real'(numbers_per_packet));
|
||||
int timeout_flag = 0;
|
||||
int packet_counter = 0;
|
||||
|
||||
if (sample_num % WINDOW_SIZE) begin
|
||||
$display("[ERROR] -dut_read_output- Sample_num must be multiple of WINDOW_SIZE: %0d %% %0d = %0d", sample_num, WINDOW_SIZE, sample_num % WINDOW_SIZE);
|
||||
if (sample_num % window_size) begin
|
||||
$error("-dut_read_output- Sample_num must be multiple of window_size: %0d %% %0d = %0d", sample_num, window_size, sample_num % window_size);
|
||||
$finish;
|
||||
end
|
||||
|
||||
@@ -256,7 +280,7 @@ module reflectometer_tb;
|
||||
// packet recv loop
|
||||
forever begin
|
||||
if (packet_counter > packet_num) begin
|
||||
$display("[ERROR] -dut_read_output- Packet overflow detected. Number of data packets exceeds expected amount of packets");
|
||||
$error("-dut_read_output- Packet overflow detected. Number of data packets exceeds expected amount of packets");
|
||||
$finish;
|
||||
end
|
||||
|
||||
@@ -278,12 +302,12 @@ module reflectometer_tb;
|
||||
|
||||
disable receive_packet_timeout;
|
||||
if (timeout_flag) begin
|
||||
$display("[ERROR] -dut_read_output- Timeout detected when receiving packet");
|
||||
$error("-dut_read_output- Timeout detected when receiving packet");
|
||||
$finish;
|
||||
end
|
||||
|
||||
if (rx_packet.size() != PACKET_SIZE) begin
|
||||
$display("[ERROR] -dut_read_output- Wrong packet size received: %0d bytes received, %0d bytes expected", rx_packet.size(), PACKET_SIZE);
|
||||
$error("-dut_read_output- Wrong packet size received: %0d bytes received, %0d bytes expected", rx_packet.size(), PACKET_SIZE);
|
||||
$finish;
|
||||
end
|
||||
|
||||
@@ -308,25 +332,323 @@ module reflectometer_tb;
|
||||
disable packet_counter_proc;
|
||||
|
||||
if (packet_counter != packet_num) begin
|
||||
$display("[ERROR] -dut_read_output- Wrong number of packets received: %0d received, %0d expected", packet_counter, packet_num);
|
||||
$error("-dut_read_output- Wrong number of packets received: %0d received, %0d expected", packet_counter, packet_num);
|
||||
$finish;
|
||||
end
|
||||
|
||||
wait(processing_done == 0);
|
||||
|
||||
endtask
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Функции и таски для верификации сигналов
|
||||
//------------------------------------------------------------
|
||||
// Таска генерации идеального тестового сигнала
|
||||
task automatic reference_signal(
|
||||
input int pulse_width,
|
||||
input int pulse_height,
|
||||
input int pulse_period_adc,
|
||||
input int window_size,
|
||||
output real result[]
|
||||
);
|
||||
/*
|
||||
Globals:
|
||||
ADC and DAC clock periods,
|
||||
Virtual ADC and DAC voltage steps
|
||||
|
||||
Task developed with assumption that first discrete values of DAC and ADC
|
||||
are syncrhonized at t==0 and started simultaneously.
|
||||
|
||||
Gains and biases of virtual ADC & DAC are default and ranges are [-5V;5V].
|
||||
Bitwidths may be altered.
|
||||
|
||||
Returned result[] array is an array of sums of voltage potentials in discrete time points.
|
||||
Discrete samples summed over a time window.
|
||||
|
||||
result[time] = (voltage)
|
||||
*/
|
||||
|
||||
int sample_num = pulse_period_adc / window_size; // total averaged output samples from accumulator
|
||||
|
||||
real current_signal_sample, partial_sum;
|
||||
real ref_signal_active_voltage = virtual_dac.code_to_voltage(pulse_height);
|
||||
real ref_signal_zero_voltage = virtual_dac.code_to_voltage(ZERO_LEVEL);
|
||||
|
||||
if (pulse_period_adc % window_size) begin
|
||||
$error("-reference_signal- pulse_period_adc must be multiple of window_size: %0d %% %0d = %0d", pulse_period_adc, window_size, pulse_period_adc % window_size);
|
||||
$finish;
|
||||
end
|
||||
|
||||
result = new[sample_num];
|
||||
partial_sum = 0;
|
||||
|
||||
for (int i = 0; i < pulse_period_adc; i++) begin
|
||||
// var i in ADC timespace
|
||||
// i == 0 is a t0 of pulse generation and sampling
|
||||
current_signal_sample = (i*CLK_ADC_PERIOD <= pulse_width*CLK_DAC_PERIOD) ? ref_signal_active_voltage : ref_signal_zero_voltage;
|
||||
partial_sum += current_signal_sample;
|
||||
if (i % window_size == (window_size-1)) begin
|
||||
result[i / window_size] = partial_sum;
|
||||
partial_sum = 0;
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
// Функция проверки размеров выборок
|
||||
function automatic void check_size(
|
||||
input real a[],
|
||||
input real b[]
|
||||
);
|
||||
if (a.size() != b.size())
|
||||
$fatal(1, "Array size mismatch: %0d != %0d",
|
||||
a.size(), b.size());
|
||||
|
||||
if (a.size() == 0)
|
||||
$error(1, "Empty array");
|
||||
endfunction
|
||||
|
||||
// Среднее по выборке
|
||||
function automatic real array_mean(
|
||||
input real a[]
|
||||
);
|
||||
real sum = 0.0;
|
||||
|
||||
foreach (a[i])
|
||||
sum += a[i];
|
||||
|
||||
return sum / a.size();
|
||||
endfunction
|
||||
|
||||
// MSE двух выборок
|
||||
function automatic real calc_mse(
|
||||
input real a[],
|
||||
input real b[]
|
||||
);
|
||||
real sum = 0.0;
|
||||
|
||||
check_size(a, b);
|
||||
|
||||
foreach (a[i]) begin
|
||||
real err;
|
||||
err = a[i] - b[i];
|
||||
sum += err * err;
|
||||
end
|
||||
|
||||
return sum / a.size();
|
||||
endfunction
|
||||
|
||||
// NRMSE двух выборок (нормирование RMSE)
|
||||
function automatic real calc_nrmse(
|
||||
input real a[],
|
||||
input real b[]
|
||||
);
|
||||
const real EPS = 1e-12;
|
||||
real mse, ms = 0;
|
||||
|
||||
mse = calc_mse(a, b);
|
||||
|
||||
foreach (a[i]) begin
|
||||
ms += a[i] * a[i];
|
||||
end
|
||||
ms /= a.size();
|
||||
|
||||
return $sqrt(mse / (ms + EPS));
|
||||
endfunction
|
||||
|
||||
// Функция модуля
|
||||
function automatic real abs_f(input real x);
|
||||
return (x < 0.0) ? -x : x;
|
||||
endfunction
|
||||
|
||||
// Максимальная абсолютная ошибка
|
||||
function automatic real calc_max_error(
|
||||
input real a[],
|
||||
input real b[]
|
||||
);
|
||||
real max_err = 0.0;
|
||||
|
||||
check_size(a, b);
|
||||
|
||||
foreach (a[i]) begin
|
||||
real err;
|
||||
|
||||
err = abs_f(a[i] - b[i]);
|
||||
|
||||
if (err > max_err)
|
||||
max_err = err;
|
||||
end
|
||||
|
||||
return max_err;
|
||||
endfunction
|
||||
|
||||
// Коэффициент корреляции Пирсона
|
||||
function automatic real calc_pearson(
|
||||
input real a[],
|
||||
input real b[]
|
||||
);
|
||||
real mean_a;
|
||||
real mean_b;
|
||||
real numerator = 0.0;
|
||||
real denom_a = 0.0;
|
||||
real denom_b = 0.0;
|
||||
|
||||
check_size(a, b);
|
||||
|
||||
mean_a = array_mean(a);
|
||||
mean_b = array_mean(b);
|
||||
|
||||
foreach (a[i]) begin
|
||||
real da;
|
||||
real db;
|
||||
|
||||
da = a[i] - mean_a;
|
||||
db = b[i] - mean_b;
|
||||
|
||||
numerator += da * db;
|
||||
denom_a += da * da;
|
||||
denom_b += db * db;
|
||||
end
|
||||
|
||||
if ((denom_a == 0.0) || (denom_b == 0.0))
|
||||
return 0.0;
|
||||
|
||||
return numerator / $sqrt(denom_a * denom_b);
|
||||
endfunction
|
||||
|
||||
// Вспомогательная функция для вывода массива
|
||||
function automatic void display_array_f(input real a[]);
|
||||
$write("\t");
|
||||
foreach(a[i])
|
||||
$write("%f ", a[i]);
|
||||
$write("\n");
|
||||
endfunction
|
||||
|
||||
// Вспомогательная функция для вывода массива
|
||||
function automatic void display_array(input int a[]);
|
||||
$write("\t");
|
||||
foreach(a[i])
|
||||
$write("%0d ", a[i]);
|
||||
$write("\n");
|
||||
endfunction
|
||||
|
||||
// Основная таска типового теста
|
||||
// todo
|
||||
task automatic run_test_case(
|
||||
virtual axis_if#(8).tb ctrl_vif,
|
||||
virtual axis_if#(8).tb accum_vif,
|
||||
input int pulse_width,
|
||||
input int pulse_period,
|
||||
input int pulse_num,
|
||||
input int pulse_height,
|
||||
input int pulse_period_adc,
|
||||
input int window_size,
|
||||
input bit rand_recv_delays,
|
||||
input bit use_reset,
|
||||
output int result
|
||||
);
|
||||
int output_data[]; // raw accum values
|
||||
real output_signal_v[]; // accum values after voltage conversion
|
||||
real reference_signal_v[]; // reference signal voltage values
|
||||
real nrmse, pearson, max_err; // error and correlation metrics
|
||||
|
||||
if (use_reset) begin
|
||||
dut_soft_reset(ctrl_vif);
|
||||
#100;
|
||||
end
|
||||
|
||||
dut_send_system_config(
|
||||
.vif(ctrl_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)
|
||||
);
|
||||
#100;
|
||||
|
||||
dut_start(ctrl_vif);
|
||||
|
||||
dut_read_output(
|
||||
.vif(accum_vif),
|
||||
.sample_num(pulse_period_adc),
|
||||
.window_size(window_size),
|
||||
.randomize_recv_delays(rand_recv_delays),
|
||||
.output_data(output_data)
|
||||
);
|
||||
// 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
|
||||
// zero level for partial sum
|
||||
real zero_level_bias = window_size * virtual_adc.ZERO_CODE;
|
||||
// common voltage multiplier for step & amplifier
|
||||
real voltage_multiplier = virtual_adc.VOLTAGE_STEP / virtual_adc.VOLTAGE_GAIN;
|
||||
// array conversion
|
||||
foreach (output_signal_v[i]) begin
|
||||
real average_code_per_pulse = real'(output_data[i]) / pulse_num;
|
||||
output_signal_v[i] = (average_code_per_pulse - zero_level_bias) * voltage_multiplier;
|
||||
end
|
||||
end
|
||||
|
||||
reference_signal(
|
||||
.pulse_width(pulse_width),
|
||||
.pulse_height(pulse_height),
|
||||
.pulse_period_adc(pulse_period_adc),
|
||||
.window_size(window_size),
|
||||
.result(reference_signal_v)
|
||||
);
|
||||
|
||||
`ifdef DEBUG
|
||||
$display("[TB] Output signal");
|
||||
display_array_f(output_signal_v);
|
||||
$display("[TB] Reference signal");
|
||||
display_array_f(reference_signal_v);
|
||||
`endif
|
||||
|
||||
nrmse = calc_nrmse(output_signal_v, reference_signal_v);
|
||||
pearson = calc_pearson(output_signal_v, reference_signal_v);
|
||||
max_err = calc_max_error(output_signal_v, reference_signal_v);
|
||||
|
||||
`ifdef DEBUG
|
||||
$display("[TB] Metrics:\n\tNRMSE = %0.4f\t|\tPearson = %0.4f\t|\tMax error = %0.4f", nrmse, pearson, max_err);
|
||||
`endif
|
||||
|
||||
// check metrics
|
||||
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
|
||||
|
||||
//------------------------------------------------------------
|
||||
// ОСНОВНОЙ ПРОЦЕСС ТЕСТИРОВАНИЯ
|
||||
//------------------------------------------------------------
|
||||
initial begin
|
||||
int output_data[];
|
||||
int result_flag;
|
||||
int total_failed_tests = 0, total_tests = 0;
|
||||
|
||||
automatic virtual axis_if.tb control_vif = axis_control_if.tb;
|
||||
automatic virtual axis_if.tb accumulator_vif = axis_accumulator_if.tb;
|
||||
|
||||
$display("[TB] DUT initializaton");
|
||||
$info("[TB] DUT initializaton");
|
||||
// Инициализация
|
||||
request_ready = 0;
|
||||
rst_n = 0;
|
||||
@@ -334,40 +656,139 @@ module reflectometer_tb;
|
||||
rst_n = 1;
|
||||
wait(mmcm_locked === 1'b1);
|
||||
#150;
|
||||
$display("[TB] MMCM locked");
|
||||
|
||||
dut_soft_reset(control_vif);
|
||||
#100;
|
||||
|
||||
$info("[TB] MMCM locked");
|
||||
|
||||
// Meause periods because actual values hardcoded in IP
|
||||
fork
|
||||
`MEASURE_CLK(DUT.clk_sampler, CLK_ADC_PERIOD);
|
||||
`MEASURE_CLK(DUT.clk_generator, CLK_DAC_PERIOD);
|
||||
join
|
||||
$info("[TB] ADC & DAC clock periods measured: ADC_period = %0.3f, DAC_period = %0.3f", CLK_ADC_PERIOD, CLK_DAC_PERIOD);
|
||||
|
||||
// Тесты
|
||||
$display("[TB] Tests start");
|
||||
dut_send_system_config(
|
||||
.vif(control_vif),
|
||||
.pulse_width(32'd123),
|
||||
.pulse_period(32'd5000),
|
||||
.pulse_num(16'd1),
|
||||
.pulse_height(14'd15000), // 0V
|
||||
.pulse_period_adc(32'd2600),
|
||||
.window_size(1)
|
||||
$info("[TB] Tests start");
|
||||
$info("[TB] Simple test run");
|
||||
run_test_case(
|
||||
.ctrl_vif(control_vif),
|
||||
.accum_vif(accumulator_vif),
|
||||
.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)
|
||||
);
|
||||
#100;
|
||||
dut_start(control_vif);
|
||||
`ERR_CHECK
|
||||
|
||||
dut_read_output(
|
||||
.vif(accumulator_vif),
|
||||
.sample_num(2600),
|
||||
.randomize_recv_delays(0),
|
||||
.output_data(output_data)
|
||||
);
|
||||
#1000;
|
||||
$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;
|
||||
|
||||
$display("Received %0d numbers", output_data.size());
|
||||
for (int i = 0; i < output_data.size(); i++) begin
|
||||
$write("%0d ", output_data[i]);
|
||||
// Генерируемые параметры
|
||||
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);
|
||||
|
||||
$display("Test #%0d", total_tests);
|
||||
`ifdef DEBUG
|
||||
$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
|
||||
$display("");
|
||||
|
||||
$display("[TB] ALL PASSED");
|
||||
|
||||
$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(1),
|
||||
.result(result_flag)
|
||||
);
|
||||
`ERR_CHECK
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user