tests: add simple tb for accum output fifo
This commit is contained in:
198
rtl/accum/tests/out_axis_fifo_tb.sv
Normal file
198
rtl/accum/tests/out_axis_fifo_tb.sv
Normal 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
|
||||
Reference in New Issue
Block a user