SmallRotation

This module rotates an I/Q vector through an angle whose tangent is a negative power of two in the spirit of the Cordic algorithm,

xn+1 = xn - 2−shift yn
yn+1 = yn + 2−shift xn

requiring only additions and bit shifts. The module is intended for interpolation between waypoints where only a small rotation each time step is required. It does not preserve the vector's magnitude, but with these small angles magnitude may be preserved sufficiently well. Although it only implements a single power-of-two rotation, it may be cascaded to better approximate a given rotation, and in fact can be used in a pipelined Cordic implementation.

The module also implements I/Q up/down conversion via the IF parameter – 0 (no frequency translation), 90 (fs/4), 180 (inversion), and 270 (-fs/4).

Ports | Parameters | Notes | Example

Ports

clkinputThe clock input.
resetinputThe reset input.
selininputWhen high, loads the register; when low, performs the rotation of the time step.
signinputThe rotation direction.
shiftinputThe negative power-of-two exponent specifying the tangent of the rotation angle. It is 5 bits wide.
x1, y1inputThe signed I/Q vector input.
x2, y2outputThe signed I/Q vector output, simultaneously clocked.
x2N, y2NoutputThe inverted signed I/Q vector output, simultaneously clocked.
seloutoutput The selin input delayed one clock.

Parameters

wd16The bit width of the signed x1, y1, x2, y2, x2N, and y2N ports.
IF0The I/Q modulation/demodulation type: 0 – none; 90 – 90-degree CCW modulation; 180 – 180-degree rotation (fs/2); and 270 – 90-degree CW rotation.

Notes

Example instantiation:

wire	signed	[w-1:0]    Iin, Qin;	// baseband input
wire	signed	[w-1:0]    IFI, IFQ;	// IF output
wire	signed	[w-1:0]    IFIN, IFQN;	// IF output (inverted)
SmallRotation
    #(.wd(w), .IF(270))
    interpolate (
        .clk(clk),		.reset(reset),
        .selin(inputvalid),
        .sign(direction),	.shift(shift),
        .x1(Iin),		.y1(Qin),	// input vector
        .x2(IFI),		.y2(IFQ),	// output vector
        .x2N(IFIN),		.y2N(IFQN),	// output vector (inverted)
        .valid(valid)
    );