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 desired output frequency F0, calculate the phase increment input value using

phase increment=(F02NFs)

, where N is the quantized accumulator word length and

Fs=1Ts=1sample time

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

The frequency resolution of an NCO is defined by

Δf=1Ts2NHz

Given a desired phase offset (in radians), calculate the phase offset input value using

phase offset=2Ndesired phase offset2π

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.

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',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.

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 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

This property is read-only.

Overflow mode for fixed-point operations.

This property is read-only.

Rounding mode for fixed-point operations.

This property is read-only.

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

This property is read-only.

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.

This property is read-only.

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 Δf=1Ts2NHz, 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 2NumQuantizerAccumulatorBits-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.

This property is read-only.

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

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. 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 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

stepRun System object algorithm
releaseRelease resources and allow changes to System object property values and input characteristics
resetReset 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 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.

Compatibility Considerations

expand all

Behavior changed in R2020a

Behavior changed in R2020a

References

[1] 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.

See Also

Objects

Blocks

Introduced in R2013a