VHDL Code für Versuch 5

top.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library altera; 
use altera.altera_primitives_components.all;
 
entity top is 
  port (
    CLOCK_24:   in std_ulogic_vector(1 downto 0);
    KEY:        in std_ulogic_vector(3 downto 0);
    SW:         in std_ulogic_vector(9 downto 0);
    I2C_SCLK:   out std_ulogic;
    I2C_SDAT:   inout std_logic; 
    AUD_ADCLRCK: out std_ulogic;
    AUD_ADCDAT:  in std_ulogic;
    AUD_DACLRCK: out std_ulogic; 
    AUD_DACDAT:  out std_ulogic; 
    AUD_XCK:     out std_ulogic;
    AUD_BCLK:    out std_ulogic; 
    LEDR:       out std_ulogic_vector(9 downto 0);
    HEX0:       out std_ulogic_vector(6 downto 0)
  );
end; 
 
architecture struct of top is
 
  component i2c_sub is 
  port (
    clk_i:      in std_ulogic;
    reset_ni:    in std_ulogic;
    i2c_clk_o:   out std_ulogic;
    i2c_dat_o:   out std_ulogic;
    i2c_dat_i:   in std_ulogic
  );
  end component; 
 
  component adcintf is 
  port (
    clk_i                  : in std_ulogic;
    reset_ni               : in std_ulogic;
    en_i                   : in std_ulogic;
    valid_o                : out std_ulogic; 
    data_o                 : out std_ulogic_vector(15 downto 0); 
    start_i                : in std_ulogic; 
    ser_dat_i              : in std_ulogic);
  end component; 
 
  component dacintf is 
  port (
    clk_i                  : in std_ulogic;
    reset_ni               : in std_ulogic;
    load_i                 : in std_ulogic; 
    data_i                 : in std_ulogic_vector(15 downto 0); 
    en_i                   : in std_ulogic; 
    ser_dat_o              : out std_ulogic);
  end component;
 
  component ringbuf is 
  port (
    clk_i                  : in std_ulogic;
    reset_ni               : in std_ulogic;
    en_i                   : in std_ulogic; 
    data_i                 : in std_ulogic_vector(15 downto 0); 
    data_o                 : out std_ulogic_vector(15 downto 0));
  end component; 
 
  component bclk is 
  port (
    clk_i                  : in std_ulogic;
    reset_ni               : in std_ulogic; 
    bclk_o                 : out std_ulogic;
    bclk_falling_edge_en_o : out std_ulogic);
  end component; 
 
  component fsgen is 
  port (
    clk_i                   : in std_ulogic;
    reset_ni                : in std_ulogic;
    bclk_falling_edge_en_i  : in std_ulogic; 
    fs_o                    : out std_ulogic);
  end component; 
 
  component mclk is 
  port (
    clk_i                  : in std_ulogic;
    reset_ni               : in std_ulogic; 
    mclk_o                 : out std_ulogic);
  end component; 
 
  signal clk, reset_n          : std_ulogic;
 
  signal i2c_dat_o             : std_ulogic;
  signal i2c_dat_i             : std_ulogic; 
 
  signal framesync             : std_ulogic;
  signal bclk_falling_edge_en  : std_ulogic; 
 
  signal adc_valid             : std_ulogic;
  signal dac_data, adc_data    : std_ulogic_vector(15 downto 0);  
 
begin
 
  reset_n <= KEY(0);
  clk     <= CLOCK_24(0); 
 
  i2c_sub_i0 : i2c_sub 
  port map (
    clk_i      => clk,
    reset_ni   => reset_n,
    i2c_clk_o  => I2C_SCLK,
    i2c_dat_o  => i2c_dat_o,
    i2c_dat_i  => i2c_dat_i);
 
  mclk_i0 : mclk
  port map(
    clk_i      => clk,
    reset_ni   => reset_n,
    mclk_o     => AUD_XCK);
 
  bclk_i0 : bclk
  port map (
    clk_i                  => clk,
    reset_ni               => reset_n,
    bclk_o                 => AUD_BCLK,
    bclk_falling_edge_en_o => bclk_falling_edge_en);
 
  fsgen_i0 : fsgen
  port map (
    clk_i                  => clk,
    reset_ni               => reset_n,
    bclk_falling_edge_en_i => bclk_falling_edge_en,
    fs_o                   => framesync);
 
  dacintf_i0 : dacintf
  port map (
    clk_i                  => clk,
    reset_ni               => reset_n,
    load_i                 => framesync,
    data_i                 => dac_data,
    en_i                   => bclk_falling_edge_en,
    ser_dat_o              => AUD_DACDAT);
 
  adcintf_i0 : adcintf
  port map (
    clk_i                  => clk,
    reset_ni               => reset_n,
    valid_o                => adc_valid, 
    data_o                 => adc_data,
    start_i                => framesync,
    en_i                   => bclk_falling_edge_en,
    ser_dat_i              => AUD_ADCDAT);
 
  AUD_DACLRCK <= framesync; 
  AUD_ADCLRCK <= framesync; 
 
  ringbuf_i0 : ringbuf
  port map (
    clk_i                  => clk,
    reset_ni               => reset_n,
    en_i                   => adc_valid,
    data_i                 => adc_data,
    data_o                 => dac_data);
 
  LEDR(9 downto 0) <= std_ulogic_vector(abs(signed(dac_data(15 downto 6))));
  HEX0 <= "0000000";
 
  -- i2c has an open-drain ouput
  i2c_dat_i <= I2C_SDAT; 
  i2c_data_buffer_i : OPNDRN
    port map (a_in => i2c_dat_o, a_out => I2C_SDAT);
 
end; -- architecture
top_tb.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity top_tb is
end; 
 
architecture beh of top_tb is
 
component top is 
  port (
    CLOCK_24:   in std_ulogic_vector(1 downto 0);
    KEY:        in std_ulogic_vector(3 downto 0);
    SW:         in std_ulogic_vector(9 downto 0);
    I2C_SCLK:   out std_ulogic;
    I2C_SDAT:   inout std_ulogic; 
    AUD_ADCLRCK: out std_ulogic;
    AUD_ADCDAT:  in std_ulogic;
    AUD_DACLRCK: out std_ulogic; 
    AUD_DACDAT:  out std_ulogic; 
    AUD_XCK:     out std_ulogic;
    AUD_BCLK:    out std_ulogic; 
    LEDR:       out std_ulogic_vector(9 downto 0);
    HEX0:       out std_ulogic_vector(6 downto 0)
  );
end component; 
 
  signal clk, reset_n : std_ulogic; 
  signal switch, ledr : std_ulogic_vector(9 downto 0);
  signal hex : std_ulogic_vector(6 downto 0);
  signal i2c_clk, i2c_dat : std_ulogic; 
  signal key : std_ulogic_vector(3 downto 0);
 
  signal aud_adclrck, aud_adcdat, aud_daclrck, aud_dacdat, aud_xck, aud_bclk : std_ulogic;
  signal clk24 : std_ulogic_vector(1 downto 0); 
 
begin
 
  top_i0 : top
    port map (
      CLOCK_24            => clk24,
      KEY                 => key,
      SW                  => switch,
      I2C_SCLK            => i2c_clk,
      I2C_SDAT            => i2c_dat,
      AUD_ADCLRCK         => aud_adclrck,
      AUD_ADCDAT          => aud_adcdat,
      AUD_DACLRCK         => aud_daclrck,
      AUD_DACDAT          => aud_dacdat,
      AUD_XCK             => aud_xck,
      AUD_BCLK            => aud_bclk,
      LEDR                => ledr,
      HEX0                => hex);
 
  clock_p : process
  begin
    clk <= '0';
    wait for 21 ns;
    clk <= '1';
    wait for 21 ns; 
  end process clock_p; 
 
  clk24(0) <= clk; 
 
  reset_p : process
  begin
    reset_n <= '0';
    wait for 15 us;
    reset_n <= '1';
    wait; 
  end process reset_p; 
 
  key(0) <= reset_n;
  key(3 downto 1) <= "000"; 
 
  switch <= "0000000000";
 
  aud_adcdat <= '1';
 
end; -- architecture
mclk.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
-- Master Clock Generator
-- Generate 12 MHz from 24 MHz
 
entity mclk is 
  port (
    clk_i                  : in std_ulogic;
    reset_ni               : in std_ulogic; 
    mclk_o                 : out std_ulogic);
end; 
 
architecture rtl of mclk is
  signal mclk : std_ulogic;
begin
 
  mclk_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then
      mclk <= '0'; 
    elsif rising_edge(clk_i) then
      mclk <= not mclk;
    end if;
  end process mclk_p;
 
  mclk_o <= mclk;
 
end; -- architecture
fsgen.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
-- Frame Sync Generator
-- The framesync is active for one bitclock cycle
 
entity fsgen is 
  port (
    clk_i                   : in std_ulogic;
    reset_ni                : in std_ulogic;
    bclk_falling_edge_en_i  : in std_ulogic; 
    fs_o                    : out std_ulogic);
end; 
 
architecture rtl of fsgen is
  signal counter          : integer range 0 to 63;
begin
 
  fs_cnt_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then
      counter <= 0; 
      fs_o <= '0'; 
    elsif rising_edge(clk_i) then
      if bclk_falling_edge_en_i = '1' then
        fs_o <= '0';  
        if counter = 63 then 
          counter <= 0;
          fs_o <= '1'; 
        else
          counter <= counter + 1; 
        end if;
      end if;  
    end if; 
  end process fs_cnt_p;
 
end; -- architecture
bclk.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
-- Bitclock generator
 
entity bclk is 
  port (
    clk_i                  : in std_ulogic;
    reset_ni               : in std_ulogic; 
    bclk_o                 : out std_ulogic;
    bclk_falling_edge_en_o : out std_ulogic);
end; 
 
architecture rtl of bclk is
  signal clk_counter          : integer range 0 to 47;
  signal bclk_rising_edge_en  : std_ulogic; 
  signal bclk_falling_edge_en : std_ulogic;  
begin
 
  bclk_cnt_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then
      clk_counter <= 0; 
    elsif rising_edge(clk_i) then
      if clk_counter = 47 then 
        clk_counter <= 0;
      else
        clk_counter <= clk_counter + 1; 
      end if; 
    end if; 
  end process bclk_cnt_p;
 
  edge_comb_p : process(clk_counter)
  begin
    bclk_rising_edge_en  <= '0';
    bclk_falling_edge_en <= '0'; 
    if clk_counter = 47 then
      bclk_rising_edge_en <= '1';
    end if; 
    if clk_counter = 23 then 
      bclk_falling_edge_en <= '1';
    end if;      
  end process edge_comb_p;
 
  bclk_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then
      bclk_o <= '0'; 
    elsif rising_edge(clk_i) then
      if bclk_rising_edge_en = '1' then
        bclk_o <= '1';
      elsif bclk_falling_edge_en = '1' then
        bclk_o <= '0'; 
      end if; 
    end if;   
  end process bclk_p; 
 
  bclk_falling_edge_en_o <= bclk_falling_edge_en;   
 
end; -- architecture
i2c_sub.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity i2c_sub is 
  port (
    clk_i:      in std_ulogic;
    reset_ni:   in std_ulogic;
    i2c_dat_o:  out std_ulogic;
	 i2c_dat_i:  in std_ulogic;
    i2c_clk_o:  out std_ulogic);
end; 
 
architecture struct of i2c_sub is
 
component i2c is 
  port (
    clk_i:      in std_ulogic;
    reset_ni:    in std_ulogic;
    load_i:     in std_ulogic;
    data_i:     in std_ulogic_vector(23 downto 0);
    i2c_clk_o:   out std_ulogic;
    i2c_dat_o:   out std_ulogic;
	 i2c_dat_i:   in std_ulogic; 
    busy_o:      out std_ulogic  
  );
end component; 
 
component i2c_write is
  port (
    clk_i:      in std_ulogic;
    reset_ni:   in std_ulogic;
    load_o:     out std_ulogic;
    data_o:     out std_ulogic_vector(23 downto 0);
    busy_i:     in std_ulogic);
end component; 
 
  signal load, busy : std_ulogic;
  signal data : std_ulogic_vector(23 downto 0);
 
begin
 
  i2c_i0 : i2c
    port map (
      clk_i        => clk_i,
      reset_ni     => reset_ni,
      load_i       => load,
      data_i       => data,
      i2c_clk_o    => i2c_clk_o,
      i2c_dat_o    => i2c_dat_o,
		i2c_dat_i    => i2c_dat_i,
      busy_o       => busy);
 
  i2_write_i0 : i2c_write
    port map (
      clk_i        => clk_i,
      reset_ni     => reset_ni,
      load_o       => load,
      data_o       => data,
      busy_i       => busy);
 
end; -- architecture
i2c.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
-- I2C or 2-Wire Bus
-- To start a transaction, pull the data line to 'L' while the clock is still 'H'
-- 7 Bits Address
-- 1 Bit R/W (0 = Write, 1 = Read)
-- 1 Bit ACK (from Slave 0 if o.k.)
-- 8 Bits Data 15..8 
-- 1 Bit Ack from slave (0 if o.k.)
-- 8 Bits Data 7..0
-- 1 Bit Ack from slave (0 if o.k.)
 
 
entity i2c is 
  port (
    clk_i:      in std_ulogic;
    reset_ni:   in std_ulogic;
    load_i:     in std_ulogic;
    data_i:     in std_ulogic_vector(23 downto 0);
    i2c_clk_o:   out std_ulogic;
    i2c_dat_o:    out std_ulogic;
	 i2c_dat_i:    in std_ulogic; 
    busy_o:      out std_ulogic  
  );
end; 
 
architecture rtl of i2c is
 
  -- Clock divider section 
  constant fd_c : integer := 24000000/20000/2; -- 24 MHz system clock, 20 kHz I2C clock   
  signal clk_cnt : integer range 0 to fd_c; 
  signal clk_cnt_reset, clk_cnt_done : std_ulogic;
 
  -- i2c data register index
  signal idx : integer range 0 to 27;
  signal idx_inc : std_ulogic;  
  signal idx_reset : std_ulogic;
 
  -- i2c registers with and without data for the acknowledgment section
  -- In cycle 8, 17 and 26 there is an i2c acknowledgement cycle where the master
  -- drives Z and the slave will drive "0" when everything is o.k. 
  -- The input data from the interface is without these acknowledgement bits
  signal load_i2c_reg_without_ack : std_ulogic;
  signal i2c_reg_without_ack      : std_ulogic_vector(23 downto 0);
  signal i2c_reg_with_ack : std_ulogic_vector(0 to 27);
 
  -- Statemachine
  type state_t is (idle_s, start_s, data_hold_s, data_s, clock_high_s, stop_s);
  signal state, next_state : state_t; 
 
  -- Selection for the i2c output data
  type i2c_dat_sel_t is (sel_old, sel_reg, sel_one, sel_zero);
  signal i2c_dat_sel : i2c_dat_sel_t;  
 
  type i2c_clk_sel_t is (sel_old, sel_one, sel_zero);
  signal i2c_clk_sel : i2c_clk_sel_t; 
 
  signal i2c_clk : std_ulogic;
  signal i2c_clk_new : std_ulogic; 
  signal i2c_dat : std_ulogic; 
  signal i2c_dat_new : std_ulogic;
 
begin
 
  -- i2c register with ack build from i2c without ack
  -- i2c data is transmitted msb first, so bus direction is changed also
  i2c_reg_with_ack(0 to 7)   <= i2c_reg_without_ack(23 downto 16);
  i2c_reg_with_ack(8)        <= '1';
  i2c_reg_with_ack(9 to 16)  <= i2c_reg_without_ack(15 downto 8);
  i2c_reg_with_ack(17)       <= '1';
  i2c_reg_with_ack(18 to 25) <= i2c_reg_without_ack(7 downto 0);
  i2c_reg_with_ack(26)       <= '1'; 
  i2c_reg_with_ack(27)       <= '0';
 
  -- This process counts the clocks for reducing the clock speed
  -- of the i2c clock
  clk_cnt_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then
	   clk_cnt <= 0; 
	 elsif rising_edge(clk_i) then
      if clk_cnt < fd_c then
        clk_cnt <= clk_cnt + 1;
      end if;
      if clk_cnt_reset = '1' then
        clk_cnt <= 0;
      end if;
	 end if; 
  end process clk_cnt_p;  
 
  clk_cnt_done <= '1' when clk_cnt = fd_c else '0';
 
  -- This is the index for the i2c register. 
  i2c_idx_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then
	   idx <= 0; 
	 elsif rising_edge(clk_i) then
      if idx_inc = '1' and idx < 27 then
        idx <= idx + 1; 
      end if;  
      if idx_reset = '1' then
        idx <= 0;
      end if;
    end if; 
  end process i2c_idx_p;  
 
  -- This are the registered outputs for the i2c clock and data
  i2c_out_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then
	   i2c_clk <= '1'; 
      i2c_dat <= '1';    
	 elsif rising_edge(clk_i) then
      i2c_dat <= i2c_dat_new;
      i2c_clk <= i2c_clk_new;  
    end if; 
  end process i2c_out_p;  
 
  -- The i2c register without ack data
  i2c_data_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then   
	   i2c_reg_without_ack <= (others => '0'); 
    elsif rising_edge(clk_i) then
     if load_i2c_reg_without_ack = '1' then
        i2c_reg_without_ack <= data_i;
      end if;
    end if; 
  end process i2c_data_p;
 
  -- i2c data selection process 
  i2c_dat_sel_p : process(i2c_dat_sel, i2c_reg_with_ack, i2c_dat, idx)
  begin
   case i2c_dat_sel is
    when sel_old   => i2c_dat_new <= i2c_dat;
	 when sel_reg   => i2c_dat_new <= i2c_reg_with_ack(idx); 
	 when sel_one   => i2c_dat_new <= '1';
	 when sel_zero  => i2c_dat_new <= '0';
	 when others    => i2c_dat_new <= '0'; 
   end case; 
  end process i2c_dat_sel_p; 
 
  -- i2c clock selection process
  i2c_clk_sel_p : process(i2c_clk, i2c_clk_sel)
  begin
    case i2c_clk_sel is
	   when sel_old   => i2c_clk_new <= i2c_clk;
	   when sel_one   => i2c_clk_new <= '1';
	   when sel_zero  => i2c_clk_new <= '0';
	   when others    => i2c_clk_new <= '0';
	 end case; 
  end process i2c_clk_sel_p;
 
  -- Sequential process for the statemachine 
  statem_seq_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then   
      state <= idle_s;
    elsif rising_edge(clk_i) then
      state <= next_state;
    end if; 
  end process statem_seq_p;
 
  statem_comb_p: process(state, load_i, idx, clk_cnt_done)
  begin
    load_i2c_reg_without_ack<= '0'; 
    idx_inc   <= '0'; 
    idx_reset <= '0';
    clk_cnt_reset <= '0';
    busy_o <= '1';
	 i2c_dat_sel <= sel_old; 
    i2c_clk_sel <= sel_old; 
    next_state <= state; 
    case state is
      when idle_s => 
        busy_o <= '0';
        i2c_clk_sel <= sel_one;
        i2c_dat_sel <= sel_one; 
        if load_i = '1' then
          load_i2c_reg_without_ack <= '1';
          clk_cnt_reset <= '1';
          idx_reset     <= '1';
          next_state <= start_s;
          i2c_dat_sel <= sel_zero; 			 
        end if;
      when start_s =>
        if clk_cnt_done = '1' then
          next_state <= data_hold_s;
          clk_cnt_reset <= '1';
          i2c_clk_sel <= sel_zero; 
        end if;
      when data_hold_s =>
          next_state  <= data_s;			 
          i2c_dat_sel <= sel_reg;
      when data_s =>
        if clk_cnt_done = '1' then  
          next_state    <= clock_high_s;			 
          i2c_clk_sel   <= sel_one;
          clk_cnt_reset <= '1';
        end if;
      when clock_high_s => 
        if clk_cnt_done = '1' then
          if idx = 27 then -- last bit transmitted
            i2c_dat_sel <= sel_one;
            next_state  <= stop_s; 
          else
            idx_inc     <= '1';
            i2c_clk_sel <= sel_zero;            
            next_state  <= data_hold_s;
          end if;  
          clk_cnt_reset  <= '1';
        end if; 
      when stop_s =>
        if clk_cnt_done = '1' then
          next_state <= idle_s;
        end if; 
      when others => 
        next_state <= idle_s;          
    end case; 
  end process statem_comb_p; 
 
  i2c_clk_o <= i2c_clk;
  i2c_dat_o <= i2c_dat; 
 
end; -- architecture
i2c_write.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity i2c_write is
  port (
    clk_i:      in std_ulogic;
    reset_ni:   in std_ulogic;
    load_o:     out std_ulogic;
    data_o:     out std_ulogic_vector(23 downto 0);
    busy_i:     in std_ulogic);
end; 
 
architecture rtl of i2c_write is
  constant num_regs_c : integer := 12;
  type state_t is (start_s, wait_s, done_s);
  signal state, next_state : state_t;
  signal counter : integer range 0 to num_regs_c-1; 
  signal counter_enable : std_ulogic;
  type data_array_t is array(0 to num_regs_c-1) of std_ulogic_vector(23 downto 0);
 
  constant data_array : data_array_t := (
    X"341200", -- Set Inactive
    X"341E00", -- Reset the Device
    X"34001A", -- Left Line In / Mute off / Volume
    X"34021A", -- Right Line In
    X"34047F", -- Headphone Left
    X"34067F", -- Headphone Right
    X"340815", -- Analog path control (MIC to ADC, DAC to output, MIC Boost)
    X"340A00", -- Digital path control
    X"340C61", -- Power Down Control (Everything switched on)
    X"340E13", -- Digital Audio Interface Format (Slave Mode, DSP Mode, 16 Bit)
    X"34100C", -- Sampling Control (8 kHz Sampling frequency, 12.288 MHz MCLK frequency)
    X"341201"); -- Active Control (Activate) 
 
begin
 
  seq_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then
      state <= start_s;
      counter <= 0;
    elsif rising_edge(clk_i) then
      state <= next_state;
      if counter_enable = '1' then
        if counter < num_regs_c - 1 then
          counter <= counter + 1; 
        else
          counter <= 0;
        end if;
      end if; 
    end if; 
  end process seq_p;
 
  data_o <= data_array(counter);
 
  process(state, counter, busy_i)
  begin
    load_o <= '0';
    counter_enable <= '0';
    next_state <= state;
    case state is
      when start_s => 
        load_o <= '1';
        next_state <= wait_s;  
      when wait_s =>
        if busy_i = '0' then
          if counter = num_regs_c-1 then
            next_state <= done_s;
            --counter_enable <= '1';
          else
            next_state     <= start_s;
            counter_enable <= '1';
          end if; 
        end if; 
      when others => 
        next_state <= state;          
    end case; 
  end process; 
 
end; -- architecture
memory.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
-- This VHDL memory description will result in FPGA memory usage. 
-- The EPC2C20 series provides a total of 52 M4K memory blocks
-- Each M4K memory block contains 4608 Bits. The following configurations are supported: 
-- 4K  1, 2K  2, 1K  4, 512  8, 512  9, 256  16, 256  18
-- The maximum is therefore 52 x 256 = 13312 samples. 
 
entity memory is 
  port (
    clk_i       : in std_ulogic;
    we_i        : in std_ulogic;
    waddr_i     : in unsigned(12 downto 0); 
    raddr_i     : in unsigned(12 downto 0);
    wdata_i     : in std_ulogic_vector(15 downto 0); 
    rdata_o     : out std_ulogic_vector(15 downto 0)
  );
end; 
 
architecture rtl of memory is
  type ram_t is array(0 to 2 ** 13 - 1) of std_ulogic_vector(15 downto 0);
  signal ram : ram_t;
begin
 
  mem_p : process(clk_i)
  begin
    if rising_edge(clk_i) then
      if we_i = '1' then
        ram(to_integer(waddr_i)) <= wdata_i;
      end if; 
      rdata_o <= ram(to_integer(raddr_i)); 
    end if; 
  end process mem_p;  
 
end; -- architecture
adcintf.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
-- ADC (Analog to Digital Converter) Interface
-- Shifts in 16 bits and provides the data in parallel
-- When all 16 bits are shifted in, the valid_o output is set to "1" for one clock cycle
 
entity adcintf is 
  port (
    clk_i                  : in std_ulogic;
    reset_ni               : in std_ulogic;
    en_i                   : in std_ulogic; 
    valid_o                : out std_ulogic; 
    data_o                 : out std_ulogic_vector(15 downto 0); 
    start_i                : in std_ulogic; 
    ser_dat_i              : in std_ulogic);
end; 
 
architecture rtl of adcintf is
 
begin
 
  seq_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then
    elsif rising_edge(clk_i) then
    end if; 
  end process seq_p;  
 
  statem_comb_p : process(start_i)
  begin
    valid_o <= '0';
  end process statem_comb_p;
 
end; -- architecture
dacintf.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
-- DAC (Digital to Analog Converter) Interface
-- Loads a word in parallel and shifts it out as serial bit stream
-- The data needs to be shifted out twice. This is required as 
-- the audio interface needs stereo data.
 
entity dacintf is 
  port (
    clk_i                  : in std_ulogic;
    reset_ni               : in std_ulogic;
    load_i                 : in std_ulogic; 
    data_i                 : in std_ulogic_vector(15 downto 0); 
    en_i                   : in std_ulogic; 
    ser_dat_o              : out std_ulogic);
end; 
 
architecture rtl of dacintf is
 
begin
 
  load_and_shift_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then
    elsif rising_edge(clk_i) then
    end if; 
  end process load_and_shift_p;
 
  ser_dat_o <= '0';
 
end; -- architecture
ringbuf.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
-- Ring Buffer stores samples in a circular buffer
-- The read buffer pointer is one buffer entry ahead 
-- of the write buffer pointer. 
 
entity ringbuf is 
  port (
    clk_i                  : in std_ulogic;
    reset_ni               : in std_ulogic;
    en_i                   : in std_ulogic; 
    data_i                 : in std_ulogic_vector(15 downto 0); 
    data_o                 : out std_ulogic_vector(15 downto 0));
end; 
 
architecture rtl of ringbuf is
 
component memory is 
  port (
    clk_i       : in std_ulogic;
    we_i        : in std_ulogic;
    waddr_i     : in unsigned(12 downto 0); 
    raddr_i     : in unsigned(12 downto 0);
    wdata_i     : in std_ulogic_vector(15 downto 0); 
    rdata_o     : out std_ulogic_vector(15 downto 0)
  );
end component; 
 
  signal raddr, waddr : unsigned(12 downto 0); 
 
begin
 
  mem_i0 : memory
  port map (
    clk_i      => clk_i,
    we_i       => en_i, 
    raddr_i    => raddr,
    waddr_i    => waddr,
    rdata_o    => data_o,
    wdata_i    => data_i);
 
  buffer_pointer_p : process(clk_i, reset_ni)
  begin
    if reset_ni = '0' then
 
    elsif rising_edge(clk_i) then
 
    end if; 
  end process buffer_pointer_p; 
 
end; -- architecture