211 lines
5.5 KiB
Systemverilog
211 lines
5.5 KiB
Systemverilog
`timescale 1ns / 1ps
|
||
|
||
module sampler_tb;
|
||
|
||
// =========================================================
|
||
// 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 [31:0] smp_num;
|
||
|
||
logic done;
|
||
logic request;
|
||
|
||
logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata;
|
||
logic m_axis_tvalid;
|
||
|
||
// =========================================================
|
||
// 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),
|
||
|
||
.request(request)
|
||
);
|
||
|
||
// =========================================================
|
||
// CLOCK
|
||
// =========================================================
|
||
initial begin
|
||
clk = 0;
|
||
forever #(CLK_PERIOD/2) clk = ~clk;
|
||
end
|
||
|
||
// =========================================================
|
||
// RESET (ONLY ONCE)
|
||
// =========================================================
|
||
initial begin
|
||
rst = 1;
|
||
done = 0;
|
||
data_in = 0;
|
||
out_of_range = 0;
|
||
smp_num = 0;
|
||
|
||
repeat(5) @(posedge clk);
|
||
rst = 0;
|
||
end
|
||
|
||
// =========================================================
|
||
// CONFIG
|
||
// =========================================================
|
||
task automatic set_config(
|
||
input int n,
|
||
input int init_delay
|
||
);
|
||
smp_num = n;
|
||
repeat(init_delay) @(posedge clk);
|
||
endtask
|
||
|
||
// =========================================================
|
||
// 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);
|
||
|
||
done <= 1'b1;
|
||
wait(request == 1'b1);
|
||
|
||
repeat(ack_duration) @(posedge clk);
|
||
|
||
done <= 1'b0;
|
||
end
|
||
else begin
|
||
wait(request == 1'b1);
|
||
|
||
repeat(delay_before_ack) @(posedge clk);
|
||
|
||
done <= 1'b1;
|
||
|
||
repeat(ack_duration) @(posedge clk);
|
||
|
||
done <= 1'b0;
|
||
end
|
||
endtask
|
||
|
||
// =========================================================
|
||
// 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("[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
|
||
|
||
endmodule |