VHDL Code für die I2C Schnittstelle

Die I2C Schnittstelle benötigt eine open-drain Anschluss für die Daten. In folgendem Toplevel ist der Open-Drain Treiber “OPNDRN” aus der Alterabibliothek instantiiert und das I2C Subsystem eingefügt. Der I2C_SDAT Port in der top entity muss als “inout” definiert sein. Dann kann man diesen Port lesen und gleichzeitig dem Port einen Wert zuweisen.

top.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
-- Notwendig für den OPNDRN Treiber : 
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; 
 
 
  signal clk, reset_n          : std_ulogic;
 
  signal i2c_dat_o             : std_ulogic;
  signal i2c_dat_i             : std_ulogic; 
 
 
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);
 
 
  -- 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