Documentation

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. When you use integer or fixed-point input signals, or use the object as a source with no input signal, the object uses quantized integer accumulation to create a sinusoid signal. The HDL NCO System object provides these features:

• 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 triggers a reset of the phase to its initial value during the sinusoid output generation.

• An optional output argument for the current NCO phase.

The System object does not support the property that allows the NCO HDL Optimized block to synthesize the lookup table to a ROM when using HDL Coder™ with an FPGA target.

Given a desired output frequency F0, calculate the phase increment input value using

$phaseincrement=\left(\frac{{F}_{0}\cdot {2}^{N}}{{F}_{s}}\right)$

where N is the accumulator word length and

${F}_{s}=\frac{1}{{T}_{s}}=\frac{1}{sampletime}$

You can specify the phase increment using a property or an input argument.

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 input value using

$phaseoffset=\frac{{2}^{N}\cdot desiredphaseoffset}{2\pi }$

You can specify the phase offset using a property or an input argument.

When you use floating-point input signals, the object does not quantize the accumulation. Therefore, you must choose increment and offset values to represent a fraction of 2π without quantization.

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.

To learn more about how System objects work, see What Are System Objects? (MATLAB).

Creation

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',14, ...
'AccumulatorWL',17);

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 an input is fixed point or when all input arguments are disabled, the object computes the output waveform based on the fixed-point property settings. When a data input is floating point, the object computes a double-precision output waveform and ignores properties related to fixed-point settings (NumDitherBits, PhaseQuantization, NumQuantizerAccumulatorBits, LUTCompress, and the fixed-point data type properties).

When you switch to using a floating-point phase increment, you must adjust the value of the increment to account for the lack of phase quantization.

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.

For more information on changing property values, see System Design in MATLAB Using System Objects (MATLAB).

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 a scalar integer. If the increment is a fixed-point value, the object uses only the integer bits and ignores any fractional bits. double and single data types are supported for simulation but not for HDL code generation. When you use floating-point input signals, you must choose increment and offset values to represent a fraction of 2π,

Dependencies

This property applies when you 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 a scalar integer. If the offset is a fixed-point value, the object uses only the integer bits and ignores any fractional bits. double and single data types are supported for simulation but not for HDL code generation. When you use floating-point input signals, you must choose increment and offset values to represent a fraction of 2π.

Dependencies

This property applies when you 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

This property applies when you set the DitherSource property to 'Property'.

Whether to quantize accumulated phase, specified as true or 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 using the NumQuantizerAccumulatorBits property.

The frequency resolution of an NCO is defined by .

When you disable this property, the object uses the accumulator data type as the address of the lookup table.

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

Dependencies

This property applies when you set PhaseQuantization to 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 sine + j*cosine. If you select 'Sine and cosine', the object returns two values, sin and cos.

Return the current phase along with the output waveform, when enabled.

Control Signals

When enabled, the object accepts a reset argument. When the reset argument is 1 (true), the object resets the accumulator to zero.

When enabled, the object accepts a valid argument. When the valid argument is 1 (true), the object increments the phase. When the valid argument is 0 (false), the phase is held.

Data Types

Overflow mode for fixed-point operations. OverflowAction is a read-only property with value 'Wrap'.

Rounding mode for fixed-point operations. RoundingMethod is a read-only property with value 'Floor'.

Accumulator data type description. AccumulatorDataType is a read-only property with value 'Binary point scaling'. The object defines the fixed-point data type using the AccumulatorSigned, AccumulatorWL, and AccumulatorFL properties.

Signed or unsigned accumulator data format. AccumulatorSigned is a read-only property with value 'Signed'. All output is signed format.

Accumulator word length, in bits, specified as a scalar integer.

If PhaseQuantization is false, this property must be less than or equal to 17 bits for HDL code generation.

Accumulator fraction length, in bits. AccumulatorFL is a read-only property. The accumulator fraction length is zero bits. The accumulator operates on integers. If the phase increment is fixed-point type with a fractional part, the object ignores the fractional part.

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

Signed or unsigned output data format. OutputSigned is a read-only property with value 'Signed'. All output is signed format.

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

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

Usage

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 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' and ValidInputPort to false. These properties are independent of each other. For example:

hdlnco = dsp.HDLNCO('PhaseIncrementSource','Property', ...
'PhaseIncrement',phIncr,...
'PhaseOffset',phOffset,...
'ValidInputPort',false,...
'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.

To use this syntax, set the PhasePort property to true. This syntax can include any of the arguments from other syntaxes. For example:

hdlnco = dsp.HDLNCO('PhaseOffsetSource','Input port',...
'DitherSource','Input port',...
'PhasePort',true)
for k = 1:1/Ts
[phase(k),y(k)] = hdlnco(phIncr,phOffset,ditherBits,true);
end

Input Arguments

expand all

Phase increment, specified as a scalar integer. If the phase increment is a fixed-point value, the object uses only the integer bits and ignores any fractional bits. double and single data types are supported for simulation but not for HDL code generation. When you use floating-point input signals, you must choose increment and offset values to represent a fraction of 2π.

Dependencies

The object accepts this argument when you 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 1 (true), the object increments the phase. When ValidIn is 0 (false), the object holds the phase.

Dependencies

The object accepts this argument when you set the ValidInputPort property to true.

Data Types: logical

Phase offset, specified as a scalar integer. If the offset is a fixed-point value, the object uses only the integer bits and ignores any fractional bits. double and single data types are supported for simulation but not for HDL code generation. When you use floating-point input signals, you must choose increment and offset values to represent a fraction of 2π.

Dependencies

The object accepts this argument when you 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 a scalar integer. double and single data types are supported for simulation but not for HDL code generation.

Dependencies

The object accepts this argument when you 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 scalar logical. When Reset is 1 (true), the object resets the accumulator to 0.

Dependencies

The object accepts this argument when you set the ResetAction property to true.

Data Types: logical

Output Arguments

expand all

Generated waveform, returned as a scalar sin or cos value, as a scalar exp value representing sine + j*cosine, or as a pair of values, [sin,cos]. If any input is floating-point type, the object returns floating-point values, otherwise the object returns fixed-point values. Floating point 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 whether the other output argument values are valid or not. When validOut is 1 (true), the values of Y and Phase are valid. When validOut is 0 (false), the values of Y and Phase are not valid.

Data Types: logical

Current phase of the NCO, returned as a scalar of type fixdt(1,M,-Z), where M is the number of quantized accumulator bits, and Z is the accumulator word length. If the input to the object is floating point, the object returns Phase as floating point. Floating point is supported for simulation but not for HDL code generation.

Dependencies

The object returns this argument when you set the PhasePort property to true.

Data Types: single | double | fixdt(1,NumQuantizerAccumulatorBits,-AccumulatorWL)

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

expand 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 2NumQuantizerAccumulatorBits-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.

 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