183 lines
4.3 KiB
Systemverilog
183 lines
4.3 KiB
Systemverilog
`timescale 1ns / 1ps
|
|
|
|
module tb_accumulator;
|
|
|
|
localparam DATA_WIDTH = 12;
|
|
localparam ACCUM_WIDTH = 32;
|
|
localparam N_MAX = 64;
|
|
localparam WINDOW_SIZE = 4;
|
|
localparam PACKET_SIZE = 8; // bytes
|
|
localparam READ_BATCH_SIZE = (PACKET_SIZE*8)/ACCUM_WIDTH; // = 2
|
|
|
|
reg clk_in;
|
|
reg rst;
|
|
reg [DATA_WIDTH-1:0] s_axis_tdata;
|
|
reg s_axis_tvalid;
|
|
reg start;
|
|
reg [31:0] smp_num;
|
|
reg [15:0] seq_num;
|
|
wire [ACCUM_WIDTH-1:0] out_data;
|
|
wire out_valid;
|
|
wire readout_begin;
|
|
reg batch_req;
|
|
reg finish;
|
|
|
|
integer i;
|
|
integer out_count;
|
|
|
|
reg [ACCUM_WIDTH-1:0] expected [0:READ_BATCH_SIZE-1];
|
|
reg [ACCUM_WIDTH-1:0] got [0:READ_BATCH_SIZE-1];
|
|
|
|
accumulator #(
|
|
.DATA_WIDTH(DATA_WIDTH),
|
|
.ACCUM_WIDTH(ACCUM_WIDTH),
|
|
.N_MAX(N_MAX),
|
|
.WINDOW_SIZE(WINDOW_SIZE),
|
|
.PACKET_SIZE(PACKET_SIZE)
|
|
) dut (
|
|
.clk_in(clk_in),
|
|
.rst(rst),
|
|
.s_axis_tdata(s_axis_tdata),
|
|
.s_axis_tvalid(s_axis_tvalid),
|
|
.start(start),
|
|
.smp_num(smp_num),
|
|
.seq_num(seq_num),
|
|
.out_data(out_data),
|
|
.out_valid(out_valid),
|
|
.readout_begin(readout_begin),
|
|
.batch_req(batch_req),
|
|
.finish(finish)
|
|
);
|
|
|
|
// clock 100 MHz
|
|
initial begin
|
|
clk_in = 0;
|
|
forever #5 clk_in = ~clk_in;
|
|
end
|
|
|
|
// send one sample
|
|
task send_sample(input [DATA_WIDTH-1:0] val);
|
|
begin
|
|
@(posedge clk_in);
|
|
s_axis_tdata <= val;
|
|
s_axis_tvalid <= 1'b1;
|
|
end
|
|
endtask
|
|
|
|
// one idle cycle after valid stream
|
|
task end_stream;
|
|
begin
|
|
@(posedge clk_in);
|
|
s_axis_tvalid <= 1'b0;
|
|
s_axis_tdata <= '0;
|
|
end
|
|
endtask
|
|
|
|
// pulse start
|
|
task pulse_start;
|
|
begin
|
|
@(posedge clk_in);
|
|
start <= 1'b1;
|
|
@(posedge clk_in);
|
|
start <= 1'b0;
|
|
end
|
|
endtask
|
|
|
|
// pulse batch request
|
|
task pulse_batch_req;
|
|
begin
|
|
@(posedge clk_in);
|
|
batch_req <= 1'b1;
|
|
@(posedge clk_in);
|
|
batch_req <= 1'b0;
|
|
end
|
|
endtask
|
|
|
|
initial begin
|
|
repeat(100) @(posedge clk_in);
|
|
// init
|
|
rst = 1'b1;
|
|
s_axis_tdata = '0;
|
|
s_axis_tvalid= 1'b0;
|
|
start = 1'b0;
|
|
smp_num = 32'd8;
|
|
seq_num = 16'd2;
|
|
batch_req = 1'b0;
|
|
finish = 1'b0;
|
|
|
|
expected[0] = 32'd60;
|
|
expected[1] = 32'd92;
|
|
|
|
repeat(50) @(posedge clk_in);
|
|
rst = 1'b0;
|
|
repeat(50) @(posedge clk_in);
|
|
|
|
$display("=== TEST START ===");
|
|
|
|
pulse_start();
|
|
|
|
// seq 0: [1..8]
|
|
send_sample(12'd1);
|
|
send_sample(12'd2);
|
|
send_sample(12'd3);
|
|
send_sample(12'd4);
|
|
send_sample(12'd5);
|
|
send_sample(12'd6);
|
|
send_sample(12'd7);
|
|
send_sample(12'd8);
|
|
end_stream();
|
|
|
|
// небольшой зазор
|
|
repeat(5) @(posedge clk_in);
|
|
|
|
// seq 1: [11..18]
|
|
send_sample(12'd11);
|
|
send_sample(12'd12);
|
|
send_sample(12'd13);
|
|
send_sample(12'd14);
|
|
send_sample(12'd15);
|
|
send_sample(12'd16);
|
|
send_sample(12'd17);
|
|
send_sample(12'd18);
|
|
end_stream();
|
|
|
|
$display("[%0t] all input data sent, waiting readout_begin...", $time);
|
|
|
|
wait(readout_begin == 1'b1);
|
|
$display("[%0t] readout_begin asserted", $time);
|
|
repeat(22) @(posedge clk_in);
|
|
pulse_batch_req();
|
|
|
|
out_count = 0;
|
|
|
|
// ждём два слова
|
|
while (out_count < READ_BATCH_SIZE) begin
|
|
@(posedge clk_in);
|
|
if (out_valid) begin
|
|
got[out_count] = out_data;
|
|
$display("[%0t] out_valid: got[%0d] = %0d", $time, out_count, out_data);
|
|
out_count = out_count + 1;
|
|
end
|
|
end
|
|
|
|
// проверка
|
|
for (i = 0; i < READ_BATCH_SIZE; i = i + 1) begin
|
|
if (got[i] !== expected[i]) begin
|
|
$error("Mismatch at index %0d: got=%0d expected=%0d", i, got[i], expected[i]);
|
|
end else begin
|
|
$display("OK index %0d: %0d", i, got[i]);
|
|
end
|
|
end
|
|
|
|
// завершаем readout
|
|
@(posedge clk_in);
|
|
finish <= 1'b1;
|
|
|
|
|
|
repeat(10) @(posedge clk_in);
|
|
|
|
$display("=== TEST PASSED ===");
|
|
$finish;
|
|
end
|
|
|
|
endmodule |