This week I built out the software validation layer for our beamforming pipeline before committing anything to RTL. The goal was to get a working, testable reference model of the full delay-sum beamforming chain in Python first, so the algorithm itself is verified before I start writing SystemVerilog.
I built the full beamforming pipeline in software, piece by piece. First, a tool that calculates, for every possible direction and every microphone, exactly how much to delay that mic’s signal — split into a whole-number part (easy to apply) and a small leftover fraction (which needs a bit more work to apply accurately). Second, a filter that keeps only the specific pitch range our leak’s ultrasonic sound lives in. Third, a way to apply that small leftover fractional delay accurately, using a standard interpolation technique, this matches how real published FPGA-based beamformers are built, which I confirmed by checking the research literature before building it myself. Fourth, the part that actually tests each candidate direction: it applies the delays, adds all the microphones together, and does this for every direction in turn, keeping track of which direction produced the loudest combined result. Finally, I ran a test where I deliberately rounded all the numbers down to a lower-precision format similar to what the actual chip will use, just to get an early sense of whether that lower precision would hurt accuracy, before committing to that precision level in real hardware.
To check that all of this actually works, I built a test setup: a simulated ultrasonic sound placed at a few different known angles, “heard” by each simulated microphone with a very precise, trustworthy timing calculation, then run through the whole pipeline above to see if it could figure out the correct angle on its own. The detected angles came out accurate to within the smallest measurable step of our current setup (2 degrees), across every angle tested. Also, the lower-precision version (the one using the rounded-down numbers meant to mimic real hardware) gave results just as accurate as the full-precision version, meaning that, at least so far, using lower-precision numbers on the actual chip likely won’t hurt accuracy.
For later reference, here’s what I used/researched this week:
- NumPy / SciPy for the signal-processing simulation environment
scipy.signal.firwinfor FIR bandpass filter design- Lagrange interpolation for the fractional (fine) delay stage
- The coarse-delay + fine-delay (Lagrange/Farrow-style) beamforming architecture used in FPGA-based ultrasound and array-signal-processing literature
- Fixed-point quantization emulation for an early resource/precision tradeoff check
I am scheduled on track relative to our project roadmap.
For next week, I plan to:
- Replace the placeholder ultrasonic passband with the actual measured frequency signature of a real leak recording, once we have one
- Update the mic spacing and count in the model to match Wes’s finalized PCB geometry
- Begin RTL implementation of the FIR filter module, verified stage by stage against the Python reference model
- Coordinate with Wes to confirm the final array geometry matches the assumptions baked into the delay-table math
