CoRotator.v

This module takes as an input an I/Q vector and outputs a prescribed reference vector rotated through the same angle or the opposite angle. It has two cordic blocks that work in parallel and without ever recording the angles through which the vectors are rotated. It works in all four quadrants and the outputs are optionally registered. The magnitude of the first vector and busy and done outputs are also available, but reset and enable inputs are not. The source is relatively simple, compact, and portable.

Vector diagram

The prescribed vector to be rotated to the output vector can be specified in either of two modes. The first is that it is specified by the two input ports Iref and Qref. The parameter mag must be zero in this case. The figure shows how the vector (Iin, Qin) is rotated to the real axis while input the vector (Iref, Qref) is rotated through the same angle to the vector (Iout, Qout). The output port Imag returns the magnitude of the vector (Iin, Qin) (times 1.65).


Vector diagram

In the second mode, where mag > 0, the input vector (Iin, Qin) is replaced by vector (mag, 0} determined by the mag parameter. That vector is then rotated by the angle of the vector (Iin, Qin). The output port Imag again returns the magnitude of (Iin, Qin).

The direction parameter sets whether the reference vector is co-rotated, or counter-rotated with the input vector (Iin, Qin).


Ports | Parameters | Notes | Example

Ports

clkinputThe clock input.
restinputThe reset input.
goinputInitiates the rotation. Can be a multi-bit trigger.
gonowinputAsserted for one clock cycle when all trigger events in the vector go have occurred.
quadinputA two-bit quadrant fiducial.
IininputThe I (in-phase) input. This signal and Qin provide a phase reference through which the reference vector is rotated. Its bit width is given by the width parameter.
QininputThe Q (quadra-phase) input. This signal and Iin provide a phase reference through which the reference vector is rotated. Its bit width is given by the width parameter.
IrefinputThe signal I input. This signal and Qref, when mag is zero, are rotated through the angle of Iin, Qin. Its bit width is given by the width parameter.
QrefinputThe signal Q input. This signal and Iref, when mag is zero, are rotated through the angle of Iin, Qin. Its bit width is given by the width parameter.
gonowoutputPulse that indicates when the multi-level trigger (go) fires to start the calculation.
IoutoutputThe I component of the output vector. Its width is one greater than the width parameter to avoid overflow.
QoutoutputThe Q component of the output vector. Its width is one greater than the width parameter to avoid overflow.
IoutNoutputThe twos-complement negative of Iout.
QoutNoutputThe twos-complement negative of Qout.
ImagoutputA diagnostic output containing, along with Qmag, the result of the rotation of the input vector (Iin, Qin) to the real axis.
QmagoutputA diagnostic output containing, along with Imag, the result of the rotation of the input vector (Iin, Qin) to the real axis.
outoutput   The four outputs Iout, Qout, IoutN, and QoutN multiplexed using the quadrant fiducial.
busyoutput   Indicates that a rotation is in progress.
doneoutputIndicates that a rotation has completed and the output data are valid (see the note below).

Parameters

w116Bit width of the Iin and Qin inputs. The outputs Imag and Qmag are of width one larger.
w2w1Bit width of the Iref and Qref inputs. The outputs Iout, Qout, IoutN, QoutN, and out are of width one larger.
stepsw1The number of clock cycles through which the Cordic calculation runs.
gobits1The number of trigger bits of the go input.
mag0When nonzero, provides the (real) reference level that is rotated to the phase of the I and Q inputs. The inputs Iref and Qref are ignored. When zero, the input Iref, and Qref together is the vector that is rotated through the angle of Iin and Qin.
direction0Selects the direction, co-rotating (0) or counter-rotating (1), that the reference vector given either by (mag, 0) or (Iref, Qref) is rotated.
registered  "no"When '"yes"', the I and Q outputs are registered. With any other value the outputs are unregistered.

Notes

Example instantiation:

localparam	w1 = 16, w2 = 18;
wire	signed	[w1-1:0]	Iin, Qin;
wire	signed	[w1  :0]	Imag, Qmag;
wire	signed	[w2-1:0]	Iref, Qref;
wire	signed	[w2  :0]	Iout, Qout, IoutN, QoutN, out;
wire				go, gonow, busy, done;
wire		[1   :0]	quad;
CoRotator
    #(.w1(w1), .w2(w2), .steps(15), .direction(1'b0), .registered("yes")) 
    cr1 (
        .clk(clk),		.go(go),
        .quad(quad),		.gonow(gonow),
        .Iin(Iin),		.Qin(Qin),
        .Iref(Iref),		.Qref(Qref),
        .Iout(Iout),		.Qout(Qout),
        .IoutN(IoutN),		.QoutN(QoutN),
        .out(out),
        .busy(busy),		.done(done)
    );