diff --git a/rtl/sampler/tests/sampler_main_tb.sv b/rtl/sampler/tests/sampler_main_tb.sv new file mode 100644 index 0000000..6ee619a --- /dev/null +++ b/rtl/sampler/tests/sampler_main_tb.sv @@ -0,0 +1,132 @@ +`timescale 1ns / 1ps + +module sampler_tb; + + parameter DATA_WIDTH = 12; + parameter PROCESS_MODE = 0; + parameter CLK_PERIOD = 15.3846; + parameter TEST_NUM = 1000; + + logic clk; + logic rst; + + logic [DATA_WIDTH-1:0] data_in; + logic out_of_range; + + logic [DATA_WIDTH-1:0] m_axis_tdata; + logic m_axis_tvalid; + + integer errors = 0; + + sampler #( + .DATA_WIDTH(DATA_WIDTH), + .PROCESS_MODE(PROCESS_MODE) + ) dut ( + .clk_in(clk), + .rst(rst), + .data_in(data_in), + .out_of_range(out_of_range), + .m_axis_tdata(m_axis_tdata), + .m_axis_tvalid(m_axis_tvalid) + ); + + 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; + + initial begin + $display("\n=== RANDOM SAMPLER TEST===\n"); + + rst = 1; + 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; + + repeat(5) @(posedge clk); + rst = 0; + repeat(2) @(posedge clk); + + repeat (TEST_NUM) begin + logic [DATA_WIDTH-1:0] rand_data; + bit rand_oor; + + rand_data = $urandom_range(0, (1 << DATA_WIDTH) - 1); + rand_oor = ($urandom_range(0, 99) < 20); + + @(negedge clk); + + if (!oor_d2) begin + if (m_axis_tvalid !== 1) begin + $display("ERROR: valid=0"); + errors++; + end + + 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; + end + + @(posedge clk); + + + 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 + end + + if (errors == 0) + $display("\n========== ALL PASSED ==========\n"); + else + $display("\n========== FAILED: %0d errors ==========\n", errors); + + $finish; + end + +endmodule \ No newline at end of file