Javier Valcarce's Homepage


This VHDL macro is a simple AC97 controller for play/record audio stereo 16-bit at 48 kHz. It has an extremely simple interface, neither FIFO queues to store audio samples nor DMA signals, only a periodic interrupt signal is used.

Block description

DC97 block ports
Port Dir Type Description
n_reset Input signal Asynchronous reset, active-low
clk Input signal System clock. 27MHz (to use other frequency, change the counter that controls the duration of reset signal)
ac97_sdata_o Output signal AC97-Link signal. Outgoing bit stream
ac97_sdata_i Input signal AC97-Link signal. Incoming bit stream
ac97_sync Output signal AC97-Link signal. Sync
ac97_bitclk Input signal AC97-Link signal. Clock generated by AC97 codec
ac97_reset Output signal AC97-Link signal. Reset
ready Output signal A one-cycle pulse every (1/48kHz) seconds signaling the start of a new AC97-Link frame, get/put audio data before 10 us elapse
L_o Output 16-bit bus 16-bit sample to play, L channel
R_o Output 16-bit bus 16-bit sample to play, R channel
L_i Input 16-bit bus Recorded 16-bit audio sample, L channel
R_i Input 16-bit bus Recorded 16-bit audio sample, R channel
cmd_addr Input 08-bit bus Address of a AC97 codec hardware register to be written
cmd_data Input 16-bit bus Data to be written in the AC97 hardware register

This VHDL macro is a simple AC97 audio controller (Digital Controller' 97 (DC97) in the nomenclature used in the standard document) for play/rec stereo 16-bit 48kHz. It has an extremely simple interface. It doesn't have neither FIFO queues to store audio samples nor DMA signals but an interrupt mechanism and, therefore, it must be serviced in real-time. After a ready signal pulse, you have aprox. 10 us to transfer audio data, if not, the opportunity is lost and you must wait to the next pulse.

  • sampling frequency is fixed at 48kHz
  • 16-bit resolution
  • play/rec stereo (L, R channel)
  • this macro in intended to let you do stereo audio experiments moving data in/out with a simple FSM controller (or PicoBlaze) without the burden of a complete SoC bus interface, but, you can implement FIFO queues and, e.g., a Wishbone bus interface on top on this macro if necessary (it's not that difficult).
Chronogram of DC97 bus
DC97 Interrupts.

The AC97 codec has internal hardware registers that store information like volume, gain, record source selection, etc. Refer to the datasheet of your codec for more information. For example: register 0x1A selects record source (MIC is 0x0000, LineIn is 0x0404). You can use dc97cmd block (included in source file) which is a simple FSM that periodically sends a standard configuration data (select input and volume). Connect dc97cmd to dc97 cmd_addr and cmd_data ports.

Synthesis report

Device utilization report
Slices93(dc97) + 12(dc97cmd)
Global clocks2
Maximum clock frequency84.764 MHz

Interface with PicoBlaze

If you want to use PicoBlaze to process audio (and why not?) the recommended way to do this is to use interrupts. Maintain the ready interrupt signal with a FF like this:

-- interrupt retainer flip-flop 
process (n_reset, clk)
    if n_reset = '0' then
        interrupt <= '0';
    elsif rising_edge(clk) then            
        if interrupt_ack = '1' then
            interrupt <= '0';
        elsif ready = '1' then
            interrupt <= '1';            
        end if;
    end if;
end process;

The ISR (Interrupt Service Routine) could store each audio sample in a buffer with a capacity of N samples prior to process them. The technique is to maintain two buffers to communicate ISR and main program and interchange its contents when required (after N interrupts).

With PicoBlaze running at 27 MHz and with a sampling frequency of 48 kHz, you have (27M/2)/48000 = 281 instructions per sample. It is not a huge DSP capacity but enough to relay audio samples to HW co-processors or to put them in simple frame formats (multimedia containers like OGG).

Take in mind that, if you plan to do a relatively complex relaying/processing, PicoBlaze will be smaller than the equivalent FSM (Finite State Machine). Do not underestimate the power and compactness (< 100 slices) of PicoBlaze.


  • dc97.vhd. This file contains two components: dc97 (the AC97 controller) and dc97cmd (a small FSM to to setup codec's registers). The latter block is not strictly required, you can setup registers by software, for example.


Today is Saturday, 24-Jun-2017 13:15:04 EDT.
This page was last modified on Monday, 02-Jan-2017 10:01:25 EST.