Practice

Codec I2S Receiver

Wrenford Town Hall fitted a new recorder for its council sessions. The audio codec was wired correctly, but every stored word sounded wrong.

On Monday's replay, voices rasped and the mayor appeared in the clerk's channel.

The FPGA read the first data bit when the word select line changed. In I2S, that first bit comes one bit clock later. Each sample lost its top bit and gained a stray bit at the end.

Your task: build the I2S receiver for the recorder. Capture each 16-bit word in its 32-bit slot. Keep left and right words together, and flag any slot with a bad boundary.

Interface

PortDirectionTypeDescription
bclkin1 bitBit clock from the codec and the only DUT clock
rstin1 bitSynchronous reset (active high)
wsin1 bitWord select: low for left, high for right
sdin1 bitSerial data from the codec
leftout16-bit vectorLast completed left sample, held
rightout16-bit vectorLast completed right sample, held
validout1 bitStereo pair complete (one-bclk pulse)
frame_errout1 bitBad word-select boundary (one-bclk pulse)

Behavior

  • The codec changes ws and sd on falling bclk edges
  • The receiver samples all inputs only on rising bclk edges
  • Each slot is 32 bits: 16 data bits first, MSB first, followed by 16 padding bits
  • Padding bits may have any value and must be ignored
  • A sampled change on ws starts a new slot but does not carry its first data bit
  • If a ws change is first sampled at edge k, the word MSB is sampled at edge k+1
  • The remaining 15 data bits are sampled on the next 15 rising edges
  • A legal slot has exactly 32 rising edges between successive first-sampled ws changes
  • The edge where a ws change is first sampled closes the old slot and carries its last padding bit. The new word's MSB arrives one edge later
  • An early or late ws change pulses frame_err for exactly one bclk
  • A bad boundary discards any partial stereo pair
  • The bad boundary edge becomes the start of a fresh slot, including the one-bit delay
  • A low ws level identifies a left slot, and a high level identifies a right slot
  • A stereo pair requires a clean left word followed by the clean right word from the immediately following slot
  • After the right word's 16th data bit is sampled, valid pulses on the next rising edge
  • left and right update together on that same edge
  • left and right hold their values between completed pairs
  • valid and frame_err are low except during their one-bclk pulses
  • After reset, all outputs are zero and capture waits until the first observed ws change
  • If capture starts with a right slot, that word is discarded
  • Pairing then begins with the next left slot
  • Samples are signed audio values, but the receiver treats them as raw 16-bit patterns
  • rst high at a rising edge clears all outputs, capture state, slot timing, and any partial pair

What the bench checks

  • The testbench drives ws and sd at falling-edge time and judges every output after each rising edge
  • Its first left word is an alignment discriminator: a capture that reads the MSB at the ws change edge itself publishes x4000 instead of x8000
  • It fills the 16 padding bits of every slot with junk that must leave no trace
  • It cuts one slot short and runs another long, expecting the one-bclk frame_err pulse, the dropped partial pair, and a re-anchor at the bad edge
  • It starts the stream during a right word and checks that the lone right word never publishes
  • It asserts reset with a left word staged and checks that outputs clear and capture waits for the next ws change

Constraints

TIMING

everything is synchronous to bclk; inputs are sampled only on rising edges, and all outputs are registered.

SCOPE

this models the digital capture contract on bclk only; there is no system-clock crossing, no volume math, and no analog anything.

Do not add ports.

Loading editor...

Click Run to execute your code. Output will appear here.