From b0e886893b71be9185745b0f666a86adfff869e1 Mon Sep 17 00:00:00 2001 From: otroubi Date: Tue, 9 Jun 2026 21:07:09 +0300 Subject: [PATCH] rtl: sampler synchronization work, not totally ready --- rtl/sampler/src/sampler.sv | 57 +++---- rtl/sampler/tests/sampler_main_tb.sv | 237 ++++++++++++++++++--------- 2 files changed, 185 insertions(+), 109 deletions(-) diff --git a/rtl/sampler/src/sampler.sv b/rtl/sampler/src/sampler.sv index 2ca3fb7..f2e99ef 100644 --- a/rtl/sampler/src/sampler.sv +++ b/rtl/sampler/src/sampler.sv @@ -1,7 +1,5 @@ `timescale 1ns / 1ps - - module sampler #( parameter DATA_WIDTH = 12, @@ -14,16 +12,16 @@ module sampler input [DATA_WIDTH-1:0] data_in, input out_of_range, input [31:0] smp_num, - input sample_req, + input done, output logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata, output logic m_axis_tvalid, - output logic sample_done + output logic request ); (* MARK_DEBUG="true" *) logic [DATA_WIDTH-1:0] data_converted; (* MARK_DEBUG="true" *) logic out_of_range_reg; (* MARK_DEBUG="true" *) logic [31:0] smp_num_reg, cnt_smp_num; - (* MARK_DEBUG="true" *) logic enable; + (* MARK_DEBUG="true" *) logic enable, enable_d; generate if (PROCESS_MODE) begin @@ -68,20 +66,22 @@ module sampler buffer_ready <= 0; cnt_smp_num <= '0; smp_num_reg <= '0; - enable <= '0; - sample_done <= 0; + enable <= 0; + request <= 0; end else begin buffer_ready <= 0; - if (sample_done && !sample_req) begin - sample_done <= 1'b0; - end - if (!enable && sample_req && !sample_done) begin - enable <= 1; - cnt_smp_num <= 0; - smp_num_reg <= smp_num; - end - if (enable) begin + enable_d <= enable; + if (!enable) begin + if (request && done) begin + enable <= 1; + request <= 0; + cnt_smp_num <= 0; + smp_num_reg <= smp_num; + end else begin + request <= 1; + end + end else begin if (!out_of_range_reg) begin if (cnt_smp_num != smp_num_reg) begin buffer <= data_converted; @@ -90,8 +90,6 @@ module sampler end else begin cnt_smp_num <= '0; - sample_done <= 1'b1; - buffer_ready <= 0; buffer <= '0; enable <= 0; end @@ -108,21 +106,21 @@ module sampler cnt_smp_num <= '0; smp_num_reg <= '0; enable <= 0; - sample_done <= 0; + request <= 0; end else begin buffer_ready <= 0; - if (sample_done && !sample_req) begin - sample_done <= 1'b0; - end - if (!enable && sample_req && !sample_done) begin - enable <= 1; - cnt_smp_num <= 0; - smp_num_reg <= smp_num; - end - if (enable) begin + if (!enable) begin + if (!request) request <= 1; + if (request && done) begin + enable <= 1; + request <= 0; + cnt_smp_num <= 0; + smp_num_reg <= smp_num; + end + end else begin if (!out_of_range_reg) begin - if (cnt_smp_num != smp_num_reg) begin + if (cnt_smp_num < smp_num_reg) begin cnt_smp_num <= cnt_smp_num +1; buffer <= {buffer[DATA_WIDTH*(PACK_FACTOR-1)-1:0], data_converted}; if (cnt == PACK_FACTOR-1) begin @@ -135,7 +133,6 @@ module sampler end end else begin - sample_done <= 1'b1; cnt_smp_num <= '0; buffer_ready <= 0; buffer <= '0; diff --git a/rtl/sampler/tests/sampler_main_tb.sv b/rtl/sampler/tests/sampler_main_tb.sv index 6ee619a..d02e60c 100644 --- a/rtl/sampler/tests/sampler_main_tb.sv +++ b/rtl/sampler/tests/sampler_main_tb.sv @@ -2,130 +2,209 @@ module sampler_tb; - parameter DATA_WIDTH = 12; - parameter PROCESS_MODE = 0; - parameter CLK_PERIOD = 15.3846; - parameter TEST_NUM = 1000; + // ========================================================= + // PARAMETERS + // ========================================================= + localparam DATA_WIDTH = 12; + localparam PACK_FACTOR = 1; + localparam PROCESS_MODE = 0; + localparam CLK_PERIOD = 15.3846; + // ========================================================= + // SIGNALS + // ========================================================= logic clk; logic rst; logic [DATA_WIDTH-1:0] data_in; logic out_of_range; - logic [DATA_WIDTH-1:0] m_axis_tdata; + logic [31:0] smp_num; + + logic done; + logic request; + + logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata; logic m_axis_tvalid; - integer errors = 0; - + // ========================================================= + // DUT + // ========================================================= sampler #( .DATA_WIDTH(DATA_WIDTH), + .PACK_FACTOR(PACK_FACTOR), .PROCESS_MODE(PROCESS_MODE) ) dut ( .clk_in(clk), .rst(rst), + .data_in(data_in), .out_of_range(out_of_range), + + .smp_num(smp_num), + .done(done), + .m_axis_tdata(m_axis_tdata), - .m_axis_tvalid(m_axis_tvalid) + .m_axis_tvalid(m_axis_tvalid), + + .request(request) ); + // ========================================================= + // CLOCK + // ========================================================= initial begin clk = 0; forever #(CLK_PERIOD/2) clk = ~clk; end - function automatic [DATA_WIDTH-1:0] ref_convert(input [DATA_WIDTH-1:0] din); - if (PROCESS_MODE == 0) - return din; - else if (din == {1'b1, {(DATA_WIDTH-1){1'b0}}}) - return din; - else - return din[DATA_WIDTH-1] ? - {1'b1, (~din[DATA_WIDTH-2:0] + 1'b1)} : - din; - endfunction - - task send(input [DATA_WIDTH-1:0] word, input bit oor); - @(posedge clk); - data_in <= word; - out_of_range <= oor; - endtask - - logic [DATA_WIDTH-1:0] exp_d0, exp_d1, exp_d2; - logic oor_d0, oor_d1, oor_d2; - + // ========================================================= + // RESET (ONLY ONCE) + // ========================================================= initial begin - $display("\n=== RANDOM SAMPLER TEST===\n"); - rst = 1; + done = 0; data_in = 0; out_of_range = 0; - - exp_d0 = 0; - exp_d1 = 0; - exp_d2 = 0; - - oor_d0 = 1; - oor_d1 = 1; - oor_d2 = 1; + smp_num = 0; repeat(5) @(posedge clk); rst = 0; - repeat(2) @(posedge clk); + end - repeat (TEST_NUM) begin - logic [DATA_WIDTH-1:0] rand_data; - bit rand_oor; + // ========================================================= + // CONFIG + // ========================================================= + task automatic set_config( + input int n, + input int init_delay + ); + smp_num = n; + repeat(init_delay) @(posedge clk); + endtask - rand_data = $urandom_range(0, (1 << DATA_WIDTH) - 1); - rand_oor = ($urandom_range(0, 99) < 20); + // ========================================================= + // HANDSHAKE (DONE/REQUEST) + // ========================================================= + task automatic synchronize_sampler( + input bit sampler_first, + input int delay_before_ack, + input int ack_duration + ); + if (sampler_first) begin + repeat(delay_before_ack) @(posedge clk); - @(negedge clk); + done <= 1'b1; + wait(request == 1'b1); - if (!oor_d2) begin - if (m_axis_tvalid !== 1) begin - $display("ERROR: valid=0"); - errors++; - end + repeat(ack_duration) @(posedge clk); - if (m_axis_tdata !== exp_d2) begin - $display("ERROR: data mismatch"); - $display(" expected = %h", exp_d2); - $display(" got = %h", m_axis_tdata); - errors++; - end - end - - send(rand_data, rand_oor); - - exp_d2 = exp_d1; - exp_d1 = exp_d0; - exp_d0 = ref_convert(rand_data); - - oor_d2 = oor_d1; - oor_d1 = oor_d0; - oor_d0 = rand_oor; + done <= 1'b0; end + else begin + wait(request == 1'b1); - @(posedge clk); + repeat(delay_before_ack) @(posedge clk); + done <= 1'b1; - if (!oor_d2) begin - - if (m_axis_tdata !== exp_d2) begin - $display("ERROR: final mismatch"); - $display(" expected = %h", exp_d2); - $display(" got = %h", m_axis_tdata); - errors++; - end + repeat(ack_duration) @(posedge clk); + + done <= 1'b0; end + endtask - if (errors == 0) - $display("\n========== ALL PASSED ==========\n"); + // ========================================================= + // DATA STREAM (STARTS AFTER SYNC) + // ========================================================= + task automatic feed_data_stream( + input int num_words, + input bit random_mode + ); + logic [DATA_WIDTH-1:0] val; + val = 1; + + for (int i = 0; i < num_words; i++) begin + @(posedge clk); + + if (random_mode) + val = $urandom_range(1, 2**DATA_WIDTH-1); + else + val = val + 1; + + data_in <= val; + out_of_range <= 0; + + end + endtask + + // ========================================================= + // COUNTER + // ========================================================= + int received_count; + + always @(posedge clk) begin + if (m_axis_tvalid) + received_count++; + end + + // ========================================================= + // TEST CASE + // ========================================================= + task automatic run_test_case( + input int n, + input int delay, + input int ack, + input bit sampler_first, + input bit random_stream + ); + received_count = 0; + + set_config(n, 2); + + // 1) сначала синхронизация + synchronize_sampler(sampler_first, delay, ack); + + // 2) СРАЗУ после sync - поток данных + feed_data_stream(n, random_stream); + + repeat(20) @(posedge clk); + + if (received_count == n) + $display("[OK] received %0d / %0d", received_count, n); else - $display("\n========== FAILED: %0d errors ==========\n", errors); + $display("[ERROR] received %0d / %0d", received_count, n); + endtask + // ========================================================= + // RANDOM STRESS TEST + // ========================================================= + task automatic check_random; + int n, d, a; + bit sf; + + for (int i = 0; i < 20; i++) begin + n = $urandom_range(3, 10); + d = $urandom_range(0, 5); + a = $urandom_range(1, 5); + sf = $urandom_range(0, 1); + + $display("\n--- TEST %0d --- n=%0d delay=%0d ack=%0d sf=%0b", + i, n, d, a, sf); + + run_test_case(n, d, a, sf, 1); + end + endtask + + // ========================================================= + // MAIN + // ========================================================= + initial begin + $display("\n=== SAMPLER TEST (FIXED FLOW: NO MULTI RESET) ===\n"); + + check_random(); + + $display("\n=== TEST FINISHED ==="); $finish; end