aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/dsp
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2021-03-08 10:42:34 +0100
committerWade Fife <wade.fife@ettus.com>2021-03-09 08:33:32 -0600
commit09995cc9954877cb56b4f028dc273f2d5fd0be10 (patch)
tree4c39b3b7b038f5aa921c4e372a05c4cdf31222be /fpga/usrp3/lib/dsp
parenta0fcdec7d5f344a5fd7873585a621bef33c25b85 (diff)
downloaduhd-09995cc9954877cb56b4f028dc273f2d5fd0be10.tar.gz
uhd-09995cc9954877cb56b4f028dc273f2d5fd0be10.tar.bz2
uhd-09995cc9954877cb56b4f028dc273f2d5fd0be10.zip
fpga: dsp: Fix formatting of rx_dcoffset and add docs
- Adapt to coding guide - Add header that explains the module
Diffstat (limited to 'fpga/usrp3/lib/dsp')
-rw-r--r--fpga/usrp3/lib/dsp/rx_dcoffset.v148
1 files changed, 110 insertions, 38 deletions
diff --git a/fpga/usrp3/lib/dsp/rx_dcoffset.v b/fpga/usrp3/lib/dsp/rx_dcoffset.v
index 02950fbd5..d34bf95d6 100644
--- a/fpga/usrp3/lib/dsp/rx_dcoffset.v
+++ b/fpga/usrp3/lib/dsp/rx_dcoffset.v
@@ -1,50 +1,122 @@
//
-// Copyright 2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
+// Copyright 2021 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
+// Module: rx_dcoffset
+//
+// Description:
+//
+// RX Offset DC Correction Module
+// ------------------------------
+//
+// This module has two modes of operation:
+// - Automatic mode: In this case, this module acts as an IIR filter of the form
+//
+// y[k] = x[k] - alpha * y[k-1] (1)
+//
+// The module thus implements a notch filter around DC.
+//
+// - Fixed mode: In this case, a known DC offset is simply subtracted from the
+// input signal.
+//
+// IQ Operation: To fix the DC offset of an IQ signal, this module is
+// typically instantiated twice, once for the I and Q signal separately.
+//
+// Settings register:
+// This module implements a single settings bus register with configurable
+// address. The 32-bit payload of the register configures the module as
+// follows:
+// - Bit 31: When 1, use "Fixed Mode" (see above). When 0, use "Automatic Mode".
+// - Bit 30: When asserted, bits 29 through 0 are used to initialize the
+// accumulator.
+// - Bit 29:0: This sets the 30 MSBs for the accumulator. In Fixed Mode, the
+// accumulator is left unchanged and is directly subtracted from
+// the input signal.
+// In Automatic Mode, the accumulator can be primed using these
+// bits, but that is uncommon. Typically, the x[k-1] value is
+// assumed to be zero at the beginning.
+//
+// Setting the register to zero is equivalent to enabling automatic mode with
+// no initial accumulator. It may be useful to set the accumulator to zero
+// between bursts if their relative DC offset is significantly different.
+//
+// Alpha value: To avoid the usage of a multiplier in this value, the alpha
+// value is limited to powers of two, and is not runtime-configurable.
+//
+// Parameters:
+// WIDTH : Input signal width
+// ADDR : Settings bus address
+// ALPHA_SHIFT : -log2(desired_alpha), where desired_alpha is the alpha value
+// in equation (1) and must be a power of two.
-module rx_dcoffset
- #(parameter WIDTH=16,
- parameter ADDR=8'd0,
- parameter alpha_shift=20)
- (input clk, input rst,
- input set_stb, input [7:0] set_addr, input [31:0] set_data,
- input in_stb, input [WIDTH-1:0] in,
- output out_stb, output [WIDTH-1:0] out);
+`default_nettype none
+module rx_dcoffset #(
+ parameter WIDTH = 16,
+ parameter ADDR = 8'd0,
+ parameter ALPHA_SHIFT = 20
+) (
+ input wire clk,
+ input wire rst,
+ // Settings bus input
+ input wire set_stb,
+ input wire [7:0] set_addr,
+ input wire [31:0] set_data,
+ // Input signal
+ input wire in_stb,
+ input wire [WIDTH-1:0] in,
+ // Output signal
+ output wire out_stb,
+ output wire [WIDTH-1:0] out
+);
- wire set_now = set_stb & (ADDR == set_addr);
- reg fixed; // uses fixed offset
- wire [WIDTH-1:0] fixed_dco;
+ localparam int_width = WIDTH + ALPHA_SHIFT;
- localparam int_width = WIDTH + alpha_shift;
- reg [int_width-1:0] integrator;
- reg integ_in_stb;
- wire [WIDTH-1:0] quantized;
+ wire set_now = set_stb & (ADDR == set_addr);
+ reg fixed; // uses fixed offset
+ reg [int_width-1:0] integrator;
+ reg integ_in_stb;
+ wire [WIDTH-1:0] quantized;
- always @(posedge clk) begin
- if(rst)
- begin
- integ_in_stb <= 0;
- fixed <= 0;
- integrator <= {int_width{1'b0}};
- end
- else if(set_now)
- begin
- fixed <= set_data[31];
- if(set_data[30])
- integrator <= {set_data[29:0],{(int_width-30){1'b0}}};
- end
- else if(~fixed & in_stb)
- integrator <= integrator + {{(alpha_shift){out[WIDTH-1]}},out};
- integ_in_stb <= in_stb;
- end
+ always @(posedge clk) begin
+ if (rst) begin
+ integ_in_stb <= 0;
+ fixed <= 0;
+ integrator <= {int_width{1'b0}};
+ end else if(set_now) begin
+ fixed <= set_data[31];
+ if (set_data[30]) begin
+ integrator <= {set_data[29:0],{(int_width-30){1'b0}}};
+ end
+ end else if(~fixed & in_stb) begin
+ integrator <= integrator + {{(ALPHA_SHIFT){out[WIDTH-1]}},out};
+ end
+ integ_in_stb <= in_stb;
+ end
- round_sd #(.WIDTH_IN(int_width),.WIDTH_OUT(WIDTH)) round_sd
- (.clk(clk), .reset(rst), .in(integrator), .strobe_in(integ_in_stb), .out(quantized), .strobe_out());
+ round_sd #(
+ .WIDTH_IN(int_width),
+ .WIDTH_OUT(WIDTH)
+ ) round_sd (
+ .clk(clk),
+ .reset(rst),
+ .in(integrator),
+ .strobe_in(integ_in_stb),
+ .out(quantized),
+ .strobe_out()
+ );
- add2_and_clip_reg #(.WIDTH(WIDTH)) add2_and_clip_reg
- (.clk(clk), .rst(rst), .in1(in), .in2(-quantized), .strobe_in(in_stb), .sum(out), .strobe_out(out_stb));
+ add2_and_clip_reg #(
+ .WIDTH(WIDTH)
+ ) add2_and_clip_reg (
+ .clk(clk),
+ .rst(rst),
+ .in1(in),
+ .in2(-quantized),
+ .strobe_in(in_stb),
+ .sum(out),
+ .strobe_out(out_stb)
+ );
endmodule // rx_dcoffset
+`default_nettype wire