198 lines
5.1 KiB
Systemverilog
198 lines
5.1 KiB
Systemverilog
`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 |