rtl: final modified sampler
This commit is contained in:
@ -2,17 +2,15 @@
|
||||
|
||||
module sampler_tb;
|
||||
|
||||
// =========================================================
|
||||
// PARAMETERS
|
||||
// =========================================================
|
||||
localparam DATA_WIDTH = 12;
|
||||
localparam PACK_FACTOR = 1;
|
||||
localparam DATA_WIDTH = 12;
|
||||
localparam PACK_FACTOR = 1;
|
||||
localparam PROCESS_MODE = 0;
|
||||
localparam CLK_PERIOD = 15.3846;
|
||||
localparam CLK_PERIOD = 15.3846;
|
||||
|
||||
// =====================================================
|
||||
// DUT SIGNALS
|
||||
// =====================================================
|
||||
|
||||
// =========================================================
|
||||
// SIGNALS
|
||||
// =========================================================
|
||||
logic clk;
|
||||
logic rst;
|
||||
|
||||
@ -27,185 +25,322 @@ module sampler_tb;
|
||||
logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata;
|
||||
logic m_axis_tvalid;
|
||||
|
||||
// =========================================================
|
||||
// =====================================================
|
||||
// SCOREBOARD
|
||||
// =====================================================
|
||||
|
||||
int received_count;
|
||||
int expected_count;
|
||||
|
||||
// =====================================================
|
||||
// DUT
|
||||
// =========================================================
|
||||
// =====================================================
|
||||
|
||||
sampler #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.PACK_FACTOR(PACK_FACTOR),
|
||||
.DATA_WIDTH (DATA_WIDTH),
|
||||
.PACK_FACTOR (PACK_FACTOR),
|
||||
.PROCESS_MODE(PROCESS_MODE)
|
||||
) dut (
|
||||
.clk_in(clk),
|
||||
.rst(rst),
|
||||
.clk_in (clk),
|
||||
.rst (rst),
|
||||
|
||||
.data_in(data_in),
|
||||
.out_of_range(out_of_range),
|
||||
.data_in (data_in),
|
||||
.out_of_range (out_of_range),
|
||||
|
||||
.smp_num(smp_num),
|
||||
.done(done),
|
||||
.smp_num (smp_num),
|
||||
.done (done),
|
||||
|
||||
.m_axis_tdata(m_axis_tdata),
|
||||
.m_axis_tdata (m_axis_tdata),
|
||||
.m_axis_tvalid(m_axis_tvalid),
|
||||
|
||||
.request(request)
|
||||
.request (request)
|
||||
);
|
||||
|
||||
// =========================================================
|
||||
// =====================================================
|
||||
// CLOCK
|
||||
// =========================================================
|
||||
// =====================================================
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
forever #(CLK_PERIOD/2) clk = ~clk;
|
||||
end
|
||||
|
||||
// =========================================================
|
||||
// RESET (ONLY ONCE)
|
||||
// =========================================================
|
||||
// =====================================================
|
||||
// RESET
|
||||
// =====================================================
|
||||
|
||||
initial begin
|
||||
rst = 1;
|
||||
done = 0;
|
||||
data_in = 0;
|
||||
rst = 1;
|
||||
|
||||
data_in = 0;
|
||||
out_of_range = 0;
|
||||
smp_num = 0;
|
||||
|
||||
done = 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;
|
||||
// =====================================================
|
||||
// RECEIVED COUNTER
|
||||
// =====================================================
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (m_axis_tvalid)
|
||||
received_count++;
|
||||
end
|
||||
|
||||
// =========================================================
|
||||
// TEST CASE
|
||||
// =========================================================
|
||||
// =====================================================
|
||||
// CONFIG
|
||||
// =====================================================
|
||||
|
||||
task automatic set_config(input int n);
|
||||
begin
|
||||
smp_num = n;
|
||||
@(posedge clk);
|
||||
end
|
||||
endtask
|
||||
|
||||
// =====================================================
|
||||
// WAIT SAMPLER START
|
||||
// =====================================================
|
||||
|
||||
task automatic wait_sampler_start;
|
||||
begin
|
||||
wait(dut.enable == 1'b1);
|
||||
// @(negedge clk);
|
||||
end
|
||||
endtask
|
||||
|
||||
// =====================================================
|
||||
// HANDSHAKE
|
||||
// =====================================================
|
||||
|
||||
task automatic synchronize_sampler(
|
||||
input bit sampler_first,
|
||||
input int delay_before_ack,
|
||||
input int ack_duration
|
||||
);
|
||||
begin
|
||||
|
||||
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
|
||||
|
||||
end
|
||||
endtask
|
||||
|
||||
// =====================================================
|
||||
// DATA FEED
|
||||
// =====================================================
|
||||
|
||||
task automatic feed_data_stream(
|
||||
input int num_words,
|
||||
input bit random_data,
|
||||
input bit random_out_of_range
|
||||
);
|
||||
|
||||
logic [DATA_WIDTH-1:0] value;
|
||||
bit oor;
|
||||
|
||||
begin
|
||||
|
||||
value = 1;
|
||||
|
||||
for (int i = 0; i < num_words; i++) begin
|
||||
|
||||
if (random_data)
|
||||
value = $urandom_range(1, (1<<DATA_WIDTH)-1);
|
||||
else
|
||||
value = value + 1;
|
||||
|
||||
if (random_out_of_range)
|
||||
oor = ($urandom_range(0,3) == 0);
|
||||
else
|
||||
oor = 0;
|
||||
|
||||
|
||||
data_in = value;
|
||||
out_of_range = oor;
|
||||
|
||||
|
||||
if (!oor)
|
||||
expected_count++;
|
||||
|
||||
@(posedge clk);
|
||||
|
||||
end
|
||||
|
||||
out_of_range <= 0;
|
||||
|
||||
end
|
||||
endtask
|
||||
|
||||
// =====================================================
|
||||
// SINGLE TEST
|
||||
// =====================================================
|
||||
|
||||
task automatic run_test_case(
|
||||
input int n,
|
||||
input int delay,
|
||||
input int ack,
|
||||
input int delay_before_ack,
|
||||
input int ack_duration,
|
||||
input bit sampler_first,
|
||||
input bit random_stream
|
||||
input bit random_data,
|
||||
input bit random_out_of_range
|
||||
);
|
||||
begin
|
||||
|
||||
received_count = 0;
|
||||
expected_count = 0;
|
||||
|
||||
set_config(n, 2);
|
||||
data_in = 0;
|
||||
out_of_range = 0;
|
||||
done = 0;
|
||||
|
||||
// 1) сначала синхронизация
|
||||
synchronize_sampler(sampler_first, delay, ack);
|
||||
set_config(n);
|
||||
|
||||
// 2) СРАЗУ после sync - поток данных
|
||||
feed_data_stream(n, random_stream);
|
||||
synchronize_sampler(
|
||||
sampler_first,
|
||||
delay_before_ack,
|
||||
1
|
||||
);
|
||||
|
||||
repeat(20) @(posedge clk);
|
||||
|
||||
if (received_count == n)
|
||||
$display("[OK] received %0d / %0d", received_count, n);
|
||||
feed_data_stream(
|
||||
n,
|
||||
random_data,
|
||||
random_out_of_range
|
||||
);
|
||||
|
||||
repeat(30)
|
||||
@(posedge clk);
|
||||
|
||||
$display(
|
||||
"Expected=%0d Received=%0d",
|
||||
expected_count,
|
||||
received_count
|
||||
);
|
||||
|
||||
if (received_count == expected_count)
|
||||
$display("[OK]");
|
||||
else
|
||||
$display("[ERROR] received %0d / %0d", received_count, n);
|
||||
$display("[ERROR]");
|
||||
|
||||
repeat(10)
|
||||
@(posedge clk);
|
||||
|
||||
end
|
||||
endtask
|
||||
|
||||
// =========================================================
|
||||
// RANDOM STRESS TEST
|
||||
// =========================================================
|
||||
task automatic check_random;
|
||||
int n, d, a;
|
||||
// =====================================================
|
||||
// RANDOM STRESS
|
||||
// =====================================================
|
||||
|
||||
task automatic random_stress_test;
|
||||
int n;
|
||||
int d;
|
||||
int a;
|
||||
bit sf;
|
||||
begin
|
||||
|
||||
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);
|
||||
n = $urandom_range(5,20);
|
||||
d = $urandom_range(0,5);
|
||||
a = $urandom_range(1,5);
|
||||
sf = $urandom_range(0,1);
|
||||
|
||||
$display("");
|
||||
$display(
|
||||
"--- TEST %0d --- n=%0d delay=%0d ack=%0d sf=%0b",
|
||||
i, n, d, a, sf
|
||||
);
|
||||
|
||||
run_test_case(
|
||||
n,
|
||||
d,
|
||||
a,
|
||||
sf,
|
||||
1, // random data
|
||||
1 // random out_of_range
|
||||
);
|
||||
|
||||
run_test_case(n, d, a, sf, 1);
|
||||
end
|
||||
|
||||
end
|
||||
endtask
|
||||
|
||||
// =========================================================
|
||||
// =====================================================
|
||||
// MAIN
|
||||
// =========================================================
|
||||
// =====================================================
|
||||
|
||||
initial begin
|
||||
$display("\n=== SAMPLER TEST (FIXED FLOW: NO MULTI RESET) ===\n");
|
||||
|
||||
check_random();
|
||||
wait(!rst);
|
||||
|
||||
$display("");
|
||||
$display("=== BASIC TEST ===");
|
||||
|
||||
run_test_case(
|
||||
10,
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
$display("");
|
||||
$display("=== OUT_OF_RANGE TEST ===");
|
||||
|
||||
run_test_case(
|
||||
20,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
);
|
||||
|
||||
$display("");
|
||||
$display("=== RANDOM STRESS TEST ===");
|
||||
|
||||
random_stress_test();
|
||||
|
||||
$display("");
|
||||
$display("=== TEST FINISHED ===");
|
||||
|
||||
$display("\n=== TEST FINISHED ===");
|
||||
$finish;
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user