Purpose
Capture one or more 1-bit PDM streams from MEMS microphones, generate the microphone clock, pack raw bits into fixed-width words and emit them over a valid/ready stream.
Public IP core
af-pdm-rx is a portable Verilog-2001 raw PDM receiver core. It generates a microphone clock, samples 1-bit PDM input, packs raw bits into fixed-width words and exposes a valid/ready stream. It does not convert PDM to PCM and does not claim hardware-ready status yet.
Positioning
af-pdm-rx is a raw PDM receiver. It is the current public proof point for AccelFury IP work.
Capture one or more 1-bit PDM streams from MEMS microphones, generate the microphone clock, pack raw bits into fixed-width words and emit them over a valid/ready stream.
Portable Verilog-2001 RTL, testbenches, simulation Makefile, board wrappers, release docs, portability notes, benchmark JSON and Tang Primer 20K Dock build evidence.
No PDM-to-PCM decimator, no audio filter chain, no production board-ready claim and no published microphone measurement capture yet.
Technical spec
The documented public interface is intentionally explicit so downstream review can happen before board integration starts.
| Parameter | Default | Meaning |
|---|---|---|
| LANES | 1 | Number of PDM data pins. |
| SLOTS_PER_LANE | 1 | 1 for one microphone per line, 2 for phase-separated slots. |
| WORD_BITS | 64 | Packed raw PDM word width. |
| FIFO_ADDR_BITS | 4 | FIFO depth is 2 ** FIFO_ADDR_BITS. |
| HALF_PERIOD_CYCLES | 8 | clk_i cycles per half PDM clock period. |
| SAMPLE_DELAY_CYCLES | 4 | Delay from PDM clock transition to sample enable. |
| LANE_ID_BITS | 1 | Width of out_lane_o; set manually for LANES > 2. |
| SEQ_BITS | 32 | Width of output sequence counter. |
| Port | Direction | Meaning |
|---|---|---|
| clk_i | input | Only internal clock. |
| rst_ni | input | Asynchronous active-low reset. |
| enable_i | input | Enables PDM clocking and capture. |
| clear_i | input | Synchronous one-cycle clear for counters, FIFO, packer and sequence state. |
| pdm_clk_o | output | External PDM microphone clock. |
| pdm_dat_i | input | Raw PDM data lines. |
| out_valid_o | output | Packed word is available. |
| out_ready_i | input | Downstream accepts the current word. |
| out_data_o | output | Packed raw PDM bits. |
| out_lane_o | output | Lane ID for the word. |
| out_slot_o | output | Slot ID for the word. |
| out_seq_o | output | Sequence value for the current output word. |
| overflow_o | output | Sticky overflow/drop indicator until reset or clear_i. |
| stat_bits_o | output | Count of raw bits accepted by the packer. |
| stat_words_o | output | Count of output handshakes. |
| stat_drops_o | output | Count of completed words dropped because FIFO was full. |
The first accepted bit in each word goes to out_data_o[0]; the last bit goes to out_data_o[WORD_BITS-1].
If a word completes while the FIFO is full, the new word is dropped. Existing queued words are not partially overwritten.
All internal logic runs from clk_i. pdm_clk_o is an external microphone clock only and is not used as an internal logic clock.
Integration
The public docs separate reusable core logic from board-local wrappers, constraints and PLL choices.
af_pdm_rx #(
.LANES(1),
.SLOTS_PER_LANE(1),
.WORD_BITS(64),
.FIFO_ADDR_BITS(4),
.HALF_PERIOD_CYCLES(8),
.SAMPLE_DELAY_CYCLES(4)
) u_af_pdm_rx (
.clk_i(clk_i),
.rst_ni(rst_ni),
.enable_i(enable_i),
.clear_i(clear_i),
.pdm_clk_o(pdm_clk_o),
.pdm_dat_i(pdm_dat_i),
.out_valid_o(out_valid_o),
.out_ready_i(out_ready_i),
.out_data_o(out_data_o),
.out_lane_o(out_lane_o),
.out_slot_o(out_slot_o),
.out_seq_o(out_seq_o),
.overflow_o(overflow_o),
.stat_bits_o(stat_bits_o),
.stat_words_o(stat_words_o),
.stat_drops_o(stat_drops_o)
);
pdm_clk_o frequency = clk_i frequency / (2 * HALF_PERIOD_CYCLES). When an exact PDM rate is needed, the public recommendation is a board-level PLL or external clock selection, not fractional logic inside rtl/.
rst_ni is asynchronous active-low. clear_i is a synchronous one-cycle clear for counters, FIFO, packer and sequence state.
Primary module: af_pdm_rx. Compatibility wrapper: pdm_rx_raw.
Verification
The public verification story is simulation-first and release-evidence oriented.
| Test | Purpose |
|---|---|
| tb_af_pdm_clkgen | Confirms exact half-period and slot sample phase. |
| tb_af_pdm_sampler_mono | Confirms sample-enable based single-lane capture. |
| tb_af_pdm_word_packer | Confirms 8/16/64-bit packing, clear and expected word completion. |
| tb_af_pdm_fifo | Confirms FIFO order, stalled output stability and simultaneous read/write from full. |
| tb_af_pdm_rx_mono | Confirms integrated one-line path. |
| tb_af_pdm_rx_bit_order | Confirms first accepted bit maps to bit 0 through the integrated RX. |
| tb_af_pdm_rx_stereo_slots | Confirms slot 0 and slot 1 do not mix. |
| tb_af_pdm_rx_multi_lane | Confirms 4 lanes are tagged and packed independently. |
| tb_af_pdm_rx_backpressure | Confirms stable outputs and sequence hold under out_ready_i=0. |
| tb_af_pdm_rx_overflow | Confirms sticky overflow and drop counter. |
| tb_af_pdm_rx_reset | Confirms reset and clear do not create false words. |
| tb_af_pdm_rx_random_ready_lfsr | Confirms pseudo-random ready stalls do not drop data when FIFO capacity is sufficient. |
| tb_pdm_rx_raw | Confirms default 64-bit compatibility-wrapper smoke path. |
Run cd sim && make test with iverilog and vvp. The mandatory public path is Verilog-only and does not depend on cocotb.
Public release maturity is board-build-ready. Portable RTL, tests, docs and archived Tang Primer 20K Dock build evidence are present.
Measured pdm_clk_o, physical GPIO loopback observation and real PDM MEMS microphone evidence are still pending.
Boards
Board support on this site is evidence-gated. A wrapper or constraint file does not equal a measured hardware claim.
| Board | Repo status | Build status | Hardware status |
|---|---|---|---|
| Sipeed Tang Primer 20K Dock | Board wrappers and constraints present | OSS Gowin-compatible build evidenced | JTAG programming evidenced; measured clock, loopback and microphone evidence pending |
| Sipeed Tang Nano 20K | Board wrappers present; constraints fail-closed | Not captured | Not captured |
| Sipeed Tang Mega 138K Dock | Board wrappers present; constraints fail-closed | Not captured | Not captured |
Licensing
The public repo uses the AccelFury Source Available License. Public-source use is allowed with attribution; proprietary or closed-source use needs a separate commercial license.
Attribution, copyright notices, license text and notices must be preserved.
Required for private repositories, proprietary products, customer-delivered bitstreams or other closed-source use.
Available for integration review, board bring-up planning and release-readiness work.
Next step
Send the board name, clock source, microphone choice, I/O voltage assumptions and expected downstream interface. Commercial or proprietary use should also include licensing scope.