Real-Time Processing Simulator
Copy this iframe to your website:
1 | |
Description
This MicroSim runs an \(L\)-tap FIR filter in blocks of \(B\) samples with double buffering. The pipeline at the top shows three blocks at once: the input buffer fills with block \(k+1\), the processor filters block \(k\), and the output buffer plays block \(k-1\). The time line below it shows how block \(k\) uses the processor during one block period: per-block overhead (gray), filter work (blue) and random background bursts (orange). The work must end before the red deadline
otherwise the output buffer underruns and the listener hears a glitch. The load chart shows the busy time of the last 60 blocks as a percentage of \(T\), with missed blocks outlined in red, and the meter shows the average load. The read-outs give the buffering latency \(2B/f_s\) (one input plus one output block), the required rate \(f_s L\) in multiply-accumulates per second (MAC/s), the processor's capacity, the expected and counted underruns, and the quantization noise floor of the word length.
- Sample rate (8–96 kHz), Block size \(B\) (16–4096 samples) and Filter taps \(L\) (8–512) set the workload.
- Processor and Word length set the capacity: clock rate × MACs per cycle.
- Background load (0–50 %) is the average share of the processor taken by other tasks.
- Speed sets the animation rate; the MicroSim opens paused, Run starts it and Pause freezes it; Reset restores the defaults and pauses. Counters restart whenever a setting changes.
The animation runs only while the mouse is over the simulation. It supports Chapter 15: Signal Processing Applications and AI Integration.
The Model
For each block the processor is busy for
where \(N\), the number of background bursts in that block period, is random (Poisson) with mean \(b\,T / 50\ \mu\text{s}\) for a background load \(b\). A block misses its deadline when \(t_{\text{busy}} > T\). The filter alone loads the processor by \(f_s L / (f_{\text{clk}} \cdot \text{MACs per cycle})\), which does not depend on \(B\); the fixed overhead per block does, and so does the size of the random swings, which average out over long blocks. The FPGA runs the filter in dedicated logic, so background tasks do not affect it.
The noise floor uses \(-6.02\,B_{\text{bits}}\) dB relative to full scale (dBFS) for fixed point; a full-scale sine then has a signal-to-quantization-noise ratio of \(6.02\,B_{\text{bits}} + 1.76\) dB. The 32-bit float has a 24-bit significand, so its rounding noise sits about 144 dB below the signal at any level. Both figures assume a wide accumulator that rounds once per output sample.
The processor presets are typical, illustrative values, not data-sheet figures:
| Preset | Clock | MACs/cycle (16-bit fixed / 24-bit fixed / 32-bit float) | Overhead per block |
|---|---|---|---|
| MCU (no DSP extensions, no FPU) | 64 MHz | 0.25 / 0.125 / 0.02 | 1000 cycles |
| Cortex-M4 (DSP extensions, FPU) | 168 MHz | 1 / 0.5 / 0.5 | 800 cycles |
| DSP | 600 MHz | 4 / 2 / 2 | 1200 cycles |
| FPGA, 16 parallel multipliers | 200 MHz | 16 / 16 / 4 | none |
Lesson Plan
Learning Objectives
After using this MicroSim, students will be able to:
- Calculate the block period \(T = B/f_s\) and the buffering latency \(2B/f_s\) for a given sample rate and block size
- Calculate the MAC rate \(f_s L\) of an FIR filter and the processor load it produces for a given clock rate and MACs per cycle
- Explain why a processor with an average load below 100 % can still miss deadlines, and how the block size changes the miss rate
- Compare fixed-point and floating-point word lengths by their noise floor (about \(-6.02\,B_{\text{bits}}\) dBFS) and their computational cost
- Evaluate a combination of processor, word length and block size against latency, load-margin and noise-floor requirements
Target Audience
Undergraduate students in electrical or computer engineering who have met FIR filters and sampling, typically in a junior- or senior-level DSP or embedded-systems course. Plan about 25 minutes.
Prerequisites
- Sampling rate and the sample period \(1/f_s\)
- FIR filters and the convolution sum (\(L\) multiply-accumulates per output sample)
- Basic quantization: bits, full scale and decibels
Activities
Activity 1: Block period and latency (5 min). Start from the defaults (48 kHz, \(B = 32\), 128 taps, MCU, 16-bit fixed, background 30 %). The read-outs show \(T = 0.667\) ms and a latency of 1.33 ms. Set \(B = 256\): \(T = 5.33\) ms and the latency is 10.7 ms. Now set the sample rate to 8 kHz: with the same 256-sample block, \(T = 32.0\) ms and the latency is 64.0 ms, six times longer, because each block now takes six times longer to fill.
Activity 2: The computational budget (8 min). Press Reset. The filter needs \(48\,000 \times 128 = 6.14\) MMAC/s and the MCU supplies \(64\ \text{MHz} \times 0.25 = 16.0\) MMAC/s, so the filter alone uses 38.4 % of the processor. Set the taps to 512: the requirement rises to 24.6 MMAC/s, the filter load to 153.6 %, the time line runs past the deadline and every block misses (expected misses 100 %). Switch the processor to the Cortex-M4: the filter load drops to 14.6 % and the average load to 45.3 %. The DSP needs 1.0 % and the FPGA 0.8 %; on the FPGA the background slider has no effect and the average load is 0.8 %.
Activity 3: The cost of precision (5 min). Press Reset, then choose 24-bit fixed. The noise floor improves from −96.3 dBFS to −144.5 dBFS, but the MCU's capacity halves to 8.00 MMAC/s, the filter load doubles to 76.8 % and the average load reaches 109.1 % (expected misses 76.2 %). Choose 32-bit float: an MCU without a floating-point unit has only 1.28 MMAC/s, the filter load is 480.0 % and the system is overloaded. With the Cortex-M4 and 32-bit float the filter load is 7.3 % and the average load 38.0 %.
Activity 4: Average load versus deadlines (7 min). Press Reset and watch the load chart: the average load is 70.7 %, yet about 1 block in 20 misses its deadline (expected misses 5.1 %). Change only the block size and record the expected misses and the latency:
| Block size \(B\) | Expected misses | Latency |
|---|---|---|
| 16 | 14.3 % | 0.667 ms |
| 32 | 5.1 % | 1.33 ms |
| 64 | 0.37 % | 2.67 ms |
| 128 | 0.01 % | 5.33 ms |
| 256 | < 0.01 % | 10.7 ms |
Now set \(B = 32\) and the taps to 256 (average load 109.1 %) and increase the block size again: the expected misses rise from 76.2 % (\(B = 32\)) to 80.7 % (\(B = 128\)) and 96.9 % (\(B = 512\)). Larger blocks average out the bursts, which helps only when the average load is below 100 %.
Assessment
- A system samples at 44.1 kHz with \(B = 256\). What are its block period and its double-buffering latency? Answer: \(T = 256/44\,100 = 5.80\) ms and the latency is \(2T = 11.6\) ms.
- A 200-tap FIR filter runs at 48 kHz on a 168 MHz processor that sustains 1 MAC per cycle. What MAC rate does it need, and what fraction of the processor does the filter use? Answer: \(48\,000 \times 200 = 9.6\) MMAC/s; \(9.6/168 = 5.7\) % (set Cortex-M4, 16-bit fixed, 200 taps to check).
- The default settings show an average load of 70.7 %. Why do some blocks still miss their deadline, and name two ways to remove the misses. Answer: the background bursts vary from block to block; in a 0.667 ms block a few extra 50 µs bursts push the busy time past \(T\). Larger blocks (at the cost of latency), a faster processor, fewer taps or less background work all reduce the misses.
- An application needs a quantization noise floor of at least −120 dBFS. Which word lengths in the simulator qualify, and what does the choice cost on the MCU? Answer: 16-bit fixed gives −96.3 dBFS and fails; 24-bit fixed (−144.5 dBFS) or 32-bit float qualify. On the MCU 24-bit fixed halves the capacity and 32-bit float cuts it from 16.0 to 1.28 MMAC/s.
- Doubling the block size from 32 to 64 samples changes the latency and the per-block overhead percentage. How? Answer: the latency doubles (1.33 ms to 2.67 ms) and the overhead percentage halves (2.3 % to 1.2 %), because the same overhead cycles are spread over twice as many samples.
Common Misconceptions
"If the average load is below 100 %, the system meets real-time deadlines." Real-time systems are judged by their worst blocks, not their average. The defaults show an average load of 70.7 % with 5.1 % of blocks missing; the chapter's advice to keep a 20–50 % timing margin is marked by the gold 80 % line.
"A bigger buffer always cures dropouts." A bigger block only smooths short-term variation and always adds latency. When the average load exceeds 100 % (128 taps on the MCU with 24-bit fixed, or 256 taps with 16-bit fixed), the expected misses grow as the block size increases.
References
- Real-time computing - Wikipedia - hard and soft deadlines, determinism and worst-case execution time
- Digital signal processor - Wikipedia - MAC units, Harvard architecture and the processors behind the DSP preset
- Field-programmable gate array - Wikipedia - parallel DSP slices and deterministic hardware timing
- Finite impulse response - Wikipedia - why an \(L\)-tap FIR filter needs \(L\) multiply-accumulates per output sample
- Multiple buffering - Wikipedia - double buffering, the input/process/output pipeline shown at the top
- Quantization (signal processing) - Wikipedia - the 6.02 dB-per-bit rule for the noise floor
- Poisson distribution - Wikipedia - the model for the number of background bursts per block
- The Scientist and Engineer's Guide to Digital Signal Processing - Steven W. Smith - free online textbook with chapters on DSP hardware and fixed versus floating point