aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/rfnoc/sine_tone.v
diff options
context:
space:
mode:
authorWade Fife <wade.fife@ettus.com>2020-06-19 15:40:12 -0500
committerAaron Rossetto <aaron.rossetto@ni.com>2020-07-30 12:51:41 -0500
commit1e94f85b8bafc3f9acab7ef35d2675fa7e61f6f4 (patch)
tree12ba30a59c8057e355971797d5cc7bf6910f520b /fpga/usrp3/lib/rfnoc/sine_tone.v
parentb0b3849a18e1f2d3cb255a507b01ac5e7a9416a0 (diff)
downloaduhd-1e94f85b8bafc3f9acab7ef35d2675fa7e61f6f4.tar.gz
uhd-1e94f85b8bafc3f9acab7ef35d2675fa7e61f6f4.tar.bz2
uhd-1e94f85b8bafc3f9acab7ef35d2675fa7e61f6f4.zip
fpga: rfnoc: Add Signal Generator RFNoC block
Diffstat (limited to 'fpga/usrp3/lib/rfnoc/sine_tone.v')
-rw-r--r--fpga/usrp3/lib/rfnoc/sine_tone.v159
1 files changed, 159 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/rfnoc/sine_tone.v b/fpga/usrp3/lib/rfnoc/sine_tone.v
new file mode 100644
index 000000000..a687472eb
--- /dev/null
+++ b/fpga/usrp3/lib/rfnoc/sine_tone.v
@@ -0,0 +1,159 @@
+//
+// Copyright 2020 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Module: sine_tone
+//
+// Description:
+//
+// Sine tone generator. This block uses the Xilinx CORDIC IP configured to
+// perform the rotate function in units of scaled radians. See the CORDIC IP
+// Product Guide (PG105) for details.
+//
+// The SR_PHASE_INC register controls the phase increment, in scaled
+// radians, for the sine waveform generator. It is a 16-bit signed
+// fixed-point phase value with 3 integer bits and 13 fractional bits. This
+// is the amount by which REG_CARTESIAN is rotated each clock cycle. In
+// other words, it controls the rate of rotation, or the frequency, of the
+// sine wave. In scaled radians, the phase value range -1 to +1 corresponds
+// to -Pi to Pi in radians.
+//
+// The SR_CARTESIAN register sets the sets the (X,Y) Cartesian coordinate
+// that will be rotated to generate the sine output. Both X and Y are 16-bit
+// signed fixed-point values with 2 integer bits and 14 fractional bits. Y
+// is in the upper 16-bits and X is in the lower 16-bits.
+//
+// In addition to rotation, the SR_CARTESIAN input vector is also scaled by
+// a "CORDIC scale factor" that equals about 1.1644 (that is, the product of
+// sqrt(1 + 2^(-2i)) for i = 1 to n, where n = 14, the number of fractional
+// bits).
+//
+// Parameters:
+//
+// SR_PHASE_INC_ADDR : The address to use for SR_PHASE_INC.
+// SR_CARTESIAN_ADDR : The address to use for SR_CARTESIAN.
+//
+
+
+module sine_tone #(
+ parameter WIDTH = 32,
+ parameter SR_PHASE_INC_ADDR = 129,
+ parameter SR_CARTESIAN_ADDR = 130
+) (
+ input clk,
+ input reset,
+ input clear,
+ input enable,
+
+ // Settings bus
+ input set_stb,
+ input [WIDTH-1:0] set_data,
+ input [ 7:0] set_addr,
+
+ // Output sinusoid
+ output [WIDTH-1:0] o_tdata,
+ output o_tlast,
+ output o_tvalid,
+ input o_tready
+);
+
+ wire [15:0] phase_in_tdata;
+ wire phase_in_tlast;
+ wire phase_in_tvalid;
+ wire phase_in_tready;
+
+ wire [15:0] phase_out_tdata;
+ wire phase_out_tlast;
+ wire phase_out_tvalid;
+ wire phase_out_tready;
+
+ wire [WIDTH-1:0] cartesian_tdata;
+ wire cartesian_tlast;
+ wire cartesian_tvalid;
+ wire cartesian_tready;
+
+ wire [WIDTH-1:0] sine_out_tdata;
+ wire sine_out_tlast;
+ wire sine_out_tvalid;
+ wire sine_out_tready;
+
+ // AXI settings bus for phase values
+ axi_setting_reg #(
+ .ADDR (SR_PHASE_INC_ADDR),
+ .AWIDTH (8),
+ .WIDTH (16),
+ .STROBE_LAST (1),
+ .REPEATS (1)
+ ) set_phase_acc (
+ .clk (clk),
+ .reset (reset),
+ .error_stb (),
+ .set_stb (set_stb),
+ .set_addr (set_addr),
+ .set_data (set_data),
+ .o_tdata (phase_in_tdata),
+ .o_tlast (phase_in_tlast),
+ .o_tvalid (phase_in_tvalid),
+ .o_tready (phase_in_tready & enable)
+ );
+
+ // AXI settings bus for Cartesian values
+ axi_setting_reg #(
+ .ADDR (SR_CARTESIAN_ADDR),
+ .AWIDTH (8),
+ .WIDTH (32),
+ .REPEATS (1)
+ ) set_axis_cartesian (
+ .clk (clk),
+ .reset (reset),
+ .error_stb (),
+ .set_stb (set_stb),
+ .set_addr (set_addr),
+ .set_data (set_data),
+ .o_tdata (cartesian_tdata),
+ .o_tlast (),
+ .o_tvalid (cartesian_tvalid),
+ .o_tready (cartesian_tready & enable)
+ );
+
+ assign cartesian_tlast = 1;
+
+ // Phase accumulator
+ phase_accum phase_acc (
+ .clk (clk),
+ .reset (reset),
+ .clear (clear),
+ .i_tdata (phase_in_tdata),
+ .i_tlast (phase_in_tlast),
+ .i_tvalid (1'b1),
+ .i_tready (phase_in_tready),
+ .o_tdata (phase_out_tdata),
+ .o_tlast (phase_out_tlast),
+ .o_tvalid (phase_out_tvalid),
+ .o_tready (phase_out_tready & enable)
+ );
+
+ // CORDIC
+ cordic_rotator cordic_inst (
+ .aclk (clk),
+ .aresetn (~(reset|clear)),
+ .s_axis_phase_tdata (phase_out_tdata),
+ .s_axis_phase_tvalid (phase_out_tvalid & cartesian_tvalid & enable),
+ .s_axis_phase_tready (phase_out_tready),
+ .s_axis_cartesian_tdata (cartesian_tdata),
+ .s_axis_cartesian_tlast (cartesian_tlast),
+ .s_axis_cartesian_tvalid (phase_out_tvalid & cartesian_tvalid & enable),
+ .s_axis_cartesian_tready (cartesian_tready),
+ .m_axis_dout_tdata (sine_out_tdata),
+ .m_axis_dout_tlast (sine_out_tlast),
+ .m_axis_dout_tvalid (sine_out_tvalid),
+ .m_axis_dout_tready (sine_out_tready & enable)
+ );
+
+ assign o_tdata = sine_out_tdata;
+ assign o_tlast = sine_out_tlast;
+ assign o_tvalid = sine_out_tvalid;
+ assign sine_out_tready = o_tready;
+
+endmodule // sine_tone