Home Knowledge Base Digital signal processing

Digital signal processing is the numerical manipulation of sampled signals to filter, transform, detect, compress, modulate, or reconstruct information. Every layer of an AI chip's surrounding system — audio front-ends, radar, image sensors, SerDes PHYs, wireless modems — relies on DSP algorithms implemented in hardware MAC arrays, dedicated DSP cores, or programmable vector engines.

<svg viewBox="0 0 760 470" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Digital Signal Processing — sampling and aliasing, FIR filter, FFT butterfly for AI chip DSP">
<defs>
<style>text{font-family:ui-monospace,'Cascadia Code',SFMono-Regular,Consolas,monospace;fill:#c9d1d9}.dim{fill:#8b949e}.hdr{font-size:12px;font-weight:700;fill:#e6edf3}.lrg{font-size:11px;fill:#e6edf3;font-weight:700}.med{font-size:10px}.sm{font-size:9px}</style>
<marker id="dsp_arr" markerWidth="7" markerHeight="7" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6" fill="#8b949e"/></marker>
<marker id="dsp_garr" markerWidth="7" markerHeight="7" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6" fill="#3fb950"/></marker>
<marker id="dsp_barr" markerWidth="7" markerHeight="7" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6" fill="#388bfd"/></marker>
</defs>
<rect width="760" height="470" fill="#0d1117"/>

<!-- ═══ PANEL 1: Sampling & Anti-Aliasing (x=8,y=8,w=234,h=290) ═══ -->
<rect x="8" y="8" width="234" height="290" rx="6" fill="#161b22"/>
<text x="125" y="27" text-anchor="middle" class="hdr">Sampling &amp; Anti-Aliasing</text>

<!-- Continuous signal -->
<text x="125" y="44" text-anchor="middle" class="sm dim">Continuous signal x(t)</text>
<path d="M18,68 C30,48 42,88 54,68 C66,48 78,88 90,68 C102,48 114,88 126,68 C138,48 150,88 162,68 C174,48 186,88 198,68 C210,48 222,88 234,68" fill="none" stroke="#388bfd" stroke-width="1.5"/>

<!-- Sampling impulses -->
<text x="125" y="85" text-anchor="middle" class="sm dim">Sample at fs = 8 kHz (Nyquist: fs &gt; 2&#183;fmax)</text>
<g stroke="#d29922" stroke-width="1.2" fill="none">
  <line x1="30" y1="90" x2="30" y2="110"/>
  <line x1="58" y1="90" x2="58" y2="110"/>
  <line x1="86" y1="90" x2="86" y2="110"/>
  <line x1="114" y1="90" x2="114" y2="110"/>
  <line x1="142" y1="90" x2="142" y2="110"/>
  <line x1="170" y1="90" x2="170" y2="110"/>
  <line x1="198" y1="90" x2="198" y2="110"/>
  <line x1="226" y1="90" x2="226" y2="110"/>
</g>
<text x="125" y="124" text-anchor="middle" class="sm dim">↑ discrete samples x[n]</text>

<!-- Nyquist zones -->
<rect x="18" y="130" width="214" height="50" rx="3" fill="#0d1117" stroke="#30363d" stroke-width="1"/>
<text x="125" y="147" text-anchor="middle" class="sm" fill="#3fb950">Nyquist: fs &gt; 2 &#215; fmax</text>
<text x="125" y="161" text-anchor="middle" class="sm dim">fs=8kHz &#8594; max signal freq = 4 kHz (voice)</text>
<text x="125" y="172" text-anchor="middle" class="sm dim">ADC anti-alias filter before sampling</text>

<!-- Aliasing illustration -->
<rect x="18" y="188" width="214" height="54" rx="3" fill="#1c1010" stroke="#f85149" stroke-width="1"/>
<text x="125" y="204" text-anchor="middle" class="sm" fill="#f85149">Aliasing: fs &lt; 2&#183;fmax &#8594; fold-back</text>
<!-- Two sine waves overlapping to show aliasing -->
<path d="M22,228 C32,210 42,246 52,228 C62,210 72,246 82,228 C92,210 102,246 112,228" fill="none" stroke="#388bfd" stroke-width="1.2"/>
<path d="M22,228 C42,210 62,246 82,228 C102,210 122,246 142,228" fill="none" stroke="#f85149" stroke-width="1.2" stroke-dasharray="4,2"/>
<text x="155" y="222" class="sm" fill="#388bfd">true</text>
<text x="155" y="234" class="sm" fill="#f85149">alias</text>
<text x="125" y="252" text-anchor="middle" class="sm dim">indistinguishable after sampling</text>

<!-- Quantization -->
<rect x="18" y="250" width="214" height="40" rx="3" fill="#0d1117" stroke="#30363d" stroke-width="1"/>
<text x="125" y="265" text-anchor="middle" class="sm" fill="#d29922">Quantization: N bits &#8594; SNR &#8776; 6N + 1.76 dB</text>
<text x="125" y="278" text-anchor="middle" class="sm dim">16-bit audio: ~98 dB SNR &#183; 12-bit ADC: ~74 dB</text>


<!-- ═══ PANEL 2: FIR Filter (x=250,y=8,w=244,h=290) ═══ -->
<rect x="250" y="8" width="244" height="290" rx="6" fill="#161b22"/>
<text x="372" y="27" text-anchor="middle" class="hdr">FIR Filter — Tapped Delay Line</text>

<!-- FIR structure: x[n] -> z^-1 -> z^-1 -> z^-1 -->
<!-- Input -->
<text x="258" y="50" class="sm dim">x[n]</text>
<line x1="275" y1="46" x2="290" y2="46" stroke="#8b949e" stroke-width="1.2" marker-end="url(#dsp_arr)"/>

<!-- Delay elements -->
<rect x="290" y="36" width="30" height="20" rx="3" fill="#0d1117" stroke="#388bfd" stroke-width="1.2"/>
<text x="305" y="51" text-anchor="middle" class="sm" fill="#388bfd">z&#8315;&#185;</text>
<line x1="320" y1="46" x2="340" y2="46" stroke="#8b949e" stroke-width="1.2" marker-end="url(#dsp_arr)"/>

<rect x="340" y="36" width="30" height="20" rx="3" fill="#0d1117" stroke="#388bfd" stroke-width="1.2"/>
<text x="355" y="51" text-anchor="middle" class="sm" fill="#388bfd">z&#8315;&#185;</text>
<line x1="370" y1="46" x2="390" y2="46" stroke="#8b949e" stroke-width="1.2" marker-end="url(#dsp_arr)"/>

<rect x="390" y="36" width="30" height="20" rx="3" fill="#0d1117" stroke="#388bfd" stroke-width="1.2"/>
<text x="405" y="51" text-anchor="middle" class="sm" fill="#388bfd">z&#8315;&#185;</text>
<line x1="420" y1="46" x2="440" y2="46" stroke="#8b949e" stroke-width="1.2" marker-end="url(#dsp_arr)"/>

<rect x="440" y="36" width="30" height="20" rx="3" fill="#0d1117" stroke="#388bfd" stroke-width="1.2"/>
<text x="455" y="51" text-anchor="middle" class="sm" fill="#388bfd">z&#8315;&#185;</text>

<!-- Coefficient taps -->
<!-- Vertical lines down from each tap -->
<line x1="275" y1="46" x2="275" y2="72" stroke="#8b949e" stroke-width="1"/>
<line x1="305" y1="56" x2="305" y2="72" stroke="#8b949e" stroke-width="1"/>
<line x1="355" y1="56" x2="355" y2="72" stroke="#8b949e" stroke-width="1"/>
<line x1="405" y1="56" x2="405" y2="72" stroke="#8b949e" stroke-width="1"/>
<line x1="455" y1="56" x2="455" y2="72" stroke="#8b949e" stroke-width="1"/>

<!-- Multiplier circles -->
<circle cx="275" cy="80" r="8" fill="#0d1117" stroke="#d29922" stroke-width="1.2"/>
<text x="275" y="84" text-anchor="middle" class="sm" fill="#d29922">h&#x2080;</text>
<circle cx="305" cy="80" r="8" fill="#0d1117" stroke="#d29922" stroke-width="1.2"/>
<text x="305" y="84" text-anchor="middle" class="sm" fill="#d29922">h&#x2081;</text>
<circle cx="355" cy="80" r="8" fill="#0d1117" stroke="#d29922" stroke-width="1.2"/>
<text x="355" y="84" text-anchor="middle" class="sm" fill="#d29922">h&#x2082;</text>
<circle cx="405" cy="80" r="8" fill="#0d1117" stroke="#d29922" stroke-width="1.2"/>
<text x="405" y="84" text-anchor="middle" class="sm" fill="#d29922">h&#x2083;</text>
<circle cx="455" cy="80" r="8" fill="#0d1117" stroke="#d29922" stroke-width="1.2"/>
<text x="455" y="84" text-anchor="middle" class="sm" fill="#d29922">h&#x2084;</text>

<!-- Adder -->
<line x1="275" y1="88" x2="275" y2="104" stroke="#8b949e" stroke-width="1"/>
<line x1="305" y1="88" x2="305" y2="104" stroke="#8b949e" stroke-width="1"/>
<line x1="355" y1="88" x2="355" y2="104" stroke="#8b949e" stroke-width="1"/>
<line x1="405" y1="88" x2="405" y2="104" stroke="#8b949e" stroke-width="1"/>
<line x1="455" y1="88" x2="455" y2="104" stroke="#8b949e" stroke-width="1"/>
<!-- Horizontal summing bus -->
<line x1="275" y1="104" x2="455" y2="104" stroke="#3fb950" stroke-width="1.5"/>
<circle cx="365" cy="108" r="8" fill="#0d1117" stroke="#3fb950" stroke-width="1.5"/>
<text x="365" y="112" text-anchor="middle" class="sm" fill="#3fb950">&#931;</text>
<line x1="365" y1="116" x2="365" y2="128" stroke="#3fb950" stroke-width="1.2" marker-end="url(#dsp_garr)"/>
<text x="370" y="128" class="sm dim">y[n]</text>

<!-- Equation -->
<text x="372" y="148" text-anchor="middle" class="sm" fill="#d29922">y[n] = &#8721; h[k] &#183; x[n&#8722;k]  (k=0..N&#8722;1)</text>
<text x="372" y="162" text-anchor="middle" class="sm dim">N taps &#8594; N multiplications + N&#8722;1 additions per output</text>

<!-- Frequency response -->
<text x="372" y="180" text-anchor="middle" class="sm dim">Frequency response H(e^j&#969;) = DFT of h[k]</text>

<!-- Low-pass filter shape -->
<line x1="260" y1="218" x2="260" y2="272" stroke="#30363d" stroke-width="1"/>
<line x1="260" y1="272" x2="480" y2="272" stroke="#30363d" stroke-width="1"/>
<path d="M262,200 L310,200 L340,218 L380,268 L480,268" fill="none" stroke="#388bfd" stroke-width="2"/>
<text x="286" y="212" class="sm" fill="#388bfd">passband</text>
<text x="410" y="260" class="sm dim">stopband</text>
<line x1="338" y1="200" x2="338" y2="272" stroke="#f85149" stroke-width="1" stroke-dasharray="2,2"/>
<text x="340" y="212" class="sm" fill="#f85149">fc</text>
<text x="372" y="286" text-anchor="middle" class="sm dim">LPF shown &#183; HPF/BPF/BSF by coefficient choice</text>


<!-- ═══ PANEL 3: FFT Butterfly (x=502,y=8,w=250,h=290) ═══ -->
<rect x="502" y="8" width="250" height="290" rx="6" fill="#161b22"/>
<text x="627" y="27" text-anchor="middle" class="hdr">FFT — Cooley-Tukey Butterfly</text>

<!-- 8-point FFT: 3 stages, 4 butterflies per stage -->
<!-- Stage labels -->
<text x="532" y="44" class="sm dim">x[n]</text>
<text x="620" y="44" class="sm dim">Stage 1</text>
<text x="665" y="44" class="sm dim">Stage 2</text>
<text x="710" y="44" class="sm dim">X[k]</text>

<!-- Input nodes (bit-reversed order) -->
<g fill="#388bfd">
  <circle cx="532" cy="56" r="4"/><text x="515" y="60" class="sm dim">x[0]</text>
  <circle cx="532" cy="86" r="4"/><text x="515" y="90" class="sm dim">x[4]</text>
  <circle cx="532" cy="116" r="4"/><text x="515" y="120" class="sm dim">x[2]</text>
  <circle cx="532" cy="146" r="4"/><text x="515" y="150" class="sm dim">x[6]</text>
  <circle cx="532" cy="176" r="4"/><text x="515" y="180" class="sm dim">x[1]</text>
  <circle cx="532" cy="206" r="4"/><text x="515" y="210" class="sm dim">x[5]</text>
  <circle cx="532" cy="236" r="4"/><text x="515" y="240" class="sm dim">x[3]</text>
  <circle cx="532" cy="266" r="4"/><text x="515" y="270" class="sm dim">x[7]</text>
</g>

<!-- Stage 1 butterfly connections (8 inputs -> 8 outputs, stride 1) -->
<!-- Butterfly pair 1: nodes 0,1 (y=56,86) -->
<line x1="536" y1="56" x2="578" y2="56" stroke="#3fb950" stroke-width="1.2"/>
<line x1="536" y1="86" x2="578" y2="86" stroke="#3fb950" stroke-width="1.2"/>
<line x1="536" y1="56" x2="578" y2="86" stroke="#3fb950" stroke-width="0.8" opacity="0.5"/>
<line x1="536" y1="86" x2="578" y2="56" stroke="#3fb950" stroke-width="0.8" opacity="0.5"/>
<!-- Butterfly pair 2: nodes 2,3 (y=116,146) -->
<line x1="536" y1="116" x2="578" y2="116" stroke="#3fb950" stroke-width="1.2"/>
<line x1="536" y1="146" x2="578" y2="146" stroke="#3fb950" stroke-width="1.2"/>
<line x1="536" y1="116" x2="578" y2="146" stroke="#3fb950" stroke-width="0.8" opacity="0.5"/>
<line x1="536" y1="146" x2="578" y2="116" stroke="#3fb950" stroke-width="0.8" opacity="0.5"/>
<!-- Butterfly pair 3: nodes 4,5 (y=176,206) -->
<line x1="536" y1="176" x2="578" y2="176" stroke="#3fb950" stroke-width="1.2"/>
<line x1="536" y1="206" x2="578" y2="206" stroke="#3fb950" stroke-width="1.2"/>
<line x1="536" y1="176" x2="578" y2="206" stroke="#3fb950" stroke-width="0.8" opacity="0.5"/>
<line x1="536" y1="206" x2="578" y2="176" stroke="#3fb950" stroke-width="0.8" opacity="0.5"/>
<!-- Butterfly pair 4: nodes 6,7 (y=236,266) -->
<line x1="536" y1="236" x2="578" y2="236" stroke="#3fb950" stroke-width="1.2"/>
<line x1="536" y1="266" x2="578" y2="266" stroke="#3fb950" stroke-width="1.2"/>
<line x1="536" y1="236" x2="578" y2="266" stroke="#3fb950" stroke-width="0.8" opacity="0.5"/>
<line x1="536" y1="266" x2="578" y2="236" stroke="#3fb950" stroke-width="0.8" opacity="0.5"/>

<!-- Stage 1 output nodes -->
<g fill="#d29922">
  <circle cx="578" cy="56" r="4"/><circle cx="578" cy="86" r="4"/>
  <circle cx="578" cy="116" r="4"/><circle cx="578" cy="146" r="4"/>
  <circle cx="578" cy="176" r="4"/><circle cx="578" cy="206" r="4"/>
  <circle cx="578" cy="236" r="4"/><circle cx="578" cy="266" r="4"/>
</g>

<!-- Stage 2 (stride 2) -->
<line x1="582" y1="56" x2="622" y2="56" stroke="#d29922" stroke-width="1.2"/>
<line x1="582" y1="116" x2="622" y2="116" stroke="#d29922" stroke-width="1.2"/>
<line x1="582" y1="56" x2="622" y2="116" stroke="#d29922" stroke-width="0.8" opacity="0.5"/>
<line x1="582" y1="116" x2="622" y2="56" stroke="#d29922" stroke-width="0.8" opacity="0.5"/>

<line x1="582" y1="86" x2="622" y2="86" stroke="#d29922" stroke-width="1.2"/>
<line x1="582" y1="146" x2="622" y2="146" stroke="#d29922" stroke-width="1.2"/>
<line x1="582" y1="86" x2="622" y2="146" stroke="#d29922" stroke-width="0.8" opacity="0.5"/>
<line x1="582" y1="146" x2="622" y2="86" stroke="#d29922" stroke-width="0.8" opacity="0.5"/>

<line x1="582" y1="176" x2="622" y2="176" stroke="#d29922" stroke-width="1.2"/>
<line x1="582" y1="236" x2="622" y2="236" stroke="#d29922" stroke-width="1.2"/>
<line x1="582" y1="176" x2="622" y2="236" stroke="#d29922" stroke-width="0.8" opacity="0.5"/>
<line x1="582" y1="236" x2="622" y2="176" stroke="#d29922" stroke-width="0.8" opacity="0.5"/>

<line x1="582" y1="206" x2="622" y2="206" stroke="#d29922" stroke-width="1.2"/>
<line x1="582" y1="266" x2="622" y2="266" stroke="#d29922" stroke-width="1.2"/>
<line x1="582" y1="206" x2="622" y2="266" stroke="#d29922" stroke-width="0.8" opacity="0.5"/>
<line x1="582" y1="266" x2="622" y2="206" stroke="#d29922" stroke-width="0.8" opacity="0.5"/>

<!-- Stage 2 output nodes -->
<g fill="#f85149">
  <circle cx="622" cy="56" r="4"/><circle cx="622" cy="86" r="4"/>
  <circle cx="622" cy="116" r="4"/><circle cx="622" cy="146" r="4"/>
  <circle cx="622" cy="176" r="4"/><circle cx="622" cy="206" r="4"/>
  <circle cx="622" cy="236" r="4"/><circle cx="622" cy="266" r="4"/>
</g>

<!-- Stage 3 (stride 4) -> outputs -->
<line x1="626" y1="56" x2="700" y2="56" stroke="#f85149" stroke-width="1.2"/>
<line x1="626" y1="176" x2="700" y2="176" stroke="#f85149" stroke-width="1.2"/>
<line x1="626" y1="56" x2="700" y2="176" stroke="#f85149" stroke-width="0.8" opacity="0.5"/>
<line x1="626" y1="176" x2="700" y2="56" stroke="#f85149" stroke-width="0.8" opacity="0.5"/>
<line x1="626" y1="86" x2="700" y2="86" stroke="#f85149" stroke-width="1.2"/>
<line x1="626" y1="206" x2="700" y2="206" stroke="#f85149" stroke-width="1.2"/>
<line x1="626" y1="86" x2="700" y2="206" stroke="#f85149" stroke-width="0.8" opacity="0.5"/>
<line x1="626" y1="206" x2="700" y2="86" stroke="#f85149" stroke-width="0.8" opacity="0.5"/>
<line x1="626" y1="116" x2="700" y2="116" stroke="#f85149" stroke-width="1.2"/>
<line x1="626" y1="236" x2="700" y2="236" stroke="#f85149" stroke-width="1.2"/>
<line x1="626" y1="116" x2="700" y2="236" stroke="#f85149" stroke-width="0.8" opacity="0.5"/>
<line x1="626" y1="236" x2="700" y2="116" stroke="#f85149" stroke-width="0.8" opacity="0.5"/>
<line x1="626" y1="146" x2="700" y2="146" stroke="#f85149" stroke-width="1.2"/>
<line x1="626" y1="266" x2="700" y2="266" stroke="#f85149" stroke-width="1.2"/>
<line x1="626" y1="146" x2="700" y2="266" stroke="#f85149" stroke-width="0.8" opacity="0.5"/>
<line x1="626" y1="266" x2="700" y2="146" stroke="#f85149" stroke-width="0.8" opacity="0.5"/>

<!-- Output labels -->
<g fill="#a5d6ff">
  <circle cx="700" cy="56" r="4"/><text x="706" y="60" class="sm dim">X[0]</text>
  <circle cx="700" cy="86" r="4"/><text x="706" y="90" class="sm dim">X[1]</text>
  <circle cx="700" cy="116" r="4"/><text x="706" y="120" class="sm dim">X[2]</text>
  <circle cx="700" cy="146" r="4"/><text x="706" y="150" class="sm dim">X[3]</text>
  <circle cx="700" cy="176" r="4"/><text x="706" y="180" class="sm dim">X[4]</text>
  <circle cx="700" cy="206" r="4"/><text x="706" y="210" class="sm dim">X[5]</text>
  <circle cx="700" cy="236" r="4"/><text x="706" y="240" class="sm dim">X[6]</text>
  <circle cx="700" cy="266" r="4"/><text x="706" y="270" class="sm dim">X[7]</text>
</g>

<!-- Complexity note -->
<text x="627" y="284" text-anchor="middle" class="sm dim">N=8: 3 stages &#215; 4 butterflies &#183; O(N log N) vs O(N&#178;) DFT</text>


<!-- ═══ CARDS (y=305, h=158) ═══ -->
<!-- Card 1: DSP Pipeline -->
<rect x="8" y="305" width="234" height="158" rx="6" fill="#161b22"/>
<text x="125" y="322" text-anchor="middle" class="lrg">DSP Pipeline</text>
<text x="16" y="338" class="sm dim">Analog &#8594; Anti-alias LPF &#8594; ADC &#8594; DSP core &#8594; DAC</text>
<text x="16" y="352" class="sm dim">Key ops: filter, FFT, convolution, correlation</text>
<text x="16" y="366" class="sm" fill="#3fb950">FIR: linear phase, always stable, N MAC/sample</text>
<text x="16" y="380" class="sm" fill="#388bfd">IIR: fewer taps, possible instability, feedback</text>
<text x="16" y="394" class="sm dim">SIMD/VLIW: MAC arrays for parallel filter taps</text>
<text x="16" y="408" class="sm dim">Fixed-point Q-format: 16-bit saves area vs float</text>
<text x="16" y="422" class="sm dim">MAC: Multiply-ACcumulate — the core DSP op</text>
<text x="16" y="436" class="sm dim">CORDIC: trigonometric ops without multipliers</text>
<text x="16" y="450" class="sm dim">Overlap-add: efficient block convolution via FFT</text>

<!-- Card 2: FFT Applications -->
<rect x="250" y="305" width="244" height="158" rx="6" fill="#161b22"/>
<text x="372" y="322" text-anchor="middle" class="lrg">FFT Applications</text>
<text x="258" y="338" class="sm dim">Spectrum analysis: find frequency content of signal</text>
<text x="258" y="352" class="sm dim">OFDM (5G/WiFi): parallel subcarrier modulation</text>
<text x="258" y="366" class="sm" fill="#3fb950">N=4096 OFDM &#8594; 4096-pt FFT per symbol period</text>
<text x="258" y="380" class="sm dim">Radar: range-doppler map via 2D FFT</text>
<text x="258" y="394" class="sm dim">SONAR, MRI reconstruction, audio compression</text>
<text x="258" y="408" class="sm" fill="#a5d6ff">AI: attention = Q&#183;K^T &#8776; convolution (FFT speedup)</text>
<text x="258" y="422" class="sm dim">Monarch Mixer: sub-quadratic attention via FFT</text>
<text x="258" y="436" class="sm dim">Cooley-Tukey: radix-2 DIT/DIF, in-place N log N</text>
<text x="258" y="450" class="sm dim">NVIDIA cuFFT: GPU-accelerated FFT library</text>

<!-- Card 3: DSP in AI Chips -->
<rect x="502" y="305" width="250" height="158" rx="6" fill="#161b22"/>
<text x="627" y="322" text-anchor="middle" class="lrg">DSP in AI Chip Context</text>
<text x="510" y="338" class="sm dim">Inference edge: dedicated DSP + NPU cores</text>
<text x="510" y="352" class="sm dim">Audio wake-word: always-on DSP at &#181;W power</text>
<text x="510" y="366" class="sm" fill="#3fb950">Beamforming: FIR filter array across mic elements</text>
<text x="510" y="380" class="sm dim">Image ISP: Bayer demosaic, noise filter, sharpening</text>
<text x="510" y="394" class="sm dim">Radar: CFAR detection, range-doppler 2D-FFT</text>
<text x="510" y="408" class="sm" fill="#a5d6ff">Mixed-signal: ADC/DAC for SerDes, HBM PHY</text>
<text x="510" y="422" class="sm dim">OFDM modem in 5G SoC: FFT/IFFT hardware block</text>
<text x="510" y="436" class="sm dim">MAC array throughput: GOps vs TFLOP/s GPU</text>
<text x="510" y="450" class="sm dim">Qualcomm Hexagon: VLIW DSP + HVX vector ext.</text>
</svg>
OperationComplexityHardwareApplication
FIR filter (N taps)O(N) MAC/sampleMAC array, SIMDAnti-aliasing, channel EQ
IIR filter (N poles)O(N) MAC/sampleFeedback MACAudio, control loops
DFT (N-point)O(N²)Rare directlyBaseline reference
FFT (N-point)O(N log N)cuFFT, HW FFTOFDM, radar, spectrum
ConvolutionO(N·M) or O(N log N) via FFTTensor core, DSPFIR filtering, image

Sampling theorem (Nyquist-Shannon) — a continuous signal must be sampled at a rate fs > 2·fmax to be reconstructed without aliasing. An anti-aliasing low-pass filter must remove all energy above fs/2 before the ADC. Violating this causes high-frequency content to fold back into the baseband as aliasing distortion, which is indistinguishable from legitimate signal. For voice (4 kHz bandwidth), fs = 8 kHz is exactly Nyquist; CD audio uses 44.1 kHz for 20 kHz bandwidth plus guard band.

FIR filters implement the convolution y[n] = Σ h[k]·x[n−k] using a tapped delay line: the input signal passes through N delay elements (z⁻¹), each tap is multiplied by a coefficient h[k], and the products are summed. FIR filters are unconditionally stable, have linear phase (constant group delay), and are fully specified by their coefficient vector — which is the sampled impulse response. The price is computational load: an N-tap FIR requires N multiplications and N−1 additions per output sample, which is why SIMD MAC arrays are universal in DSP hardware.

FFT and frequency-domain processing — the Discrete Fourier Transform (DFT) converts N time-domain samples to N complex frequency-domain coefficients. Direct computation costs O(N²); the Cooley-Tukey FFT exploits the DFT's periodicity and symmetry to reduce this to O(N log₂N) using a butterfly network of complex additions and twiddle-factor multiplications. An 8-point FFT requires 3 stages of 4 butterflies; a 4096-point FFT requires 12 stages of 2048 butterflies. OFDM modems (5G, Wi-Fi 6E, DOCSIS) implement 4096-point FFTs as hard IP blocks, processing one symbol per FFT latency.

AI connections — long-range attention in transformer models can be viewed as a form of learned convolution in the sequence domain. Monarch Mixer and other sub-quadratic attention proposals leverage FFT-based convolution (O(N log N)) to replace O(N²) attention. In a more direct sense, every GPU runs cuFFT for spectral analysis workloads, and AI inference chips for edge devices typically include a DSP subsystem for pre-processing sensor data — beamforming, voice activity detection, image ISP — before the neural-network accelerator core.

Fixed-point and quantization — embedded DSP systems represent samples in Q-format fixed-point (e.g., Q1.15 for 16-bit signed) to save area and power versus floating-point. The SNR of a uniform quantizer is approximately 6N + 1.76 dB for N bits, setting ADC resolution requirements: 12-bit gives ~74 dB, 16-bit gives ~98 dB. The same principle applies to AI inference: INT8 quantization trades 24 dB of numeric headroom for 4× throughput and 4× memory bandwidth reduction.

Read DSP through a frequency-domain decomposition lens rather than a time-domain operations lens: almost every DSP algorithm is most clearly understood in terms of which frequency components it preserves, attenuates, or shifts — the filter, the FFT, and the sampling theorem are all fundamentally statements about the frequency axis.

digital signal processingdspdigital signal processorsignal processingmixed signal verification

Explore 500+ Semiconductor & AI Topics

From EUV lithography to CUDA optimization — search the full knowledge base or chat with our AI assistant.