Public IP core

af-pdm-rx: raw PDM receiver IP core for FPGA audio pipelines

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

What the core does

af-pdm-rx is a raw PDM receiver. It is the current public proof point for AccelFury IP work.

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.

What is public

Portable Verilog-2001 RTL, testbenches, simulation Makefile, board wrappers, release docs, portability notes, benchmark JSON and Tang Primer 20K Dock build evidence.

What is not public

No PDM-to-PCM decimator, no audio filter chain, no production board-ready claim and no published microphone measurement capture yet.

Technical spec

Interface

The documented public interface is intentionally explicit so downstream review can happen before board integration starts.

ParameterDefaultMeaning
LANES1Number of PDM data pins.
SLOTS_PER_LANE11 for one microphone per line, 2 for phase-separated slots.
WORD_BITS64Packed raw PDM word width.
FIFO_ADDR_BITS4FIFO depth is 2 ** FIFO_ADDR_BITS.
HALF_PERIOD_CYCLES8clk_i cycles per half PDM clock period.
SAMPLE_DELAY_CYCLES4Delay from PDM clock transition to sample enable.
LANE_ID_BITS1Width of out_lane_o; set manually for LANES > 2.
SEQ_BITS32Width of output sequence counter.
PortDirectionMeaning
clk_iinputOnly internal clock.
rst_niinputAsynchronous active-low reset.
enable_iinputEnables PDM clocking and capture.
clear_iinputSynchronous one-cycle clear for counters, FIFO, packer and sequence state.
pdm_clk_ooutputExternal PDM microphone clock.
pdm_dat_iinputRaw PDM data lines.
out_valid_ooutputPacked word is available.
out_ready_iinputDownstream accepts the current word.
out_data_ooutputPacked raw PDM bits.
out_lane_ooutputLane ID for the word.
out_slot_ooutputSlot ID for the word.
out_seq_ooutputSequence value for the current output word.
overflow_ooutputSticky overflow/drop indicator until reset or clear_i.
stat_bits_ooutputCount of raw bits accepted by the packer.
stat_words_ooutputCount of output handshakes.
stat_drops_ooutputCount of completed words dropped because FIFO was full.

Bit order

The first accepted bit in each word goes to out_data_o[0]; the last bit goes to out_data_o[WORD_BITS-1].

Overflow policy

If a word completes while the FIFO is full, the new word is dropped. Existing queued words are not partially overwritten.

Clock domain assumptions

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

Integration notes

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)
);

Timing formula

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/.

Reset behavior

rst_ni is asynchronous active-low. clear_i is a synchronous one-cycle clear for counters, FIFO, packer and sequence state.

Compatibility wrapper

Primary module: af_pdm_rx. Compatibility wrapper: pdm_rx_raw.

Verification

Verification and evidence

The public verification story is simulation-first and release-evidence oriented.

TestPurpose
tb_af_pdm_clkgenConfirms exact half-period and slot sample phase.
tb_af_pdm_sampler_monoConfirms sample-enable based single-lane capture.
tb_af_pdm_word_packerConfirms 8/16/64-bit packing, clear and expected word completion.
tb_af_pdm_fifoConfirms FIFO order, stalled output stability and simultaneous read/write from full.
tb_af_pdm_rx_monoConfirms integrated one-line path.
tb_af_pdm_rx_bit_orderConfirms first accepted bit maps to bit 0 through the integrated RX.
tb_af_pdm_rx_stereo_slotsConfirms slot 0 and slot 1 do not mix.
tb_af_pdm_rx_multi_laneConfirms 4 lanes are tagged and packed independently.
tb_af_pdm_rx_backpressureConfirms stable outputs and sequence hold under out_ready_i=0.
tb_af_pdm_rx_overflowConfirms sticky overflow and drop counter.
tb_af_pdm_rx_resetConfirms reset and clear do not create false words.
tb_af_pdm_rx_random_ready_lfsrConfirms pseudo-random ready stalls do not drop data when FIFO capacity is sufficient.
tb_pdm_rx_rawConfirms default 64-bit compatibility-wrapper smoke path.

Simulation path

Run cd sim && make test with iverilog and vvp. The mandatory public path is Verilog-only and does not depend on cocotb.

Release status

Public release maturity is board-build-ready. Portable RTL, tests, docs and archived Tang Primer 20K Dock build evidence are present.

Known blockers

Measured pdm_clk_o, physical GPIO loopback observation and real PDM MEMS microphone evidence are still pending.

Boards

Board targets and hardware status

Board support on this site is evidence-gated. A wrapper or constraint file does not equal a measured hardware claim.

BoardRepo statusBuild statusHardware status
Sipeed Tang Primer 20K DockBoard wrappers and constraints presentOSS Gowin-compatible build evidencedJTAG programming evidenced; measured clock, loopback and microphone evidence pending
Sipeed Tang Nano 20KBoard wrappers present; constraints fail-closedNot capturedNot captured
Sipeed Tang Mega 138K DockBoard wrappers present; constraints fail-closedNot capturedNot captured

Licensing

License and commercial use

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.

Public-source use

Attribution, copyright notices, license text and notices must be preserved.

Commercial license

Required for private repositories, proprietary products, customer-delivered bitstreams or other closed-source use.

Paid support

Available for integration review, board bring-up planning and release-readiness work.

Next step

Need integration support for your board?

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.