Files
reflectometer_fpga_project/rtl/accum/tests/out_axis_fifo_tb.sv
2026-04-17 21:51:00 +03:00

198 lines
5.1 KiB
Systemverilog
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

`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