From 04eb927a2525160d9e15e4c80c290d04bbad11a1 Mon Sep 17 00:00:00 2001 From: "babintsev.lv" Date: Fri, 17 Jul 2026 15:21:49 +0300 Subject: [PATCH 1/4] fix: encoding issues, generator explicit default state --- designs/adc_dac_synchoronizer/tb_sync_top.sv | 109 +++++++++---------- rtl/generator/src/generator.sv | 8 ++ 2 files changed, 61 insertions(+), 56 deletions(-) diff --git a/designs/adc_dac_synchoronizer/tb_sync_top.sv b/designs/adc_dac_synchoronizer/tb_sync_top.sv index b029cd1..3c74f0e 100644 --- a/designs/adc_dac_synchoronizer/tb_sync_top.sv +++ b/designs/adc_dac_synchoronizer/tb_sync_top.sv @@ -3,7 +3,7 @@ module tb_top; //------------------------------------------------------------ - // ��������� + // Параметры //------------------------------------------------------------ parameter string ZERO_LEVEL_PARAM = "logic"; // "logic" VS "true" parameter VERBOSE = 1; @@ -22,14 +22,14 @@ module tb_top; localparam CLOCK_DEVIATION = 3; // Maximum clock deviation of pulse stats //------------------------------------------------------------ - // �������� ������� � ����� + // Тактовые сигналы и сброс //------------------------------------------------------------ logic clk_dac; logic rst_dac; logic clk_adc; logic rst_adc; //------------------------------------------------------------ - // ���������� � ������ + // Управление и конфиг //------------------------------------------------------------ logic dac_start; logic [31:0] pulse_width; @@ -38,11 +38,11 @@ module tb_top; logic [15:0] pulse_num; logic [31:0] smp_num; //------------------------------------------------------------ - // ����� + // Входы //------------------------------------------------------------ reg out_of_range; //------------------------------------------------------------ - // ������ + // Выходы //------------------------------------------------------------ wire [ADC_DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata; wire m_axis_tvalid; @@ -72,7 +72,7 @@ module tb_top; .out_of_range(out_of_range) ); - // �������� ������� + // Тактовые сигналы initial begin clk_adc = 0; 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; end - // === ����� ��� ������������ === - // ������� ������ + // === Таски для тестирования === + // Функция модуля function automatic real fabs(real val); return (val < 0.0) ? -val : val; endfunction `define MIN(x, y) (((x) < (y)) ? (x) : (y)) - // ����� ������ DAC DUT + // Таска сброса DAC DUT task automatic reset_dut_dac( - input int rst_duration // ������� ������ ������� ����� + input int rst_duration // сколько тактов держать сброс ); @(negedge clk_dac); rst_dac <= 1; @@ -100,9 +100,9 @@ module tb_top; rst_dac <= 0; endtask - // ����� ������ ADC DUT + // Таска сброса ADC DUT task automatic reset_dut_adc( - input int rst_duration // ������� ������ ������� ����� + input int rst_duration // сколько тактов держать сброс ); @(negedge clk_adc); rst_adc <= 1; @@ -110,9 +110,9 @@ module tb_top; rst_adc <= 0; endtask - // ����� ������� DUT + // Таска запуска DUT task automatic start_dut( - input int start_duration // ������� ������ ������� ������� + input int start_duration // сколько тактов держать импульс ); @(negedge clk_dac); // to make signal stable dac_start <= 1; @@ -120,15 +120,15 @@ module tb_top; dac_start <= 0; endtask - // ����� ������������ DUT + // Таска конфигурации DUT task automatic set_config( - input logic [31:0] w, // ������ �������� - input logic [31:0] p, // ������ �������� - input logic [15:0] n, // ���������� ��������� - input logic [DAC_DATA_WIDTH-1:0] h, // ������ �������� - input logic [31:0] sn // ����� ������� + input logic [31:0] w, // ширина импульса + input logic [31:0] p, // период импульса + input logic [15:0] n, // количество импульсов + input logic [DAC_DATA_WIDTH-1:0] h, // высота импульса + input logic [31:0] sn // число сэмплов ); - // ������ ���������������� �������� + // Задаем конфигурационные регистры pulse_width <= w; pulse_period <= p; pulse_num <= n; @@ -136,7 +136,7 @@ module tb_top; smp_num <= sn; endtask - // �������� ����� �������� DUT + // Основная таска проверки DUT task automatic run_test_case( input int pulse_width, input int pulse_period, @@ -192,7 +192,7 @@ module tb_top; start_dut(start_hold_time); begin @(posedge clk_dac); - // ����� ������ ������������� + // старт первой синхронизации sync_start_time = $realtime; end join_none @@ -209,28 +209,27 @@ module tb_top; if (VERBOSE >= 3) begin $display("[TB] -run_test_case- Found valid pulse response data positive front"); end - // ����� �����. ���������� ������������� + // Старт цикла. Завершение синхронизации sync_time_stats.push_back($realtime - sync_start_time); pulse_start_time = $realtime; fork - // ����� ����� ������� ��� ��������� ��������� � �������������� ���������� ��� ������ ����������� ���������� �������� - // ������ �������� + // Поток будет запущен для ненулевых импульсов и гарантированно завершится как только зафиксирует статистику импульса + // Начало импульса if (pulse_height != ZERO_LEVEL && pulse_width != 0) begin if (VERBOSE >= 4) begin $display("[TB] -run_test_case- Wait until pulse become high"); end wait(m_axis_tdata != ZERO_LEVEL); - // ����������� ������ ��������. ����������� �������� ������ + // Фактическое начало импульса. Поступление высокого уровня pulse_update_val_time = $realtime; pulse_delay_time_stats.push_back(pulse_update_val_time - pulse_start_time); - // �������� ��� ������ �������� ������� � ��������. �.�. OTR != 0 ������ �� �������� ������ ��������, �� �� ����� ��������� ����� ������. + // Проверим что высота импульса совпала с заданной. Т.к. OTR != 0 влияет на выходные данные сэмплера, то не будем проверять такие случаи. @(posedge clk_adc); - #1.5; // �������� ���������� ���������� ��������� - // todo fix - // ����� ������� ��� ��-�� OTR ������ ���������� (�� ������� OTR + MSB), �������� ������������, �.�. ������ ������ ������ �������� OTR � ������ ��������� ������ �� tdata - if (m_axis_tdata != (pulse_height >> 2) && !(randomize_out_of_range || out_of_range_val)) begin + #1.5; // Ожидание завершения переходных процессов + // Будем считать что из-за OTR данные изменились (по условию OTR + MSB), проверка пропускается, т.к. сложно понять точное значение OTR в момент обработки данных от tdata + 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); $finish; end @@ -241,14 +240,14 @@ module tb_top; wait(m_axis_tdata == ZERO_LEVEL); pulse_width_time_stats.push_back($realtime - pulse_update_val_time); end - // ����� �������� + // Конец импульса join_none @(negedge m_axis_tvalid); if (VERBOSE >= 3) begin $display("[TB] -run_test_case- Found valid pulse response data negative front"); end - // ���������� �����. ����� ������������� + // Завершение цикла. Старт синхронизации pulse_period_time_stats.push_back($realtime - pulse_start_time); sync_start_time = $realtime; end @@ -257,7 +256,7 @@ module tb_top; $display("[TB] -run_test_case- Stop pulse generation"); end - fork // �������� � ��������� �� ������ ����� + fork // Проверка с таймаутом на лишние циклы @(posedge m_axis_tvalid); repeat(30) @(posedge clk_adc); join_any @@ -278,8 +277,7 @@ module tb_top; end out_of_range = 0; - // �������� �� ����������. ������� ������� �������� - // 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 $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; @@ -325,7 +323,7 @@ module tb_top; $display("[ERROR] -run_test_case- avearge_pulse_delay too big: %0.3f", avearge_pulse_delay); error_flag = 1; 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); error_flag = 1; end @@ -345,13 +343,13 @@ module tb_top; $display("[TB] -run_test_case- Passed checks"); end endtask - // ����� + // Таска - // --- �������� ������� ����??�����??� --- + // --- ОСНОВНОЙ ПРОЦЕСС ТЕСТИРОВАНИЯ --- initial begin $display("[TB] Tests start"); - // ??������������ + // Инициализация dac_start = 0; pulse_width = 0; pulse_period = 0; @@ -477,12 +475,12 @@ module tb_top; .randomize_out_of_range(0) ); - // �������� ��������� ������ ����������. �.�. ����� ������ ������������ �� tvalid ��������, � �� ����������� ������ ������. ����� �� ���������� start ��������� �����, ���� + // Ожидание окончания работы генератора. Т.к. конец работы определяется по tvalid сэмплера, а он завершается сильно раньше. Чтобы не пропустить start следующей таски, ждем wait(dut.generator_inst.enable == 0); #50; $display("[TB] Test 2. Edge cases. Sample num == 0. (6/7)"); - // �������� � ������ �������, �.�. run_test_case ����������� ���� pulse num ������. �������� ����� ������������ �� ���������� �������. �� �� ������ ���� ��� sample num = 0 + // Запустим в работу вручную, т.к. run_test_case обязательно ждет pulse num циклов. Детекция цикла производится по активности сэплера. Ее не должно быть при sample num = 0 set_config( .w(10), .p(125), @@ -504,9 +502,8 @@ module tb_top; disable wait_sampler_active_proc; repeat(30) @(posedge clk_adc); - // ������ ���� ������ ��������� � ����, ��� ������� ����� ������ ������� �������� ������ ��������� pulse height ��-�� OTR=1 - // TODO �������� ��� ��� ����� ���������� OTR = 1 ���������. ����� ����������� ������� - // �������� ���� ���� + // Данный тест должен приводить к тому, что сэмплер будет давать крайние значения вместо заданного pulse height из-за OTR=1 + // Дописать авто тест $display("[TB] Test 2. Edge cases. OTR == 1. (7/7)"); run_test_case( .pulse_width(10), @@ -538,15 +535,15 @@ module tb_top; int r_w, r_p, r_n, r_h, r_sn; bit r_skip, r_otr, r_otr_rand; - // ���������� ��������� - r_p = $urandom_range(50, 150); // ������ �� 5 �� 50 - r_w = $urandom_range(10, r_p); // ������ �� ������ ������� - r_n = $urandom_range(1, 10); // ���������� ��������� - r_h = $urandom_range(0, 2**(`MIN(ADC_DATA_WIDTH, DAC_DATA_WIDTH))-1); // ������ �������� - r_sn = $urandom_range(2, 40); // ����� ������� - r_skip = $urandom_range(0, 1); // ��������� ����� (0 - �����, 1 - �������) - r_otr = 0; // Out Of Range ��������� �������� - r_otr_rand = 0; // ������� OTR ��������� + // Генерируем параметры + r_p = $urandom_range(50, 150); // Период от 5 до 50 + r_w = $urandom_range(10, r_p); // Ширина не больше периода + r_n = $urandom_range(1, 10); // Количество импульсов + r_h = $urandom_range(0, 2**(`MIN(ADC_DATA_WIDTH, DAC_DATA_WIDTH))-1); // Высота импульса + r_sn = $urandom_range(2, 40); // Число сэмплов + r_skip = $urandom_range(0, 1); // Случайный сброс (0 - сброс, 1 - пропуск) + r_otr = 0; // Out Of Range стартовое значение + r_otr_rand = 0; // Сделать OTR случайным if (VERBOSE >= 1) $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) ); - wait(dut.generator_inst.enable == 0); // �������� �� ���������� ������ + wait(dut.generator_inst.enable == 0); // Проверка на завершение работы #50; end $display("[TB] Test 3 complete"); diff --git a/rtl/generator/src/generator.sv b/rtl/generator/src/generator.sv index 865677a..04c9eb3 100644 --- a/rtl/generator/src/generator.sv +++ b/rtl/generator/src/generator.sv @@ -27,6 +27,14 @@ module generator 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 if (rst) begin pulse_height_reg <= ZERO_LEVEL; From a52883874110f4cbbaa02eeb2cb11e9e13019a46 Mon Sep 17 00:00:00 2001 From: "babintsev.lv" Date: Fri, 17 Jul 2026 17:29:58 +0300 Subject: [PATCH 2/4] fix: patch for sampler upd: reflectometer TB readaout data task --- .../reflectometer_base/reflectometer_tb.sv | 104 ++++++++++++------ rtl/sampler/src/sampler.sv | 13 +-- 2 files changed, 77 insertions(+), 40 deletions(-) diff --git a/designs/reflectometer_base/reflectometer_tb.sv b/designs/reflectometer_base/reflectometer_tb.sv index 3b1b2d7..1ffdfba 100644 --- a/designs/reflectometer_base/reflectometer_tb.sv +++ b/designs/reflectometer_base/reflectometer_tb.sv @@ -11,13 +11,13 @@ module reflectometer_tb; localparam LOGIC_ZERO_LEVEL = 0; // DAC -5V for logic zero localparam VOLTAGE_ZERO_LEVEL = 2**(DAC_DATA_WIDTH-1); // DAC 0V for logic zero localparam PACK_FACTOR = 1; // not used in TB - localparam PROCESS_MODE = 0; // 0 - uint, 1 - int + localparam PROCESS_MODE = 1; // 0 - uint, 1 - int localparam ACCUM_WIDTH = 32; // accumulator number bit witdth localparam N_MAX = 4096; // max value of windows to average by experiments localparam WINDOW_SIZE = 65; // fixed subwindow size to average by time localparam PACKET_SIZE = 1024; // bytes per UDP packet - localparam ZERO_LEVEL = VOLTAGE_ZERO_LEVEL; // "logic" VS "true" + localparam ZERO_LEVEL = LOGIC_ZERO_LEVEL; // "logic" VS "voltage" localparam CLK_ETH_PHY_PERIOD = 8.000; // 125 MHz localparam CLK_REF_PERIOD = 5.000; // 200 MHz @@ -63,7 +63,7 @@ module reflectometer_tb; wire [ADC_DATA_WIDTH-1:0] adc_data; // Интерфейс хендшейка с MAC-PHY wire send_request; - logic request_ready = 1'b0; + logic request_ready; // Сигналы ЦАП и АЦП real signal_voltage; @@ -72,6 +72,7 @@ module reflectometer_tb; //------------------------------------------------------------ virtual_dac_model #( // default voltage range is +/- 5V .DAC_DATA_WIDTH(DAC_DATA_WIDTH) + // ,.VOLTAGE_GAIN(2) ) virtual_dac ( .clk_i(clk_dac), .wrt_i(dac_wrt), @@ -149,6 +150,7 @@ module reflectometer_tb; //------------------------------------------------------------ // Таски для тестирования //------------------------------------------------------------ + // Таски работы с AXI-Stream task automatic dut_soft_reset(virtual axis_if#(8).tb vif); logic [7:0] tx_packet[]; tx_packet = '{8'h0f}; @@ -160,6 +162,7 @@ module reflectometer_tb; tx_packet = '{8'hf0}; vif.master_send(tx_packet); endtask + task automatic dut_send_system_config( virtual axis_if#(8).tb vif, input logic [31:0] pulse_width, @@ -183,60 +186,99 @@ module reflectometer_tb; endtask // Таски сбора и обработки статистики + task automatic dut_read_output( + virtual axis_if#(8).tb vif, + input int sample_num, + input bit randomize_recv_delays, + output int output_data[] + ); + logic [7:0] rx_packet[]; + logic [ACCUM_WIDTH-1:0] data_packet[]; + int packet_num = $ceil(real'(sample_num / WINDOW_SIZE) / real'(PACKET_SIZE)); + int numbers_per_packet = PACKET_SIZE/(ACCUM_WIDTH/8); + int idx = 0; + if (sample_num % WINDOW_SIZE) begin + $display("[TB] -dut_read_output- Error, sample_num must be multiple of WINDOW_SIZE: %0d %% %0d = %0d", sample_num, WINDOW_SIZE, sample_num % WINDOW_SIZE); + $finish; + end + + data_packet = new[numbers_per_packet]; + output_data = new[numbers_per_packet * packet_num]; + // count send_request posedge todo + // timeout todo + + // recv loop + for (int i = 0; i < packet_num; i++) begin + // randomize_recv_delays todo + request_ready = 1; + vif.slave_recv(rx_packet); + request_ready = 0; + + // unpack values + data_packet = {<< byte {rx_packet}}; + data_packet = {<< ACCUM_WIDTH {data_packet}}; + + // copy and convert values + for (int j = 0; j < data_packet.size(); j++) begin + output_data[i * data_packet.size() + j] = int'(data_packet[j]); + end + end + + // wait for dut.finish posedge todo + // timeout todo + + // error handling todo + endtask //------------------------------------------------------------ // ОСНОВНОЙ ПРОЦЕСС ТЕСТИРОВАНИЯ //------------------------------------------------------------ initial begin - logic [7:0] rx_packet[]; + int output_data[]; + automatic virtual axis_if.tb control_vif = axis_control_if.tb; automatic virtual axis_if.tb accumulator_vif = axis_accumulator_if.tb; - $display("[TB] Tests start"); - + $display("[TB] DUT initializaton"); // Инициализация + request_ready = 0; rst_n = 0; #100; rst_n = 1; wait(mmcm_locked === 1'b1); #150; $display("[TB] MMCM locked"); - + dut_soft_reset(control_vif); #100; + + // Тесты + $display("[TB] Tests start"); dut_send_system_config( .vif(control_vif), - .pulse_width(32'd12345), - .pulse_period(32'd50000), - .pulse_num(16'd10), - .pulse_height(14'd16000), // 0V - .pulse_period_adc(32'd26000) + .pulse_width(32'd123), + .pulse_period(32'd5000), + .pulse_num(16'd1), + .pulse_height(14'd15000), // 0V + .pulse_period_adc(32'd2600) ); #100; dut_start(control_vif); - #1000; - request_ready = 1'b1; - accumulator_vif.slave_recv(rx_packet); - $display("receive %0d bytes", rx_packet.size()); - for (int i = 0; i < rx_packet.size(); i+=4) begin - $write("%0d ", {rx_packet[i], rx_packet[i+1], rx_packet[i+2], rx_packet[i+3]}); + dut_read_output( + .vif(accumulator_vif), + .sample_num(2600), + .randomize_recv_delays(0), + .output_data(output_data) + ); + + $display("Received %0d numbers", output_data.size()); + for (int i = 0; i < output_data.size(); i++) begin + $write("%0d ", output_data[i]); end $display(""); - #1000; - request_ready = 1'b1; - accumulator_vif.slave_recv(rx_packet); - $display("receive %0d bytes", rx_packet.size()); - for (int i = 0; i < rx_packet.size(); i+=4) begin - $write("%0d ", {rx_packet[i], rx_packet[i+1], rx_packet[i+2], rx_packet[i+3]}); - end - $display(""); - // wait(); - // #100000; - // #93000; - // rst_n = 0; - #10000 + $display("[TB] ALL PASSED"); $finish; end diff --git a/rtl/sampler/src/sampler.sv b/rtl/sampler/src/sampler.sv index 19fc901..98f6841 100644 --- a/rtl/sampler/src/sampler.sv +++ b/rtl/sampler/src/sampler.sv @@ -27,20 +27,15 @@ module sampler data_converted = '0; if (PROCESS_MODE) begin if (out_of_range) begin - if (data_in[DATA_WIDTH-1]==1'b1) data_converted = {1'b1, {(DATA_WIDTH-2){1'b0}}}; - else if (data_in[DATA_WIDTH-1]==1'b0) data_converted = {1'b0, {(DATA_WIDTH-2){1'b1}}}; + data_converted = {~data_in[DATA_WIDTH-1], {(DATA_WIDTH-1){data_in[DATA_WIDTH-1]}}}; end else begin - if (data_in == {1'b1, {(DATA_WIDTH-1){1'b0}}}) - data_converted = data_in; - else - data_converted = data_in[DATA_WIDTH-1] ?{1'b1, (~data_in[DATA_WIDTH-2:0] + 1'b1)}:data_in; + data_converted = {~data_in[DATA_WIDTH-1], data_in[DATA_WIDTH-2:0]}; end end else begin if (out_of_range) begin - if (data_in[DATA_WIDTH-1]==1'b1) data_converted = '1; - else if (data_in[DATA_WIDTH-1]==1'b0) data_converted = '0; + data_converted = {DATA_WIDTH{data_in[DATA_WIDTH-1]}}; end else begin - data_converted = data_in; + data_converted = data_in; end end end From 81970c8b425b55eaed0c10959914e8256cec8873 Mon Sep 17 00:00:00 2001 From: "babintsev.lv" Date: Tue, 21 Jul 2026 16:54:06 +0300 Subject: [PATCH 3/4] upd: new TB, sampler refactor --- rtl/sampler/src/sampler.sv | 34 ++--- rtl/sampler/tests/sampler_tb.sv | 246 ++++++++++++++++++-------------- 2 files changed, 153 insertions(+), 127 deletions(-) diff --git a/rtl/sampler/src/sampler.sv b/rtl/sampler/src/sampler.sv index 98f6841..5da3d81 100644 --- a/rtl/sampler/src/sampler.sv +++ b/rtl/sampler/src/sampler.sv @@ -13,18 +13,18 @@ module sampler input [31:0] smp_num, input request, - output logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata, - output logic m_axis_tvalid, + output logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata, + output logic m_axis_tvalid, output logic done ); - + // WARNING: number of samples smp_num must be multiple of PACK_FACTOR + // Last (smp_num % PACK_FACTOR) will be lost and not transmitted logic [DATA_WIDTH-1:0] data_converted; logic [31:0] smp_num_reg, cnt_smp_num; - logic synced; + logic synced; logic [$clog2(PACK_FACTOR):0] pack_cnt; always_comb begin - data_converted = '0; if (PROCESS_MODE) begin if (out_of_range) begin data_converted = {~data_in[DATA_WIDTH-1], {(DATA_WIDTH-1){data_in[DATA_WIDTH-1]}}}; @@ -39,7 +39,12 @@ module sampler end end end - + + initial begin + synced = 0; + m_axis_tdata = '0; + m_axis_tvalid = 0; + end always_ff @(posedge clk_in) begin if (rst) begin @@ -51,10 +56,9 @@ module sampler synced <= 0; done <= 0; end else begin - m_axis_tvalid <= 0; if (!synced) begin if (done && request) begin - synced <= 1; + synced <= 1; done <= 0; cnt_smp_num <= 0; smp_num_reg <= smp_num; @@ -63,23 +67,21 @@ module sampler end end else begin if (cnt_smp_num != smp_num_reg) begin - cnt_smp_num <= cnt_smp_num +1; + cnt_smp_num++; m_axis_tdata[pack_cnt*DATA_WIDTH +: DATA_WIDTH] <= data_converted; if (pack_cnt == PACK_FACTOR-1) begin pack_cnt <= 0; m_axis_tvalid <= 1; end else begin - pack_cnt <= pack_cnt + 1; + pack_cnt++; + m_axis_tvalid <= 0; end end else begin - cnt_smp_num <= '0; - pack_cnt <= '0; + pack_cnt <= '0; synced <= 0; - done <= 1; - m_axis_tdata <= '0; + m_axis_tvalid <= 0; end end end - end - + end endmodule diff --git a/rtl/sampler/tests/sampler_tb.sv b/rtl/sampler/tests/sampler_tb.sv index 07d6176..e6c9988 100644 --- a/rtl/sampler/tests/sampler_tb.sv +++ b/rtl/sampler/tests/sampler_tb.sv @@ -3,15 +3,17 @@ module sampler_tb; localparam DATA_WIDTH = 12; - localparam PACK_FACTOR = 1; + localparam PACK_FACTOR = 7; localparam PROCESS_MODE = 0; localparam CLK_PERIOD = 15.3846; + localparam OTR_OFFSET = 0; logic clk; - logic rst; + logic rst_dut; + logic rst_gen; - logic [DATA_WIDTH-1:0] data_in; - logic out_of_range; + wire [DATA_WIDTH-1:0] data_in; + wire out_of_range; logic [31:0] smp_num; @@ -21,15 +23,13 @@ module sampler_tb; logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata; logic m_axis_tvalid; - int received_count; - sampler #( .DATA_WIDTH (DATA_WIDTH), .PACK_FACTOR (PACK_FACTOR), .PROCESS_MODE(PROCESS_MODE) ) dut ( .clk_in (clk), - .rst (rst), + .rst (rst_dut), .data_in (data_in), .out_of_range (out_of_range), @@ -54,122 +54,97 @@ module sampler_tb; // ===================================================== // RESET // ===================================================== - initial begin - rst = 1; - data_in = 0; - out_of_range = 0; - done = 0; - smp_num = 0; - - repeat(5) @(posedge clk); - rst = 0; - end - - // ===================================================== - // OUTPUT COUNTER - // ===================================================== - always @(posedge clk) begin - if (m_axis_tvalid) - received_count++; - end + task automatic reset_dut(); + @(posedge clk); + rst_dut = 1; + @(posedge clk); + rst_dut = 0; + endtask // ===================================================== // FEED DATA // ===================================================== - task automatic feed_data_stream( - input int num_words, - input bit random_data, - input bit random_out_of_range + triangle_wave_gen #( + .DATA_WIDTH(DATA_WIDTH), + .OFFSET(OTR_OFFSET), // offset of bits from '0 and '1 for OTR + .STEP(1) // LSB bit per clock + ) signal_gen ( + .clk(clk), + .rst(rst_gen), + .signal(data_in), + .otr(out_of_range) ); - logic [DATA_WIDTH-1:0] value; - bit oor; - begin - value = 1; - - for (int i = 0; i < num_words; i++) begin - - if (random_data) - value = $urandom_range(1, (1< MAX_VALUE - OTR_OFFSET)) begin + // need clipping + tmp_input_val = ((tmp_input_val - MIN_VALUE) < 2**(DATA_WIDTH-1)) ? + MIN_VALUE : MAX_VALUE; + end + + if (tmp_input_val != tmp_output_val) flag = 1; end - $write("\n"); - for (int i = 0; i < input_values.size(); i++) begin - $write(" %0d", output_values[i]); + // $display("Total: %0d", output_values.size()); + if (flag) begin + $display("[ERROR] -run_test_case- Sampled data not correct and not equal to generated signal."); + $finish; end - $write("\n"); - $display("Total: %0d", output_values.size()); - if (flag) $display("FUCK"); - else $display("SUCKASS"); - endtask // ===================================================== // MAIN // ===================================================== initial begin + int random_number; $display("\n=== BASIC TEST ==="); @@ -161,12 +176,20 @@ module sampler_tb; rst_dut = 0; repeat(2) @(posedge clk); + $display("basic test #1"); + run_test_case(10); run_test_case(100); - + run_test_case(10000); + $display("basic test #2"); + run_test_case(0); $display("\n=== RANDOM STRESS TEST ==="); - // todo - + for (int i = 0; i < 10; i++) begin + $display("Random test #%0d", i); + random_number = $urandom_range(0, 3 * 2**(DATA_WIDTH)); // up to 1.5 triangle waves + run_test_case(random_number); + end + $display("\n=== TEST FINISHED ==="); $finish;