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

Reply via email to