Files
b210-k7-fpga/lib/packet_proc/cvita_chunker_tb.v
T
Ben Hilburn 29086f9001 b2xx: Updating FPGA source with recent bugfixes.
Original-commit: 4b4365a517938b365af57674a3ab1462432c2c3a
2013-12-03 10:35:35 -08:00

200 lines
6.2 KiB
Verilog

//
// Copyright 2013 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
`timescale 500ps/1ps
module cvita_chunker_tb();
// TB stimulus
reg clk = 0;
reg reset = 1;
reg clear = 0;
reg [15:0] quantum;
// Check vars
reg [31:0] o_xfer_count = 0, i_xfer_count = 0;
reg [63:0] o_last_tdata = 0;
always #10 clk = ~clk;
initial $dumpfile("cvita_chunker_tb.vcd");
initial $dumpvars(0,cvita_chunker_tb);
function check_result;
input [31:0] o_xfer_count_arg;
input [31:0] i_xfer_count_arg;
input [63:0] o_last_tdata_arg;
input error_arg;
begin
//Check vars
check_result = 1;
check_result = check_result & ((o_xfer_count_arg == o_xfer_count) !== 0);
check_result = check_result & ((i_xfer_count_arg == i_xfer_count) !== 0);
check_result = check_result & ((o_last_tdata_arg == o_last_tdata) !== 0);
check_result = check_result & ((error_arg == error) != 0);
if (check_result) begin
$display ("... Passed");
end else begin
$display ("... FAILED!!!");
$display ("o_xfer_count = %d (Expected %d)",o_xfer_count,o_xfer_count_arg);
$display ("i_xfer_count = %d (Expected %d)",i_xfer_count,i_xfer_count_arg);
$display ("o_last_tdata = %h (Expected %h)",o_last_tdata,o_last_tdata_arg);
$display ("error = %d (Expected %d)",error,error_arg);
end
//Reset vars
o_xfer_count = 0;
i_xfer_count = 0;
o_last_tdata = 64'h0;
end
endfunction
task send_packet;
input [63:0] data_start;
input [31:0] len;
begin
if(len < 9) begin
{i_tlast, i_tdata} <= { 1'b1, data_start[63:48],len[15:0], data_start[31:0] };
i_tvalid <= 1;
@(posedge clk);
i_tvalid <= 0;
end else begin
{i_tlast, i_tdata} <= { 1'b0, data_start[63:48],len[15:0], data_start[31:0] };
i_tvalid <= 1;
@(posedge clk);
repeat(((len-1)/8)-1) begin
i_tdata <= i_tdata + 64'h0000_0002_0000_0002;
@(posedge clk);
end
i_tdata <= i_tdata + 64'h0000_0002_0000_0002;
i_tlast <= 1;
@(posedge clk);
i_tvalid <= 0;
end // else: !if(len < 3)
end
endtask // send_packet
task reset_quantum_atomic;
input [15:0] quant;
begin
quantum <= quant;
clear <= 1;
@(posedge clk);
clear <= 0;
@(posedge clk);
end
endtask // reset_quantum_atomic
initial begin
#100 reset = 0;
#200000;
$finish;
end
reg [63:0] i_tdata;
reg i_tlast;
reg i_tvalid;
wire i_tready;
wire [63:0] o_tdata;
wire o_tlast, o_tvalid, o_tready;
wire error;
initial begin
quantum <= 256;
i_tvalid <= 0;
while(reset) @(posedge clk);
$write ("Running test case: First packet after reset");
send_packet(64'h00000001_00000000, 128);
while(o_tvalid) @(posedge clk);
check_result(256,16,64'hFFFFFFFF_FFFFFFFF,0);
reset_quantum_atomic(8);
$write ("Running test case: sizeof(packet) < quantum");
send_packet(64'h00000001_00000000, 40);
while(o_tvalid) @(posedge clk);
check_result(8,5,64'hFFFFFFFF_FFFFFFFF,0);
reset_quantum_atomic(5);
$write ("Running test case: sizeof(packet) == quantum");
send_packet(64'h00000001_00000000, 40);
while(o_tvalid) @(posedge clk);
check_result(5,5,64'h00000030_00000008,0);
$write ("Running test case: sizeof(packet) == quantum - 64bits");
send_packet(64'h00000001_00000000, 32);
while(o_tvalid) @(posedge clk);
check_result(5,4,64'hFFFFFFFF_FFFFFFFF,0);
$write ("Running test case: sizeof(packet) == quantum + 64bits");
send_packet(64'h00000001_00000000, 48);
while(o_tvalid) @(posedge clk);
check_result(32'hxxxxxxxx,32'hxxxxxxxx,64'hxxxxxxxx_xxxxxxxx,1);
$write ("Running test case: Error reset");
reset_quantum_atomic(8);
check_result(32'hxxxxxxxx,32'hxxxxxxxx,64'hxxxxxxxx_xxxxxxxx,0);
$write ("Running test case: sizeof(packet) > quantum");
send_packet(64'h00000001_00000000, 80);
while(o_tvalid) @(posedge clk);
check_result(32'hxxxxxxxx,32'hxxxxxxxx,64'hxxxxxxxx_xxxxxxxx,1);
reset_quantum_atomic(8);
$write ("Running test case: sizeof(packet) == 2");
send_packet(64'h00000001_00000000, 8);
while(o_tvalid) @(posedge clk);
check_result(8,1,64'hFFFFFFFF_FFFFFFFF,0);
$write ("Running test case: Multiple packets back-to-back");
send_packet(64'h00000001_00000000, 40);
while(o_tvalid) @(posedge clk);
send_packet(64'h00000001_00000000, 16);
while(o_tvalid) @(posedge clk);
send_packet(64'h00000001_00000000, 64);
while(o_tvalid) @(posedge clk);
check_result(24,15,64'h0000004e0000000e,0);
end // initial begin
cvita_chunker dut (
.clk(clk), .reset(reset), .clear(clear), .frame_size(quantum),
.i_tdata(i_tdata), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
.o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready),
.error(error));
assign o_tready = 1;
always @(posedge clk) begin
if (o_tvalid & o_tready) begin
o_xfer_count <= o_xfer_count + 1;
o_last_tdata <= o_tdata;
end
if (i_tvalid & i_tready) i_xfer_count <= i_xfer_count + 1;
end
endmodule // cvita_chunker_tb