tests: add simple tb for accum output fifo

This commit is contained in:
Phil
2026-04-17 21:51:00 +03:00
parent 4786d2d7f6
commit 7f9ad95e68
2 changed files with 250 additions and 0 deletions

View File

@ -0,0 +1,198 @@
`timescale 1ns/1ps
module tb_out_axis_fifo;
localparam int ACCUM_WIDTH = 32;
localparam int WINDOW_SIZE = 65;
localparam int PACKET_SIZE = 1024;
logic eth_clk_in;
logic acc_clk_in;
logic rst;
logic [31:0] smp_num;
logic [7:0] s_axis_tdata;
logic s_axis_tvalid;
logic s_axis_tready;
logic s_axis_tlast;
logic [ACCUM_WIDTH-1:0] acc_din;
logic din_valid;
logic readout_begin;
logic batch_req;
logic finish;
out_axis_fifo #(
.ACCUM_WIDTH(ACCUM_WIDTH),
.WINDOW_SIZE(WINDOW_SIZE),
.PACKET_SIZE(PACKET_SIZE)
) dut (
.eth_clk_in (eth_clk_in),
.acc_clk_in (acc_clk_in),
.rst (rst),
.smp_num (smp_num),
.s_axis_tdata (s_axis_tdata),
.s_axis_tvalid (s_axis_tvalid),
.s_axis_tready (s_axis_tready),
.s_axis_tlast (s_axis_tlast),
.acc_din (acc_din),
.din_valid (din_valid),
.readout_begin (readout_begin),
.batch_req (batch_req),
.finish (finish)
);
// -----------------------------
// clocks
// -----------------------------
initial begin
eth_clk_in = 0;
forever #4 eth_clk_in = ~eth_clk_in; // 125 MHz
end
initial begin
acc_clk_in = 0;
forever #3 acc_clk_in = ~acc_clk_in; // ~166.7 MHz
end
// -----------------------------
// simple AXIS sink
// -----------------------------
initial begin
s_axis_tready = 1'b1;
end
// У DUT нет своей логики rd_en, поэтому для теста подадим её force-ом.
initial begin
force dut.rd_en = dut.s_axis_tvalid && s_axis_tready;
end
// -----------------------------
// helpers
// -----------------------------
task automatic do_reset();
begin
rst = 1'b1;
readout_begin = 1'b0;
din_valid = 1'b0;
acc_din = '0;
smp_num = '0;
repeat (10) @(posedge acc_clk_in);
rst = 1'b0;
repeat (10) @(posedge acc_clk_in);
end
endtask
task automatic pulse_readout_begin(input logic [31:0] smp_num_i);
begin
smp_num = smp_num_i;
@(posedge acc_clk_in);
readout_begin <= 1'b1;
@(posedge acc_clk_in);
readout_begin <= 1'b0;
end
endtask
task automatic send_random_words(input int unsigned n_words);
int unsigned i;
begin
for (i = 0; i < n_words; i++) begin
@(posedge acc_clk_in);
din_valid <= 1'b1;
acc_din <= $urandom;
end
@(posedge acc_clk_in);
din_valid <= 1'b0;
acc_din <= '0;
end
endtask
// Один запуск:
// 1) задаём smp_num
// 2) даём readout_begin
// 3) каждый раз, когда DUT просит batch_req, отправляем PACKET_SIZE слов
// 4) ждём finish
task automatic run_case(input logic [31:0] smp_num_i);
int batch_count;
begin
batch_count = 0;
$display("[%0t] run_case start, smp_num=%0d", $time, smp_num_i);
pulse_readout_begin(smp_num_i);
while (finish !== 1'b1) begin
@(posedge acc_clk_in);
if (batch_req) begin
batch_count++;
$display("[%0t] batch_req #%0d -> send %0d words",
$time, batch_count, PACKET_SIZE / ACCUM_WIDTH * 8);
// send packets to accomplish 1kb packet.
send_random_words(PACKET_SIZE / ACCUM_WIDTH * 8);
end
end
$display("[%0t] run_case done, smp_num=%0d, batches=%0d, wr_cnt=%0d, wr_total=%0d",
$time, smp_num_i, batch_count, dut.wr_cnt, dut.wr_total);
@(posedge acc_clk_in);
end
endtask
// -----------------------------
// monitor
// -----------------------------
int axis_byte_count;
always_ff @(posedge eth_clk_in or posedge rst) begin
if (rst) begin
axis_byte_count <= 0;
end else begin
if (s_axis_tvalid && s_axis_tready) begin
axis_byte_count <= axis_byte_count + 1;
end
end
end
// -----------------------------
// main
// -----------------------------
initial begin
// init
rst = 1'b0;
readout_begin = 1'b0;
din_valid = 1'b0;
acc_din = '0;
smp_num = '0;
// 1-й запуск
do_reset();
run_case(32'd17);
// 2-й запуск
do_reset();
run_case(32'd1024);
// 3-й запуск
do_reset();
run_case(32'd77777);
do_reset();
repeat (50) @(posedge acc_clk_in);
$display("[%0t] ALL TESTS DONE", $time);
$finish;
end
endmodule