rtl: final modified sampler

This commit is contained in:
otroubi
2026-06-10 15:50:39 +03:00
parent cf2985813a
commit 4270c2fca8
2 changed files with 291 additions and 171 deletions

View File

@ -21,7 +21,7 @@ module sampler
(* MARK_DEBUG="true" *) logic [DATA_WIDTH-1:0] data_converted;
(* MARK_DEBUG="true" *) logic out_of_range_reg;
(* MARK_DEBUG="true" *) logic [31:0] smp_num_reg, cnt_smp_num;
(* MARK_DEBUG="true" *) logic enable;
(* MARK_DEBUG="true" *) logic enable, enable_d;
generate
if (PROCESS_MODE) begin
@ -54,7 +54,7 @@ module sampler
endgenerate
(* MARK_DEBUG="true" *) logic [DATA_WIDTH*PACK_FACTOR-1:0] buffer;
(* MARK_DEBUG="true" *) logic buffer_ready, wait_sync;
(* MARK_DEBUG="true" *) logic buffer_ready;
logic [$clog2(PACK_FACTOR):0] cnt;
@ -68,42 +68,34 @@ module sampler
smp_num_reg <= '0;
enable <= 0;
request <= 0;
wait_sync <= 0;
end
else begin
buffer_ready <= 0;
if (!enable) begin
if (!wait_sync) begin
request <= 1'b0;
if (done) begin
wait_sync <= 1'b1;
request <= 1'b1;
end
if (request && done) begin
enable <= 1;
request <= 0;
cnt_smp_num <= 0;
smp_num_reg <= smp_num;
end else begin
if (!done) begin
enable <= 1'b1;
request <= 1'b0;
wait_sync <= 1'b0;
cnt_smp_num <= 0;
smp_num_reg <= smp_num;
request <= 1;
end
end
end else begin
if (!out_of_range_reg) begin
if (cnt_smp_num != smp_num_reg) begin
if (cnt_smp_num != smp_num_reg) begin
cnt_smp_num <= cnt_smp_num +1;
if (!out_of_range_reg) begin
buffer <= data_converted;
buffer_ready <= 1;
cnt_smp_num <= cnt_smp_num +1;
end
end
else begin
cnt_smp_num <= '0;
buffer <= '0;
buffer_ready <= 0;
enable <= 0;
end
end
end
end
end
end else begin
always @(posedge clk_in) begin
if (rst) begin
@ -118,25 +110,18 @@ module sampler
else begin
buffer_ready <= 0;
if (!enable) begin
if (!wait_sync) begin
request <= 1'b0;
if (done) begin
wait_sync <= 1'b1;
request <= 1'b1;
end
if (request && done) begin
enable <= 1;
request <= 0;
cnt_smp_num <= 0;
smp_num_reg <= smp_num;
end else begin
if (!done) begin
enable <= 1'b1;
request <= 1'b0;
wait_sync <= 1'b0;
cnt_smp_num <= 0;
smp_num_reg <= smp_num;
request <= 1;
end
end
end else begin
if (!out_of_range_reg) begin
if (cnt_smp_num < smp_num_reg) begin
cnt_smp_num <= cnt_smp_num +1;
if (cnt_smp_num != smp_num_reg) begin
cnt_smp_num <= cnt_smp_num +1;
if (!out_of_range_reg) begin
buffer <= {buffer[DATA_WIDTH*(PACK_FACTOR-1)-1:0], data_converted};
if (cnt == PACK_FACTOR-1) begin
cnt <= 0;
@ -147,15 +132,15 @@ module sampler
cnt <= cnt + 1;
end
end
end
else begin
cnt_smp_num <= '0;
buffer_ready <= 0;
buffer <= '0;
enable <= 0;
cnt <= 0;
end
end
end
end
end
end
endgenerate

View File

@ -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