Differences

This shows you the differences between two versions of the page.

Link to this comparison view

dtpr_v5_code [2010/12/13 02:15] (current)
beckmanf created
Line 1: Line 1:
 +=== VHDL Code für Versuch 5 ===
  
 +<code vhdl 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
 +</​code>​
 +
 +<code vhdl 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
 +
 +</​code>​
 +
 +<code vhdl 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
 +</​code>​
 +
 +<code vhdl 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
 +</​code>​
 +
 +<code vhdl 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
 +</​code>​
 +
 +<code vhdl 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
 +</​code>​
 +
 +<code vhdl 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
 +</​code>​
 +
 +<code vhdl 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
 +</​code>​
 +
 +<code vhdl 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
 +</​code>​
 +
 +<code vhdl 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
 +</​code>​
 +
 +<code vhdl 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
 +</​code>​
 +
 +<code vhdl 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
 +</​code>​
  • dtpr_v5_code.txt
  • Last modified: 2010/12/13 02:15
  • by beckmanf