`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