fix: encoding issues, generator explicit default state

This commit is contained in:
2026-07-17 15:21:49 +03:00
parent 4240604f26
commit 04eb927a25
2 changed files with 61 additions and 56 deletions

View File

@ -3,7 +3,7 @@
module tb_top; module tb_top;
//------------------------------------------------------------ //------------------------------------------------------------
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Параметры
//------------------------------------------------------------ //------------------------------------------------------------
parameter string ZERO_LEVEL_PARAM = "logic"; // "logic" VS "true" parameter string ZERO_LEVEL_PARAM = "logic"; // "logic" VS "true"
parameter VERBOSE = 1; parameter VERBOSE = 1;
@ -22,14 +22,14 @@ module tb_top;
localparam CLOCK_DEVIATION = 3; // Maximum clock deviation of pulse stats localparam CLOCK_DEVIATION = 3; // Maximum clock deviation of pulse stats
//------------------------------------------------------------ //------------------------------------------------------------
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> // Тактовые сигналы и сброс
//------------------------------------------------------------ //------------------------------------------------------------
logic clk_dac; logic clk_dac;
logic rst_dac; logic rst_dac;
logic clk_adc; logic clk_adc;
logic rst_adc; logic rst_adc;
//------------------------------------------------------------ //------------------------------------------------------------
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Управление и конфиг
//------------------------------------------------------------ //------------------------------------------------------------
logic dac_start; logic dac_start;
logic [31:0] pulse_width; logic [31:0] pulse_width;
@ -38,11 +38,11 @@ module tb_top;
logic [15:0] pulse_num; logic [15:0] pulse_num;
logic [31:0] smp_num; logic [31:0] smp_num;
//------------------------------------------------------------ //------------------------------------------------------------
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Входы
//------------------------------------------------------------ //------------------------------------------------------------
reg out_of_range; reg out_of_range;
//------------------------------------------------------------ //------------------------------------------------------------
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Выходы
//------------------------------------------------------------ //------------------------------------------------------------
wire [ADC_DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata; wire [ADC_DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata;
wire m_axis_tvalid; wire m_axis_tvalid;
@ -72,7 +72,7 @@ module tb_top;
.out_of_range(out_of_range) .out_of_range(out_of_range)
); );
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Тактовые сигналы
initial begin initial begin
clk_adc = 0; clk_adc = 0;
forever #(CLK_ADC_PERIOD/2) clk_adc = ~clk_adc; forever #(CLK_ADC_PERIOD/2) clk_adc = ~clk_adc;
@ -82,17 +82,17 @@ module tb_top;
forever #(CLK_DAC_PERIOD/2) clk_dac = ~clk_dac; forever #(CLK_DAC_PERIOD/2) clk_dac = ~clk_dac;
end end
// === <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> === // === Таски для тестирования ===
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Функция модуля
function automatic real fabs(real val); function automatic real fabs(real val);
return (val < 0.0) ? -val : val; return (val < 0.0) ? -val : val;
endfunction endfunction
`define MIN(x, y) (((x) < (y)) ? (x) : (y)) `define MIN(x, y) (((x) < (y)) ? (x) : (y))
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DAC DUT // Таска сброса DAC DUT
task automatic reset_dut_dac( task automatic reset_dut_dac(
input int rst_duration // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> input int rst_duration // сколько тактов держать сброс
); );
@(negedge clk_dac); @(negedge clk_dac);
rst_dac <= 1; rst_dac <= 1;
@ -100,9 +100,9 @@ module tb_top;
rst_dac <= 0; rst_dac <= 0;
endtask endtask
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ADC DUT // Таска сброса ADC DUT
task automatic reset_dut_adc( task automatic reset_dut_adc(
input int rst_duration // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> input int rst_duration // сколько тактов держать сброс
); );
@(negedge clk_adc); @(negedge clk_adc);
rst_adc <= 1; rst_adc <= 1;
@ -110,9 +110,9 @@ module tb_top;
rst_adc <= 0; rst_adc <= 0;
endtask endtask
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DUT // Таска запуска DUT
task automatic start_dut( task automatic start_dut(
input int start_duration // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> input int start_duration // сколько тактов держать импульс
); );
@(negedge clk_dac); // to make signal stable @(negedge clk_dac); // to make signal stable
dac_start <= 1; dac_start <= 1;
@ -120,15 +120,15 @@ module tb_top;
dac_start <= 0; dac_start <= 0;
endtask endtask
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DUT // Таска конфигурации DUT
task automatic set_config( task automatic set_config(
input logic [31:0] w, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> input logic [31:0] w, // ширина импульса
input logic [31:0] p, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> input logic [31:0] p, // период импульса
input logic [15:0] n, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> input logic [15:0] n, // количество импульсов
input logic [DAC_DATA_WIDTH-1:0] h, // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> input logic [DAC_DATA_WIDTH-1:0] h, // высота импульса
input logic [31:0] sn // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> input logic [31:0] sn // число сэмплов
); );
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Задаем конфигурационные регистры
pulse_width <= w; pulse_width <= w;
pulse_period <= p; pulse_period <= p;
pulse_num <= n; pulse_num <= n;
@ -136,7 +136,7 @@ module tb_top;
smp_num <= sn; smp_num <= sn;
endtask endtask
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DUT // Основная таска проверки DUT
task automatic run_test_case( task automatic run_test_case(
input int pulse_width, input int pulse_width,
input int pulse_period, input int pulse_period,
@ -192,7 +192,7 @@ module tb_top;
start_dut(start_hold_time); start_dut(start_hold_time);
begin begin
@(posedge clk_dac); @(posedge clk_dac);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // старт первой синхронизации
sync_start_time = $realtime; sync_start_time = $realtime;
end end
join_none join_none
@ -209,28 +209,27 @@ module tb_top;
if (VERBOSE >= 3) begin if (VERBOSE >= 3) begin
$display("[TB] -run_test_case- Found valid pulse response data positive front"); $display("[TB] -run_test_case- Found valid pulse response data positive front");
end end
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Старт цикла. Завершение синхронизации
sync_time_stats.push_back($realtime - sync_start_time); sync_time_stats.push_back($realtime - sync_start_time);
pulse_start_time = $realtime; pulse_start_time = $realtime;
fork fork
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Поток будет запущен для ненулевых импульсов и гарантированно завершится как только зафиксирует статистику импульса
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Начало импульса
if (pulse_height != ZERO_LEVEL && pulse_width != 0) begin if (pulse_height != ZERO_LEVEL && pulse_width != 0) begin
if (VERBOSE >= 4) begin if (VERBOSE >= 4) begin
$display("[TB] -run_test_case- Wait until pulse become high"); $display("[TB] -run_test_case- Wait until pulse become high");
end end
wait(m_axis_tdata != ZERO_LEVEL); wait(m_axis_tdata != ZERO_LEVEL);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Фактическое начало импульса. Поступление высокого уровня
pulse_update_val_time = $realtime; pulse_update_val_time = $realtime;
pulse_delay_time_stats.push_back(pulse_update_val_time - pulse_start_time); pulse_delay_time_stats.push_back(pulse_update_val_time - pulse_start_time);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20>.<2E>. OTR != 0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. // Проверим что высота импульса совпала с заданной. Т.к. OTR != 0 влияет на выходные данные сэмплера, то не будем проверять такие случаи.
@(posedge clk_adc); @(posedge clk_adc);
#1.5; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> #1.5; // Ожидание завершения переходных процессов
// todo fix // Будем считать что из-за OTR данные изменились (по условию OTR + MSB), проверка пропускается, т.к. сложно понять точное значение OTR в момент обработки данных от tdata
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><>-<2D><> OTR <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> OTR + MSB), <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>.<2E>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> OTR <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> tdata if (m_axis_tdata != (pulse_height >> 2) && (randomize_out_of_range || out_of_range_val)) begin
if (m_axis_tdata != (pulse_height >> 2) && !(randomize_out_of_range || out_of_range_val)) begin
$display("[ERROR] -run_test_case- Wrong pulse height: %d. Must be: %d", m_axis_tdata, pulse_height >> 2); $display("[ERROR] -run_test_case- Wrong pulse height: %d. Must be: %d", m_axis_tdata, pulse_height >> 2);
$finish; $finish;
end end
@ -241,14 +240,14 @@ module tb_top;
wait(m_axis_tdata == ZERO_LEVEL); wait(m_axis_tdata == ZERO_LEVEL);
pulse_width_time_stats.push_back($realtime - pulse_update_val_time); pulse_width_time_stats.push_back($realtime - pulse_update_val_time);
end end
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Конец импульса
join_none join_none
@(negedge m_axis_tvalid); @(negedge m_axis_tvalid);
if (VERBOSE >= 3) begin if (VERBOSE >= 3) begin
$display("[TB] -run_test_case- Found valid pulse response data negative front"); $display("[TB] -run_test_case- Found valid pulse response data negative front");
end end
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Завершение цикла. Старт синхронизации
pulse_period_time_stats.push_back($realtime - pulse_start_time); pulse_period_time_stats.push_back($realtime - pulse_start_time);
sync_start_time = $realtime; sync_start_time = $realtime;
end end
@ -257,7 +256,7 @@ module tb_top;
$display("[TB] -run_test_case- Stop pulse generation"); $display("[TB] -run_test_case- Stop pulse generation");
end end
fork // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> fork // Проверка с таймаутом на лишние циклы
@(posedge m_axis_tvalid); @(posedge m_axis_tvalid);
repeat(30) @(posedge clk_adc); repeat(30) @(posedge clk_adc);
join_any join_any
@ -278,8 +277,7 @@ module tb_top;
end end
out_of_range = 0; out_of_range = 0;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Проверка по статистике. Подсчет средних значений
// todo randomize_out_of_range || out_of_range_val
if (pulse_delay_time_stats.size() != pulse_num && pulse_height != ZERO_LEVEL && pulse_width != 0 && !(randomize_out_of_range || out_of_range_val)) begin // Detected with pulse level. Skip if pulse level undetectable if (pulse_delay_time_stats.size() != pulse_num && pulse_height != ZERO_LEVEL && pulse_width != 0 && !(randomize_out_of_range || out_of_range_val)) begin // Detected with pulse level. Skip if pulse level undetectable
$display("[ERROR] -run_test_case- Size of pulse_delay_time_stats samples not equal to pulse_num: %d VS %d", pulse_delay_time_stats.size(), pulse_num); $display("[ERROR] -run_test_case- Size of pulse_delay_time_stats samples not equal to pulse_num: %d VS %d", pulse_delay_time_stats.size(), pulse_num);
$finish; $finish;
@ -325,7 +323,7 @@ module tb_top;
$display("[ERROR] -run_test_case- avearge_pulse_delay too big: %0.3f", avearge_pulse_delay); $display("[ERROR] -run_test_case- avearge_pulse_delay too big: %0.3f", avearge_pulse_delay);
error_flag = 1; error_flag = 1;
end end
if (fabs(average_pulse_width - pulse_width * CLK_DAC_PERIOD * (pulse_height != ZERO_LEVEL)) > CLOCK_DEVIATION * CLK_ADC_PERIOD && sample_num * CLK_ADC_PERIOD >= pulse_width * CLK_DAC_PERIOD && !(randomize_out_of_range || out_of_range_val)) begin if (fabs(average_pulse_width - pulse_width * CLK_DAC_PERIOD * (pulse_height != ZERO_LEVEL)) > CLOCK_DEVIATION * CLK_ADC_PERIOD && sample_num * CLK_ADC_PERIOD >= pulse_width * CLK_DAC_PERIOD) begin
$display("[ERROR] -run_test_case- average_pulse_width deviates from choosen pulse_width. Deviation: %0.3f > %0.3f ns", fabs(average_pulse_width - pulse_width * CLK_DAC_PERIOD), CLOCK_DEVIATION * CLK_ADC_PERIOD); $display("[ERROR] -run_test_case- average_pulse_width deviates from choosen pulse_width. Deviation: %0.3f > %0.3f ns", fabs(average_pulse_width - pulse_width * CLK_DAC_PERIOD), CLOCK_DEVIATION * CLK_ADC_PERIOD);
error_flag = 1; error_flag = 1;
end end
@ -345,13 +343,13 @@ module tb_top;
$display("[TB] -run_test_case- Passed checks"); $display("[TB] -run_test_case- Passed checks");
end end
endtask endtask
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Таска
// --- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>??<3F><><EFBFBD><EFBFBD><EFBFBD>??<3F> --- // --- ОСНОВНОЙ ПРОЦЕСС ТЕСТИРОВАНИЯ ---
initial begin initial begin
$display("[TB] Tests start"); $display("[TB] Tests start");
// ??<3F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Инициализация
dac_start = 0; dac_start = 0;
pulse_width = 0; pulse_width = 0;
pulse_period = 0; pulse_period = 0;
@ -477,12 +475,12 @@ module tb_top;
.randomize_out_of_range(0) .randomize_out_of_range(0)
); );
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20>.<2E>. <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> tvalid <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> start <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> // Ожидание окончания работы генератора. Т.к. конец работы определяется по tvalid сэмплера, а он завершается сильно раньше. Чтобы не пропустить start следующей таски, ждем
wait(dut.generator_inst.enable == 0); wait(dut.generator_inst.enable == 0);
#50; #50;
$display("[TB] Test 2. Edge cases. Sample num == 0. (6/7)"); $display("[TB] Test 2. Edge cases. Sample num == 0. (6/7)");
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>.<2E>. run_test_case <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> pulse num <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> sample num = 0 // Запустим в работу вручную, т.к. run_test_case обязательно ждет pulse num циклов. Детекция цикла производится по активности сэплера. Ее не должно быть при sample num = 0
set_config( set_config(
.w(10), .w(10),
.p(125), .p(125),
@ -504,9 +502,8 @@ module tb_top;
disable wait_sampler_active_proc; disable wait_sampler_active_proc;
repeat(30) @(posedge clk_adc); repeat(30) @(posedge clk_adc);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> pulse height <EFBFBD><EFBFBD>-<2D><> OTR=1 // Данный тест должен приводить к тому, что сэмплер будет давать крайние значения вместо заданного pulse height из-за OTR=1
// TODO <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> OTR = 1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Дописать авто тест
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
$display("[TB] Test 2. Edge cases. OTR == 1. (7/7)"); $display("[TB] Test 2. Edge cases. OTR == 1. (7/7)");
run_test_case( run_test_case(
.pulse_width(10), .pulse_width(10),
@ -538,15 +535,15 @@ module tb_top;
int r_w, r_p, r_n, r_h, r_sn; int r_w, r_p, r_n, r_h, r_sn;
bit r_skip, r_otr, r_otr_rand; bit r_skip, r_otr, r_otr_rand;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // Генерируем параметры
r_p = $urandom_range(50, 150); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> 5 <EFBFBD><EFBFBD> 50 r_p = $urandom_range(50, 150); // Период от 5 до 50
r_w = $urandom_range(10, r_p); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> r_w = $urandom_range(10, r_p); // Ширина не больше периода
r_n = $urandom_range(1, 10); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> r_n = $urandom_range(1, 10); // Количество импульсов
r_h = $urandom_range(0, 2**(`MIN(ADC_DATA_WIDTH, DAC_DATA_WIDTH))-1); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> r_h = $urandom_range(0, 2**(`MIN(ADC_DATA_WIDTH, DAC_DATA_WIDTH))-1); // Высота импульса
r_sn = $urandom_range(2, 40); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> r_sn = $urandom_range(2, 40); // Число сэмплов
r_skip = $urandom_range(0, 1); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> (0 - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 1 - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) r_skip = $urandom_range(0, 1); // Случайный сброс (0 - сброс, 1 - пропуск)
r_otr = 0; // Out Of Range <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> r_otr = 0; // Out Of Range стартовое значение
r_otr_rand = 0; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> OTR <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> r_otr_rand = 0; // Сделать OTR случайным
if (VERBOSE >= 1) if (VERBOSE >= 1)
$display("[TB] --- Test #%0d (Config: W=%0d, P=%0d, N=%0d, H=%0d, SN=%0d, SkipReset=%0b) ---", $display("[TB] --- Test #%0d (Config: W=%0d, P=%0d, N=%0d, H=%0d, SN=%0d, SkipReset=%0b) ---",
@ -564,7 +561,7 @@ module tb_top;
.randomize_out_of_range(r_otr_rand) .randomize_out_of_range(r_otr_rand)
); );
wait(dut.generator_inst.enable == 0); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> wait(dut.generator_inst.enable == 0); // Проверка на завершение работы
#50; #50;
end end
$display("[TB] Test 3 complete"); $display("[TB] Test 3 complete");

View File

@ -27,6 +27,14 @@ module generator
logic enable, synced; logic enable, synced;
initial begin
cnt_pulse_period = '0;
cnt_pulse_num = '0;
enable = 0;
synced = 0;
dac_out = ZERO_LEVEL;
end
always @(posedge clk_dac) begin always @(posedge clk_dac) begin
if (rst) begin if (rst) begin
pulse_height_reg <= ZERO_LEVEL; pulse_height_reg <= ZERO_LEVEL;