# dsp.HDLNCO

Generate real or complex sinusoidal signals—optimized for HDL code generation

## Description

The HDL NCO System object™ generates real or complex sinusoidal signals, while providing hardware-friendly control signals. The object uses the same phase accumulation and lookup table algorithm as implemented in the NCO System object. The object uses quantized integer accumulation to create a sinusoid signal. The HDL NCO System object provides these features.

• Optional frame-based output.

• A lookup table compression option to reduce the lookup table size. This compression results in less than one LSB loss in precision. See Lookup Table Compression for more information.

• An optional input argument for external dither.

• An optional reset argument that resets the phase accumulator to its initial value.

• An optional output argument for the current NCO phase.

Given a sample time, Ts, and the desired output frequency resolution, Δf, calculate the necessary accumulator size by $Nacc=\mathrm{ceil}\left({\mathrm{log}}_{2}\left(\frac{1}{{T}_{s}\cdot \Delta f}\right)\right)$.

Assuming that your desired output frequency Fo is much lower than the Nyquist frequency, you can use an approximation for the noise per bit in dB, based on the spurious free dynamic range (SFDR), and determine how much you can quantize the output of the accumulator. The quantized word length to achieve a specified SFDR is $Nq=\mathrm{ceil}\left(\frac{SFDR-12}{6}\right)$.

For a desired output frequency Fo, calculate the phase increment using $phaseincrement=\mathrm{round}\left({F}_{0}{T}_{s}{2}^{Nacc}\right)$, where Nacc is the quantized accumulator word length. You can specify the phase increment using a property or an input argument.

Given a desired phase offset (in radians), calculate the phase offset using$phaseoffset=\frac{{2}^{Nacc}\cdot desiredphaseoffset}{2\pi }$. You can specify the phase offset using a property or an input argument.

To generate real or complex sinusoidal signals:

1. Create the `dsp.HDLNCO` object and set its properties.

2. Call the object with arguments, as if it were a function.

## Creation

### Syntax

``hdlnco = dsp.HDLNCO``
``hdlnco = dsp.HDLNCO(Name,Value)``
``hdlnco = dsp.HDLNCO(Inc,'PhaseIncrementSource','Property')``

### Description

````hdlnco = dsp.HDLNCO` creates a numerically controlled oscillator (NCO) System object, `hdlnco`, that generates a real or complex sinusoidal signal. The amplitude of the generated signal is always 1.```

example

````hdlnco = dsp.HDLNCO(Name,Value)` sets properties using one or more name-value pairs. Enclose each property name in single quotes. For example, hdlnco = dsp.HDLNCO('NumQuantizerAccumulatorBits',12, ... 'AccumulatorWL',16);```
````hdlnco = dsp.HDLNCO(Inc,'PhaseIncrementSource','Property')` creates an NCO with the `PhaseIncrement` property set to `Inc`, an integer scalar. To use the PhaseIncrement property, set the PhaseIncrementSource property to `'Property'`. You can add other `Name,Value` pairs before or after `PhaseIncrementSource`.```

## Properties

expand all

Note

This object supports floating-point types for simulation but not for HDL code generation. When all input values are fixed-point type or all input arguments are disabled, the object determines the output type using the `OutputDataType` property. When any input value is floating-point type, the object ignores the `OutputDataType` property. In this case, the object returns the waveform and optional `Phase` as floating-point values.

Unless otherwise indicated, properties are nontunable, which means you cannot change their values after calling the object. Objects lock when you call them, and the `release` function unlocks them.

If a property is tunable, you can change its value at any time.

### Waveform Generation

You can set the phase increment with an input argument or by specifying a value for the property. Specify `'Property'` to configure the phase increment using the `PhaseIncrement` property. Specify `'Input port'` to set the phase increment using the `inc` argument.

Phase increment for generated waveform, specified as an integer.

#### Dependencies

To enable this property, set the `PhaseIncrementSource` property to `'Property'`.

Data Types: `single` | `double` | `int8` | `int16` | `int32` | `uint8` | `uint16` | `uint32` | `fixdt([],N,0)`

You can set the phase offset with an input argument or by specifying a value for the property. Specify `'Property'` to configure the phase increment using the `PhaseOffset` property. Specify ```'Input port'``` to set the phase increment using the `offset` argument.

Phase offset for the generated waveform, specified as an integer.

#### Dependencies

To enable this property, set the `PhaseOffsetSource` property to `'Property'`.

Data Types: `single` | `double` | `int8` | `int16` | `int32` | `uint8` | `uint16` | `uint32` | `fixdt([],N,0)`

You can set the number of dither bits from an input argument or from a property, or you can disable dither. Specify `'Property'` to configure the number of dither bits using the `NumDitherBits` property. Specify `'Input port'` to set the number of dither bits using the `dither` argument. Specify `'None'` to disable dither.

Number of dither bits, specified as a positive integer.

#### Dependencies

To enable this property, set the `DitherSource` property to `'Property'`.

Vector size for frame-based output, specified as a positive integer. When you set this value to `1`, the object has scalar input and output. When this value is greater than `1`, the `Dither` input argument must be a column vector of length `SamplesPerFrame` and the `Y` and `Phase` output arguments return column vectors of length `SamplesPerFrame`.

Lookup table compression, specified as a logical 0 (`false`) or 1 (`true`). By default, the object implements a noncompressed lookup table, and the output matches the output of the `dsp.NCO` System object. When you enable this option, the object implements a compressed lookup table. The Sunderland compression method reduces the size of the lookup table, losing less than one LSB of precision. The spurious free dynamic range (SFDR) is empirically 1-3 dB lower than the noncompressed case. The hardware savings of the compressed lookup table allow room to improve performance by increasing the word length of the accumulator and the number of quantize bits. For details of the compression method, see Algorithms.

Type of output waveform. If you select `'Sine'` or `'Cosine'`, the object returns a `sin` or `cos` value. If you select ```'Complex exponential'```, the output value, `exp`, is of the form `cosine + j*sine`. If you select ```'Sine and cosine'```, the object returns two values, `sin` and `cos`.

Set this property to `1` (`true`) to return the current NCO phase in the `phase` output argument. The phase is the output of the quantized accumulator with offset and increment applied. If quantization is disabled, this argument returns the output of the accumulator with offset and increment applied.

When this property is `1` (`true`), the object accepts a `ResetAccum` input argument. When the `ResetAccum` argument is `1` (`true`), the object resets the accumulator to its initial value.

### Data Types

Overflow mode for fixed-point operations.

Rounding mode for fixed-point operations.

Accumulator data type description. The object defines the fixed-point data type using the `AccumulatorSigned`, `AccumulatorWL`, and `AccumulatorFL` properties.

Signed or unsigned accumulator data format. All output is signed format.

Accumulator word length, in bits, specified as an integer. This value must include the sign bit.

If the `PhaseQuantization` property is `0` (`false`), this property must be less than or equal to 17 bits for HDL code generation. In the nonquantized case, the lookup table of sine values has 2AccumulatorWL-2 entries.

Accumulator fraction length, in bits. The accumulator operates on integers. If the phase increment is fixed-point type with a fractional part, the object returns an error.

Whether to quantize accumulated phase, specified as `1` (`true`) or `0` (`false`). When this property is enabled, the object quantizes the result of the phase accumulator to a fixed bit-width. This quantized value is used to select a waveform value from the lookup table. Select the resolution of the lookup table by using the `NumQuantizerAccumulatorBits` property.

The frequency resolution of an NCO is defined by $\Delta f=\frac{1}{{T}_{s}\cdot {2}^{N}}\text{Hz}$, where N is the `NumQuantizerAccumulatorBits` property value.

When you disable this property, the object uses the accumulator data type as the address of the lookup table. In this case, N is the `AccumulatorWL` property value.

Number of quantizer accumulator bits, specified as an integer greater than 4 and less than the `AccumulatorWL` property value. This property must be less than or equal to 17 bits for HDL code generation. The lookup table of sine values has 2`NumQuantizerAccumulatorBits`-2 entries.

#### Dependencies

To enable this property, set the `PhaseQuantization` property to `1` (`true`).

Output data type. If you specify `'Binary point scaling'`, the object defines the fixed-point data type using the `OutputSigned`, `OutputWL`, and `OutputFL` properties.

This parameter is ignored if any input is of floating-point type. In that case, the output data type is `double`.

Signed or unsigned output data format. All output is signed format.

Output word length, in bits, specified as an integer. This value must include the sign bit.

Output fraction length, in bits, specified as a scalar integer.

## Usage

### Syntax

``````[Y,ValidOut] = hdlnco(Inc,ValidIn)``````
``````[Y,ValidOut] = hdlnco (ValidIn)``````
``````[Y,ValidOut] = hdlnco(Inc,Offset,Dither,ValidIn)``````
``[Y,Phase,ValidOut] = hdlnco(___)``
``[___] = hdlnco(___,ResetAccum,ValidIn)``

### Description

The object returns the waveform value, `Y`, as a sine value, a cosine value, a complex exponential value, or a [`Sine,Cosine`] pair of values, depending on the Waveform property.

``````[Y,ValidOut] = hdlnco(Inc,ValidIn)``` returns a sinusoidal signal, `Y`, generated by the HDLNCO System object, using the phase increment, `Inc`. When `ValidIn` is `true`, `Inc` is added to the accumulator. The `Inc` argument is optional. Alternatively, you can specify the phase increment as a property.```

example

``````[Y,ValidOut] = hdlnco (ValidIn)``` returns a waveform, `Y`, using waveform parameters from properties rather than input arguments.To use this syntax, set the PhaseIncrementSource, PhaseOffsetSource, and DitherSource properties to `'Property'`. These properties are independent of each other. For example: hdlnco = dsp.HDLNCO('PhaseIncrementSource','Property', ... 'PhaseIncrement',phIncr,... 'PhaseOffset',phOffset,... 'NumDitherBits',4)```

example

``````[Y,ValidOut] = hdlnco(Inc,Offset,Dither,ValidIn)``` returns a waveform, `Y`, with phase increment, `Inc`, phase offset, `Offset`, and dither, `Dither`. This syntax applies when you set the PhaseIncrementSource, PhaseOffsetSource, and DitherSource properties to `'Input port'`. These properties are independent of each other. You can mix and match the activation of these arguments. `PhaseIncrementSource` is `'Input port'` by default. For example: hdlnco = dsp.HDLNCO('PhaseOffsetSource','Input port',... 'DitherSource','Input port') for k = 1:1/Ts y(k) = hdlnco(phIncr,phOffset,ditherBits,true); end```
````[Y,Phase,ValidOut] = hdlnco(___)` returns a waveform, `Y`, and current phase, `Phase`. The phase is the output of the quantized accumulator.To use this syntax, set the PhasePort property to `true`. This syntax can include any of the arguments from other syntaxes.```
````[___] = hdlnco(___,ResetAccum,ValidIn)` resets the accumulator value, but does not reset the output samples in the pipeline. If `ValidIn` is `true`, then the object continues to generate the output waveform starting from the reset accumulator value. To use this syntax, set the ResetAction property to `1` (`true`). This syntax can include any of the arguments from other syntaxes.```

### Input Arguments

expand all

Phase increment, specified as a scalar integer.

`double` and `single` data types are supported for simulation, but not for HDL code generation.

#### Dependencies

To enable this argument, set the PhaseIncrementSource property to ```'Input port'```.

Data Types: `single` | `double` | `int8` | `int16` | `int32` | `int64` | `uint8` | `uint16` | `uint32` | `uint64` | `fixdt([],N,0)`

Control signal that enables NCO operation, specified as a `logical` scalar. When `ValidIn` is `true`, the object increments the phase and captures any input values. When `ValidIn` is `false`, the object holds the phase accumulator and ignores any input values.

When the `SamplesPerFrame` property value is greater than `1`, this signal enables processing of `SamplesPerFrame` samples.

Data Types: `logical`

Phase offset, specified as a scalar integer.

`double` and `single` data types are supported for simulation but not for HDL code generation.

#### Dependencies

To enable this argument, set the PhaseOffsetSource property to `'Input port'`.

Data Types: `single` | `double` | `int8` | `int16` | `int32` | `int64` | `uint8` | `uint16` | `uint32` | `uint64` | `fixdt([],N,0)`

Dither, specified as an integer or as a column vector of integers. The length of the vector must equal the `SamplesPerFrame` property value.

`double` and `single` data types are supported for simulation, but not for HDL code generation.

#### Dependencies

To enable this argument, set the DitherSource property to `'Input port'`.

Data Types: `single` | `double` | `int8` | `int16` | `int32` | `int64` | `uint8` | `uint16` | `uint32` | `uint64` | `fixdt([],N,0)`

Control signal that resets the accumulator, specified as a `logical` scalar . When this signal is `true`, the object resets the accumulator to its initial value. This signal does not reset the output samples in the pipeline.

#### Dependencies

To enable this argument, set the ResetAction property to `1` (`true`).

Data Types: `logical`

### Output Arguments

expand all

Generated waveform, returned as a scalar or a vector of length `SamplesPerFrame`. This argument can be a `sin` or `cos` value, an `exp` value representing `cosine + j*sine`, or a pair of arguments in the form `[Sine,Cosine]`.

If any input is of floating-point type, the object returns floating-point values for the waveform and `Phase` arguments, otherwise the object returns values using the type defined by the `OutputDataType` property.

`double` and `single` data types are supported for simulation, but not for HDL code generation.

#### Dependencies

By default, the output waveform is a sine wave. The format of the output waveform depends on the Waveform property.

Control signal that indicates validity of output data, specified as a `logical` scalar. When `validOut` is `true`, the values of `Y` and `Phase` are valid. When `validOut` is `false`, the values of `Y` and `Phase` are not valid.

When the `SamplesPerFrame` property value is greater than `1`, this signal indicates the validity of all elements in the output vectors.

Data Types: `logical`

Current phase of the NCO, returned as a scalar or as a vector of length `SamplesPerFrame`. The phase is the output of the quantized accumulator with offset and increment applied. If quantization is disabled, this port returns the output of the accumulator with offset and increment applied.

The values are of type `fixdt(1,N,0)`, where `N` is the `NumQuantizerAccumulatorBits` property value. If quantization is disabled, then `N` is the `AccumulatorWL` property value.

If any input argument is floating-point type, the object returns the `Phase` argument as a floating point value. Floating-point types are supported for simulation but not for HDL code generation.

#### Dependencies

To enable this argument, set the PhasePort property to `1` (`true`).

Data Types: `single` | `double` | `fixdt(1,N,0)`

## Object Functions

To use an object function, specify the System object as the first input argument. For example, to release system resources of a System object named `obj`, use this syntax:

`release(obj)`

expand all

 `step` Run System object algorithm `release` Release resources and allow changes to System object property values and input characteristics `reset` Reset internal states of System object

## Examples

collapse all

This example shows how to design an HDL-compatible NCO source.

Write a function that creates and calls the System object™, based on the waveform requirements. You can generate HDL from this function.

Note: This object syntax runs only in R2016b or later. If you are using an earlier release, replace each call of an object with the equivalent `step` syntax. For example, replace `myObject(x)` with `step(myObject,x)`.

```function yOut = HDLNCO510(validIn) %HDLNCO510 % Generates one sample of NCO waveform using the dsp.HDLNCO System object(TM) % validIn is a logical scalar value % phase increment, phase offset, and dither are fixed. % You can generate HDL code from this function. persistent nco510; if isempty(nco510) % Since calculation of the object parameters results in constant values, this % code is not included in the generated HDL. The generated HDL code for % the NCO object is initialized with the constant property values. F0 = 510; % Target output frequency in Hz dphi = pi/2; % Target phase offset df = 0.05; % Frequency resolution in Hz minSFDR = 96; % Spurious free dynamic range(SFDR) in dB Ts = 1/4000; % Sample period in seconds % Calculate the number of accumulator bits required for the frequency % resolution and the number of quantized accumulator bits to satisfy the SFDR % requirement. Nacc = ceil(log2(1/(df*Ts))); % Actual frequency resolution achieved = 1/(Ts*2^Nacc) Nqacc = ceil((minSFDR-12)/6); % Calculate the phase increment and offset to achieve the target frequency % and offset. phIncr = round(F0*Ts*2^Nacc); phOffset = 2^Nacc*dphi/(2*pi); nco510 = dsp.HDLNCO('PhaseIncrementSource','Property', ... 'PhaseIncrement',phIncr,... 'PhaseOffset',phOffset,... 'NumDitherBits',4, ... 'NumQuantizerAccumulatorBits',Nqacc,... 'AccumulatorWL',Nacc); end yOut = nco510(validIn); end ```

Call the object to generate data points in a sine wave. The input to the object is a valid control signal.

```Ts = 1/4000; y = zeros(1,1/Ts); for k = 1:1/Ts y(k) = HDLNCO510(true); end ```

Plot the mean-square spectrum of the 510 Hz sine wave generated by the NCO.

```sa = dsp.SpectrumAnalyzer('SampleRate',1/Ts); sa.SpectrumType = 'Power density'; sa.PlotAsTwoSidedSpectrum = false; sa(y') ``` ## Algorithms

expand all

The NCO implementation depends on whether you enable the `LUTCompress` property.

Without lookup table compression, the object uses the same quarter-sine lookup table as the NCO block. The size of the LUT is 2`NumQuantizerAccumulatorBits`-2×`OutputWL` bits. If you do not enable `PhaseQuantization`, then `NumQuantizerAccumulatorBits`=`AccumulatorWL`. Consider the impact on simulator memory and hardware resources when you select these parameters.

## Compatibility Considerations

expand all

Behavior changed in R2020a

Behavior changed in R2020a

 Cordesses, L., "Direct Digital Synthesis: A Tool for Periodic Wave Generation (Part 1)." IEEE Signal Processing Magazine. Volume 21, Issue 4, July 2004, pp. 50–54.

Watch now