%% Generate a Sine Wave
% This example shows how to use the NCO HDL Optimized block to generate
% a sine wave. The example generates a sine wave with these specifications.
%
% Copyright 2021 The MathWorks, Inc.

F0 = 510;       % Desired output frequency (Hz)
Deltaf = 0.05;  % Frequency resolution (Hz)
SFDR = 90;      % Spurious free dynamic range (dB)
Ts = 1/8000;    % Sample period (s)
phOffd = pi/2;  % Desired phase offset (rad)

%%
% The frequency resolution of the sine wave depends on the size of the 
% accumulator. Calculate the number of required accumulator bits to achieve
% the desired frequency resolution. |N| must be an integer value. Use this
% value to set the accumulator data type *Word length* parameter.
%
% $$ N = {\mathop{\rm ceil}}({\mathop{\rm log2}}({1 \over {{T_s} \cdot {\Delta f}}})) $$
%

N = ceil(log2(1/(Ts*Deltaf))) %#ok<*NOPTS> 

%%
% Quantizing the output of the accumulator allows you to achieve better 
% frequency resolution without increasing the lookup table size. Calculate
% the number of quantized accumulator bits from the spurious free dynamic 
% range specification. Ensure that the *Quantize phase*
% parameter is selected, and then use this value to set the set the *Number of 
% quantizer accumulator bits* parameter. 
%
% $$ Q = {\mathop{\rm ceil}}({\frac{{SFDR} - 12}{6}}) $$
%

Q = ceil((SFDR - 12)/6)

%%
% Calculate the phase increment. Use this value to set the *Phase increment* 
% parameter.
%
% $$ phIncr = {\mathop{\rm round}}({{{F_0} \cdot {2^N}} {T_s}}) $$
%

phIncr = round(F0*2^N*Ts)

%%
% Phase offset and dither are optionally added in the accumulator stage. 
% Calculate the phase offset that the block adds from the desired phase 
% offset of the output wave.  Use this value to set the *Phase offset* 
% parameter.
%
% $$ phOff = {{{2^{N}} \cdot PhOff_d} \over {2\pi }} $$
%
 
phOff = (2^N*phOffd)/(2*pi)

%%
% 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. Use this value to set the *Number
% of dither bits* parameter.

ditherBits = N - Q

%%
% Open and simulate the model. The NCO HDL Optimized block in the model is 
% configured with the variables calculated in this script. 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. 

open_system('GenerateSineWaveHDL')
sim('GenerateSineWaveHDL')
%%
%
% The Peak Finder results in the Spectrum Analyzer show that the output 
% waveform is generated at 510 Hz. 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.


