diff options
author | Andrew Moch <Andrew.Moch@ni.com> | 2020-06-09 20:35:31 +0100 |
---|---|---|
committer | Wade Fife <wade.fife@ettus.com> | 2020-06-18 09:09:34 -0500 |
commit | 3af8dcaacfa4bf36dcae3bdbf0b353385b7063c6 (patch) | |
tree | cac4cae52b2b096570bd69229b43c9259d44ca7e /fpga/usrp3/lib | |
parent | 19f19c77a91dcba6c1bf0f99e73ae9ffca1d75a4 (diff) | |
download | uhd-3af8dcaacfa4bf36dcae3bdbf0b353385b7063c6.tar.gz uhd-3af8dcaacfa4bf36dcae3bdbf0b353385b7063c6.tar.bz2 uhd-3af8dcaacfa4bf36dcae3bdbf0b353385b7063c6.zip |
fpga: rfnoc: Add support for 512-bit CHDR widths
This fixes the rfnoc_null_src_sink, chdr_crossbar_nxn, and
chdr_stream_endpoint blocks so that wider CHDR widths are properly
supported. It also updates PkgChdrBfm to able to properly test these
blocks. The testbenches have been updated to test both 64 and 512-bit
widths.
Diffstat (limited to 'fpga/usrp3/lib')
16 files changed, 358 insertions, 220 deletions
diff --git a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/Makefile b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/Makefile index 30ce14aec..4d2e33633 100644 --- a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/Makefile +++ b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/Makefile @@ -29,10 +29,11 @@ $(RFNOC_OOT_SRCS) \ #------------------------------------------------- # Testbench Specific #------------------------------------------------- -SIM_TOP = rfnoc_block_null_src_sink_tb +SIM_TOP = rfnoc_block_null_src_sink_all_tb SIM_SRCS = \ $(abspath rfnoc_block_null_src_sink_tb.sv) \ +$(abspath rfnoc_block_null_src_sink_all_tb.sv) \ # MODELSIM_USER_DO = $(abspath wave.do) diff --git a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/noc_shell_null_src_sink.v b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/noc_shell_null_src_sink.v index cef213920..3676ffbd3 100644 --- a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/noc_shell_null_src_sink.v +++ b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/noc_shell_null_src_sink.v @@ -23,6 +23,8 @@ module noc_shell_null_src_sink #( parameter [9:0] THIS_PORTID = 10'd0, parameter CHDR_W = 64, + parameter ITEM_W = 32, + parameter NIPC = 2, parameter [5:0] MTU = 10 ) ( //--------------------- @@ -82,8 +84,8 @@ module noc_shell_null_src_sink #( output wire axis_data_clk, output wire axis_data_rst, // Payload Stream to User Logic: sink - output wire [32*2-1:0] m_sink_payload_tdata, - output wire [2-1:0] m_sink_payload_tkeep, + output wire [ITEM_W*NIPC-1:0] m_sink_payload_tdata, + output wire [NIPC-1:0] m_sink_payload_tkeep, output wire m_sink_payload_tlast, output wire m_sink_payload_tvalid, input wire m_sink_payload_tready, @@ -94,8 +96,8 @@ module noc_shell_null_src_sink #( output wire m_sink_context_tvalid, input wire m_sink_context_tready, // Payload Stream to User Logic: loop - output wire [32*2-1:0] m_loop_payload_tdata, - output wire [2-1:0] m_loop_payload_tkeep, + output wire [ITEM_W*NIPC-1:0] m_loop_payload_tdata, + output wire [NIPC-1:0] m_loop_payload_tkeep, output wire m_loop_payload_tlast, output wire m_loop_payload_tvalid, input wire m_loop_payload_tready, @@ -106,8 +108,8 @@ module noc_shell_null_src_sink #( output wire m_loop_context_tvalid, input wire m_loop_context_tready, // Payload Stream from User Logic: source - input wire [32*2-1:0] s_source_payload_tdata, - input wire [1:0] s_source_payload_tkeep, + input wire [ITEM_W*NIPC-1:0] s_source_payload_tdata, + input wire [NIPC-1:0] s_source_payload_tkeep, input wire s_source_payload_tlast, input wire s_source_payload_tvalid, output wire s_source_payload_tready, @@ -118,8 +120,8 @@ module noc_shell_null_src_sink #( input wire s_source_context_tvalid, output wire s_source_context_tready, // Payload Stream from User Logic: loop - input wire [32*2-1:0] s_loop_payload_tdata, - input wire [1:0] s_loop_payload_tkeep, + input wire [ITEM_W*NIPC-1:0] s_loop_payload_tdata, + input wire [NIPC-1:0] s_loop_payload_tkeep, input wire s_loop_payload_tlast, input wire s_loop_payload_tvalid, output wire s_loop_payload_tready, @@ -233,8 +235,8 @@ module noc_shell_null_src_sink #( chdr_to_axis_pyld_ctxt #( .CHDR_W (CHDR_W), - .ITEM_W (32), - .NIPC (2), + .ITEM_W (ITEM_W), + .NIPC (NIPC), .SYNC_CLKS (1), .CONTEXT_FIFO_SIZE ($clog2(2)), .PAYLOAD_FIFO_SIZE ($clog2(2)), @@ -266,8 +268,8 @@ module noc_shell_null_src_sink #( chdr_to_axis_pyld_ctxt #( .CHDR_W (CHDR_W), - .ITEM_W (32), - .NIPC (2), + .ITEM_W (ITEM_W), + .NIPC (NIPC), .SYNC_CLKS (1), .CONTEXT_FIFO_SIZE ($clog2(2)), .PAYLOAD_FIFO_SIZE ($clog2(2)), @@ -303,8 +305,8 @@ module noc_shell_null_src_sink #( axis_pyld_ctxt_to_chdr #( .CHDR_W (CHDR_W), - .ITEM_W (32), - .NIPC (2), + .ITEM_W (ITEM_W), + .NIPC (NIPC), .SYNC_CLKS (1), .CONTEXT_FIFO_SIZE ($clog2(2)), .PAYLOAD_FIFO_SIZE ($clog2(2)), @@ -338,8 +340,8 @@ module noc_shell_null_src_sink #( axis_pyld_ctxt_to_chdr #( .CHDR_W (CHDR_W), - .ITEM_W (32), - .NIPC (2), + .ITEM_W (ITEM_W), + .NIPC (NIPC), .SYNC_CLKS (1), .CONTEXT_FIFO_SIZE ($clog2(2)), .PAYLOAD_FIFO_SIZE ($clog2(2)), diff --git a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/rfnoc_block_null_src_sink.v b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/rfnoc_block_null_src_sink.v index 53c764627..9e1cdb117 100644 --- a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/rfnoc_block_null_src_sink.v +++ b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/rfnoc_block_null_src_sink.v @@ -4,30 +4,46 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // // Module: rfnoc_block_null_src_sink +// // Description: // +// This block can source, sink, or loopback data. Each port is used for a +// specific purpose. The RFNoC CHDR ports are mapped is as follows: +// +// Input Port 0 : Sink +// Input Port 1 : Loopback in +// Output Port 0 : Source +// Output Port 1 : Loopback out +// // Parameters: +// THIS_PORTID : Control crossbar port to which this block is connected +// CHDR_W : AXIS-CHDR data bus width +// MTU : Maximum transmission unit (i.e., maximum packet size in +// CHDR words is 2**MTU). +// ITEM_W : Item width +// NIPC : Items per Clock // // Signals: module rfnoc_block_null_src_sink #( parameter [9:0] THIS_PORTID = 10'd0, parameter CHDR_W = 64, - parameter NIPC = 2, - parameter [5:0] MTU = 10 + parameter [5:0] MTU = 10, + parameter ITEM_W = 32, + parameter NIPC = CHDR_W/ITEM_W )( // RFNoC Framework Clocks and Resets input wire rfnoc_chdr_clk, input wire rfnoc_ctrl_clk, - // RFNoC Backend Interface + // RFNoC Backend Interface input wire [511:0] rfnoc_core_config, output wire [511:0] rfnoc_core_status, - // 2 CHDR Input Ports (from framework) + // 2 CHDR Input Ports (from framework) input wire [(CHDR_W*2)-1:0] s_rfnoc_chdr_tdata, input wire [1:0] s_rfnoc_chdr_tlast, input wire [1:0] s_rfnoc_chdr_tvalid, output wire [1:0] s_rfnoc_chdr_tready, - // 2 CHDR Output Ports (to framework) + // 2 CHDR Output Ports (to framework) output wire [(CHDR_W*2)-1:0] m_rfnoc_chdr_tdata, output wire [1:0] m_rfnoc_chdr_tlast, output wire [1:0] m_rfnoc_chdr_tvalid, @@ -72,22 +88,24 @@ module rfnoc_block_null_src_sink #( reg ctrlport_resp_ack; reg [31:0] ctrlport_resp_data; - wire [(32*NIPC)-1:0] src_pyld_tdata , loop_pyld_tdata ; - wire [NIPC-1:0] src_pyld_tkeep , loop_pyld_tkeep ; - wire src_pyld_tlast , snk_pyld_tlast , loop_pyld_tlast ; - wire src_pyld_tvalid, snk_pyld_tvalid, loop_pyld_tvalid; - wire src_pyld_tready, snk_pyld_tready, loop_pyld_tready; + wire [(ITEM_W*NIPC)-1:0] src_pyld_tdata , loop_pyld_tdata ; + wire [NIPC-1:0] src_pyld_tkeep , loop_pyld_tkeep ; + wire src_pyld_tlast , snk_pyld_tlast , loop_pyld_tlast ; + wire src_pyld_tvalid, snk_pyld_tvalid, loop_pyld_tvalid; + wire src_pyld_tready, snk_pyld_tready, loop_pyld_tready; - wire [CHDR_W-1:0] src_ctxt_tdata , loop_ctxt_tdata ; - wire [3:0] src_ctxt_tuser , loop_ctxt_tuser ; - wire src_ctxt_tlast , loop_ctxt_tlast ; - wire src_ctxt_tvalid, loop_ctxt_tvalid; - wire src_ctxt_tready, snk_ctxt_tready, loop_ctxt_tready; + wire [CHDR_W-1:0] src_ctxt_tdata , loop_ctxt_tdata ; + wire [3:0] src_ctxt_tuser , loop_ctxt_tuser ; + wire src_ctxt_tlast , loop_ctxt_tlast ; + wire src_ctxt_tvalid, loop_ctxt_tvalid; + wire src_ctxt_tready, snk_ctxt_tready, loop_ctxt_tready; // NoC Shell // --------------------------- noc_shell_null_src_sink #( .THIS_PORTID (THIS_PORTID), + .NIPC (NIPC), + .ITEM_W (ITEM_W), .CHDR_W (CHDR_W), .MTU (MTU) ) noc_shell_null_src_sink_i ( @@ -257,18 +275,17 @@ module rfnoc_block_null_src_sink #( end end - assign src_pyld_tdata = {NIPC{{~src_line_cnt[15:0], src_line_cnt[15:0]}}}; + assign src_pyld_tdata = {NIPC{{~src_line_cnt[ITEM_W/2-1:0], src_line_cnt[ITEM_W/2-1:0]}}}; assign src_pyld_tkeep = {NIPC{1'b1}}; assign src_pyld_tlast = (lines_left == 12'd0); assign src_pyld_tvalid = (state == ST_PYLD); assign src_ctxt_tdata = chdr_build_header( 6'd0, 1'b0, 1'b0, CHDR_PKT_TYPE_DATA, CHDR_NO_MDATA, src_pkt_cnt[15:0], reg_src_bpp, 16'd0); - assign src_ctxt_tuser = CONTEXT_FIELD_HDR; + assign src_ctxt_tuser = CHDR_W > 64 ? CONTEXT_FIELD_HDR_TS : CONTEXT_FIELD_HDR; assign src_ctxt_tlast = 1'b1; assign src_ctxt_tvalid = (state == ST_HDR && reg_src_en); - // Register Interface // --------------------------- always @(posedge rfnoc_chdr_clk) begin @@ -294,7 +311,7 @@ module rfnoc_block_null_src_sink #( if (ctrlport_req_rd) begin case(ctrlport_req_addr) REG_CTRL_STATUS: - ctrlport_resp_data <= {NIPC[7:0], 8'd32, state, 12'h0, reg_src_en, reg_clear_cnts}; + ctrlport_resp_data <= {NIPC[7:0],ITEM_W[7:0], state, 12'h0, reg_src_en, reg_clear_cnts}; REG_SRC_LINES_PER_PKT: ctrlport_resp_data <= {20'h0, reg_src_lpp}; REG_SRC_BYTES_PER_PKT: diff --git a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/rfnoc_block_null_src_sink_all_tb.sv b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/rfnoc_block_null_src_sink_all_tb.sv new file mode 100644 index 000000000..ed5745a44 --- /dev/null +++ b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/rfnoc_block_null_src_sink_all_tb.sv @@ -0,0 +1,26 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// Module: chdr_stream_endpoint_all_tb +// +// Description: Testbench for chdr_stream_endpoint that runs multiple widths +// + +module rfnoc_block_null_src_sink_all_tb#( + /* no PARAM */ +)( + /* no IO */ +); + + rfnoc_block_null_src_sink_tb #(.TEST_NAME("64B"),.CHDR_W(64)) CHDR64 (); + rfnoc_block_null_src_sink_tb #(.TEST_NAME("512B"),.CHDR_W(512)) CHDR512 (); + + // Wait for all done + bit clk,rst; + sim_clock_gen #(100.0) clk_gen (clk, rst); + always_ff@(posedge clk) + if (CHDR64.test.done && CHDR512.test.done) $finish(1); + +endmodule diff --git a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/rfnoc_block_null_src_sink_tb.sv b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/rfnoc_block_null_src_sink_tb.sv index 192a8143b..2ef2e31ea 100644 --- a/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/rfnoc_block_null_src_sink_tb.sv +++ b/fpga/usrp3/lib/rfnoc/blocks/rfnoc_block_null_src_sink/rfnoc_block_null_src_sink_tb.sv @@ -1,5 +1,5 @@ // -// Copyright 2019 Ettus Research, A National Instruments Company +// Copyright 2020 Ettus Research, A National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // @@ -9,9 +9,15 @@ `default_nettype none -module rfnoc_block_null_src_sink_tb; +module rfnoc_block_null_src_sink_tb #( + parameter TEST_NAME = "rfnoc_block_null_src_sink_tb", + parameter CHDR_W = 64 +)( + /* no IO */ +); // Include macros and time declarations for use with PkgTestExec + `define TEST_EXEC_OBJ test `include "test_exec.svh" import PkgTestExec::*; @@ -23,10 +29,10 @@ module rfnoc_block_null_src_sink_tb; localparam NOC_ID = 32'h0000_0001; localparam [9:0] THIS_PORTID = 10'h17; localparam [15:0] THIS_EPID = 16'hDEAD; - localparam int CHDR_W = 64; - localparam int ITEM_W = 32; + localparam int ITEM_W = 32; + localparam int NIPC = CHDR_W/ITEM_W; // Expected Data generation only works for full words localparam int SPP = 201; - localparam int LPP = ((SPP+1)/2); + localparam int LPP = SPP % NIPC == 0 ? SPP/NIPC : SPP/NIPC+1; localparam int NUM_PKTS = 50; localparam int PORT_SRCSNK = 0; @@ -49,6 +55,8 @@ module rfnoc_block_null_src_sink_tb; AxiStreamIf #(CHDR_W) s0_chdr (rfnoc_chdr_clk); // Optional data iface AxiStreamIf #(CHDR_W) s1_chdr (rfnoc_chdr_clk); // Optional data iface + TestExec test = new(); + typedef ChdrData #(CHDR_W, ITEM_W)::chdr_word_t chdr_word_t; // Bus functional model for a software block controller @@ -58,29 +66,30 @@ module rfnoc_block_null_src_sink_tb; rfnoc_block_null_src_sink #( .THIS_PORTID (THIS_PORTID), .CHDR_W (CHDR_W), - .NIPC (2), + .ITEM_W (ITEM_W), + .NIPC (NIPC), .MTU (10) ) dut ( .rfnoc_chdr_clk (backend.chdr_clk), .rfnoc_ctrl_clk (backend.ctrl_clk), - .rfnoc_core_config (backend.slave.cfg), - .rfnoc_core_status (backend.slave.sts), - .s_rfnoc_chdr_tdata ({m1_chdr.slave.tdata , m0_chdr.slave.tdata }), - .s_rfnoc_chdr_tlast ({m1_chdr.slave.tlast , m0_chdr.slave.tlast }), - .s_rfnoc_chdr_tvalid({m1_chdr.slave.tvalid , m0_chdr.slave.tvalid }), - .s_rfnoc_chdr_tready({m1_chdr.slave.tready , m0_chdr.slave.tready }), - .m_rfnoc_chdr_tdata ({s1_chdr.master.tdata , s0_chdr.master.tdata }), - .m_rfnoc_chdr_tlast ({s1_chdr.master.tlast , s0_chdr.master.tlast }), - .m_rfnoc_chdr_tvalid({s1_chdr.master.tvalid, s0_chdr.master.tvalid}), - .m_rfnoc_chdr_tready({s1_chdr.master.tready, s0_chdr.master.tready}), - .s_rfnoc_ctrl_tdata (m_ctrl.slave.tdata ), - .s_rfnoc_ctrl_tlast (m_ctrl.slave.tlast ), - .s_rfnoc_ctrl_tvalid(m_ctrl.slave.tvalid ), - .s_rfnoc_ctrl_tready(m_ctrl.slave.tready ), - .m_rfnoc_ctrl_tdata (s_ctrl.master.tdata ), - .m_rfnoc_ctrl_tlast (s_ctrl.master.tlast ), - .m_rfnoc_ctrl_tvalid(s_ctrl.master.tvalid), - .m_rfnoc_ctrl_tready(s_ctrl.master.tready) + .rfnoc_core_config (backend.cfg), + .rfnoc_core_status (backend.sts), + .s_rfnoc_chdr_tdata ({m1_chdr.tdata , m0_chdr.tdata }), + .s_rfnoc_chdr_tlast ({m1_chdr.tlast , m0_chdr.tlast }), + .s_rfnoc_chdr_tvalid({m1_chdr.tvalid , m0_chdr.tvalid }), + .s_rfnoc_chdr_tready({m1_chdr.tready , m0_chdr.tready }), + .m_rfnoc_chdr_tdata ({s1_chdr.tdata , s0_chdr.tdata }), + .m_rfnoc_chdr_tlast ({s1_chdr.tlast , s0_chdr.tlast }), + .m_rfnoc_chdr_tvalid({s1_chdr.tvalid, s0_chdr.tvalid}), + .m_rfnoc_chdr_tready({s1_chdr.tready, s0_chdr.tready}), + .s_rfnoc_ctrl_tdata (m_ctrl.tdata ), + .s_rfnoc_ctrl_tlast (m_ctrl.tlast ), + .s_rfnoc_ctrl_tvalid(m_ctrl.tvalid ), + .s_rfnoc_ctrl_tready(m_ctrl.tready ), + .m_rfnoc_ctrl_tdata (s_ctrl.tdata ), + .m_rfnoc_ctrl_tlast (s_ctrl.tlast ), + .m_rfnoc_ctrl_tvalid(s_ctrl.tvalid), + .m_rfnoc_ctrl_tready(s_ctrl.tready) ); // ---------------------------------------- @@ -95,7 +104,7 @@ module rfnoc_block_null_src_sink_tb; // Initialize // ---------------------------------------- - test.start_tb("rfnoc_block_null_src_sink_tb"); + test.start_tb({TEST_NAME,"rfnoc_block_null_src_sink_tb"}); // Start the stream endpoint BFM blk_ctrl = new(backend, m_ctrl, s_ctrl); @@ -107,7 +116,7 @@ module rfnoc_block_null_src_sink_tb; // Startup block (Software initialization) // ---------------------------------------- - test.start_test("Flush block then reset it"); + test.start_test({TEST_NAME,"Flush block then reset it"}); begin test.start_timeout(timeout, 10us, "Waiting for flush_and_reset"); #100; //Wait for GSR to deassert @@ -118,7 +127,7 @@ module rfnoc_block_null_src_sink_tb; // Run Tests // ---------------------------------------- - test.start_test("Read Block Info"); + test.start_test({TEST_NAME,"Read Block Info"}); begin test.start_timeout(timeout, 1us, "Waiting for block info response"); // Get static block info and validate it @@ -130,19 +139,20 @@ module rfnoc_block_null_src_sink_tb; // Read status register and validate it blk_ctrl.reg_read(dut.REG_CTRL_STATUS, rvalue); - `ASSERT_ERROR(rvalue[31:24] == 2, "Incorrect NIPC Value"); + `ASSERT_ERROR(rvalue[31:24] == NIPC, "Incorrect NIPC Value"); `ASSERT_ERROR(rvalue[23:16] == ITEM_W, "Incorrect ITEM_W Value"); test.end_timeout(timeout); end test.end_test(); - test.start_test("Stream Data Through Loopback Port"); + test.start_test({TEST_NAME,"Stream Data Through Loopback Port m1->s1"}); begin // Send and receive packets repeat (NUM_PKTS) begin chdr_word_t rx_data[$]; int rx_bytes; - automatic ItemDataBuff #(logic[ITEM_W-1:0]) tx_dbuff = new, rx_dbuff = new; + automatic ItemDataBuff #(logic[ITEM_W-1:0],CHDR_W) tx_dbuff = new; + automatic ItemDataBuff #(logic[ITEM_W-1:0],CHDR_W) rx_dbuff = new; for (int i = 0; i < SPP; i++) tx_dbuff.put($urandom()); test.start_timeout(timeout, 5us, "Waiting for pkt to loop back"); @@ -173,16 +183,16 @@ module rfnoc_block_null_src_sink_tb; end test.end_test(); - test.start_test("Stream Data To Sink Port"); + test.start_test({TEST_NAME,"Stream Data To Sink Port m0"}); begin // Send packets repeat (NUM_PKTS) begin chdr_word_t rx_data[$]; int rx_bytes; - automatic ItemDataBuff #(logic[ITEM_W-1:0]) tx_dbuff = new; + automatic ItemDataBuff #(logic[ITEM_W-1:0],CHDR_W) tx_dbuff = new; for (int i = 0; i < SPP; i++) tx_dbuff.put($urandom()); - test.start_timeout(timeout, 5us, "Waiting for pkt to loop back"); + test.start_timeout(timeout, 5us, "Waiting to send packet"); blk_ctrl.send(PORT_SRCSNK, tx_dbuff.to_chdr_payload(), tx_dbuff.get_bytes()); test.end_timeout(timeout); end @@ -208,11 +218,12 @@ module rfnoc_block_null_src_sink_tb; end test.end_test(); - test.start_test("Stream Data From Source Port"); + test.start_test({TEST_NAME,"Stream Data From Source Port s0"}); begin // Turn on the source for some time then stop it blk_ctrl.reg_write(dut.REG_SRC_LINES_PER_PKT, LPP-1); - blk_ctrl.reg_write(dut.REG_SRC_BYTES_PER_PKT, (LPP+1)*8); + // A line is generated as NIPC Items + blk_ctrl.reg_write(dut.REG_SRC_BYTES_PER_PKT, (LPP+1)*ITEM_W/8*NIPC); blk_ctrl.reg_write(dut.REG_CTRL_STATUS, 2'b10); repeat ((NUM_PKTS / 10) * LPP) @(posedge rfnoc_chdr_clk); blk_ctrl.reg_write(dut.REG_CTRL_STATUS, 2'b00); @@ -228,7 +239,7 @@ module rfnoc_block_null_src_sink_tb; test.start_timeout(timeout, 5us, "Waiting for pkt to arrive"); exp_data.delete(); for (int i = p*LPP; i < (p+1)*LPP; i++) - exp_data.push_back({~i[15:0], i[15:0], ~i[15:0], i[15:0]}); + exp_data.push_back({NIPC{{~i[ITEM_W/2-1:0], i[ITEM_W/2-1:0]}}}); blk_ctrl.recv(PORT_SRCSNK, rx_data, rx_bytes); `ASSERT_ERROR(blk_ctrl.compare_data(exp_data, rx_data), "Data mismatch"); test.end_timeout(timeout); @@ -236,7 +247,7 @@ module rfnoc_block_null_src_sink_tb; end test.end_test(); - test.start_test("Clear Counts"); + test.start_test({TEST_NAME,"Clear Counts"}); begin test.start_timeout(timeout, 1us, "Waiting for clear and readbacks"); // Clear @@ -266,7 +277,7 @@ module rfnoc_block_null_src_sink_tb; // Finish Up // ---------------------------------------- // Display final statistics and results - test.end_tb(); + test.end_tb(.finish(0)); end endmodule diff --git a/fpga/usrp3/lib/rfnoc/core/chdr_stream_output.v b/fpga/usrp3/lib/rfnoc/core/chdr_stream_output.v index 271c7fccc..c21649d44 100644 --- a/fpga/usrp3/lib/rfnoc/core/chdr_stream_output.v +++ b/fpga/usrp3/lib/rfnoc/core/chdr_stream_output.v @@ -411,7 +411,7 @@ module chdr_stream_output #( if (CHDR_W < 128) state <= ST_STRC_W1; else - state <= ST_STRC_WAIT; + state <= fc_resync_req ? ST_PASS_DATA : ST_STRC_WAIT; end // ST_STRC_W1 @@ -527,7 +527,7 @@ module chdr_stream_output #( assign msg_o_tready = msg_o_tvalid && (state == ST_PASS_DATA || state == ST_STRC_WAIT); // Acknowledge a flow control resync command - assign fc_resync_ack = fc_resync_req && (state == ST_STRC_W1) && + assign fc_resync_ack = fc_resync_req && (state == ST_STRC_W1 || state == ST_STRC_W0) && chdr_out_tvalid && chdr_out_tready && chdr_out_tlast; // --------------------------------------------------- diff --git a/fpga/usrp3/lib/rfnoc/core/chdr_to_axis_ctrl.v b/fpga/usrp3/lib/rfnoc/core/chdr_to_axis_ctrl.v index 1f9dba2eb..130915de2 100644 --- a/fpga/usrp3/lib/rfnoc/core/chdr_to_axis_ctrl.v +++ b/fpga/usrp3/lib/rfnoc/core/chdr_to_axis_ctrl.v @@ -116,7 +116,7 @@ module chdr_to_axis_ctrl #( ST_CHDR_HDR: begin ch2ct_nmdata <= chdr_get_num_mdata(ch2ct_tdata[63:0]) - 5'd1; if (!ch2ct_tlast) - ch2ct_state <= (chdr_get_num_mdata(ch2ct_tdata[63:0]) == 5'd0) ? + ch2ct_state <= (chdr_get_num_mdata(ch2ct_tdata[63:0]) == 5'd0) ? ST_CTRL_HDR : ST_CHDR_MDATA; else ch2ct_state <= ST_CHDR_HDR; // Premature termination @@ -152,7 +152,7 @@ module chdr_to_axis_ctrl #( ); // Create the first two lines of the Ctrl word (wide) - // using data from CHDR packet + // using data from CHDR packet wire [CHDR_W-1:0] ch2ct_new_ctrl_hdr; assign ch2ct_new_ctrl_hdr[63:0] = { axis_ctrl_build_hdr_hi( @@ -172,7 +172,7 @@ module chdr_to_axis_ctrl #( assign ch2ct_new_ctrl_hdr[CHDR_W-1:64] = ch2ct_tdata[CHDR_W-1:64]; end endgenerate - wire [CHDR_W-1:0] ch2ct_wctrl_tdata = + wire [CHDR_W-1:0] ch2ct_wctrl_tdata = (ch2ct_state == ST_CTRL_HDR) ? ch2ct_new_ctrl_hdr : ch2ct_tdata; axis_width_conv #( @@ -205,7 +205,7 @@ module chdr_to_axis_ctrl #( // - Use the Ctrl RemDstPort as the CHDR DstPort (forward the master's request) // - Use the this_epid as CHDR SrcEPID (return path for the CHDR packet) // - Use the Ctrl SrcPort as the CHDR SrcPort (return path to the master) - // - Ignore the Ctrl DstPort because the packet has already been routed + // - Ignore the Ctrl DstPort because the packet has already been routed wire [CHDR_W-1:0] ct2ch_wctrl_tdata; wire ct2ch_wctrl_tlast, ct2ch_wctrl_tvalid, ct2ch_wctrl_tready; @@ -238,8 +238,7 @@ module chdr_to_axis_ctrl #( end else if (ct2ch_tvalid && ct2ch_tready) begin case (ct2ch_state) ST_CHDR_HDR: begin - if (!ct2ch_tlast) - ct2ch_state <= ST_CTRL_HDR; + ct2ch_state <= ST_CTRL_HDR; end ST_CTRL_HDR: begin if (ct2ch_tlast) @@ -264,56 +263,60 @@ module chdr_to_axis_ctrl #( // Hold the first line to generate info for the outgoing CHDR header assign ct2ch_wctrl_tready = (ct2ch_state == ST_CTRL_HDR || ct2ch_state == ST_CTRL_BODY) ? ct2ch_tready : 1'b0; - wire [7:0] ct2ch_32bit_lines = 8'd3 + // Header + OpWord - (axis_ctrl_get_has_time(ct2ch_wctrl_tdata[31:0]) ? 8'd2 : 8'd0) + // Timestamp - ({4'h0, axis_ctrl_get_num_data(ct2ch_wctrl_tdata[31:0])}); // Data words + wire [7:0] ct2ch_num_data = {4'h0, axis_ctrl_get_num_data(ct2ch_wctrl_tdata[31:0])}; + wire [7:0] ct2ch_timestamp = axis_ctrl_get_has_time(ct2ch_wctrl_tdata[31:0]) ? 8'd2 : 8'd0; + wire [7:0] ct2ch_32bit_lines = CHDR_W/32 + // CHDR header + 8'd3 + // CTL Header + OpWord + ct2ch_timestamp + // Timestamp + ct2ch_num_data; // Data words - wire [15:0] ct2ch_chdr_lines = 16'd1 + // CHDR header - ct2ch_32bit_lines[7:$clog2(CHDR_W/32)] + // Convert 32-bit lines to CHDR_W - (|ct2ch_32bit_lines[$clog2(CHDR_W/32)-1:0]); // Residue + reg [CHDR_W-1:0] ct2ch_sm_tdata,ct2ch_chdr_hdr; + reg [63:0] ct2ch_ctrl_hdr; - reg [63:0] ct2ch_chdr_tdata; + always @(*) begin + ct2ch_chdr_hdr = 0; + ct2ch_chdr_hdr = chdr_build_header( + 6'd0, /* VC */ + 1'b0, 1'b0, /* eob, eov */ + CHDR_PKT_TYPE_CTRL, + CHDR_NO_MDATA, + ct2ch_seqnum, + (ct2ch_32bit_lines << $clog2(32/8)), /* length in bytes */ + axis_ctrl_get_rem_dst_epid(ct2ch_wctrl_tdata[63:32])); + ct2ch_ctrl_hdr = { + axis_ctrl_build_hdr_hi( + 10'd0, /* Unused in CHDR Control payload */ + this_epid /* This is the SrcEPID */ + ), + axis_ctrl_build_hdr_lo( + axis_ctrl_get_is_ack (ct2ch_wctrl_tdata[31:0]), + axis_ctrl_get_has_time(ct2ch_wctrl_tdata[31:0]), + axis_ctrl_get_seq_num (ct2ch_wctrl_tdata[31:0]), + axis_ctrl_get_num_data(ct2ch_wctrl_tdata[31:0]), + axis_ctrl_get_src_port(ct2ch_wctrl_tdata[31:0]), + axis_ctrl_get_rem_dst_port(ct2ch_wctrl_tdata[63:32]) + ) + }; + end always @(*) begin case (ct2ch_state) ST_CHDR_HDR: begin - ct2ch_chdr_tdata = chdr_build_header( - 6'd0, /* VC */ - 1'b0, 1'b0, /* eob, eov */ - CHDR_PKT_TYPE_CTRL, - CHDR_NO_MDATA, - ct2ch_seqnum, - (ct2ch_chdr_lines << $clog2(CHDR_W/8)), /* length in bytes */ - axis_ctrl_get_rem_dst_epid(ct2ch_wctrl_tdata[63:32]) - ); + // regardless of width CHDR is always a full word + ct2ch_sm_tdata = ct2ch_chdr_hdr; end ST_CTRL_HDR: begin - ct2ch_chdr_tdata = { - axis_ctrl_build_hdr_hi( - 10'd0, /* Unused in CHDR Control payload */ - this_epid /* This is the SrcEPID */ - ), - axis_ctrl_build_hdr_lo( - axis_ctrl_get_is_ack (ct2ch_wctrl_tdata[31:0]), - axis_ctrl_get_has_time(ct2ch_wctrl_tdata[31:0]), - axis_ctrl_get_seq_num (ct2ch_wctrl_tdata[31:0]), - axis_ctrl_get_num_data(ct2ch_wctrl_tdata[31:0]), - axis_ctrl_get_src_port(ct2ch_wctrl_tdata[31:0]), - axis_ctrl_get_rem_dst_port(ct2ch_wctrl_tdata[63:32]) - ) - }; + ct2ch_sm_tdata = ct2ch_wctrl_tdata; + ct2ch_sm_tdata[63:0] = ct2ch_ctrl_hdr; end default: begin - ct2ch_chdr_tdata = ct2ch_wctrl_tdata[63:0]; + ct2ch_sm_tdata = ct2ch_wctrl_tdata; end endcase end // Output signals - assign ct2ch_tdata[63:0] = ct2ch_chdr_tdata; - assign ct2ch_tlast = ct2ch_wctrl_tlast; + assign ct2ch_tdata = ct2ch_sm_tdata; + assign ct2ch_tlast = ct2ch_wctrl_tlast && (ct2ch_state != ST_CHDR_HDR); assign ct2ch_tvalid = ct2ch_wctrl_tvalid; - generate if (CHDR_W > 64) begin - assign ct2ch_tdata[CHDR_W-1:64] = ct2ch_wctrl_tdata[CHDR_W-1:64]; - end endgenerate endmodule // chdr_to_axis_ctrl diff --git a/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_crossbar_nxn_tb/Makefile b/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_crossbar_nxn_tb/Makefile index 399515640..cbeacc387 100644 --- a/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_crossbar_nxn_tb/Makefile +++ b/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_crossbar_nxn_tb/Makefile @@ -34,9 +34,10 @@ $(RFNOC_CORE_SRCS) \ # Testbench Specific #------------------------------------------------- # Define only one toplevel module -SIM_TOP = chdr_crossbar_nxn_tb +SIM_TOP = chdr_crossbar_nxn_all_tb SIM_SRCS = \ +$(abspath chdr_crossbar_nxn_all_tb.sv) \ $(abspath chdr_crossbar_nxn_tb.sv) \ $(abspath ../crossbar_tb.sv) \ $(abspath ../chdr_traffic_source_sim.sv) \ diff --git a/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_crossbar_nxn_tb/chdr_crossbar_nxn_all_tb.sv b/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_crossbar_nxn_tb/chdr_crossbar_nxn_all_tb.sv new file mode 100644 index 000000000..9dbaa2568 --- /dev/null +++ b/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_crossbar_nxn_tb/chdr_crossbar_nxn_all_tb.sv @@ -0,0 +1,26 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// Module: chdr_crossbar_nxn +// +// Description: Testbench for chdr_crossbar_nxn that runs multiple widths +// + +module chdr_crossbar_nxn_all_tb#( + /* no PARAM */ +)( + /* no IO */ +); + + chdr_crossbar_nxn_tb #(.TEST_NAME("64B"),.CHDR_W(64)) CHDR64 (); + chdr_crossbar_nxn_tb #(.TEST_NAME("512B"),.CHDR_W(512)) CHDR512 (); + + // Wait for all done + bit clk,rst; + sim_clock_gen #(100.0) clk_gen (clk, rst); + always_ff@(posedge clk) + if (CHDR64.impl.done && CHDR512.impl.done) $finish(1); + +endmodule diff --git a/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_crossbar_nxn_tb/chdr_crossbar_nxn_tb.sv b/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_crossbar_nxn_tb/chdr_crossbar_nxn_tb.sv index 1c5cace63..f5217c66f 100644 --- a/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_crossbar_nxn_tb/chdr_crossbar_nxn_tb.sv +++ b/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_crossbar_nxn_tb/chdr_crossbar_nxn_tb.sv @@ -6,12 +6,17 @@ `timescale 1ns/1ps -module chdr_crossbar_nxn_tb(); +module chdr_crossbar_nxn_tb#( + parameter TEST_NAME = "chdr_crossbar_nxn_tb", + parameter CHDR_W = 64 +)( + /* no IO */ +); crossbar_tb #( - .TEST_NAME ("chdr_crossbar_nxn_tb"), + .TEST_NAME (TEST_NAME ), .ROUTER_IMPL ("chdr_crossbar_nxn" ), // Router implementation .ROUTER_PORTS (10 ), // Number of ports - .ROUTER_DWIDTH (64 ), // Router datapath width + .ROUTER_DWIDTH (CHDR_W ), // Router datapath width .MTU_LOG2 (7 ), // log2 of max packet size for router .NUM_MASTERS (10 ), // Number of data generators in test .TEST_MAX_PACKETS (100 ), // How many packets to stream per test case? diff --git a/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_traffic_sink_sim.sv b/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_traffic_sink_sim.sv index a9fe3ba27..c6af03582 100644 --- a/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_traffic_sink_sim.sv +++ b/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_traffic_sink_sim.sv @@ -88,7 +88,7 @@ module chdr_traffic_sink_sim #( s_chdr.reset(); while (1) begin // A session begins on the posedge of start_stb - while (~start_stb) @(posedge clk); + while (start_stb !== 1) @(posedge clk); session = session + 1; $sformat(filename, "%s/pkts_node%05d_inj%03d_lpp%05d_traffic%c_sess%04d.csv", FILE_PATH, NODE_ID, injection_rate, lines_per_pkt, traffic_patt, session); diff --git a/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_traffic_source_sim.sv b/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_traffic_source_sim.sv index e6cb7c5d9..8f8e2665d 100644 --- a/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_traffic_source_sim.sv +++ b/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/chdr_traffic_source_sim.sv @@ -107,7 +107,7 @@ module chdr_traffic_source_sim #( m_chdr.reset(); while (1) begin // A generation session begins on the posedge of start_stb - while (~start_stb) @(posedge clk); + while (start_stb !== 1) @(posedge clk); curr_pkt_num = 'd0; m_chdr.reset(); num_samps_xferd = 'd0; diff --git a/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv b/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv index fc9d53fe7..33b09dfd5 100644 --- a/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv +++ b/fpga/usrp3/lib/rfnoc/crossbar/crossbar_tb/crossbar_tb.sv @@ -58,12 +58,18 @@ module crossbar_tb #( //---------------------------------------------------- // Instantiate traffic generators, checkers, buses //---------------------------------------------------- - localparam FILE_PATH = {`WORKING_DIR, "/data/", ROUTER_IMPL}; + `ifndef WORKING_DIR + // For XSim + localparam FILE_PATH = {`WORKING_DIR, "/data/", ROUTER_IMPL}; + `else + // For ModelSim + localparam FILE_PATH = {"./work", "/data/", ROUTER_IMPL}; + `endif // Data buses axis_t #(.DWIDTH(ROUTER_DWIDTH), .NUM_STREAMS(ROUTER_PORTS)) src2rtr_axis (.clk(clk)); axis_t #(.DWIDTH(ROUTER_DWIDTH), .NUM_STREAMS(ROUTER_PORTS)) rtr2snk_axis (.clk(clk)); - + // Control buses settings_bus_master #(.SR_AWIDTH(16), .SR_DWIDTH(32)) rtr_sb (.clk(clk)); wire rtr_sb_ack; @@ -75,6 +81,7 @@ module crossbar_tb #( logic [31:0] set_num_pkts_to_send; logic snk_start_stb = 0; logic src_start_stb = 0; + bit done = 0; wire [63:0] session_duration [0:ROUTER_PORTS-1]; wire [ROUTER_PORTS-1:0] src_active; @@ -99,7 +106,7 @@ module crossbar_tb #( .MTU (MTU_LOG2), .NODE_ID (i), .NUM_NODES (ROUTER_PORTS) - ) traffic_src ( + ) traffic_src ( .clk (clk), .rst (rst), .current_time (timestamp), @@ -117,14 +124,14 @@ module crossbar_tb #( .xfer_count (src_xfer_count[i]), .pkt_count (src_pkt_count[i]) ); - + chdr_traffic_sink_sim #( .WIDTH (ROUTER_DWIDTH), .MTU (MTU_LOG2), .NODE_ID (i), .NUM_NODES (ROUTER_PORTS), .FILE_PATH (TEST_GEN_LL_FILES==1 ? FILE_PATH : "") - ) traffic_sink ( + ) traffic_sink ( .clk (clk), .rst (rst), .current_time (timestamp), @@ -152,8 +159,8 @@ module crossbar_tb #( axi_fifo #( .WIDTH(ROUTER_DWIDTH+1), .SIZE(0) ) fifo_i ( - .clk (clk), - .reset (rst), + .clk (clk), + .reset (rst), .clear (1'b0), .i_tdata ({src2rtr_axis.tlast[i], src2rtr_axis.tdata[((i+1)*ROUTER_DWIDTH)-1:i*ROUTER_DWIDTH]}), .i_tvalid (src2rtr_axis.tvalid[i]), @@ -178,7 +185,7 @@ module crossbar_tb #( .reset (rst), .clear (1'b0), .local_addr (8'd0), - // Inputs + // Inputs .i_tdata (src2rtr_axis.tdata), .i_tlast (src2rtr_axis.tlast), .i_tvalid (src2rtr_axis.tvalid), @@ -210,7 +217,7 @@ module crossbar_tb #( .NPORTS_MGMT (0), .EXT_RTCFG_PORT (1) ) router_dut_i ( - // General + // General .clk (clk), .reset (rst), // Inputs @@ -242,12 +249,12 @@ module crossbar_tb #( // General .clk (clk), .reset (rst), - // Inputs + // Inputs .s_axis_tdata (src2rtr_axis.tdata), .s_axis_tlast (src2rtr_axis.tlast), .s_axis_tvalid (src2rtr_axis.tvalid), .s_axis_tready (src2rtr_axis.tready), - // Output + // Output .m_axis_tdata (rtr2snk_axis.tdata), .m_axis_tlast (rtr2snk_axis.tlast), .m_axis_tvalid (rtr2snk_axis.tvalid), @@ -313,7 +320,7 @@ module crossbar_tb #( @(posedge clk); if (deadlock_re) $display("WARNING: Deadlock detected"); if (deadlock_fe) $display("Recovered from deadlock"); - end + end // Wait for sink blocks to finish consuming $display("All packets transmitted. Waiting to flush..."); while (|snk_active) @(posedge clk); @@ -423,6 +430,7 @@ module crossbar_tb #( `TEST_CASE_DONE(1) `TEST_BENCH_DONE + done = 1; end // initial begin endmodule diff --git a/fpga/usrp3/lib/rfnoc/sim/chdr_stream_endpoint_tb/Makefile b/fpga/usrp3/lib/rfnoc/sim/chdr_stream_endpoint_tb/Makefile index b2773db02..d7152134d 100644 --- a/fpga/usrp3/lib/rfnoc/sim/chdr_stream_endpoint_tb/Makefile +++ b/fpga/usrp3/lib/rfnoc/sim/chdr_stream_endpoint_tb/Makefile @@ -29,11 +29,12 @@ $(RFNOC_XBAR_SRCS) \ #------------------------------------------------- # Testbench Specific #------------------------------------------------- -SIM_TOP = chdr_stream_endpoint_tb +SIM_TOP = chdr_stream_endpoint_all_tb SIM_SRCS = \ $(abspath lossy_xport_model.v) \ $(abspath chdr_stream_endpoint_tb.sv) \ +$(abspath chdr_stream_endpoint_all_tb.sv) \ #------------------------------------------------- # Bottom-of-Makefile diff --git a/fpga/usrp3/lib/rfnoc/sim/chdr_stream_endpoint_tb/chdr_stream_endpoint_all_tb.sv b/fpga/usrp3/lib/rfnoc/sim/chdr_stream_endpoint_tb/chdr_stream_endpoint_all_tb.sv new file mode 100644 index 000000000..c382be654 --- /dev/null +++ b/fpga/usrp3/lib/rfnoc/sim/chdr_stream_endpoint_tb/chdr_stream_endpoint_all_tb.sv @@ -0,0 +1,26 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// Module: chdr_stream_endpoint_all_tb +// +// Description: Testbench for chdr_stream_endpoint that runs multiple widths +// + +module chdr_stream_endpoint_all_tb#( + /* no PARAM */ +)( + /* no IO */ +); + + chdr_stream_endpoint_tb #(.TEST_NAME("64B"),.CHDR_W(64)) CHDR64 (); + chdr_stream_endpoint_tb #(.TEST_NAME("512B"),.CHDR_W(512)) CHDR512 (); + + // Wait for all done + bit clk,rst; + sim_clock_gen #(100.0) clk_gen (clk, rst); + always_ff@(posedge clk) + if (CHDR64.test.done && CHDR512.test.done) $finish(1); + +endmodule diff --git a/fpga/usrp3/lib/rfnoc/sim/chdr_stream_endpoint_tb/chdr_stream_endpoint_tb.sv b/fpga/usrp3/lib/rfnoc/sim/chdr_stream_endpoint_tb/chdr_stream_endpoint_tb.sv index 34bf10707..daa7bf522 100644 --- a/fpga/usrp3/lib/rfnoc/sim/chdr_stream_endpoint_tb/chdr_stream_endpoint_tb.sv +++ b/fpga/usrp3/lib/rfnoc/sim/chdr_stream_endpoint_tb/chdr_stream_endpoint_tb.sv @@ -1,5 +1,5 @@ // -// Copyright 2019 Ettus Research, A National Instruments Company +// Copyright 2020 Ettus Research, A National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // @@ -8,14 +8,18 @@ `default_nettype none - -module chdr_stream_endpoint_tb; - +module chdr_stream_endpoint_tb#( + parameter TEST_NAME = "chdr_stream_endpoint_tb", + parameter CHDR_W = 64 +)( + /* no IO */ +); // ---------------------------------------- // Global settings // ---------------------------------------- - + // Include macros and time declarations for use with PkgTestExec + `define TEST_EXEC_OBJ test `include "test_exec.svh" import PkgTestExec::*; @@ -34,7 +38,6 @@ module chdr_stream_endpoint_tb; localparam int FAST_STALL_PROB = 0; localparam int SLOW_STALL_PROB = 35; - localparam int CHDR_W = 64; localparam int MTU = 7; localparam [15:0] PROTOVER = {8'd1, 8'd0}; localparam [15:0] DEV_ID = 16'hBEEF; @@ -108,14 +111,14 @@ module chdr_stream_endpoint_tb; .m_axis_chdr_tlast (a2c_chdr_tlast ), .m_axis_chdr_tvalid (a2c_chdr_tvalid ), .m_axis_chdr_tready (a2c_chdr_tready ), - .s_axis_data_tdata ({m_a1_data.slave.tdata , m_a0_data.slave.tdata }), - .s_axis_data_tlast ({m_a1_data.slave.tlast , m_a0_data.slave.tlast }), - .s_axis_data_tvalid ({m_a1_data.slave.tvalid , m_a0_data.slave.tvalid }), - .s_axis_data_tready ({m_a1_data.slave.tready , m_a0_data.slave.tready }), - .m_axis_data_tdata ({s_a1_data.master.tdata , s_a0_data.master.tdata }), - .m_axis_data_tlast ({s_a1_data.master.tlast , s_a0_data.master.tlast }), - .m_axis_data_tvalid ({s_a1_data.master.tvalid, s_a0_data.master.tvalid}), - .m_axis_data_tready ({s_a1_data.master.tready, s_a0_data.master.tready}), + .s_axis_data_tdata ({m_a1_data.tdata , m_a0_data.tdata }), + .s_axis_data_tlast ({m_a1_data.tlast , m_a0_data.tlast }), + .s_axis_data_tvalid ({m_a1_data.tvalid , m_a0_data.tvalid }), + .s_axis_data_tready ({m_a1_data.tready , m_a0_data.tready }), + .m_axis_data_tdata ({s_a1_data.tdata , s_a0_data.tdata }), + .m_axis_data_tlast ({s_a1_data.tlast , s_a0_data.tlast }), + .m_axis_data_tvalid ({s_a1_data.tvalid, s_a0_data.tvalid}), + .m_axis_data_tready ({s_a1_data.tready, s_a0_data.tready}), .s_axis_ctrl_tdata (a_ctrl_out_tdata ), .s_axis_ctrl_tlast (a_ctrl_loop_tlast ), .s_axis_ctrl_tvalid (a_ctrl_loop_tvalid ), @@ -157,14 +160,14 @@ module chdr_stream_endpoint_tb; .m_axis_chdr_tlast (b2c_chdr_tlast ), .m_axis_chdr_tvalid (b2c_chdr_tvalid ), .m_axis_chdr_tready (b2c_chdr_tready ), - .s_axis_data_tdata ({m_b1_data.slave.tdata , m_b0_data.slave.tdata }), - .s_axis_data_tlast ({m_b1_data.slave.tlast , m_b0_data.slave.tlast }), - .s_axis_data_tvalid ({m_b1_data.slave.tvalid , m_b0_data.slave.tvalid }), - .s_axis_data_tready ({m_b1_data.slave.tready , m_b0_data.slave.tready }), - .m_axis_data_tdata ({s_b1_data.master.tdata , s_b0_data.master.tdata }), - .m_axis_data_tlast ({s_b1_data.master.tlast , s_b0_data.master.tlast }), - .m_axis_data_tvalid ({s_b1_data.master.tvalid, s_b0_data.master.tvalid}), - .m_axis_data_tready ({s_b1_data.master.tready, s_b0_data.master.tready}), + .s_axis_data_tdata ({m_b1_data.tdata , m_b0_data.tdata }), + .s_axis_data_tlast ({m_b1_data.tlast , m_b0_data.tlast }), + .s_axis_data_tvalid ({m_b1_data.tvalid , m_b0_data.tvalid }), + .s_axis_data_tready ({m_b1_data.tready , m_b0_data.tready }), + .m_axis_data_tdata ({s_b1_data.tdata , s_b0_data.tdata }), + .m_axis_data_tlast ({s_b1_data.tlast , s_b0_data.tlast }), + .m_axis_data_tvalid ({s_b1_data.tvalid, s_b0_data.tvalid}), + .m_axis_data_tready ({s_b1_data.tready, s_b0_data.tready}), .s_axis_ctrl_tdata (b_ctrl_out_tdata ), .s_axis_ctrl_tlast (b_ctrl_loop_tlast ), .s_axis_ctrl_tvalid (b_ctrl_loop_tvalid ), @@ -194,14 +197,14 @@ module chdr_stream_endpoint_tb; .clk (rfnoc_chdr_clk), .reset (rfnoc_chdr_rst), .device_id (DEV_ID), - .s_axis_tdata ({b2c_chdr_tdata, a2c_chdr_tdata, m_tb_chdr.slave.tdata }), - .s_axis_tlast ({b2c_chdr_tlast, a2c_chdr_tlast, m_tb_chdr.slave.tlast }), - .s_axis_tvalid ({b2c_chdr_tvalid, a2c_chdr_tvalid, m_tb_chdr.slave.tvalid }), - .s_axis_tready ({b2c_chdr_tready, a2c_chdr_tready, m_tb_chdr.slave.tready }), - .m_axis_tdata ({c2bx_chdr_tdata, c2ax_chdr_tdata, s_tb_chdr.master.tdata }), - .m_axis_tlast ({c2bx_chdr_tlast, c2ax_chdr_tlast, s_tb_chdr.master.tlast }), - .m_axis_tvalid ({c2bx_chdr_tvalid, c2ax_chdr_tvalid, s_tb_chdr.master.tvalid}), - .m_axis_tready ({c2bx_chdr_tready, c2ax_chdr_tready, s_tb_chdr.master.tready}), + .s_axis_tdata ({b2c_chdr_tdata, a2c_chdr_tdata, m_tb_chdr.tdata }), + .s_axis_tlast ({b2c_chdr_tlast, a2c_chdr_tlast, m_tb_chdr.tlast }), + .s_axis_tvalid ({b2c_chdr_tvalid, a2c_chdr_tvalid, m_tb_chdr.tvalid }), + .s_axis_tready ({b2c_chdr_tready, a2c_chdr_tready, m_tb_chdr.tready }), + .m_axis_tdata ({c2bx_chdr_tdata, c2ax_chdr_tdata, s_tb_chdr.tdata }), + .m_axis_tlast ({c2bx_chdr_tlast, c2ax_chdr_tlast, s_tb_chdr.tlast }), + .m_axis_tvalid ({c2bx_chdr_tvalid, c2ax_chdr_tvalid, s_tb_chdr.tvalid}), + .m_axis_tready ({c2bx_chdr_tready, c2ax_chdr_tready, s_tb_chdr.tready}), .ext_rtcfg_stb ('0), .ext_rtcfg_addr ('0), .ext_rtcfg_data ('0), @@ -264,14 +267,15 @@ module chdr_stream_endpoint_tb; end end // Respond with an ACK and the source and destination ports swapped - assign a_ctrl_out_tdata = + assign a_ctrl_out_tdata = a_first ? {1'b1, a_ctrl_in_tdata[30:20], a_ctrl_in_tdata[9:0], a_ctrl_in_tdata[19:10]} : a_ctrl_in_tdata; - assign b_ctrl_out_tdata = + assign b_ctrl_out_tdata = b_first ? {1'b1, b_ctrl_in_tdata[30:20], b_ctrl_in_tdata[9:0], b_ctrl_in_tdata[19:10]} : b_ctrl_in_tdata; // ---------------------------------------- // Test Utilities // ---------------------------------------- + TestExec test = new(); integer cached_mgmt_seqnum = 0; integer cached_ctrl_seqnum = 0; integer cached_data_seqnum = 0; @@ -320,7 +324,7 @@ module chdr_stream_endpoint_tb; op_payload:{32'h0, sep_a.REG_OSTRM_DATA_ERR_CNT}, op_code:MGMT_OP_CFG_RD_REQ, ops_pending:8'd2}; tx_mgmt_pl.ops[3] = '{ // Hop 2: Read status op_payload:{32'h0, sep_a.REG_OSTRM_ROUTE_ERR_CNT}, op_code:MGMT_OP_CFG_RD_REQ, ops_pending:8'd1}; - tx_mgmt_pl.ops[4] = '{ // Hop 2: Stream Endpoint: Return + tx_mgmt_pl.ops[4] = '{ // Hop 2: Stream Endpoint: Return op_payload:48'h0, op_code:MGMT_OP_RETURN, ops_pending:8'd0}; tx_mgmt_pl.ops[5] = '{ // Hop 3: Nop for return op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0}; @@ -357,7 +361,7 @@ module chdr_stream_endpoint_tb; automatic ctrl_op_word_t ctrl_op; automatic ctrl_word_t ctrl_data[$]; automatic chdr_word_t ctrl_ts; - + ctrl_data.delete(); for (int i = 0; i < $urandom_range(15,1); i++) ctrl_data[i] = $urandom(); @@ -406,6 +410,7 @@ module chdr_stream_endpoint_tb; if (VERBOSE) begin $write("ExpRx"); exp_chdr.print(); end // Validate contents + exp_chdr.disable_comparing_beyond_length = 1; `ASSERT_ERROR(exp_chdr.equal(rx_chdr), "Received CHDR control packet was incorrect"); end @@ -527,12 +532,12 @@ module chdr_stream_endpoint_tb; // Shared Variables // ---------------------------------------- - timeout_t timeout; - string tc_label; - bit stop_responder = 0; - logic [31:0] seq_err_count; - logic [31:0] route_err_count; - logic [31:0] data_err_count; + timeout_t timeout; + string tc_label; + automatic bit stop_responder = 0; + logic [31:0] seq_err_count; + logic [31:0] route_err_count; + logic [31:0] data_err_count; a_signal_data_err = 0; b_signal_data_err = 0; @@ -543,9 +548,10 @@ module chdr_stream_endpoint_tb; b_rterr_prob = 0; b_lossy_input = 0; + // Initialize // ---------------------------------------- - test.start_tb("chdr_stream_endpoint_tb"); + test.start_tb({TEST_NAME,"chdr_stream_endpoint_tb"}); // Start the BFMs a0_data_bfm.run(); @@ -562,7 +568,7 @@ module chdr_stream_endpoint_tb; rfnoc_ctrl_clk_gen.reset(); rfnoc_chdr_clk_gen.reset(); - test.start_test("Wait for reset"); + test.start_test({TEST_NAME,"Wait for reset"}); test.start_timeout(timeout, 1us, "Waiting for reset"); while (rfnoc_ctrl_rst) @(posedge rfnoc_ctrl_clk); while (rfnoc_chdr_rst) @(posedge rfnoc_chdr_clk); @@ -572,7 +578,7 @@ module chdr_stream_endpoint_tb; // Discover Topology // ---------------------------------------- - test.start_test("Discover Topology"); + test.start_test({TEST_NAME,"Discover Topology"}); begin automatic chdr_header_t tx_mgmt_hdr, rx_mgmt_hdr; automatic chdr_mgmt_t tx_mgmt_pl, rx_mgmt_pl; @@ -587,9 +593,9 @@ module chdr_stream_endpoint_tb; // Send a node info request to the crossbar tx_mgmt_pl.header.num_hops = 2; tx_mgmt_pl.ops.delete(); - tx_mgmt_pl.ops[0] = '{ // Hop 1: Send node info + tx_mgmt_pl.ops[0] = '{ // Hop 1: Send node info op_payload:48'h0, op_code:MGMT_OP_INFO_REQ, ops_pending:8'd1}; - tx_mgmt_pl.ops[1] = '{ // Hop 1: Return + tx_mgmt_pl.ops[1] = '{ // Hop 1: Return op_payload:48'h0, op_code:MGMT_OP_RETURN, ops_pending:8'd0}; tx_mgmt_pl.ops[2] = '{ // Hop 2: Nop for return op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0}; @@ -605,7 +611,7 @@ module chdr_stream_endpoint_tb; `ASSERT_ERROR(rx_mgmt_pl.ops[1] == exp_mgmt_op, "Discover XB: Mgmt response ops were incorrect"); - // *Status* We just discovered a crossbar with 3 ports! + // *Status* We just discovered a crossbar with 3 ports! // Configure the crossbar routing table with our (TB) address // then send node info request on the other two ports @@ -613,11 +619,11 @@ module chdr_stream_endpoint_tb; tx_mgmt_pl.ops.delete(); tx_mgmt_pl.ops[0] = '{ // Hop 1: Crossbar: Config router to return packet to dest op_payload:{22'h0, PORT_TB, EPID_TB}, op_code:MGMT_OP_CFG_WR_REQ, ops_pending:8'd1}; - tx_mgmt_pl.ops[1] = '{ // Hop 1: Crossbar: Config router + tx_mgmt_pl.ops[1] = '{ // Hop 1: Crossbar: Config router op_payload:{38'h0, PORT_A}, op_code:MGMT_OP_SEL_DEST, ops_pending:8'd0}; - tx_mgmt_pl.ops[2] = '{ // Hop 2: Stream Endpoint: Send node info + tx_mgmt_pl.ops[2] = '{ // Hop 2: Stream Endpoint: Send node info op_payload:48'h0, op_code:MGMT_OP_INFO_REQ, ops_pending:8'd1}; - tx_mgmt_pl.ops[3] = '{ // Hop 2: Return + tx_mgmt_pl.ops[3] = '{ // Hop 2: Return op_payload:48'h0, op_code:MGMT_OP_RETURN, ops_pending:8'd0}; tx_mgmt_pl.ops[4] = '{ // Hop 3: TB: Nop for return op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0}; @@ -638,11 +644,11 @@ module chdr_stream_endpoint_tb; // Send node info request on the last port tx_mgmt_pl.header.num_hops = 3; tx_mgmt_pl.ops.delete(); - tx_mgmt_pl.ops[0] = '{ // Hop 1: Crossbar: Config router + tx_mgmt_pl.ops[0] = '{ // Hop 1: Crossbar: Config router op_payload:{38'h0, PORT_B}, op_code:MGMT_OP_SEL_DEST, ops_pending:8'd0}; - tx_mgmt_pl.ops[1] = '{ // Hop 2: Stream Endpoint: Send node info + tx_mgmt_pl.ops[1] = '{ // Hop 2: Stream Endpoint: Send node info op_payload:48'h0, op_code:MGMT_OP_INFO_REQ, ops_pending:8'd1}; - tx_mgmt_pl.ops[2] = '{ // Hop 2: Return + tx_mgmt_pl.ops[2] = '{ // Hop 2: Return op_payload:48'h0, op_code:MGMT_OP_RETURN, ops_pending:8'd0}; tx_mgmt_pl.ops[3] = '{ // Hop 3: TB: Nop for return op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0}; @@ -664,7 +670,7 @@ module chdr_stream_endpoint_tb; // Configure Routes to Stream Endpoints A and B // ---------------------------------------- - test.start_test("Configure Routes"); + test.start_test({TEST_NAME,"Configure Routes"}); begin automatic chdr_header_t tx_mgmt_hdr, rx_mgmt_hdr; automatic chdr_mgmt_t tx_mgmt_pl, rx_mgmt_pl; @@ -680,9 +686,9 @@ module chdr_stream_endpoint_tb; tx_mgmt_pl.ops[0] = '{ // Hop 1: Crossbar: Config path to EP A op_payload:{22'h0, PORT_A, EPID_A}, op_code:MGMT_OP_CFG_WR_REQ, ops_pending:8'd2}; - tx_mgmt_pl.ops[1] = '{ // Hop 1: Crossbar: Config path to EP B + tx_mgmt_pl.ops[1] = '{ // Hop 1: Crossbar: Config path to EP B op_payload:{22'h0, PORT_B, EPID_B}, op_code:MGMT_OP_CFG_WR_REQ, ops_pending:8'd1}; - tx_mgmt_pl.ops[2] = '{ // Hop 1: Request node info to make the packet come back + tx_mgmt_pl.ops[2] = '{ // Hop 1: Request node info to make the packet come back op_payload:48'h0, op_code:MGMT_OP_RETURN, ops_pending:8'd0}; tx_mgmt_pl.ops[3] = '{ // Hop 2: Nop for return op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0}; @@ -701,13 +707,13 @@ module chdr_stream_endpoint_tb; // Configure Stream Endpoints // ---------------------------------------- - test.start_test("Configure Stream Endpoints"); + test.start_test({TEST_NAME,"Configure Stream Endpoints"}); begin automatic chdr_header_t tx_mgmt_hdr, rx_mgmt_hdr; automatic chdr_mgmt_t tx_mgmt_pl, rx_mgmt_pl; automatic chdr_mgmt_op_t exp_mgmt_op; - logic [15:0] epids[2] = {EPID_A, EPID_B}; + automatic logic [15:0] epids[2] = {EPID_A, EPID_B}; foreach (epids[i]) begin // Generic management header tx_mgmt_pl.header = '{ @@ -727,13 +733,13 @@ module chdr_stream_endpoint_tb; op_payload:{32'h0, sep_a.REG_EPID_SELF}, op_code:MGMT_OP_CFG_RD_REQ, ops_pending:8'd2}; tx_mgmt_pl.ops[4] = '{ // Hop 2: Read EPID op_payload:{32'h0, sep_a.REG_OSTRM_CTRL_STATUS}, op_code:MGMT_OP_CFG_RD_REQ, ops_pending:8'd1}; - tx_mgmt_pl.ops[5] = '{ // Hop 2: Stream Endpoint: Return + tx_mgmt_pl.ops[5] = '{ // Hop 2: Stream Endpoint: Return op_payload:48'h0, op_code:MGMT_OP_RETURN, ops_pending:8'd0}; tx_mgmt_pl.ops[6] = '{ // Hop 3: Nop for return op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0}; tx_mgmt_hdr = '{ pkt_type:CHDR_MANAGEMENT, seq_num:cached_mgmt_seqnum++, dst_epid:epids[i], default:'0}; - + // Send the packet and check the response send_recv_mgmt_packet(tx_mgmt_hdr, tx_mgmt_pl, rx_mgmt_hdr, rx_mgmt_pl); `ASSERT_ERROR(rx_mgmt_pl.header.num_hops == 1, @@ -752,13 +758,13 @@ module chdr_stream_endpoint_tb; // Setup a stream between Endpoint A and B // ---------------------------------------- - test.start_test("Setup bidirectional stream between endpoints A and B"); + test.start_test({TEST_NAME,"Setup bidirectional stream between endpoints A and B"}); begin automatic chdr_header_t tx_mgmt_hdr, rx_mgmt_hdr; automatic chdr_mgmt_t tx_mgmt_pl, rx_mgmt_pl; automatic chdr_mgmt_op_t exp_mgmt_op; - logic [15:0] epids[2] = {EPID_A, EPID_B}; + automatic logic [15:0] epids[2] = {EPID_A, EPID_B}; foreach (epids[i]) begin // Generic management header tx_mgmt_pl.header = '{ @@ -784,7 +790,7 @@ module chdr_stream_endpoint_tb; op_payload:{32'h44, sep_a.REG_ISTRM_CTRL_STATUS}, op_code:MGMT_OP_CFG_WR_REQ, ops_pending:8'd2}; // Swap 32-bit words, endianness tx_mgmt_pl.ops[7] = '{ // Hop 2: Configure lossy and start config op_payload:{32'h47, sep_a.REG_OSTRM_CTRL_STATUS}, op_code:MGMT_OP_CFG_WR_REQ, ops_pending:8'd1}; // Swap 32-bit words, endianness, lossy and reset - tx_mgmt_pl.ops[8] = '{ // Hop 2: Stream Endpoint: Return + tx_mgmt_pl.ops[8] = '{ // Hop 2: Stream Endpoint: Return op_payload:48'h0, op_code:MGMT_OP_RETURN, ops_pending:8'd0}; tx_mgmt_pl.ops[9] = '{ // Hop 3: Nop for return op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0}; @@ -818,7 +824,7 @@ module chdr_stream_endpoint_tb; op_payload:{32'h0, sep_a.REG_OSTRM_DATA_ERR_CNT}, op_code:MGMT_OP_CFG_RD_REQ, ops_pending:8'd2}; tx_mgmt_pl.ops[7] = '{ // Hop 2: Read status op_payload:{32'h0, sep_a.REG_OSTRM_ROUTE_ERR_CNT}, op_code:MGMT_OP_CFG_RD_REQ, ops_pending:8'd1}; - tx_mgmt_pl.ops[8] = '{ // Hop 2: Stream Endpoint: Return + tx_mgmt_pl.ops[8] = '{ // Hop 2: Stream Endpoint: Return op_payload:48'h0, op_code:MGMT_OP_RETURN, ops_pending:8'd0}; tx_mgmt_pl.ops[9] = '{ // Hop 3: Nop for return op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0}; @@ -859,7 +865,7 @@ module chdr_stream_endpoint_tb; cached_ctrl_seqnum = 0; for (int cfg = 0; cfg < 2; cfg++) begin $sformat(tc_label, "Control Xact to A (%s)", (cfg?"Slow":"Fast")); - test.start_test(tc_label); + test.start_test({TEST_NAME,tc_label}); begin tb_chdr_bfm.set_master_stall_prob(cfg?SLOW_STALL_PROB:FAST_STALL_PROB); tb_chdr_bfm.set_slave_stall_prob(cfg?SLOW_STALL_PROB:FAST_STALL_PROB); @@ -874,7 +880,7 @@ module chdr_stream_endpoint_tb; cached_ctrl_seqnum = 0; for (int cfg = 0; cfg < 2; cfg++) begin $sformat(tc_label, "Control Xact to B (%s)", (cfg?"Slow":"Fast")); - test.start_test(tc_label); + test.start_test({TEST_NAME,tc_label}); begin tb_chdr_bfm.set_master_stall_prob(cfg?SLOW_STALL_PROB:FAST_STALL_PROB); tb_chdr_bfm.set_slave_stall_prob(cfg?SLOW_STALL_PROB:FAST_STALL_PROB); @@ -892,7 +898,7 @@ module chdr_stream_endpoint_tb; automatic logic slv_cfg = cfg[1]; $sformat(tc_label, "Stream Data from A to B (%s Mst, %s Slv)", (mst_cfg?"Slow":"Fast"), (slv_cfg?"Slow":"Fast")); - test.start_test(tc_label); + test.start_test({TEST_NAME,tc_label}); begin set_unidir_stall_prob(EPID_A, EPID_B, mst_cfg?SLOW_STALL_PROB:FAST_STALL_PROB, @@ -911,7 +917,7 @@ module chdr_stream_endpoint_tb; automatic logic slv_cfg = cfg[1]; $sformat(tc_label, "Stream Data from B to A (%s Mst, %s Slv)", (mst_cfg?"Slow":"Fast"), (slv_cfg?"Slow":"Fast")); - test.start_test(tc_label); + test.start_test({TEST_NAME,tc_label}); begin set_unidir_stall_prob(EPID_B, EPID_A, mst_cfg?SLOW_STALL_PROB:FAST_STALL_PROB, @@ -929,7 +935,7 @@ module chdr_stream_endpoint_tb; automatic logic slv_cfg = cfg[1]; $sformat(tc_label, "Stream Data between A <=> B simultaneously (%s Mst, %s Slv)", (mst_cfg?"Slow":"Fast"), (slv_cfg?"Slow":"Fast")); - test.start_test(tc_label); + test.start_test({TEST_NAME,tc_label}); begin set_bidir_stall_prob( mst_cfg?SLOW_STALL_PROB:FAST_STALL_PROB, @@ -950,7 +956,7 @@ module chdr_stream_endpoint_tb; automatic logic slv_cfg = cfg[1]; $sformat(tc_label, "Stream Data and Control between A <=> B (%s Mst, %s Slv)", (mst_cfg?"Slow":"Fast"), (slv_cfg?"Slow":"Fast")); - test.start_test(tc_label); + test.start_test({TEST_NAME,tc_label}); begin tb_chdr_bfm.set_master_stall_prob(mst_cfg?SLOW_STALL_PROB:FAST_STALL_PROB); tb_chdr_bfm.set_slave_stall_prob(slv_cfg?SLOW_STALL_PROB:FAST_STALL_PROB); @@ -976,9 +982,9 @@ module chdr_stream_endpoint_tb; // Check zero sequence errors after streaming // ---------------------------------------- - test.start_test("Check zero sequence errors after streaming"); + test.start_test({TEST_NAME,"Check zero sequence errors after streaming"}); begin - logic [15:0] epids[2] = {EPID_A, EPID_B}; + automatic logic [15:0] epids[2] = {EPID_A, EPID_B}; foreach (epids[i]) begin mgmt_read_err_counts(epids[i], seq_err_count, route_err_count, data_err_count); `ASSERT_ERROR(seq_err_count == 32'd0, "Check NoErrs: Incorrect seq error count"); @@ -988,9 +994,13 @@ module chdr_stream_endpoint_tb; end test.end_test(); + // Force sequence error + // Note: Occasional StreamCommand to resynch occur, which + // can cause the count to be greater than just the number data packets + // that are sent, so the comparisons are to > instead of == // ---------------------------------------- - test.start_test("Force sequence error"); + test.start_test({TEST_NAME,"Force sequence error"}); begin // First sequence error send_recv_data_packets(EPID_A, EPID_B, 1, cached_data_seqnum++, 1); @@ -999,7 +1009,7 @@ module chdr_stream_endpoint_tb; b_seqerr_prob = 0; repeat (100) @(posedge rfnoc_chdr_clk); // Wait for sequence error to reach the upstream port mgmt_read_err_counts(EPID_A, seq_err_count, route_err_count, data_err_count); - `ASSERT_ERROR(seq_err_count == 32'd1, "Force SeqErr: Incorrect seq error count"); + `ASSERT_ERROR(seq_err_count > 32'd0, "Force SeqErr: Incorrect seq error count"); `ASSERT_ERROR(route_err_count == 32'd0, "Force SeqErr: Incorrect route error count"); `ASSERT_ERROR(data_err_count == 32'd0, "Force SeqErr: Incorrect data error count"); @@ -1010,7 +1020,7 @@ module chdr_stream_endpoint_tb; b_seqerr_prob = 0; repeat (100) @(posedge rfnoc_chdr_clk); // Wait for sequence error to reach the upstream port mgmt_read_err_counts(EPID_A, seq_err_count, route_err_count, data_err_count); - `ASSERT_ERROR(seq_err_count > 32'd1, "Force SeqErr: Incorrect seq error count"); + `ASSERT_ERROR(seq_err_count > 32'd2, "Force SeqErr: Incorrect seq error count"); `ASSERT_ERROR(route_err_count == 32'd0, "Force SeqErr: Incorrect route error count"); `ASSERT_ERROR(data_err_count == 32'd0, "Force SeqErr: Incorrect data error count"); end @@ -1018,7 +1028,7 @@ module chdr_stream_endpoint_tb; // Force routing error // ---------------------------------------- - test.start_test("Force routing error"); + test.start_test({TEST_NAME,"Force routing error"}); begin logic [31:0] old_route_err_count; // First sequence error @@ -1048,13 +1058,13 @@ module chdr_stream_endpoint_tb; // Setup a stream between Endpoint A and B // ---------------------------------------- - test.start_test("Reconfigure flow control (reset state)"); + test.start_test({TEST_NAME,"Reconfigure flow control (reset state)"}); begin automatic chdr_header_t tx_mgmt_hdr, rx_mgmt_hdr; automatic chdr_mgmt_t tx_mgmt_pl, rx_mgmt_pl; automatic chdr_mgmt_op_t exp_mgmt_op; - logic [15:0] epids[2] = {EPID_A, EPID_B}; + automatic logic [15:0] epids[2] = {EPID_A, EPID_B}; foreach (epids[i]) begin // Generic management header tx_mgmt_pl.header = '{ @@ -1070,7 +1080,7 @@ module chdr_stream_endpoint_tb; op_payload:{32'd0, sep_a.REG_ISTRM_CTRL_STATUS}, op_code:MGMT_OP_CFG_WR_REQ, ops_pending:8'd2}; tx_mgmt_pl.ops[2] = '{ // Hop 2: Configure lossy and start config op_payload:{32'd3, sep_a.REG_OSTRM_CTRL_STATUS}, op_code:MGMT_OP_CFG_WR_REQ, ops_pending:8'd1}; - tx_mgmt_pl.ops[3] = '{ // Hop 2: Stream Endpoint: Return + tx_mgmt_pl.ops[3] = '{ // Hop 2: Stream Endpoint: Return op_payload:48'h0, op_code:MGMT_OP_RETURN, ops_pending:8'd0}; tx_mgmt_pl.ops[4] = '{ // Hop 3: Nop for return op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0}; @@ -1092,7 +1102,7 @@ module chdr_stream_endpoint_tb; op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0}; tx_mgmt_pl.ops[1] = '{ // Hop 2: Read status op_payload:{32'h0, sep_a.REG_OSTRM_CTRL_STATUS}, op_code:MGMT_OP_CFG_RD_REQ, ops_pending:8'd1}; - tx_mgmt_pl.ops[2] = '{ // Hop 2: Stream Endpoint: Return + tx_mgmt_pl.ops[2] = '{ // Hop 2: Stream Endpoint: Return op_payload:48'h0, op_code:MGMT_OP_RETURN, ops_pending:8'd0}; tx_mgmt_pl.ops[3] = '{ // Hop 3: Nop for return op_payload:48'h0, op_code:MGMT_OP_NOP, ops_pending:8'd0}; @@ -1112,9 +1122,9 @@ module chdr_stream_endpoint_tb; // Check zero errors after reinit // ---------------------------------------- - test.start_test("Check zero errors after reinit"); + test.start_test({TEST_NAME,"Check zero errors after reinit"}); begin - logic [15:0] epids[2] = {EPID_A, EPID_B}; + automatic logic [15:0] epids[2] = {EPID_A, EPID_B}; foreach (epids[i]) begin mgmt_read_err_counts(epids[i], seq_err_count, route_err_count, data_err_count); `ASSERT_ERROR(seq_err_count == 32'd0, "Check NoErrs: Incorrect seq error count"); @@ -1126,7 +1136,7 @@ module chdr_stream_endpoint_tb; // Stream data between A <=> B simultaneously // ---------------------------------------- - test.start_test("Stream Data between A <=> B with a lossy link"); + test.start_test({TEST_NAME,"Stream Data between A <=> B with a lossy link"}); begin cached_data_seqnum = 0; set_bidir_stall_prob(FAST_STALL_PROB, SLOW_STALL_PROB); @@ -1145,7 +1155,8 @@ module chdr_stream_endpoint_tb; // Finish Up // ---------------------------------------- // Display final statistics and results - test.end_tb(); + test.end_tb(.finish(0)); end endmodule +`default_nettype wire
\ No newline at end of file |