RandomVibe
RandomVibe

Reputation: 41

Direct Digital Synthesis - What is Phase Truncation?

I'm developing a Direct Digital Synthesis (DDS) waveform generator on the Arduino Due in C/C++. But I'm first implementing an example in Matlab to make sure I understand the main components, which are: the Phase or Angle Accumulator (N-bits), the Lookup table (P-bits), and the Digital-to-Analog converter (12-bits). I understand these basic elements.

The Lookup table size will match the DAC resolution, so P=12. The Accumulator will be at least 16-bits long (N=16). So phase truncation must occur here. Therein lies my confusion and my question. How does this truncation work? What does it mean to take the P significant bits of N?

Upvotes: 3

Views: 1295

Answers (2)

RandomVibe
RandomVibe

Reputation: 41

This binary math and bitwise manipulation is new to me, but I'm beginning to understand. I implemented a Direct Digital Synthesis (DDS) example in Matlab. Code below for others. May also run on Octave.

% INPUT PARAMETERS
%-----------------------
fs    = 2^14;   % Clock Sample Rate (hz)
NT    = 1e4;    % Total Samples for example 
foutd = 80;     % Desired Output Freq. (hz)
N     = 16;     % Accumulator resolution (bits)
P     = 12;     % Lookup Table resolution (bits)


% FREQUENCY TUNING WORD
%------------------------------
FTWf = foutd/fs*2^N;          % float
FTW  = round(foutd/fs*2^N);   % actual integer term for accumulator
fout = FTW*fs/2^N;            % actual output frequency


% SINE WAVE LOOKUP TABLE
%---------------------------
x = [0:2^P-1]';
y = sin(x*2*pi / (2^P-1) );


% INITIALIZE
%--------------------------
dt    = 1/fs;                % Time Step (sec)
t     = [0:dt:dt*(NT-1)]';   % Time Vector
phase = zeros(NT,1);         % Save phase vs. time
wave  = zeros(NT,1);         % Save wave amplitude vs. time


% SAMPLE THROUGH TIME
%-----------------------
pa = 0;   % Phase accumulator

for ii=1:length(t)

    % ACCUMULATE PHASE
    pa = pa + FTW;

    % ROLLOVER PHASE
    if pa > 2^N
        pa = 1;
    end 

    % PHASE TRUNCATION
    indx = ceil(pa * 2^(P-N));

    % LOOKUP
    phase(ii) = pa;
    wave(ii)  = y( indx );

end

figure;
subplot(211),  plot(t, phase); grid on;
subplot(212),  plot(t, wave);  grid on; hold on
               plot(t,sin(foutd*2*pi*t), 'r-.');

My next step is to implement this on the ArduinoDue. This algorithm will be the basis of the ISR interrupt function. I will definitely use binary operators to speed up the division (i.e., "Phase Truncation").

After that, I need to figure out how to handle non-integer frequency inputs.

Upvotes: 1

Ziezi
Ziezi

Reputation: 6467

In general, if you have N bit long value, one possible value, let say (in binary, i.e. epxressed using 2 bits (1's and 0's), where each bit, depending on its position represents a power of 2) is:
1000 1111 0000 1010
The most significant bits are the ones counting from left to right, i.e.: the four most significant bits in the example are: 1000. So, truncating by taking the P significant bits means that you count till P from left to right and what is left is ignored.
In decimal representation, i.e. expressed using 10 numbers (0,1,..,8,9), this will be analogous to: if your values is : 110124 and you take only P=3 significant numbers, you will remain with: 110000, i.e. the 3 least significant numbers (124) are not regarded, thereby loosing some detail.

Upvotes: 1

Related Questions