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 >> >
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