Generate real or complex sinusoidal signals
Signal Operations
dspsigops
Sources
dspsrcs4
The block appears in dspsigops
with Phase increment
Source parameter set to Input port
.
In addition, the block also appears in dspsrsc4
library with
Phase increment Source parameter set to Specify
via dialog
.
The NCO block generates a multichannel real or complex sinusoidal signal, with independent frequency and phase in each output channel. The amplitude of the created signal is always 1. The block implements the algorithm as shown in the following diagram:
The implementation of a numerically controlled oscillator (NCO) has two distinct parts. First, a phase accumulator accumulates the phase increment and adds in the phase offset. In this stage, an optional internal dither signal can also be added. The NCO output is then calculated by quantizing the results of the phase accumulator section and using them to select values from a lookup table. Since the lookup table contains a finite set of entries, in its normal mode of operation, the NCO block allows the adder’s numeric values to overflow and wrap around. The FixedPoint infrastructure then causes overflow warnings to appear on the command line. This overflow is of no consequence.
Given a desired output frequency F_{0}, calculate the value of the Phase increment block parameter with
$$phaseincrement=(\frac{{F}_{0}\cdot {2}^{N}}{{F}_{s}})$$
$${F}_{s}=\frac{1}{{T}_{s}}=\frac{1}{sampletime}$$
The frequency resolution of an NCO is defined by
$$\Delta f=\frac{1}{{T}_{s}\cdot {2}^{N}}\text{Hz}$$
Given a desired phase offset (in radians), calculate the Phase offset block parameter with
$$phaseoffset=\frac{{2}^{N}\cdot desiredphaseoffset}{2\pi}$$
The spurious free dynamic range (SFDR) is estimated as follows for a lookup table with $${2}^{P}$$ entries, where P is the number of quantized accumulator bits:
$$\begin{array}{l}SFDR=\left(6P\right)\text{dBwithoutdither}\\ SFDR=\left(6P+12\right)\text{dBwithdither}\end{array}$$
This block uses a quarterwave lookup table technique that stores table values from 0 to π/2. The block calculates other values on demand using the accumulator data type, then casts them into the output data type. This can lead to quantization effects at the range limits of a given data type. For example, consider a case where you would expect the value of the sine wave to be –1 at π. Because the lookup table value at that point must be calculated, the block might not yield exactly –1, depending on the precision of the accumulator and output data types.
The NCO block supports real inputs only. All outputs are real except for the output
signal in Complex exponential
mode.
To produce a multichannel output, specify a vector quantity for the Phase increment and Phase offset parameters. Both parameters must have the same length, which defines the number of output channels. Each element of each vector is applied to a different output channel.
The following diagram shows the data types used within the NCO block.
You can set the accumulator and output data types in the block dialog as discussed in Dialog Box below.
The lookup table for this block is constructed from doubleprecision floatingpoint values. Thus, the maximum amount of precision you can achieve in your output is 53 bits. Setting the word length of the Output data type to values greater than 53 bits does not improve the precision of your output.
The phase increment and phase offset inputs must be integers or fixedpoint data types with zero fraction length.
You specify the number of quantized accumulator bits in the Number of quantized accumulator bits parameter.
The phase quantization error word length is equal to the accumulator word length minus the number of quantized accumulator bits, and the fraction length is zero.
The NCO block is used in the GSM Digital Down
Converter product example. Open this example by typing
dspddc
at the MATLAB^{®} command line.
You can also try the following example. Design an NCO source with the following specifications:
Desired output frequency $${F}_{0}=510\text{Hz}$$
Frequency resolution $$\Delta f=0.05\text{Hz}$$
Spurious free dynamic range $$SFDR\ge 90\text{dB}$$
Sample period $${T}_{s}=1/8000\text{s}$$
Desired phase offset $$\pi /2$$
Calculate the number of required accumulator bits from the equation for frequency resolution:
$$\begin{array}{l}\Delta f=\frac{1}{{T}_{s}\cdot {2}^{N}}\text{Hz}\\ 0.05=\frac{1}{\frac{1}{8000}\cdot {2}^{N}}\text{Hz}\\ N=18\end{array}$$
Note that N must be an integer value. The value of N is rounded up to the nearest integer; 18 accumulator bits are needed to accommodate the value of the frequency resolution.
Using this best value of N, calculate the frequency resolution that will be achieved by the NCO block:
$$\begin{array}{l}\Delta f=\frac{1}{{T}_{s}\cdot {2}^{N}}\text{Hz}\\ \Delta f=\frac{1}{\frac{1}{8000}\cdot {2}^{18}}\text{Hz}\\ \Delta f=0.0305\end{array}$$
Calculate the number of quantized accumulator bits from the equation for spurious free dynamic range and the fact that for a lookup table with $${2}^{P}$$ entries, P is the number of quantized accumulator bits:
$$\begin{array}{l}SFDR=\left(6P+12\right)\text{dB}\\ 96\text{dB}=(6P+12)\text{dB}\\ P=14\end{array}$$
Select the number of dither bits. In general, a good choice for the number of dither bits is the accumulator word length minus the number of quantized accumulator bits; in this case 4.
Calculate the phase increment:
$$\begin{array}{l}phaseincrement=\mathrm{round}(\frac{{F}_{0}\cdot {2}^{N}}{{F}_{s}})\\ phaseincrement=\mathrm{round}(\frac{510\cdot {2}^{18}}{8000})\\ phaseincrement=16712\end{array}$$
Calculate the phase offset:
$$\begin{array}{l}phaseoffset=\frac{{2}^{accumulatorwordlength}\cdot desiredphaseoffset}{2\pi}\\ phaseoffset=\frac{{2}^{18}\cdot \frac{\pi}{2}}{2\pi}\\ phaseoffset=65536\end{array}$$
Type ex_nco_example
at the MATLAB command line to open the following model:
The NCO block in the model is populated with the specifications and quantities you just calculated. The output word length and fraction length depend on the constraints of your hardware; this example uses a word length of 16 and a fraction length of 14. You can verify that the specifications of this problem have been met by looking at the NCO Characterization pane of the NCO block.
Experiment with the model to observe the effects on the output shown on the Spectrum Analyzer. For example, try turning dithering on and off, and try changing the number of dither bits.
The Main pane of the NCO dialog appears as follows.
Choose how you specify the phase increment. The phase increment can come from an input port or from the dialog.
If you select Input port
, the inc port
appears on the block icon.
If you select Specify via dialog
, the
Phase increment parameter appears.
Specify the phase increment. Only integer data types, including fixedpoint data types with zero fraction length, are allowed. The dimensions of the phase increment are dictated by those of the phase offset:
When you specify the phase offset on the block dialog box, the phase increment must be a scalar or a vector with the same length as the phase offset. The block applies each element of the vector to a different channel, and therefore the vector length defines the number of output channels.
When you specify the phase offset via an input port, the offset port treats each column of the input as an independent channel. The phase increment length must equal the number of columns in the input to the offset port.
This parameter is visible only if you set the Phase increment
source parameter to Specify via
dialog
.
Choose how you specify the phase offset. The phase offset can come from an input port or from the dialog.
If you select Input port
, the offset
port appears on the block icon.
If you select Specify via dialog
, the
Phase offset parameter appears.
When you specify the phase offset via an input port, it can be a scalar, vector, or a full matrix. The block treats each column of the input to the offset port as an independent channel. The number of channels in the phase offset must match the number of channels in the data input. For each frame of the input, the block can apply different phase offsets to each sample and channel. Only integer data types, including fixedpoint data types with zero fraction length, are allowed.
Specify the phase offset. When you specify the phase offset using this parameter rather than via an input port, it must be a scalar or vector with the same length as the phase increment. Scalars are expanded to a vector with the same length as the phase increment. Each element of the phase offset vector is applied to a different channel of the input, and therefore the vector length defines the number of output channels. Only integer data types, including fixedpoint data types with zero fraction length, are allowed.
This parameter is visible only if Specify via
dialog
is selected for the Phase offset
source parameter.
Select to add internal dithering to the NCO algorithm. Dithering is added using the PN Sequence Generator from the Communications System Toolbox™ product.
Specify the number of dither bits.
This parameter is visible only if Add internal dither is selected.
Select to enable quantization of the accumulated phase.
Specify the number of quantized accumulator bits. This determines the number of entries in the lookup table. The number of quantized accumulator bits must be less than the accumulator word length.
This parameter is visible only if Quantize phase is selected.
Select to output the phase quantization error. When you select this, the Qerr port appears on the block icon.
This parameter is visible only if Quantize phase is selected.
Choose whether the block should output a Sine
,
Cosine
, Complex
exponential
, or Sine and cosine
signals. If you select Sine and cosine
, the two
signals output on different ports.
Specify the sample time in seconds when the block is acting as a source. When either the phase increment or phase offset come in via block input ports, the sample time is inherited and this parameter is not visible.
Specify the number of samples per frame. When the value is greater than 1, the phase increment and phase offset can vary from channel to channel and from frame to frame, but they are constant along each channel in a given frame.
When the phase offset input port exists, it has the same frame status as any output port present. When the phase increment input port exists, it does not support frames.
This parameter is only visible if either Phase increment
source or Phase offset source is set to
Specify via dialog
.
The Data Types pane of the NCO dialog appears as follows.
The rounding
mode used for this block when inputs are fixed point is always
Floor
.
The overflow
mode used for this block when inputs are fixed point is always
Wrap
.
Specify the word length of the accumulator data type. The fraction length is always zero; this is an integer data type.
Specify the output data type.
Choose double
or
single
for a floatingpoint
implementation.
When you select Binary point scaling
,
you can enter the word length and the fraction length of the output,
in bits.
The lookup table for this block is constructed from doubleprecision floatingpoint values. Thus, the maximum amount of precision you can achieve in your output is 53 bits. Setting the word length of the Output data type to values greater than 53 bits does not improve the precision of your output.
The NCO Characterization pane of the NCO dialog appears as follows.
The NCO Characterization pane does not have any parameters. Instead, it provides you with details on the NCO signal currently being implemented by the block:
Number of data points for lookup table
— The
lookup table is implemented as a quarterwave sine table. The number of lookup
table data points is defined by
$${2}^{\text{numberofquantizedaccumulatorbits}2}+1$$
Quarter wave sine lookup table size
— The
quarter wave sine lookup table size is defined by
$$\frac{(\text{numberofdatapointsforlookuptable})\cdot \left(\text{outputwordlength}\right)}{8}\text{bytes}$$
Theoretical spurious free dynamic range
—
The spurious free dynamic range (SFDR) is calculated as follows for a lookup
table with $${2}^{P}$$ entries:
$$\begin{array}{l}SFDR=\left(6P\right)\text{dBwithoutdither}\\ SFDR=\left(6P+12\right)\text{dBwithdither}\end{array}$$
Port  Supported Data Types 

inc 

offset 

sin 

Qerr 

This block supports HDL code generation using HDL Coder™. HDL Coder provides additional configuration options that affect HDL implementation and synthesized logic. For more information on implementations, properties, and restrictions for HDL code generation, see NCO in the HDL Coder documentation. Also consider the NCO HDL Optimized block.