diff options
Diffstat (limited to 'host/utils/rfnoc_blocktool/templates/rfnoc_block_template_tb.sv.mako')
-rw-r--r-- | host/utils/rfnoc_blocktool/templates/rfnoc_block_template_tb.sv.mako | 238 |
1 files changed, 163 insertions, 75 deletions
diff --git a/host/utils/rfnoc_blocktool/templates/rfnoc_block_template_tb.sv.mako b/host/utils/rfnoc_blocktool/templates/rfnoc_block_template_tb.sv.mako index 0bf4641b0..4ec1d1b93 100644 --- a/host/utils/rfnoc_blocktool/templates/rfnoc_block_template_tb.sv.mako +++ b/host/utils/rfnoc_blocktool/templates/rfnoc_block_template_tb.sv.mako @@ -1,3 +1,4 @@ +<%namespace name="func" file="/functions.mako"/>\ // // Copyright 2019 Ettus Research, A National Instruments Company // @@ -5,42 +6,53 @@ // // Module: rfnoc_block_${config['module_name']}_tb // +// Description: Testbench for the ${config['module_name']} RFNoC block. +// `default_nettype none module rfnoc_block_${config['module_name']}_tb; - // Simulation Timing - timeunit 1ns; - timeprecision 1ps; + `include "test_exec.svh" import PkgTestExec::*; import PkgChdrUtils::*; import PkgRfnocBlockCtrlBfm::*; import PkgRfnocItemUtils::*; - // Parameters - localparam [9:0] THIS_PORTID = 10'h17; - localparam [15:0] THIS_EPID = 16'hDEAD; - localparam int CHDR_W = 64; - localparam int SPP = 201; - localparam int LPP = ((SPP+1)/2); - localparam int NUM_PKTS = 50; - - localparam int PORT_SRCSNK = 0; - localparam int PORT_LOOP = 1; - - //adjust clocks to testbench needs - localparam int CHDR_CLK_PER = 5; // 200 MHz + //--------------------------------------------------------------------------- + // Testbench Configuration + //--------------------------------------------------------------------------- + + localparam [ 9:0] THIS_PORTID = 10'h123; + localparam [31:0] NOC_ID = 32'h${format(config['noc_id'], "08X")}; + localparam int CHDR_W = ${config['chdr_width']}; +%if 'parameters' in config: +%for param, value in config['parameters'].items(): + localparam int ${'{:<15}'.format(param)} = ${value}; +% endfor +%endif + localparam int NUM_PORTS_I = ${func.num_ports_in_str()}; + localparam int NUM_PORTS_O = ${func.num_ports_out_str()}; + localparam int MTU = 13; + localparam int SPP = 64; + localparam int PKT_SIZE_BYTES = SPP * 4; // Assumes 4 bytes per sample + localparam int STALL_PROB = 25; // Default BFM stall probability + localparam real CHDR_CLK_PER = 5.0; // 200 MHz + localparam real CTRL_CLK_PER = 25.0; // 40 MHz %for clock in config['clocks']: %if clock['name'] not in ["rfnoc_chdr", "rfnoc_ctrl"]: - localparam int ${clock['name'].upper()}_CLK_PER = 5; // 200 MHz + localparam real ${clock['name'].upper()}_CLK_PER = 5.0; // 200 MHz %endif %endfor - // Clock and Reset Definition + //--------------------------------------------------------------------------- + // Clocks and Resets + //--------------------------------------------------------------------------- + bit rfnoc_chdr_clk; + bit rfnoc_ctrl_clk; %for clock in config['clocks']: %if clock['name'] not in ["rfnoc_chdr", "rfnoc_ctrl"]: bit ${clock['name']}_clk; @@ -48,82 +60,158 @@ module rfnoc_block_${config['module_name']}_tb; %endfor sim_clock_gen #(CHDR_CLK_PER) rfnoc_chdr_clk_gen (.clk(rfnoc_chdr_clk), .rst()); + sim_clock_gen #(CTRL_CLK_PER) rfnoc_ctrl_clk_gen (.clk(rfnoc_ctrl_clk), .rst()); %for clock in config['clocks']: %if clock['name'] not in ["rfnoc_chdr", "rfnoc_ctrl"]: sim_clock_gen #(${clock['name'].upper()}_CLK_PER) ${clock['name']}_clk_gen (.clk(${clock['name']}_clk), .rst()); %endif %endfor - // ---------------------------------------- - // Instantiate DUT - // ---------------------------------------- + //--------------------------------------------------------------------------- + // Bus Functional Models + //--------------------------------------------------------------------------- - // Connections to DUT as interfaces: - RfnocBackendIf backend (rfnoc_chdr_clk, rfnoc_chdr_clk); // Required backend iface - AxiStreamIf #(32) m_ctrl (rfnoc_chdr_clk); // Required control iface - AxiStreamIf #(32) s_ctrl (rfnoc_chdr_clk); // Required control iface - AxiStreamIf #(CHDR_W) m0_chdr (rfnoc_chdr_clk); // Optional data iface - AxiStreamIf #(CHDR_W) m1_chdr (rfnoc_chdr_clk); // Optional data iface - AxiStreamIf #(CHDR_W) s0_chdr (rfnoc_chdr_clk); // Optional data iface - AxiStreamIf #(CHDR_W) s1_chdr (rfnoc_chdr_clk); // Optional data iface + // Backend Interface + RfnocBackendIf backend (rfnoc_chdr_clk, rfnoc_ctrl_clk); - // Bus functional model for a software block controller - RfnocBlockCtrlBfm #(.CHDR_W(CHDR_W)) blk_ctrl; + // AXIS-Ctrl Interface + AxiStreamIf #(32) m_ctrl (rfnoc_ctrl_clk, 1'b0); + AxiStreamIf #(32) s_ctrl (rfnoc_ctrl_clk, 1'b0); + + // AXIS-CHDR Interfaces + AxiStreamIf #(CHDR_W) m_chdr [NUM_PORTS_I] (rfnoc_chdr_clk, 1'b0); + AxiStreamIf #(CHDR_W) s_chdr [NUM_PORTS_O] (rfnoc_chdr_clk, 1'b0); + + // Block Controller BFM + RfnocBlockCtrlBfm #(.CHDR_W(CHDR_W)) blk_ctrl = new(backend, m_ctrl, s_ctrl); + + // Connect block controller to BFMs + for (genvar i = 0; i < NUM_PORTS_I; i++) begin : gen_bfm_input_connections + initial begin + blk_ctrl.connect_master_data_port(i, m_chdr[i], PKT_SIZE_BYTES); + blk_ctrl.set_master_stall_prob(i, STALL_PROB); + end + end + for (genvar i = 0; i < NUM_PORTS_O; i++) begin : gen_bfm_output_connections + initial begin + blk_ctrl.connect_slave_data_port(i, s_chdr[i]); + blk_ctrl.set_slave_stall_prob(i, STALL_PROB); + end + end + + //--------------------------------------------------------------------------- + // Device Under Test (DUT) + //--------------------------------------------------------------------------- + + // DUT Slave (Input) Port Signals + logic [CHDR_W*NUM_PORTS_I-1:0] s_rfnoc_chdr_tdata; + logic [ NUM_PORTS_I-1:0] s_rfnoc_chdr_tlast; + logic [ NUM_PORTS_I-1:0] s_rfnoc_chdr_tvalid; + logic [ NUM_PORTS_I-1:0] s_rfnoc_chdr_tready; + + // DUT Master (Output) Port Signals + logic [CHDR_W*NUM_PORTS_O-1:0] m_rfnoc_chdr_tdata; + logic [ NUM_PORTS_O-1:0] m_rfnoc_chdr_tlast; + logic [ NUM_PORTS_O-1:0] m_rfnoc_chdr_tvalid; + logic [ NUM_PORTS_O-1:0] m_rfnoc_chdr_tready; + + // Map the array of BFMs to a flat vector for the DUT connections + for (genvar i = 0; i < NUM_PORTS_I; i++) begin : gen_dut_input_connections + // Connect BFM master to DUT slave port + assign s_rfnoc_chdr_tdata[CHDR_W*i+:CHDR_W] = m_chdr[i].tdata; + assign s_rfnoc_chdr_tlast[i] = m_chdr[i].tlast; + assign s_rfnoc_chdr_tvalid[i] = m_chdr[i].tvalid; + assign m_chdr[i].tready = s_rfnoc_chdr_tready[i]; + end + for (genvar i = 0; i < NUM_PORTS_O; i++) begin : gen_dut_output_connections + // Connect BFM slave to DUT master port + assign s_chdr[i].tdata = m_rfnoc_chdr_tdata[CHDR_W*i+:CHDR_W]; + assign s_chdr[i].tlast = m_rfnoc_chdr_tlast[i]; + assign s_chdr[i].tvalid = m_rfnoc_chdr_tvalid[i]; + assign m_rfnoc_chdr_tready[i] = s_chdr[i].tready; + end - // DUT rfnoc_block_${config['module_name']} #( - .THIS_PORTID (THIS_PORTID), - .CHDR_W (CHDR_W), - .MTU (10) + .THIS_PORTID (THIS_PORTID), + .CHDR_W (CHDR_W), + .MTU (MTU) ) dut ( - .rfnoc_chdr_clk (backend.chdr_clk), - .rfnoc_ctrl_clk (backend.ctrl_clk), + .rfnoc_chdr_clk (rfnoc_chdr_clk), + .rfnoc_ctrl_clk (rfnoc_ctrl_clk), %for clock in config['clocks']: %if clock['name'] not in ["rfnoc_chdr", "rfnoc_ctrl"]: - .${clock['name']}_clk(${clock['name']}_clk_gen.clk), - .${clock['name']}_rst(${clock['name']}_clk_gen.rst), + .${'{:<19}'.format(clock['name']+'_clk')} (${clock['name']}_clk), %endif %endfor - .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) + .rfnoc_core_config (backend.cfg), + .rfnoc_core_status (backend.sts), + .s_rfnoc_chdr_tdata (s_rfnoc_chdr_tdata), + .s_rfnoc_chdr_tlast (s_rfnoc_chdr_tlast), + .s_rfnoc_chdr_tvalid (s_rfnoc_chdr_tvalid), + .s_rfnoc_chdr_tready (s_rfnoc_chdr_tready), + .m_rfnoc_chdr_tdata (m_rfnoc_chdr_tdata), + .m_rfnoc_chdr_tlast (m_rfnoc_chdr_tlast), + .m_rfnoc_chdr_tvalid (m_rfnoc_chdr_tvalid), + .m_rfnoc_chdr_tready (m_rfnoc_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) ); - // ---------------------------------------- - // Test Process - // ---------------------------------------- - TestExec test; - initial begin - // Shared Variables - // ---------------------------------------- - timeout_t timeout; - ctrl_word_t rvalue; - rvalue = 0; - - // Initialize - // ---------------------------------------- - test = new("noc_block_${config['module_name']}_tb.v"); - test.start_tb(); + //--------------------------------------------------------------------------- + // Main Test Process + //--------------------------------------------------------------------------- + + initial begin : tb_main + // Initialize the test exec object for this testbench + test.start_tb("rfnoc_block_${config['module_name']}_tb"); + + // Start the BFMs running + blk_ctrl.run(); + + //-------------------------------- + // Reset + //-------------------------------- + + test.start_test("Flush block then reset it", 10us); + blk_ctrl.flush_and_reset(); + test.end_test(); + + //-------------------------------- + // Verify Block Info + //-------------------------------- + + test.start_test("Verify Block Info", 2us); + `ASSERT_ERROR(blk_ctrl.get_noc_id() == NOC_ID, "Incorrect NOC_ID Value"); + `ASSERT_ERROR(blk_ctrl.get_num_data_i() == NUM_PORTS_I, "Incorrect NUM_DATA_I Value"); + `ASSERT_ERROR(blk_ctrl.get_num_data_o() == NUM_PORTS_O, "Incorrect NUM_DATA_O Value"); + `ASSERT_ERROR(blk_ctrl.get_mtu() == MTU, "Incorrect MTU Value"); + test.end_test(); + + //-------------------------------- + // Test Sequences + //-------------------------------- + + // <Add your test code here> + test.start_test("<Name your first test", 10us); + `ASSERT_WARNING(0, "This testbench doesn't test anything yet!"); + test.end_test(); + + //-------------------------------- // Finish Up - // ---------------------------------------- + //-------------------------------- + // Display final statistics and results test.end_tb(); - end + end : tb_main + +endmodule : rfnoc_block_${config['module_name']}_tb + -endmodule +`default_nettype wire |