aboutsummaryrefslogtreecommitdiffstats
path: root/host/examples/rfnoc-example
diff options
context:
space:
mode:
authorWade Fife <wade.fife@ettus.com>2021-10-27 10:56:45 -0500
committerWade Fife <wade.fife@ettus.com>2021-11-04 15:50:54 -0500
commita99fec3973488e27eec1a06cb48a0725219b8c1b (patch)
tree0f3c6e82ac17ea7522deff8c3cdec58764757f77 /host/examples/rfnoc-example
parent2a3cd5d9a4528a11e25935ae0dc397ce1530868e (diff)
downloaduhd-a99fec3973488e27eec1a06cb48a0725219b8c1b.tar.gz
uhd-a99fec3973488e27eec1a06cb48a0725219b8c1b.tar.bz2
uhd-a99fec3973488e27eec1a06cb48a0725219b8c1b.zip
examples: Make IQ order clear in gain RFNoC block
Diffstat (limited to 'host/examples/rfnoc-example')
-rw-r--r--host/examples/rfnoc-example/fpga/rfnoc_block_gain/rfnoc_block_gain.v41
1 files changed, 25 insertions, 16 deletions
diff --git a/host/examples/rfnoc-example/fpga/rfnoc_block_gain/rfnoc_block_gain.v b/host/examples/rfnoc-example/fpga/rfnoc_block_gain/rfnoc_block_gain.v
index c6f0bcfbb..b8d24c5ef 100644
--- a/host/examples/rfnoc-example/fpga/rfnoc_block_gain/rfnoc_block_gain.v
+++ b/host/examples/rfnoc-example/fpga/rfnoc_block_gain/rfnoc_block_gain.v
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Ettus Research, A National Instruments Brand
+// Copyright 2021 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
@@ -32,7 +32,7 @@ module rfnoc_block_gain #(
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,
@@ -234,7 +234,7 @@ module rfnoc_block_gain #(
localparam REG_GAIN_DEFAULT = 1; // Default gain value
reg [15:0] reg_gain = REG_GAIN_DEFAULT;
-
+
always @(posedge ctrlport_clk) begin
if (ctrlport_rst) begin
reg_gain = REG_GAIN_DEFAULT;
@@ -267,20 +267,25 @@ module rfnoc_block_gain #(
//---------------------------------------------------------------------------
// 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.
+ //
+ //---------------------------------------------------------------------------
- wire [63:0] mult_tdata; // Multiply results in 32-bit I and 32-bit Q (sc32)
+ // Multiply result. I/real in [63:32], Q/imaginary in [31:0] (sc32).
+ wire [63:0] mult_tdata;
wire mult_tlast;
wire mult_tvalid;
wire mult_tready;
- // Multiply each complex sample by a real-valued gain. Only input the gain
- // when we have payload data to go in (m_in_payload_tdata). That way the
- // current gain value always applies to the current sample. This assumes that
- // the tready of both inputs have identical behavior.
- //
- // Note that we receive the data with I on bits [31:16] and Q on bits [15:0],
- // but the I/Q order does not matter to our complex multiplier.
-
generate
// Use a generate statement to choose which IP to use for the multiply.
// These all do the same thing and we only have multiple options to show
@@ -344,6 +349,9 @@ module rfnoc_block_gain #(
// Use the out-of-tree "cmplx_mul" IP, which is a Xilinx Complex
// Multiplier LogiCORE IP located in the IP directory of this example.
+ // This IP expects real/I in the lower bits and imaginary/Q in the upper
+ // bits, so we swap I and Q on the input and output to match RFNoC.
+ //
// This IP has a 33-bit output, but because it's AXI-Stream, each
// component is placed in a 5-byte word. Since our gain is real only,
// we'll never need all 33-bits.
@@ -352,11 +360,12 @@ module rfnoc_block_gain #(
cmplx_mul cmplx_mul_i (
.aclk (axis_data_clk),
.aresetn (~axis_data_rst),
- .s_axis_a_tdata ({16'd0, reg_gain}),
+ .s_axis_a_tdata ({16'd0, reg_gain}), // Real gain
.s_axis_a_tlast (m_in_payload_tlast),
.s_axis_a_tvalid (m_in_payload_tvalid),
.s_axis_a_tready (),
- .s_axis_b_tdata (m_in_payload_tdata),
+ .s_axis_b_tdata ({m_in_payload_tdata[15:0], // Imaginary
+ m_in_payload_tdata[31:16]}), // Real
.s_axis_b_tlast (m_in_payload_tlast),
.s_axis_b_tvalid (m_in_payload_tvalid),
.s_axis_b_tready (m_in_payload_tready),
@@ -366,8 +375,8 @@ module rfnoc_block_gain #(
.m_axis_dout_tready (mult_tready)
);
- assign mult_tdata[31: 0] = m_axis_dout_tdata[31: 0];
- assign mult_tdata[63:32] = m_axis_dout_tdata[71:40];
+ assign mult_tdata[63:32] = m_axis_dout_tdata[31: 0]; // Real
+ assign mult_tdata[31: 0] = m_axis_dout_tdata[71:40]; // Imaginary
end
endgenerate