This is great, thank you so much!  But for gain example according
to original RFNOC block, I added ce clock to my module...bitstream is
generated successfully. but in Gnuradio block does not work correctly...
 Error in Gnuradio:
gr::log :DEBUG: rfnoc_rx_streamer0 - Committing graph...
gr::log :DEBUG: rfnoc_rx_streamer0 - Sending start stream command...
[WARNING] [0/Radio#0] Attempting to set tick rate to 0. Skipping.
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO

I attached rfnoc_block_gain.v file and noc_shell_gain.v and  gain.yml. Can
you examine which snippet of my code has a bug or the wrong in ce clock?
Can you share a gain example that work correctly in Gnuradio and UHD
4.1.0.5.

thanks in advance


On Sat, May 21, 2022 at 11:04 PM Jeffrey Cuenco <jcue...@ucsd.edu> wrote:

> Hello,
>
> I am also currently developing with UHD v4.1.0.5 and the default verilog
> template code generated by *rfnoc_mod_tool *does not automatically
> include ce_clk.
>
> If you would like to use ce_clk you can use the *rfnoc_create_verilog* tool
> to regenerate and customize the verilog code from the template with
> parameters you specify in your block .YML file.
>
> Example:
>
> python3
> $PATH_TO_UHD_DIR/host/utils/rfnoc_blocktool/rfnoc_create_verilog.py -c
> $PATH_TO_BLOCK_YML/yourblock.yml -d $DESIRED_PATH/rfnoc_block_yourblock
>
> If you are more interested in as to what the various clocks are intended
> to be used for, the general explanation is that certain parts of RFNoC are
> designed to operate at the primary bus clock of the USRP, yet one's logic
> may need to operate at a different clock, especially if it was designed to
> operate at a specific frequency... so the customizability is built into
> RFNoC.
>
> The following RFNoC 4 Workshop video may help provide more of a deep-dive:
> https://www.youtube.com/watch?v=M9ntwQie9vs
>
> There are also a few other slide materials (some from RFNoC 3 but are
> still useful). Recommend going into the RFNoC 4 Migration Guide as it
> discusses the differences if you have prior experience working with RFNoC 3
>
> Slides: Part 1: Overview of RFNoC 4 -
> https://kb.ettus.com/images/5/5b/rfno...
> <https://www.youtube.com/redirect?event=video_description&redir_token=QUFFLUhqbkZQeUJnei1iS1hkYTcyTnUwclVOOFZKMEJtZ3xBQ3Jtc0tuNnk0dlZHdjYxUXkxZzFPd2I1dnBmM2NobFRkbG9hckd0VU0yaGc2MzREeWhzNE10c25GVUxSaE9Rc0FGb2Q4em1waUphOWZxbkZ5TGh6NHpqVjRYODRqcW5fU3ZmVzVIaWtGZ1lPUlZaaTdNTmxERQ&q=https%3A%2F%2Fkb.ettus.com%2Fimages%2F5%2F5b%2Frfnoc4_workshop_slides_2020_part_1.pdf&v=M9ntwQie9vs>
> Part 2: Deep dive into RFNoC 4 - https://kb.ettus.com/images/e/e9/rfno...
> <https://www.youtube.com/redirect?event=video_description&redir_token=QUFFLUhqbmJabXRUbGJhVHNzak4wVGhNeXVXc2h4RUpkQXxBQ3Jtc0tsNlJJNGJjY0VRSWJqLTNhenZoWUhoODZ1cGJYNEVyTFRPNjl5UURxVmRuYmVmQTktMnlrWmJzMksxS1Y5b0xxd2lTaFdoTUhyYWdQM1FHMHk4bkpRQ2ZXS3R3QTI0TXJNM0hwX3h2SU5LUnJZdHM0SQ&q=https%3A%2F%2Fkb.ettus.com%2Fimages%2Fe%2Fe9%2Frfnoc4_workshop_slides_2020_part_2.pdf&v=M9ntwQie9vs>
> Useful Knowledge Base Application Notes: Getting Started with RFNoC in UHD
> 4.0 - https://kb.ettus.com/Getting_Started_...
> <https://www.youtube.com/redirect?event=video_description&redir_token=QUFFLUhqa2d3MFBKZzJCUW5VRFd2cFlIalR6MGtCLTZmUXxBQ3Jtc0trY0pKOWNCamw5dmd2N2NMbFl5MHFXb2JVUEdWLVZNSWk2TkZRTy03X0FuRFo5aVdSdGtialVrLTN1T0lUSGNYTy1OaGRWOUh3T0NhdWV2dTF0LVljNkxlUFBvY0pqZ2RHLTkxUmIwZEdfcmczYjY3TQ&q=https%3A%2F%2Fkb.ettus.com%2FGetting_Started_with_RFNoC_in_UHD_4.0&v=M9ntwQie9vs>
> RFNoC 4 Migration Guide - https://kb.ettus.com/RFNoC_4_Migratio...
> <https://www.youtube.com/redirect?event=video_description&redir_token=QUFFLUhqbkhKQ09JV3gyQXplRGo2X29ibXR1bXFHUENUUXxBQ3Jtc0ttZV9ma1VZU2RDNWhpNEUxM0FDSWxiQTZwS0V2RHpMalRkWnZ6VVAtUUZXOWk1T0REWE5WMDVwcXM5QlNFRGhLSkNGY3dlRkxYZ1NzTHVDSWZJTFhlUE83dG9KbzdiWUsyMXlFUmVrMXVQUTNzOUsyOA&q=https%3A%2F%2Fkb.ettus.com%2FRFNoC_4_Migration_Guide&v=M9ntwQie9vs>
> Other useful videos: Exploring RFNoC 4 with the UHD Python API -
> https://youtu.be/fbcxm7f-Tj0
> <https://www.youtube.com/watch?v=fbcxm7f-Tj0&t=0s> RFNoC 3 workshop video
> - https://youtu.be/VbODcrmpLaU
> <https://www.youtube.com/watch?v=VbODcrmpLaU&t=0s>
>
> Hope this helps,
> -Jeff
>
> On Sat, May 21, 2022 at 2:33 AM sp h <stackprogra...@gmail.com> wrote:
>
>> when I examine RFNOC block that is in the below path, I am faced with a
>> wire ce_clk and ce_rst, but in rfnoc-example there is not a ce_clk.
>>
>> uhd-4.1.0.5/fpga/usrp3/lib/rfnoc/blocks
>>
>> Can anyone guide me ce clocks?  why instead using rfnoc_chdr clk,
>> original blocks uses ce clock?
>>
>>
>> _______________________________________________
>> USRP-users mailing list -- usrp-users@lists.ettus.com
>> To unsubscribe send an email to usrp-users-le...@lists.ettus.com
>>
>

Attachment: gain.yml
Description: application/yaml

//
// Module: noc_shell_gain
//
// Description:
//
//   This is a tool-generated NoC-shell for the gain block.
//   See the RFNoC specification for more information about NoC shells.
//
// 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
//

`default_nettype none


module noc_shell_gain #(
  parameter [9:0] THIS_PORTID     = 10'd0,
  parameter       CHDR_W          = 64,
  parameter [5:0] MTU             = 10
) (
  //---------------------
  // Framework Interface
  //---------------------

  // RFNoC Framework Clocks
  input  wire rfnoc_chdr_clk,
  input  wire rfnoc_ctrl_clk,
  input  wire ce_clk,


  // NoC Shell Generated Resets
  output wire rfnoc_chdr_rst,
  output wire rfnoc_ctrl_rst,
  output wire ce_rst,


  // 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 [(1)*CHDR_W-1:0] m_rfnoc_chdr_tdata,
  output wire [(1)-1:0]        m_rfnoc_chdr_tlast,
  output wire [(1)-1:0]        m_rfnoc_chdr_tvalid,
  input  wire [(1)-1:0]        m_rfnoc_chdr_tready,

  // AXIS-Ctrl Control 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 Control 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,

  //---------------------
  // Client Interface
  //---------------------

  // CtrlPort Clock and Reset
  output wire               ctrlport_clk,
  output wire               ctrlport_rst,
  // CtrlPort Master
  output wire               m_ctrlport_req_wr,
  output wire               m_ctrlport_req_rd,
  output wire [19:0]        m_ctrlport_req_addr,
  output wire [31:0]        m_ctrlport_req_data,
  input  wire               m_ctrlport_resp_ack,
  input  wire [31:0]        m_ctrlport_resp_data,

  // AXI-Stream Payload Context Clock and Reset
  output wire               axis_data_clk,
  output wire               axis_data_rst,
  // Payload Stream to User Logic: in
  output wire [32*1-1:0]    m_in_payload_tdata,
  output wire [1-1:0]       m_in_payload_tkeep,
  output wire               m_in_payload_tlast,
  output wire               m_in_payload_tvalid,
  input  wire               m_in_payload_tready,
  // Context Stream to User Logic: in
  output wire [CHDR_W-1:0]  m_in_context_tdata,
  output wire [3:0]         m_in_context_tuser,
  output wire               m_in_context_tlast,
  output wire               m_in_context_tvalid,
  input  wire               m_in_context_tready,
  // Payload Stream from User Logic: out
  input  wire [32*1-1:0]    s_out_payload_tdata,
  input  wire [0:0]         s_out_payload_tkeep,
  input  wire               s_out_payload_tlast,
  input  wire               s_out_payload_tvalid,
  output wire               s_out_payload_tready,
  // Context Stream from User Logic: out
  input  wire [CHDR_W-1:0]  s_out_context_tdata,
  input  wire [3:0]         s_out_context_tuser,
  input  wire               s_out_context_tlast,
  input  wire               s_out_context_tvalid,
  output wire               s_out_context_tready
);

  //---------------------------------------------------------------------------
  //  Backend Interface
  //---------------------------------------------------------------------------

  wire         data_i_flush_en;
  wire [31:0]  data_i_flush_timeout;
  wire [63:0]  data_i_flush_active;
  wire [63:0]  data_i_flush_done;
  wire         data_o_flush_en;
  wire [31:0]  data_o_flush_timeout;
  wire [63:0]  data_o_flush_active;
  wire [63:0]  data_o_flush_done;

  backend_iface #(
    .NOC_ID        (32'h45069D40),
    .NUM_DATA_I    (1),
    .NUM_DATA_O    (1),
    .CTRL_FIFOSIZE ($clog2(32)),
    .MTU           (MTU)
  ) backend_iface_i (
    .rfnoc_chdr_clk       (rfnoc_chdr_clk),
    .rfnoc_chdr_rst       (rfnoc_chdr_rst),
    .rfnoc_ctrl_clk       (rfnoc_ctrl_clk),
    .rfnoc_ctrl_rst       (rfnoc_ctrl_rst),
    .rfnoc_core_config    (rfnoc_core_config),
    .rfnoc_core_status    (rfnoc_core_status),
    .data_i_flush_en      (data_i_flush_en),
    .data_i_flush_timeout (data_i_flush_timeout),
    .data_i_flush_active  (data_i_flush_active),
    .data_i_flush_done    (data_i_flush_done),
    .data_o_flush_en      (data_o_flush_en),
    .data_o_flush_timeout (data_o_flush_timeout),
    .data_o_flush_active  (data_o_flush_active),
    .data_o_flush_done    (data_o_flush_done)
  );
  //---------------------------------------------------------------------------
  //  Reset Generation
  //---------------------------------------------------------------------------

  wire ce_rst_pulse;

  pulse_synchronizer #(.MODE ("POSEDGE")) pulse_synchronizer_ce (
    .clk_a(rfnoc_chdr_clk), .rst_a(1'b0), .pulse_a (rfnoc_chdr_rst), .busy_a (),
    .clk_b(ce_clk), .pulse_b (ce_rst_pulse)
  );

  pulse_stretch_min #(.LENGTH(32)) pulse_stretch_min_ce (
    .clk(ce_clk), .rst(1'b0),
    .pulse_in(ce_rst_pulse), .pulse_out(ce_rst)
  );

  //---------------------------------------------------------------------------
  //  Control Path
  //---------------------------------------------------------------------------

  assign ctrlport_clk = ce_clk;
  assign ctrlport_rst = ce_rst;

  ctrlport_endpoint #(
    .THIS_PORTID      (THIS_PORTID),
    .SYNC_CLKS        (0),
    .AXIS_CTRL_MST_EN (0),
    .AXIS_CTRL_SLV_EN (1),
    .SLAVE_FIFO_SIZE  ($clog2(32))
  ) ctrlport_endpoint_i (
    .rfnoc_ctrl_clk            (rfnoc_ctrl_clk),
    .rfnoc_ctrl_rst            (rfnoc_ctrl_rst),
    .ctrlport_clk              (ctrlport_clk),
    .ctrlport_rst              (ctrlport_rst),
    .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),
    .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),
    .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_req_byte_en    (),
    .m_ctrlport_req_has_time   (),
    .m_ctrlport_req_time       (),
    .m_ctrlport_resp_ack       (m_ctrlport_resp_ack),
    .m_ctrlport_resp_status    (2'b0),
    .m_ctrlport_resp_data      (m_ctrlport_resp_data),
    .s_ctrlport_req_wr         (1'b0),
    .s_ctrlport_req_rd         (1'b0),
    .s_ctrlport_req_addr       (20'b0),
    .s_ctrlport_req_portid     (10'b0),
    .s_ctrlport_req_rem_epid   (16'b0),
    .s_ctrlport_req_rem_portid (10'b0),
    .s_ctrlport_req_data       (32'b0),
    .s_ctrlport_req_byte_en    (4'hF),
    .s_ctrlport_req_has_time   (1'b0),
    .s_ctrlport_req_time       (64'b0),
    .s_ctrlport_resp_ack       (),
    .s_ctrlport_resp_status    (),
    .s_ctrlport_resp_data      ()
  );

  //---------------------------------------------------------------------------
  //  Data Path
  //---------------------------------------------------------------------------

  genvar i;

  assign axis_data_clk = ce_clk;
  assign axis_data_rst = ce_rst;

  //---------------------
  // Input Data Paths
  //---------------------

  chdr_to_axis_pyld_ctxt #(
    .CHDR_W              (CHDR_W),
    .ITEM_W              (32),
    .NIPC                (1),
    .SYNC_CLKS           (1),
    .CONTEXT_FIFO_SIZE   ($clog2(2)),
    .PAYLOAD_FIFO_SIZE   ($clog2(2)),
    .CONTEXT_PREFETCH_EN (1)
  ) chdr_to_axis_pyld_ctxt_in_in (
    .axis_chdr_clk         (rfnoc_chdr_clk),
    .axis_chdr_rst         (rfnoc_chdr_rst),
    .axis_data_clk         (axis_data_clk),
    .axis_data_rst         (axis_data_rst),
    .s_axis_chdr_tdata     (s_rfnoc_chdr_tdata[(0)*CHDR_W+:CHDR_W]),
    .s_axis_chdr_tlast     (s_rfnoc_chdr_tlast[0]),
    .s_axis_chdr_tvalid    (s_rfnoc_chdr_tvalid[0]),
    .s_axis_chdr_tready    (s_rfnoc_chdr_tready[0]),
    .m_axis_payload_tdata  (m_in_payload_tdata),
    .m_axis_payload_tkeep  (m_in_payload_tkeep),
    .m_axis_payload_tlast  (m_in_payload_tlast),
    .m_axis_payload_tvalid (m_in_payload_tvalid),
    .m_axis_payload_tready (m_in_payload_tready),
    .m_axis_context_tdata  (m_in_context_tdata),
    .m_axis_context_tuser  (m_in_context_tuser),
    .m_axis_context_tlast  (m_in_context_tlast),
    .m_axis_context_tvalid (m_in_context_tvalid),
    .m_axis_context_tready (m_in_context_tready),
    .flush_en              (data_i_flush_en),
    .flush_timeout         (data_i_flush_timeout),
    .flush_active          (data_i_flush_active[0]),
    .flush_done            (data_i_flush_done[0])
  );

  //---------------------
  // Output Data Paths
  //---------------------

  axis_pyld_ctxt_to_chdr #(
    .CHDR_W              (CHDR_W),
    .ITEM_W              (32),
    .NIPC                (1),
    .SYNC_CLKS           (1),
    .CONTEXT_FIFO_SIZE   ($clog2(2)),
    .PAYLOAD_FIFO_SIZE   ($clog2(2)),
    .MTU                 (MTU),
    .CONTEXT_PREFETCH_EN (1)
  ) axis_pyld_ctxt_to_chdr_out_out (
    .axis_chdr_clk         (rfnoc_chdr_clk),
    .axis_chdr_rst         (rfnoc_chdr_rst),
    .axis_data_clk         (axis_data_clk),
    .axis_data_rst         (axis_data_rst),
    .m_axis_chdr_tdata     (m_rfnoc_chdr_tdata[(0)*CHDR_W+:CHDR_W]),
    .m_axis_chdr_tlast     (m_rfnoc_chdr_tlast[0]),
    .m_axis_chdr_tvalid    (m_rfnoc_chdr_tvalid[0]),
    .m_axis_chdr_tready    (m_rfnoc_chdr_tready[0]),
    .s_axis_payload_tdata  (s_out_payload_tdata),
    .s_axis_payload_tkeep  (s_out_payload_tkeep),
    .s_axis_payload_tlast  (s_out_payload_tlast),
    .s_axis_payload_tvalid (s_out_payload_tvalid),
    .s_axis_payload_tready (s_out_payload_tready),
    .s_axis_context_tdata  (s_out_context_tdata),
    .s_axis_context_tuser  (s_out_context_tuser),
    .s_axis_context_tlast  (s_out_context_tlast),
    .s_axis_context_tvalid (s_out_context_tvalid),
    .s_axis_context_tready (s_out_context_tready),
    .framer_errors         (),
    .flush_en              (data_o_flush_en),
    .flush_timeout         (data_o_flush_timeout),
    .flush_active          (data_o_flush_active[0]),
    .flush_done            (data_o_flush_done[0])
  );

endmodule // noc_shell_gain


`default_nettype wire

//
// Copyright 2021 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: rfnoc_block_gain
//
// Description:
//
//   This is an example RFNoC block. It applies a numeric gain to incoming
//   samples then outputs the result. A single register is used to control the
//   gain setting.
//
// 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).
//   IP_OPTION   : Select which IP to use for the complex multiply. Use one of
//                 the following options:
//                 HDL_IP         = In-tree RFNoC HDL, with a DSP48E1 primitive
//                 IN_TREE_IP     = In-tree "complex_multiplier" (Xilinx IP)
//                 OUT_OF_TREE_IP = Out-of-tree "cmplx_mul" (Xilinx IP)
//

`default_nettype none

module rfnoc_block_gain #(
  parameter [9:0] THIS_PORTID     = 10'd0,
  parameter       CHDR_W          = 64,
  parameter [5:0] MTU             = 10,
  parameter       IP_OPTION       = "HDL_IP"
) (
  // RFNoC Framework Clocks and Resets
  input  wire                   rfnoc_chdr_clk,
  input  wire                   rfnoc_ctrl_clk,
  input  wire                   ce_clk,
 // input  wire                   ce_rst,


  // 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 [(1)*CHDR_W-1:0] m_rfnoc_chdr_tdata,
  output wire [(1)-1:0]        m_rfnoc_chdr_tlast,
  output wire [(1)-1:0]        m_rfnoc_chdr_tvalid,
  input  wire [(1)-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
);

  // These are examples of how to include an in-tree header file. UHD_FPGA_DIR
  // is defined automatically and can be referenced as needed. Tools vary
  // somewhat in how they support using macros in `include statements.
  //
  // This works in Vivado:
  //
  //   `include `"`UHD_FPGA_DIR/usrp3/lib/rfnoc/core/rfnoc_chdr_utils.vh`"
  //
  // Some tools allow this:
  //
  //   `define INCLUDE_UHD_FILE(REL_PATH) `"`UHD_FPGA_DIR/REL_PATH`"
  //   `include `INCLUDE_UHD_FILE(usrp3/lib/rfnoc/core/rfnoc_chdr_utils.vh)
  //
  // This should work in most tools:
  `define RFNOC_CHDR_UTILS_PATH `"`UHD_FPGA_DIR/usrp3/lib/rfnoc/core/rfnoc_chdr_utils.vh`"
  `include `RFNOC_CHDR_UTILS_PATH


  //---------------------------------------------------------------------------
  // Signal Declarations
  //---------------------------------------------------------------------------

  // Clocks and Resets
  wire               ctrlport_clk;
  wire               ctrlport_rst;
  wire               axis_data_clk;
  wire               axis_data_rst;
  //Add custom clocks
  //wire               rfnoc_chdr_clk;
  //wire               rfnoc_chdr_rst;
  //wire               ce_clk;
  //wire               ce_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: out
  wire [32*1-1:0]    s_out_payload_tdata;
  wire [0:0]         s_out_payload_tkeep;
  wire               s_out_payload_tlast;
  wire               s_out_payload_tvalid;
  wire               s_out_payload_tready;
  // Context Stream from User Logic: out
  wire [CHDR_W-1:0]  s_out_context_tdata;
  wire [3:0]         s_out_context_tuser;
  wire               s_out_context_tlast;
  wire               s_out_context_tvalid;
  wire               s_out_context_tready;

  //---------------------------------------------------------------------------
  // NoC Shell
  //---------------------------------------------------------------------------
   wire ce_rst;
  noc_shell_gain #(
    .CHDR_W      (CHDR_W),
    .THIS_PORTID (THIS_PORTID),
    .MTU         (MTU)
  ) noc_shell_gain_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                  (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: out
    .s_out_payload_tdata  (s_out_payload_tdata),
    .s_out_payload_tkeep  (s_out_payload_tkeep),
    .s_out_payload_tlast  (s_out_payload_tlast),
    .s_out_payload_tvalid (s_out_payload_tvalid),
    .s_out_payload_tready (s_out_payload_tready),
    // Context Stream from User Logic: out
    .s_out_context_tdata  (s_out_context_tdata),
    .s_out_context_tuser  (s_out_context_tuser),
    .s_out_context_tlast  (s_out_context_tlast),
    .s_out_context_tvalid (s_out_context_tvalid),
    .s_out_context_tready (s_out_context_tready)
  );

  //---------------------------------------------------------------------------
  // User Logic
  //---------------------------------------------------------------------------
  //
  // The code above this point is essentially unmodified from what was
  // generated by the tool. The code below implements the gain example.
  //
  // All registers are in the ctrlport_clk domain and the signal processing is
  // in the axis_data_clk domain. However, we specified in the block YAML
  // configuration file that we want both the control and data interfaces on
  // the rfnoc_chdr clock. So we don't need to worry about crossing the
  // register data from ctrlport_clk and axis_data_clk.
  //
  //---------------------------------------------------------------------------

  //---------------------------------------------------------------------------
  // Registers
  //---------------------------------------------------------------------------
  //
  // There's only one register now, but we'll structure the register code to
  // make it easier to add more registers later.
  //
  //---------------------------------------------------------------------------

  localparam REG_GAIN_ADDR    = 0;    // Address for gain value
  localparam REG_GAIN_DEFAULT = 1;    // Default gain value

  reg [15:0] reg_gain = REG_GAIN_DEFAULT;

  always @(posedge ce_clk) begin
    //$display("clockport ctrl posedge");
    if (ce_rst) begin
      reg_gain = REG_GAIN_DEFAULT;
    end else begin
      // Default assignment
      m_ctrlport_resp_ack <= 0;

      // Handle read requests
      if (m_ctrlport_req_rd) begin
        case (m_ctrlport_req_addr)
          REG_GAIN_ADDR: begin
            m_ctrlport_resp_ack  <= 1;
            m_ctrlport_resp_data <= { 16'b0, reg_gain };
          end
        endcase
      end

      // Handle write requests
      if (m_ctrlport_req_wr) begin
        case (m_ctrlport_req_addr)
          REG_GAIN_ADDR: begin
            m_ctrlport_resp_ack <= 1;
            reg_gain            <= m_ctrlport_req_data[15:0];
          end
        endcase
      end
    end
  end

  //---------------------------------------------------------------------------
  // Signal Processing
  //---------------------------------------------------------------------------
  //
  // Multiply each complex sample by a real-valued gain. The RFNoC signals
  // m_in_payload_* and m_out_payload_* expect the data with the real/I
  // component on the upper bits [31:16] and the imaginary/Q component on the
  // lower bits [15:0].
  //
  // We only input the real-valued gain (reg_gain) when we have payload data to
  // go in (m_in_payload_*). That way the current gain value always applies to
  // the current sample. This assumes that the tready of both inputs have
  // identical behavior.
  //
  //---------------------------------------------------------------------------
  //assign ce_clk = rfnoc_chdr_clk;
  //assign ce_rst = rfnoc_chdr_rst;

  // Multiply result. I/real in [63:32], Q/imaginary in [31:0] (sc32).
  wire [63:0] o_tdata;
  wire        o_tlast;
  wire        o_tvalid;
  wire        o_tready;   

   if (IP_OPTION == "HDL_IP") begin : gen_rfnoc_ip
      // Use the RFNoC mult_rc Verilog module, which uses a DSP48E1 primitive
      mult_rc #(
        .WIDTH_REAL (16),
        .WIDTH_CPLX (16),
        .WIDTH_P    (32),
        .DROP_TOP_P (5),     // Must be 5 for a normal multiply in DSP48E1
        .LATENCY    (4)      // Turn on all pipeline registers in the DSP48E1
      ) mult_rc_i (
        .clk         (ce_clk),
        .reset       (ce_rst),
        .real_tdata  (reg_gain),
        .real_tlast  (m_in_payload_tlast),
        .real_tvalid (m_in_payload_tvalid),
        .real_tready (),
        .cplx_tdata  (m_in_payload_tdata),
        .cplx_tlast  (m_in_payload_tlast),
        .cplx_tvalid (m_in_payload_tvalid),
        .cplx_tready (m_in_payload_tready),
        .p_tdata     (o_tdata),
        .p_tlast     (o_tlast),
        .p_tvalid    (o_tvalid),
        .p_tready    (o_tready)
      );
 
   end
  


  // Clip the results
  axi_clip_complex #(
    .WIDTH_IN  (32),
    .WIDTH_OUT (16)
  ) axi_clip_complex_i (
    .clk      (ce_clk),
    .reset    (ce_rst),
    .i_tdata  (o_tdata),
    .i_tlast  (o_tlast),
    .i_tvalid (o_tvalid),
    .i_tready (o_tready),
    .o_tdata  (s_out_payload_tdata),
    .o_tlast  (s_out_payload_tlast),
    .o_tvalid (s_out_payload_tvalid),
    .o_tready (s_out_payload_tready)
  );

  // Only 1-sample per clock, so tkeep should always be asserted
  assign s_out_payload_tkeep = 1'b1;

  // We're not doing anything fancy with the context (the CHDR header info) so
  // we can simply pass the input context through unchanged.
  assign s_out_context_tdata  = m_in_context_tdata;
  assign s_out_context_tuser  = m_in_context_tuser;
  assign s_out_context_tlast  = m_in_context_tlast;
  assign s_out_context_tvalid = m_in_context_tvalid;
  assign m_in_context_tready  = s_out_context_tready;

endmodule // rfnoc_block_gain




`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