upd: new TB, sampler refactor

This commit is contained in:
2026-07-21 16:54:06 +03:00
parent a528838741
commit 81970c8b42
2 changed files with 153 additions and 127 deletions

View File

@ -13,18 +13,18 @@ module sampler
input [31:0] smp_num, input [31:0] smp_num,
input request, input request,
output logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata, output logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata,
output logic m_axis_tvalid, output logic m_axis_tvalid,
output logic done output logic done
); );
// WARNING: number of samples smp_num must be multiple of PACK_FACTOR
// Last (smp_num % PACK_FACTOR) will be lost and not transmitted
logic [DATA_WIDTH-1:0] data_converted; logic [DATA_WIDTH-1:0] data_converted;
logic [31:0] smp_num_reg, cnt_smp_num; logic [31:0] smp_num_reg, cnt_smp_num;
logic synced; logic synced;
logic [$clog2(PACK_FACTOR):0] pack_cnt; logic [$clog2(PACK_FACTOR):0] pack_cnt;
always_comb begin always_comb begin
data_converted = '0;
if (PROCESS_MODE) begin if (PROCESS_MODE) begin
if (out_of_range) begin if (out_of_range) begin
data_converted = {~data_in[DATA_WIDTH-1], {(DATA_WIDTH-1){data_in[DATA_WIDTH-1]}}}; data_converted = {~data_in[DATA_WIDTH-1], {(DATA_WIDTH-1){data_in[DATA_WIDTH-1]}}};
@ -39,7 +39,12 @@ module sampler
end end
end end
end end
initial begin
synced = 0;
m_axis_tdata = '0;
m_axis_tvalid = 0;
end
always_ff @(posedge clk_in) begin always_ff @(posedge clk_in) begin
if (rst) begin if (rst) begin
@ -51,10 +56,9 @@ module sampler
synced <= 0; synced <= 0;
done <= 0; done <= 0;
end else begin end else begin
m_axis_tvalid <= 0;
if (!synced) begin if (!synced) begin
if (done && request) begin if (done && request) begin
synced <= 1; synced <= 1;
done <= 0; done <= 0;
cnt_smp_num <= 0; cnt_smp_num <= 0;
smp_num_reg <= smp_num; smp_num_reg <= smp_num;
@ -63,23 +67,21 @@ module sampler
end end
end else begin end else begin
if (cnt_smp_num != smp_num_reg) begin if (cnt_smp_num != smp_num_reg) begin
cnt_smp_num <= cnt_smp_num +1; cnt_smp_num++;
m_axis_tdata[pack_cnt*DATA_WIDTH +: DATA_WIDTH] <= data_converted; m_axis_tdata[pack_cnt*DATA_WIDTH +: DATA_WIDTH] <= data_converted;
if (pack_cnt == PACK_FACTOR-1) begin if (pack_cnt == PACK_FACTOR-1) begin
pack_cnt <= 0; pack_cnt <= 0;
m_axis_tvalid <= 1; m_axis_tvalid <= 1;
end else begin end else begin
pack_cnt <= pack_cnt + 1; pack_cnt++;
m_axis_tvalid <= 0;
end end
end else begin end else begin
cnt_smp_num <= '0; pack_cnt <= '0;
pack_cnt <= '0;
synced <= 0; synced <= 0;
done <= 1; m_axis_tvalid <= 0;
m_axis_tdata <= '0;
end end
end end
end end
end end
endmodule endmodule

View File

@ -3,15 +3,17 @@
module sampler_tb; module sampler_tb;
localparam DATA_WIDTH = 12; localparam DATA_WIDTH = 12;
localparam PACK_FACTOR = 1; localparam PACK_FACTOR = 7;
localparam PROCESS_MODE = 0; localparam PROCESS_MODE = 0;
localparam CLK_PERIOD = 15.3846; localparam CLK_PERIOD = 15.3846;
localparam OTR_OFFSET = 0;
logic clk; logic clk;
logic rst; logic rst_dut;
logic rst_gen;
logic [DATA_WIDTH-1:0] data_in; wire [DATA_WIDTH-1:0] data_in;
logic out_of_range; wire out_of_range;
logic [31:0] smp_num; logic [31:0] smp_num;
@ -21,15 +23,13 @@ module sampler_tb;
logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata; logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata;
logic m_axis_tvalid; logic m_axis_tvalid;
int received_count;
sampler #( sampler #(
.DATA_WIDTH (DATA_WIDTH), .DATA_WIDTH (DATA_WIDTH),
.PACK_FACTOR (PACK_FACTOR), .PACK_FACTOR (PACK_FACTOR),
.PROCESS_MODE(PROCESS_MODE) .PROCESS_MODE(PROCESS_MODE)
) dut ( ) dut (
.clk_in (clk), .clk_in (clk),
.rst (rst), .rst (rst_dut),
.data_in (data_in), .data_in (data_in),
.out_of_range (out_of_range), .out_of_range (out_of_range),
@ -54,122 +54,97 @@ module sampler_tb;
// ===================================================== // =====================================================
// RESET // RESET
// ===================================================== // =====================================================
initial begin task automatic reset_dut();
rst = 1; @(posedge clk);
data_in = 0; rst_dut = 1;
out_of_range = 0; @(posedge clk);
done = 0; rst_dut = 0;
smp_num = 0; endtask
repeat(5) @(posedge clk);
rst = 0;
end
// =====================================================
// OUTPUT COUNTER
// =====================================================
always @(posedge clk) begin
if (m_axis_tvalid)
received_count++;
end
// ===================================================== // =====================================================
// FEED DATA // FEED DATA
// ===================================================== // =====================================================
task automatic feed_data_stream( triangle_wave_gen #(
input int num_words, .DATA_WIDTH(DATA_WIDTH),
input bit random_data, .OFFSET(OTR_OFFSET), // offset of bits from '0 and '1 for OTR
input bit random_out_of_range .STEP(1) // LSB bit per clock
) signal_gen (
.clk(clk),
.rst(rst_gen),
.signal(data_in),
.otr(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;
@(posedge clk);
end
out_of_range = 0;
end
endtask
// ===================================================== // =====================================================
// TEST CASE // TEST TASKS
// ===================================================== // =====================================================
task automatic run_test_case( task automatic run_test_case(
input int n, input int sample_num
input bit random_data,
input bit random_out_of_range
); );
begin logic [DATA_WIDTH-1:0] input_values[$];
received_count = 0; logic [DATA_WIDTH-1:0] output_values[$];
bit flag;
data_in = 0; // Startup sequence
out_of_range = 0; rst_gen <= 1;
done = 0; smp_num <= sample_num;
request <= 1;
smp_num = n;
// handshake
@(posedge clk); @(posedge clk);
done <= 1'b1;
wait(request == 1'b1); // syncronize
@(posedge clk); while (!done)
done <= 1'b0; @(posedge clk);
request <= 0;
// Wait for sync and start signal generator
// while (!dut.synced)
// @(posedge clk);
wait(dut.synced === 1);
rst_gen <= 0;
// wait enable // Wait for valid data
wait(dut.enable == 1'b1); 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
// feed data // Wait until end
feed_data_stream(n + 10, random_data, random_out_of_range); // while (dut.synced)
// @(posedge clk);
wait(dut.synced === 0);
// wait completion disable stat_mon_proc;
wait(dut.enable == 1'b0); // Pop last input value. Signal is ahead of tdata for 1 cycle
input_values.pop_back();
$display("Expected smp_num=%0d Received=%0d", smp_num, received_count); // check data
if (input_values.size() != output_values.size()) begin
if (received_count == smp_num) $display("[ERROR] -run_test_case- Input queue size don't equal to output queue size: %0d vs %0d", input_values.size(), output_values.size());
$display("[OK]"); $finish;
else
$display("[ERROR]");
repeat(10) @(posedge clk);
end
endtask
// =====================================================
// RANDOM TESTS
// =====================================================
task automatic random_stress_test;
int n;
begin
for (int i = 0; i < 20; i++) begin
n = $urandom_range(5,20);
$display("\n--- TEST %0d --- n=%0d", i, n);
run_test_case(
n,
1,
1
);
end end
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 endtask
// ===================================================== // =====================================================
@ -178,17 +153,66 @@ module sampler_tb;
initial begin initial begin
$display("\n=== BASIC TEST ==="); $display("\n=== BASIC TEST ===");
run_test_case(10, 0, 0);
$display("\n=== OUT_OF_RANGE TEST ==="); rst_dut = 1;
run_test_case(20, 1, 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 ==="); $display("\n=== RANDOM STRESS TEST ===");
random_stress_test(); // todo
$display("\n=== TEST FINISHED ==="); $display("\n=== TEST FINISHED ===");
$finish; $finish;
end end
endmodule 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