Files
reflectometer_fpga_project/rtl/sampler/tests/sampler_tb.sv

219 lines
5.5 KiB
Systemverilog

`timescale 1ns / 1ps
module sampler_tb;
localparam DATA_WIDTH = 12;
localparam PACK_FACTOR = 7;
localparam PROCESS_MODE = 0;
localparam CLK_PERIOD = 15.3846;
localparam OTR_OFFSET = 0;
logic clk;
logic rst_dut;
logic rst_gen;
wire [DATA_WIDTH-1:0] data_in;
wire out_of_range;
logic [31:0] smp_num;
logic done;
logic request;
logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata;
logic m_axis_tvalid;
sampler #(
.DATA_WIDTH (DATA_WIDTH),
.PACK_FACTOR (PACK_FACTOR),
.PROCESS_MODE(PROCESS_MODE)
) dut (
.clk_in (clk),
.rst (rst_dut),
.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),
.request (request)
);
// =====================================================
// CLOCK
// =====================================================
initial begin
clk = 0;
forever #(CLK_PERIOD/2) clk = ~clk;
end
// =====================================================
// RESET
// =====================================================
task automatic reset_dut();
@(posedge clk);
rst_dut = 1;
@(posedge clk);
rst_dut = 0;
endtask
// =====================================================
// FEED DATA
// =====================================================
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)
);
// =====================================================
// TEST TASKS
// =====================================================
task automatic run_test_case(
input int sample_num
);
logic [DATA_WIDTH-1:0] input_values[$];
logic [DATA_WIDTH-1:0] output_values[$];
bit flag;
// Startup sequence
rst_gen <= 1;
smp_num <= sample_num;
request <= 1;
@(posedge clk);
// syncronize
while (!done)
@(posedge clk);
request <= 0;
// Wait for sync and start signal generator
// while (!dut.synced)
// @(posedge clk);
wait(dut.synced === 1);
rst_gen <= 0;
// Wait for valid data
fork
begin : stat_mon_proc
forever begin
@(posedge clk);
input_values.push_back(data_in);
if (m_axis_tvalid) begin
for (int i = 0; i < PACK_FACTOR; i++)
output_values.push_back(m_axis_tdata[DATA_WIDTH*i +: DATA_WIDTH]);
end
end
end
join_none
// Wait until end
// while (dut.synced)
// @(posedge clk);
wait(dut.synced === 0);
disable stat_mon_proc;
// Pop last input value. Signal is ahead of tdata for 1 cycle
input_values.pop_back();
// check data
if (input_values.size() != output_values.size()) begin
$display("[ERROR] -run_test_case- Input queue size don't equal to output queue size: %0d vs %0d", input_values.size(), output_values.size());
$finish;
end
flag = 0;
for (int i = 0; i < input_values.size(); i++) begin
$write(" %0d", input_values[i]);
if (input_values[i] != output_values[i])
flag = 1;
end
$write("\n");
for (int i = 0; i < input_values.size(); i++) begin
$write(" %0d", output_values[i]);
end
$write("\n");
$display("Total: %0d", output_values.size());
if (flag) $display("FUCK");
else $display("SUCKASS");
endtask
// =====================================================
// MAIN
// =====================================================
initial begin
$display("\n=== BASIC TEST ===");
rst_dut = 1;
rst_gen = 1;
smp_num = 0;
repeat(2) @(posedge clk);
rst_dut = 0;
repeat(2) @(posedge clk);
run_test_case(100);
$display("\n=== RANDOM STRESS TEST ===");
// todo
$display("\n=== TEST FINISHED ===");
$finish;
end
endmodule
module triangle_wave_gen #(
parameter DATA_WIDTH = 12,
parameter OFFSET = 100, // offset of bits from '0 and '1 for OTR
parameter STEP = 1 // LSB bit per clock
) (
input clk,
input rst,
output logic [DATA_WIDTH-1:0] signal,
output logic otr
);
logic [DATA_WIDTH:0] counter;
logic direction;
initial begin
counter = '0;
direction = 1;
end
assign signal = counter > (2**DATA_WIDTH-1) ? (2**DATA_WIDTH-1) : counter;
always_comb begin
if (signal < OFFSET || (2**DATA_WIDTH - signal) <= OFFSET)
otr <= 1;
else
otr <= 0;
end
always @(posedge clk) begin
if (rst) begin
counter = 0;
direction = 1;
end else begin
if (direction)
counter += STEP;
else
counter -= STEP;
if (counter >= 2**DATA_WIDTH-1 || counter <= 0)
direction <= ~direction;
end
end
endmodule