| Design | Schematics | Embedded CPU | JAM STAPL | Loop Filter | Spectra | MASH | Simulation | Back to projects |
3rd-order is more the norm; but in this project I used a 4th-order (i.e. 4-stage) 32-bit MASH. The yellow delays are latches clocked by the VCO divider:
Figure 1
The long-term average of output ΔN is exactly F/M, where M is the modulus of the 32-bit overflowing accumulators. ΔN is computed (via a chain of summers, delays and negations) from the carry overflows. When input F is a constant K, the first accumulator overflows K times in every 232 clock cycles, and the long-term mean of ΔN is K/232. Carries from the other accumulators have no long-term effect.
Although ΔN can only take 16 integer values (between -7 and +8 for a 4-stage MASH) the achievable resolution, after low-pass filtering, is extremely high. ΔN resembles a pseudo-random sequence:
Figure 2 - ΔN sequence - time & frequency domains [ C++ Code ]
Right: Fourier series of 4-stage, 24-bit MASH;
F=1;
Hanning Window length = 2^20;
Slope = 80dB/decade.
Another important property is the way the MASH colours its output spectral content. Output noise is actively concentrated at higher frequencies, where it is easily removed by low-pass filtering. This is termed noise shaping. Each stage cancels its predecessor's noise, substituting new noise of its own. Noise from the final stage remains, but is subjected to several orders of high-pass filtering. This will be demonstrated mathematically using the z-transform. If you've never heard of it, you may need to study elsewhere first; but only a very basic awareness is necessary. Only two z-transforms are actually required:
| Transform | Description | Example |
| z-1 | Unit time delay (one sample period) | X[n].z-1 = X[n-1] |
| 1 - z-1 | Differentiation (high-pass filter) | X[n].(1 - z-1) = X[n] - X[n-1] |
Still with me? OK. First, before we get down to the nitty-gritty, a small digression ...
![]() |
Y[n] = X[n].(1-z-1) = X[n] - X[n-1] |
The structure depicted in figure 1 is not the only way to construct a MASH. The stored program which controls this synthesizer is based on an alternative form, which calculates ΔN by a weighted-sum of delayed carries, with weights resembling the rows of Pascal's triangle:
ΔN[n] = C1[n] + C2[n].(1-z-1) + C3[n].(1-z-1)2 + C4[n].(1-z-1)3 ..... [1]
ΔN[n] = C1[n] + C2[n].(1-z-1) + C3[n].(1-2z-1+z-2) + C4[n].(1-3z-1+3z-2-z-3) ..... [2]
In equation 1, the chain of differentiators is represented by powers of (1-z-1) which are expanded in equation 2 to reveal the familiar Pascal's triangle pattern:
+1
+1 -1
+1 -2 +1
+1 -3 +3 -1
Terms of the form Ci[n].z-a represent the delayed carries; the negative exponent is the number of clock cycles delayed.
Since each row of the triangle, except the first, sums to zero, it's easy to see why only carries from the first stage have a long-term net-effect.
Returning to the main topic ...
The challenge comes in modelling carry and overflow. Whenever a carry occurs, we need to subtract 1.0 from the sum:
|
|
† this can exceed 1.00; it's not the same as the residual sum
†† see below |
We can't use non-linear functions like int() and mod() to generate the carry. The equations need to be algebraically manipulable. The standard trick is to inject "quantisation noise" like so:
Figure 3(a) overflowing accumulator; 3(b) 1st order ΣΔ modulator (error feedback topology)
The awkward non-linearity has been absorbed in e[n], which happens to be the negation of the residual sum at the accumulator output. This is very handy, as you will see. You should convince yourself the linearised model on the right is equivalent to the circuit on the left. Also, note the position of the binary point.
We can now derive the transfer function of the stage:
C[n] = S[n] + e[n]
S[n] = X[n] - e[n].z-1
Eliminating S[n] yields:
C[n] = X[n] + e[n].(1-z-1)
This is the transfer function of a first-order sigma delta modulator. Known as the error feedback topology, figure 3(b) is not the only way to draw it. Being a negative feedback system, containing an integrator, it exhibits a high-pass response to the injected noise. The output equals the input plus (shaped) quantisation noise, and the (quantised) output is only 1-bit wide.
Using the transfer function derived above, we can now write down equations for the overflow carries:
C1[n] = e1[n].(1-z-1) + F[n]
C2[n] = e2[n].(1-z-1) - e1[n]
C3[n] = e3[n].(1-z-1) - e2[n]
C4[n] = e4[n].(1-z-1) - e3[n]
Finally, we can express output ΔN in terms of fractional input command F:
ΔN[n] = C1[n] + C2[n].(1-z-1) + C3[n].(1-z-1)2 + C4[n].(1-z-1)3
ΔN[n] = e4[n].(1-z-1)4 + F[n]
Each stage cancels the noise of its predecessor.
ΔN equals F plus the (highly shaped) noise of the last stage. The high-pass term is raised to the 4th power, and simulated output noise rises at 80dB/decade for a 4-stage MASH, suggesting that e4 is white noise. Also note: the MASH has an ideal step response.
| Copyright © Andrew Holme, 2005. |
|