RotatorPipelined (Rotator.v)

Generates an I/Q vector given an I/Q input vector and a phase angle. The phase is specified as binary input, where full scale wraps to zero phase. This module is a pipelined version providing a new I/Q pair every clock, and is recursively defined. It is used in DDSPipelined.

This module is simpler to use than the serial version. In normal use, the reset input is low and the enable input is high. The module clocks the calculation through the pipeline, with a new I/Q pair appearing at the output each cycle. The phase angle input can change each cycle. The I/Q input ports can also change each cycle, but are ordinarily set to constants. The outputs are naturally registered.

Ports | Parameters | Performance | Notes | Example

Ports

clkinputThe clock input.
resetinputThe reset input.
eninputThe enable input. The module clocks through the calculation when en = 1, and holds its state when en = 0.
phaseininputThe phase by which the phase of the input I/Q vector is to be shifted, on a 2wpa (360-degree) scale.
Iin, QininputThe input I/Q pair, which is rotated through the angle phasein.
Iout, QoutoutputThe output I/Q pair. It is the input pair is rotated through angle phasein.

Parameters

Parameters, their defaults, and descriptions:

wd16The bit width of the inputs Iin and Qin. Through the Cordic rotation, this vector grows by the factor 1.6468. It is up to the user to be sure that Iin and Qin are small enough that the calculation does not overflow.
apb0The internal Cordic calculation is performed at apb bits higher precision. Use this to gain a few decibels greater signal-to-noise ratio of the output over ofl=0.
wpawd+apb+1The precision of the phase part of the Cordic calculation. A value higher than the default benefits signal to noise, but with quickly diminishing returns.
b0The default is used for a 360° rotation range. When only a smaller range is required, a larger value of b may be specified, which has the benefit of instantiating fewer pipeline stages. Use b=1 for ±54.88°, b=2 for ±28.3°, b=3 for ±14.28°, etc.

Performance

The plot shows an example power spectrum for 16-bit data and 20-bit phase when stepping through a full cycle in 217 steps. The signal-to-noise ratio is the ratio of the intensity in the single signal channel at 0 dBc, to the sum of the intensities of all other Fourier channels in the spectrum.


Noise performance The next plot shows the signal-to-noise ratio as a function of output bit width. The blue points were simulated using Xilinx ISim, the green points were simulated using a Mathematica function, and the red point is from a test in logic where the data were acquired through scope dumps. For reference, the quantization noise intensity is the dashed line having functional dependence S/N = 3×22wd-1. In the absence of internal roundoff, a rotation with roundoff will yield noise at the level of the quantization noise line. Because the Mathematica and ISim simulations computed nearly identical noise levels, the excess noise must be due to accumulation of roundoff error through the Cordic stages. The serial and pipelined versions have the same noise characteristics because they implement the same algorithm.

For a given data-port bit width, greater bit width of the phase port (wpa) results in some improvement of signal to noise, although only with diminishing returns. When used in a DDS, a large bit width of its phase accumulator (wpa) is needed for high frequency resolution, but RotatorPipelined need not see all of the least-significant bits.

Notes

Example instantiation:

localparam	wd = 16, wpa = wd+4;

// phase accumulator: 33.569 kHz (40 MHz clock)
reg			[wpa-1:0]	phase = 0;
wire			[wpa-1:0]	phaseincrement = 880;
always @(posedge clk)	phase <= phase + phaseincrement;

// Cordic computer
wire		signed	[wd-1:0]	I, Q;
Rotator #(.wd(wd), .wpa(wpa)) instname (
    .clk(clk),			.reset(reset),
    .en(1'b1),			.phasein(phase),
    .Iin(76*2**(wd-8)),		.Qin(0)
    .Iout(I),			.Qout(Q)
);