This module is a signal generator that outputs I/Q vectors with a given phase increment between samples, a given interval in clocks between samples, and it outputs a pulse every given number of samples. It has a reset port, a start port, output sample and cycle ticks, and an up-converted output. Once started, it runs until it is reset. It is phase continuous with respect to changes of frequency, and more generally, the interval between phase increments and the interval between timer pulse outputs can be changed on the fly.
clk | input | The clock input. |
reset | input | The reset input. |
go | input | A multi-bit trigger to start conversions. |
PhIncr | input | The phase increment per Cordic rotation on a 2wpi phase scale per revolution. Its bit width is wdp. |
clockinterval | input | The interval in clocks between output samples |
phasecount | input | The number of samples between cycle ticks. |
I, Q | output | The main I/Q-pair output. |
IN, QN | output | The two's-complement negative of the I and Q outputs. |
out | output | The up-converted (I, Q, −I, −Q ... ) data stream. |
quad | input | A two-bit quadrant counter used for timing and to generate the upconverted out output from I, Q, IN, and QN |
busy | output | When asserted, the module is running and outputting samples. It is first asserted when all go trigger conditions are met. |
valid | output | Assertedfor one clock cycle when the Cordic rotation has finished and that data are valid on the Iout, Qout, IoutN, and QoutN outputs. |
cycle | output | A timer tick that is asserted for one clock cycle every phasecount samples. |
turntick | output | A tick that indicates completion of a turn of the I/Q vector. |
Parameters, their defaults, and descriptions:
wd | 16 | The bit width of the outputs I, Q, IN, QN, and out. |
wpi | 16 | The width of the internal phase accumulator. A phase of 2wpi corresponds to 360 degrees. The input PhIncr is added to the accumulator every sample cycle. |
wdp | 13 | The width of the phase increment PhIncr input port. |
wpc | 16 | The width of the sample counter. The width of the phasecount input port is one larger. |
wl | 11 | The width of the inter-sample-interval sample counter. The width of the input port clockinterval is one greater. |
gb | 1 | The width of the go trigger input port. |
For normal use, the sequence of events looks something like this:
The intention of the cycle timing pulses are to provide a fiducial that indicate an integral number cycles of the I/Q output. With integration synchronized to this fiducial, end effects are minimized, lessening the need for windowing. For example, with a 40-MHz clock and the settings of the example below, the 71.81-Hz cycle pulses separate 280 cycles of 20.1057-kHz I/Q output. The fundamental relation is
I/Q cycle count × 2wpi = phasecount × PhiIncr
where all parameters are integers, and phase increments occur every 17 clock cycles.
Note that because the timing parameters can be changed on the fly, the phase of the DDS output is not in any way synchronized with the cyclepulses. For this reason analysis of one or more signals should be in parallel with analysis of a reference signal, which can be the DDS signal itself.
localparam wd = 16, wpi = 16, wdp = 13, wpc = 16, wl = 11, gb = 1, clockinterval = 17, // l phasecount = 32768, // count between pulses PhIncr = 280; // phase increment; wire signed [wd-1:0] I1, Q1, IN1, QN1, out1; wire busy, valid, cycletick; DDS #(.wd(wd), .wpi(wpi), .wdp(wdp), .wpc(wpc), .wl(wl), .gb(gb)) dds1 ( .clk(clk), .reset(reset), .go(go), .clockinterval(clockinterval[wl:0]), .phasecount(phasecount[wpc:0]), .PhIncr(PhIncr[wdp-1:0]), .quad(quad), // outputs .I(I1), .Q(Q1), .IN(IN1), .QN(QN1), .out(out1), // upconverted output .busy(busy), .valid(valid), .cycle(cycletick) );