Pushing the bulk of UHD-3.7.0 code.
Original-commit: ff1546f8137f7f92bb250f685561b0c34cc0e053
This commit is contained in:
@@ -0,0 +1,297 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// USRP3 Task Libaray
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
`define SID(a,b,c,d) ((a & 'hff) << 24) | ((b & 'hff) << 16)| ((c & 'hff) << 8) | (d & 'hff)
|
||||
|
||||
`ifndef TB_FILE_IN_NUMBER
|
||||
`define TB_FILE_IN_NUMBER 0
|
||||
`endif
|
||||
`ifndef TB_FILE_OUT_NUMBER
|
||||
`define TB_FILE_OUT_NUMBER 0
|
||||
`endif
|
||||
`ifndef TB_FILE_GOLDEN_NUMBER
|
||||
`define TB_FILE_GOLDEN_NUMBER 0
|
||||
`endif
|
||||
`ifndef TB_FILE_IN_NAME
|
||||
`define TB_FILE_IN_NAME "tb_file_in"
|
||||
`endif
|
||||
`ifndef TB_FILE_OUT_NAME
|
||||
`define TB_FILE_OUT_NAME "tb_file_out"
|
||||
`endif
|
||||
`ifndef TB_FILE_GOLDEN_NAME
|
||||
`define TB_FILE_GOLDEN_NAME "tb_file_golden"
|
||||
`endif
|
||||
|
||||
integer tb_file_in_desc[`TB_FILE_IN_NUMBER-1:0];
|
||||
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
reg clk;
|
||||
reg reset;
|
||||
reg clear;
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
reg set_stb;
|
||||
reg [7:0] set_addr;
|
||||
reg [31:0] set_data;
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
|
||||
`ifndef CHDR_IN_NUMBER
|
||||
`define CHDR_IN_NUMBER 1
|
||||
`endif
|
||||
|
||||
|
||||
reg [63:0] data_in[`CHDR_IN_NUMBER-1:0];
|
||||
reg last_in[`CHDR_IN_NUMBER-1:0];
|
||||
reg valid_in[`CHDR_IN_NUMBER-1:0];
|
||||
wire ready_in[`CHDR_IN_NUMBER-1:0];
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// open_files
|
||||
//
|
||||
// The "open_files" task opens all standard stimulus, response, and
|
||||
// golden response files to drive other tasks in the library.
|
||||
// Both the numbers of files and there names can be altered by pre-defining
|
||||
// the TB_FILE* pre-processor definitions. All files are assumed to be
|
||||
// readmemh style format and will use a ".hex" file extension.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
task open_files;
|
||||
reg [7:0] x;
|
||||
reg [7:0] y;
|
||||
reg [8*32:0] filename;
|
||||
|
||||
begin
|
||||
x = 0;
|
||||
// Caveman verilog string handling to dynamicly form file name
|
||||
while (x != `TB_FILE_IN_NUMBER) begin
|
||||
y = x;
|
||||
filename = {`TB_FILE_IN_NAME,("0" + (y % 10))};
|
||||
while (y/10 >0) begin
|
||||
filename = {(filename << 8),("0" + (y % 10))};
|
||||
y = y/10;
|
||||
end
|
||||
// Always use .hex as file extention for readmemh style data
|
||||
filename = {filename,".hex"};
|
||||
tb_file_in_desc[x] = $fopen(filename);
|
||||
x = x + 1;
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// close_files
|
||||
//
|
||||
// The "close_files" task closes all files opened by a previous
|
||||
// call to "open_files".
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
task close_files;
|
||||
reg [7:0] x;
|
||||
|
||||
begin
|
||||
x = 0;
|
||||
while (x != `TB_FILE_IN_NUMBER) begin
|
||||
$fclose(tb_file_in_desc[x]);
|
||||
x = x + 1;
|
||||
end
|
||||
end
|
||||
endtask // close_files
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// write_settings_bus
|
||||
//
|
||||
// The "write settings_bus" task performs a single settings bus
|
||||
// transaction in 3 clock cycles, the first and 3rd cycles being
|
||||
// idle cycles. "write_settings_bus" is not re-entrant and should
|
||||
// only be used sequentially in a single test bench thread.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
task write_setting_bus;
|
||||
input [15:0] address;
|
||||
input [31:0] data;
|
||||
|
||||
begin
|
||||
|
||||
@(posedge clk);
|
||||
set_stb <= 1'b0;
|
||||
set_addr <= 16'h0;
|
||||
set_data <= 32'h0;
|
||||
@(posedge clk);
|
||||
set_stb <= 1'b1;
|
||||
set_addr <= address;
|
||||
set_data <= data;
|
||||
@(posedge clk);
|
||||
set_stb <= 1'b0;
|
||||
set_addr <= 16'h0;
|
||||
set_data <= 32'h0;
|
||||
|
||||
end
|
||||
endtask // write_setting_bus
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Place 64bits of data on CHDR databus, set last if indicated.
|
||||
// Wait unitl ready asserted before returning with valid de-assrted.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
task automatic enqueue_line;
|
||||
input [7:0] input_port;
|
||||
input last;
|
||||
input [63:0] data;
|
||||
begin
|
||||
data_in[input_port] <= data;
|
||||
last_in[input_port] <= last;
|
||||
valid_in[input_port] <= 1;
|
||||
@(posedge clk);
|
||||
while (~ready_in[input_port]) begin
|
||||
@(posedge clk);
|
||||
end
|
||||
data_in[input_port] <= 0;
|
||||
last_in[input_port] <= 0;
|
||||
valid_in[input_port] <= 0;
|
||||
end
|
||||
endtask // enqueue_line
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Place 64bits of data on CHDR databus, set last if indicated.
|
||||
// Wait unitl ready asserted before returning with valid de-assrted.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
task automatic dequeue_line;
|
||||
input [7:0] output_port;
|
||||
output last;
|
||||
output [63:0] data;
|
||||
begin
|
||||
while (~valid_out[output_port]) begin
|
||||
ready_out[output_port] <= 1;
|
||||
@(posedge clk);
|
||||
end
|
||||
|
||||
// NOTE: A subtle constraint of Verilog is that non-blocking assignments can not be used
|
||||
// to an automatically allocated variable. Fall back to blocking assignent
|
||||
data = data_out[output_port];
|
||||
last = last_out[output_port];
|
||||
ready_out[output_port] <= 1;
|
||||
@(posedge clk);
|
||||
ready_out[output_port] <= 0;
|
||||
|
||||
end
|
||||
endtask // enqueue_line
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHDR Header format:
|
||||
// Word1: FLAGS [63:60], SEQ_ID [59:48], SIZE [47:32], SID [31:0]
|
||||
// [63]ExtensionContext, [62]HasTrailer, [61]HasTime, [60]EOB
|
||||
// Word2: Time [63:0] (Optional, see header bit [61])
|
||||
// Word3+: Payload
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
task automatic enqueue_chdr_pkt_count;
|
||||
input [7:0] input_port; // Which test bench CHDR ingress port
|
||||
input [11:0] seq_id; // CHDR sequence ID.
|
||||
input [15:0] chdr_size; // Total CHDR packet size in bytes.
|
||||
input has_time; // This CHDR packet has 64bit time field.
|
||||
input [63:0] chdr_time; // 64bit CHDR time value
|
||||
input is_extension; // This packet is flaged extension context
|
||||
input is_eob; // This packet is the end of a CHDR burst.
|
||||
input [31:0] chdr_sid; // CHDR SID address pair.
|
||||
|
||||
integer i;
|
||||
reg [15:0] j;
|
||||
|
||||
begin
|
||||
@(posedge clk);
|
||||
enqueue_line(input_port, 0, {is_extension,1'b0,has_time,is_eob,seq_id,chdr_size,chdr_sid});
|
||||
if (has_time) // If time flag set add 64bit time as second word.
|
||||
enqueue_line(input_port, 0, chdr_time);
|
||||
j = 0;
|
||||
|
||||
for (i = (has_time ? 24 : 16); i < chdr_size; i = i + 8) begin
|
||||
enqueue_line(input_port, 0 , {j,j+16'h1,j+16'h2,j+16'h3});
|
||||
j = j + 4;
|
||||
end
|
||||
// Populate last line with data even if sizes shows it's not used.
|
||||
enqueue_line(input_port, 1, {j,j+16'h1,j+16'h2,j+16'h3});
|
||||
|
||||
end
|
||||
endtask // automatic
|
||||
|
||||
|
||||
task automatic dequeue_chdr_pkt_count;
|
||||
input [7:0] output_port; // Which test bench CHDR ingress port
|
||||
input [11:0] seq_id; // CHDR sequence ID.
|
||||
input [15:0] chdr_size; // Total CHDR packet size in bytes.
|
||||
input has_time; // This CHDR packet has 64bit time field.
|
||||
input [63:0] chdr_time; // 64bit CHDR time value
|
||||
input is_extension; // This packet is flaged extension context
|
||||
input is_eob; // This packet is the end of a CHDR burst.
|
||||
input [31:0] chdr_sid; // CHDR SID address pair.
|
||||
|
||||
integer i;
|
||||
reg [15:0] j;
|
||||
|
||||
reg last;
|
||||
reg [63:0] data;
|
||||
|
||||
begin
|
||||
@(posedge clk);
|
||||
dequeue_line(output_port, last, data);
|
||||
if ({is_extension,1'b0,has_time,is_eob,seq_id,chdr_size,chdr_sid} !== data)
|
||||
$display("FAILED: Output port: %3d Bad CHDR Header. Got %8x, expected %8x @ time: %d ",
|
||||
output_port, data, {is_extension,1'b0,has_time,is_eob,seq_id,chdr_size,chdr_sid},$time);
|
||||
// else
|
||||
// $display("PASSED: Output port: %3d Bad CHDR Header. Got %8x, expected %8x @ time: %d ",
|
||||
// output_port, data, {is_extension,1'b0,has_time,is_eob,seq_id,chdr_size,chdr_sid},$time);
|
||||
if (has_time) // If time flag set add 64bit time as second word.
|
||||
begin
|
||||
dequeue_line(output_port, last, data);
|
||||
if (data !== chdr_time)
|
||||
$display("FAILED: Output port: %3d Bad CHDR Time. Got %8x, expected %8x @ time: %d ",
|
||||
output_port, data, chdr_time, $time);
|
||||
// else
|
||||
// $display("PASSED: Output port: %3d Bad CHDR Time. Got %8x, expected %8x @ time: %d ",
|
||||
// output_port, data, chdr_time, $time);
|
||||
end
|
||||
j = 0;
|
||||
|
||||
for (i = (has_time ? 24 : 16); i < chdr_size; i = i + 8) begin
|
||||
dequeue_line(output_port, last , data);
|
||||
if ({j,j+16'h1,j+16'h2,j+16'h3} !== data)
|
||||
$display("FAILED: Output port: %3d Bad CHDR Payload. Got %8x, expected %8x @ time: %d ",
|
||||
output_port, data,{j,j+16'h1,j+16'h2,j+16'h3} ,$time);
|
||||
// else
|
||||
// $display("PASSED: Output port: %3d Bad CHDR Payload. Got %8x, expected %8x @ time: %d ",
|
||||
// output_port, data, {is_extension,1'b0,has_time,is_eob,seq_id,chdr_size,chdr_sid},$time);
|
||||
j = j + 4;
|
||||
end
|
||||
// Check only bytes included in packet
|
||||
dequeue_line(output_port, last, data);
|
||||
if (({j,j+16'h1,j+16'h2,j+16'h3} >> (8-j)) !== ( data>> (8-j)))
|
||||
$display("FAILED: Output port: %3d Bad CHDR Payload. Got %8x, expected %8x @ time: %d ",
|
||||
output_port, data >> (8-j),
|
||||
{j,j+16'h1,j+16'h2,j+16'h3} >> (8-j),$time);
|
||||
// else
|
||||
// $display("PASSED: Output port: %3d Bad CHDR Payload. Got %8x, expected %8x @ time: %d ",
|
||||
// output_port, data >> (8-j),
|
||||
// {is_extension,1'b0,has_time,is_eob,seq_id,chdr_size,chdr_sid} >> (8-j),$time);
|
||||
|
||||
end
|
||||
|
||||
endtask // dequeue_packet
|
||||
|
||||
Reference in New Issue
Block a user