diff options
Diffstat (limited to 'fpga/usrp3/lib/rfnoc')
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 |