Hi all,
I am currently working on a RFNoC block that has a ‘passthrough’ port and ‘results’ port that outputs data based on the samples seen in the passthrough stream. I am currently using the AXI-stream payload context interface and I am having trouble deterministically generating packets. My current test block outputs the value of the counter as the payload, but the count seems to be about a quarter of the length of the desired length. For instance, my current test block is supposed to output 1024 samples from 0-1022 with a zero as the last payload element. But I am only getting 0-251. This is not an issue that I am having in my functional simulations of the state machine and so I believe that I may be misunderstanding something critical about the interface. Any suggestions are greatly appreciated. I am using UHD 4.0 with an x310 using Dual 10Gig ethernet. A test version of the block with only the transmit packet logic is attached. Thank you, Rylee Mattingly University of Oklahoma Graduate Research Assistant Email: rmattin...@ou.edu<mailto:rmattin...@ou.edu> Attachment
// // Copyright 2021 Ettus Research, a National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later // // Module: rfnoc_block_stream // // Description: // // <Add block description here> // // 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). // `default_nettype none module rfnoc_block_stream #( parameter [9:0] THIS_PORTID = 10'd0, parameter CHDR_W = 64, parameter [5:0] MTU = 10 )( // RFNoC Framework Clocks and Resets input wire rfnoc_chdr_clk, input wire rfnoc_ctrl_clk, input wire ce_clk, // RFNoC Backend Interface input wire [511:0] rfnoc_core_config, output wire [511:0] rfnoc_core_status, // AXIS-CHDR Input Ports (from framework) input wire [(1)*CHDR_W-1:0] s_rfnoc_chdr_tdata, input wire [(1)-1:0] s_rfnoc_chdr_tlast, input wire [(1)-1:0] s_rfnoc_chdr_tvalid, output wire [(1)-1:0] s_rfnoc_chdr_tready, // AXIS-CHDR Output Ports (to framework) output wire [(2)*CHDR_W-1:0] m_rfnoc_chdr_tdata, output wire [(2)-1:0] m_rfnoc_chdr_tlast, output wire [(2)-1:0] m_rfnoc_chdr_tvalid, input wire [(2)-1:0] m_rfnoc_chdr_tready, // AXIS-Ctrl Input Port (from framework) input wire [31:0] s_rfnoc_ctrl_tdata, input wire s_rfnoc_ctrl_tlast, input wire s_rfnoc_ctrl_tvalid, output wire s_rfnoc_ctrl_tready, // AXIS-Ctrl Output Port (to framework) output wire [31:0] m_rfnoc_ctrl_tdata, output wire m_rfnoc_ctrl_tlast, output wire m_rfnoc_ctrl_tvalid, input wire m_rfnoc_ctrl_tready ); //--------------------------------------------------------------------------- // Signal Declarations //--------------------------------------------------------------------------- // Clocks and Resets wire ctrlport_clk; wire ctrlport_rst; wire axis_data_clk; wire axis_data_rst; // CtrlPort Master wire m_ctrlport_req_wr; wire m_ctrlport_req_rd; wire [19:0] m_ctrlport_req_addr; wire [31:0] m_ctrlport_req_data; reg m_ctrlport_resp_ack; reg [31:0] m_ctrlport_resp_data; // Payload Stream to User Logic: in wire [32*1-1:0] m_in_payload_tdata; wire [1-1:0] m_in_payload_tkeep; wire m_in_payload_tlast; wire m_in_payload_tvalid; wire m_in_payload_tready; // Context Stream to User Logic: in wire [CHDR_W-1:0] m_in_context_tdata; wire [3:0] m_in_context_tuser; wire m_in_context_tlast; wire m_in_context_tvalid; wire m_in_context_tready; // Payload Stream from User Logic: out1 wire [32*1-1:0] s_out1_payload_tdata; wire [0:0] s_out1_payload_tkeep; wire s_out1_payload_tlast; wire s_out1_payload_tvalid; wire s_out1_payload_tready; // Context Stream from User Logic: out1 wire [CHDR_W-1:0] s_out1_context_tdata; wire [3:0] s_out1_context_tuser; wire s_out1_context_tlast; wire s_out1_context_tvalid; wire s_out1_context_tready; // Payload Stream from User Logic: out2 reg [32*1-1:0] s_out2_payload_tdata; reg [0:0] s_out2_payload_tkeep; reg s_out2_payload_tlast; reg s_out2_payload_tvalid; wire s_out2_payload_tready; // Context Stream from User Logic: out2 reg [CHDR_W-1:0] s_out2_context_tdata; reg [3:0] s_out2_context_tuser; reg s_out2_context_tlast; reg s_out2_context_tvalid; wire s_out2_context_tready; //--------------------------------------------------------------------------- // NoC Shell //--------------------------------------------------------------------------- noc_shell_stream #( .CHDR_W (CHDR_W), .THIS_PORTID (THIS_PORTID), .MTU (MTU) ) noc_shell_stream_i ( //--------------------- // Framework Interface //--------------------- // Clock Inputs .rfnoc_chdr_clk (rfnoc_chdr_clk), .rfnoc_ctrl_clk (rfnoc_ctrl_clk), .ce_clk (ce_clk), // Reset Outputs .rfnoc_chdr_rst (), .rfnoc_ctrl_rst (), .ce_rst (), // RFNoC Backend Interface .rfnoc_core_config (rfnoc_core_config), .rfnoc_core_status (rfnoc_core_status), // CHDR Input Ports (from framework) .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), // CHDR Output Ports (to framework) .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), // AXIS-Ctrl Input Port (from framework) .s_rfnoc_ctrl_tdata (s_rfnoc_ctrl_tdata), .s_rfnoc_ctrl_tlast (s_rfnoc_ctrl_tlast), .s_rfnoc_ctrl_tvalid (s_rfnoc_ctrl_tvalid), .s_rfnoc_ctrl_tready (s_rfnoc_ctrl_tready), // AXIS-Ctrl Output Port (to framework) .m_rfnoc_ctrl_tdata (m_rfnoc_ctrl_tdata), .m_rfnoc_ctrl_tlast (m_rfnoc_ctrl_tlast), .m_rfnoc_ctrl_tvalid (m_rfnoc_ctrl_tvalid), .m_rfnoc_ctrl_tready (m_rfnoc_ctrl_tready), //--------------------- // Client Interface //--------------------- // CtrlPort Clock and Reset .ctrlport_clk (ctrlport_clk), .ctrlport_rst (ctrlport_rst), // CtrlPort Master .m_ctrlport_req_wr (m_ctrlport_req_wr), .m_ctrlport_req_rd (m_ctrlport_req_rd), .m_ctrlport_req_addr (m_ctrlport_req_addr), .m_ctrlport_req_data (m_ctrlport_req_data), .m_ctrlport_resp_ack (m_ctrlport_resp_ack), .m_ctrlport_resp_data (m_ctrlport_resp_data), // AXI-Stream Payload Context Clock and Reset .axis_data_clk (axis_data_clk), .axis_data_rst (axis_data_rst), // Payload Stream to User Logic: in .m_in_payload_tdata (m_in_payload_tdata), .m_in_payload_tkeep (m_in_payload_tkeep), .m_in_payload_tlast (m_in_payload_tlast), .m_in_payload_tvalid (m_in_payload_tvalid), .m_in_payload_tready (m_in_payload_tready), // Context Stream to User Logic: in .m_in_context_tdata (m_in_context_tdata), .m_in_context_tuser (m_in_context_tuser), .m_in_context_tlast (m_in_context_tlast), .m_in_context_tvalid (m_in_context_tvalid), .m_in_context_tready (m_in_context_tready), // Payload Stream from User Logic: out1 .s_out1_payload_tdata (s_out1_payload_tdata), .s_out1_payload_tkeep (s_out1_payload_tkeep), .s_out1_payload_tlast (s_out1_payload_tlast), .s_out1_payload_tvalid (s_out1_payload_tvalid), .s_out1_payload_tready (s_out1_payload_tready), // Context Stream from User Logic: out1 .s_out1_context_tdata (s_out1_context_tdata), .s_out1_context_tuser (s_out1_context_tuser), .s_out1_context_tlast (s_out1_context_tlast), .s_out1_context_tvalid (s_out1_context_tvalid), .s_out1_context_tready (s_out1_context_tready), // Payload Stream from User Logic: out2 .s_out2_payload_tdata (s_out2_payload_tdata), .s_out2_payload_tkeep (s_out2_payload_tkeep), .s_out2_payload_tlast (s_out2_payload_tlast), .s_out2_payload_tvalid (s_out2_payload_tvalid), .s_out2_payload_tready (s_out2_payload_tready), // Context Stream from User Logic: out2 .s_out2_context_tdata (s_out2_context_tdata), .s_out2_context_tuser (s_out2_context_tuser), .s_out2_context_tlast (s_out2_context_tlast), .s_out2_context_tvalid (s_out2_context_tvalid), .s_out2_context_tready (s_out2_context_tready) ); //--------------------------------------------------------------------------- // Register Logic //--------------------------------------------------------------------------- // Note: Register addresses increment by 4 localparam REG_USER_ADDR = 0; // Address for example user register localparam REG_USER_DEFAULT = 0; // This should be set to -80 dB down from 1. reg [31:0] reg_user = REG_USER_DEFAULT; always @(posedge ctrlport_clk) begin if (ctrlport_rst) begin reg_user = REG_USER_DEFAULT; end else begin // Default assignment m_ctrlport_resp_ack <= 0; // Read user register if (m_ctrlport_req_rd) begin // Read request case (m_ctrlport_req_addr) REG_USER_ADDR: begin m_ctrlport_resp_ack <= 1; m_ctrlport_resp_data <= reg_user; end endcase end // Write user register if (m_ctrlport_req_wr) begin // Write requst case (m_ctrlport_req_addr) REG_USER_ADDR: begin m_ctrlport_resp_ack <= 1; reg_user <= m_ctrlport_req_data[31:0]; end endcase end end end //--------------------------------------------------------------------------- // User Logic //--------------------------------------------------------------------------- // Setup context passthrough for out1 assign s_out1_context_tdata = m_in_context_tdata; assign s_out1_context_tuser = m_in_context_tuser; assign s_out1_context_tlast = m_in_context_tlast; assign s_out1_context_tvalid = m_in_context_tvalid; // Setup payload passthrough for out1 assign s_out1_payload_tdata = m_in_payload_tdata; assign s_out1_payload_tlast = m_in_payload_tlast; assign s_out1_payload_tvalid = m_in_payload_tvalid; parameter SendHeader = 3'b000; parameter SendTimestamp = 3'b001; parameter SendPayload = 3'b010; parameter SendLast = 3'b011; parameter Clean = 3'b100; reg [31:0] counter = 32'd0; reg [63:0] inputHeader = 64'd0; reg [2:0] state = SendHeader; reg [15:0] seq = 16'd0; always @ (posedge axis_data_clk) begin if(m_in_context_tuser == 4'b0) begin inputHeader <= m_in_context_tdata; end if(axis_data_rst) begin seq <= 16'd0; counter <= 32'd0; state <= SendHeader; end case (state) SendHeader: begin if(s_out2_context_tready) begin // Context Signals s_out2_context_tuser <= 4'd0; s_out2_context_tvalid <= 1'b1; s_out2_context_tlast <= 0; s_out2_context_tdata <= {inputHeader[63:48], seq, 16'd1026, inputHeader[15:0]}; // Payload Signals s_out2_payload_tdata <= 32'd0; s_out2_payload_tvalid <= 0; s_out2_payload_tlast <= 0; // Increment Sequence and Change state seq <= seq + 16'd1; state <= SendTimestamp; end end SendTimestamp: begin if(s_out2_context_tready) begin // Context Signals s_out2_context_tuser <= 4'd2; s_out2_context_tvalid <= 1'b1; s_out2_context_tlast <= 1'b1; s_out2_context_tdata <= 64'd0; // Payload Signals s_out2_payload_tdata <= 32'd0; s_out2_payload_tvalid <= 1'b0; s_out2_payload_tlast <= 1'b0; // Change state state <= SendPayload; end end SendPayload: begin if(s_out2_payload_tready) begin // Context Signals s_out2_context_tuser <= 4'd0; s_out2_context_tvalid <= 1'b0; s_out2_context_tlast <= 1'b0; s_out2_context_tdata <= 64'd0; // Payload Signals s_out2_payload_tdata <= {16'b0, counter}; s_out2_payload_tvalid <= 1'b1; s_out2_payload_tlast <= 1'b0; counter <= counter + 32'd1; if (counter == 32'd1022) begin // Change State state <= SendLast; end end end SendLast: begin if(s_out2_payload_tready) begin // Context Signals s_out2_context_tuser <= 4'd0; s_out2_context_tvalid <= 1'b0; s_out2_context_tlast <= 1'b0; s_out2_context_tdata <= 64'd0; // Payload Signals s_out2_payload_tdata <= 32'd0; s_out2_payload_tvalid <= 1'b1; s_out2_payload_tlast <= 1'b1; // Change the state state <= SendHeader; counter <= 32'd0; end end Clean: begin // Context Signals s_out2_context_tuser <= 4'd0; s_out2_context_tvalid <= 1'b0; s_out2_context_tlast <= 1'b0; s_out2_context_tdata <= 64'd0; // Context Signals s_out2_payload_tvalid <= 1'b0; s_out2_payload_tlast <= 1'b0; s_out2_payload_tdata <= 32'd0; // Change State state <= SendHeader; counter <= 32'd0; end endcase end // Wire the tready signals together assign m_in_context_tready = s_out1_context_tready; assign m_in_payload_tready = s_out1_payload_tready; endmodule // rfnoc_block_stream `default_nettype wire
_______________________________________________ USRP-users mailing list -- usrp-users@lists.ettus.com To unsubscribe send an email to usrp-users-le...@lists.ettus.com