------------------------------------------------------------------------------------------------------------------ -- -- Projekt I2C SLAVE -- mit Anschluss an existierendes Design -- -- Autor Jörg Betz -- -- Datum 13.09.2005 -- -- -- Info top- entity -- -- -- Historie ------------------------------------------------------------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use work.i2c_syn_pkg.all; entity top_i2c is generic (version : integer range 0 to 255 := 1); port ( clk_t : in std_logic; reset_t : in std_logic; -- active high -- I2C Takt und Daten (SDA ist open Drain) scl_t : in std_logic; -- sda_t : inout std_logic; sda_in : in std_logic; sda_out : out std_logic; -- Multiplexer- Eingänge I_5_t : in std_logic_vector(7 downto 0); I_6_t : in std_logic_vector(7 downto 0); -- Output- Register rg0q : out std_logic_vector(7 downto 0); rg1q : out std_logic_vector(7 downto 0); rg2q : out std_logic_vector(7 downto 0); rg3q : out std_logic_vector(7 downto 0); rg4q : out std_logic_vector(7 downto 0) ); end; architecture behave of top_i2c is -- Multiplexer Eingänge signal I_7_t : std_logic_vector(7 downto 0); constant slv_adr_t : SLV_ADR_TYPE := 100; -- interne TX-Buffer- Signale signal tx_data_i : BYTE; signal tx_wr_i : std_logic; signal tx_empty_i : std_logic; -- interne RX_Buffer- Signale signal rx_vld_i : std_logic; signal rx_data_i : BYTE; signal rx_ack_i : std_logic; -- internes Signal für Ausgang Multiplexer signal y_i : std_logic_vector(7 downto 0); -- interne Output- Register signal reg0i : std_logic_vector(7 downto 0); signal reg1i : std_logic_vector(7 downto 0); signal reg2i : std_logic_vector(7 downto 0); signal reg3i : std_logic_vector(7 downto 0); signal reg4i : std_logic_vector(7 downto 0); -- Reset signal reset : std_logic; signal s_i : std_logic_vector(2 downto 0); signal so_i : std_logic_vector(2 downto 0); signal busy_write_i : std_logic; signal we_i : std_logic; -- Komponenten Deklaration: component i2c_slave generic (SDA_DELAY : integer range 1 to 16); port ( clk : in std_logic; reset : in std_logic; scl : in std_logic; -- sda : inout std_logic; sda_in : in std_logic; sda_out : out std_logic; slv_adr : in SLV_ADR_TYPE; tx_data : in BYTE; tx_wr : in std_logic; tx_empty : out std_logic; rx_data : out BYTE; rx_vld : buffer std_logic; rx_ack : in std_logic; busy : out std_logic; busy_write : out std_logic ); end component; component mux8to1_8b port ( I_0 : in std_logic_vector (7 downto 0); I_1 : in std_logic_vector (7 downto 0); I_2 : in std_logic_vector (7 downto 0); I_3 : in std_logic_vector (7 downto 0); I_4 : in std_logic_vector (7 downto 0); I_5 : in std_logic_vector (7 downto 0); I_6 : in std_logic_vector (7 downto 0); I_7 : in std_logic_vector (7 downto 0); s : in std_logic_vector (2 downto 0); y : out std_logic_vector (7 downto 0) ); end component; begin --reset <= not(reset_t); reset <= reset_t; I_7_t <= conv_std_logic_vector(version,8); -- Instanziierung der Komponenten BUS_System: i2c_slave generic map (SDA_DELAY => 5) port map (clk => clk_t, reset => reset, scl => scl_t, -- sda => sda_t, sda_in => sda_in, sda_out => sda_out, slv_adr => slv_adr_t, tx_data => tx_data_i, tx_wr => tx_wr_i, tx_empty => tx_empty_i, rx_data => rx_data_i, rx_vld => rx_vld_i, rx_ack => rx_ack_i, busy => open, busy_write => busy_write_i); Mult: mux8to1_8b port map(I_0 => reg0i, I_1 => reg1i, I_2 => reg2i, I_3 => reg3i, I_4 => reg4i, I_5 => I_5_t, I_6 => I_6_t, I_7 => I_7_t, s => s_i, y => y_i); process(clk_t, reset) begin if reset = '1' then rx_ack_i <= '0'; s_i <= (others => '0'); elsif rising_edge(clk_t) then if rx_vld_i = '1' then rx_ack_i <= '1'; s_i <= rx_data_i (2 downto 0); -- letzen 3 Bits von rx_data werden an Multiplexer übertragen else rx_ack_i <= '0'; end if; end if; end process; process(clk_t, reset) begin if reset = '1' then tx_wr_i <= '0'; tx_data_i <= (others => '0'); elsif rising_edge(clk_t) then if tx_empty_i = '1' then -- wenn tx- Buffer leer: Einlesen eines neuen Wertes. tx_wr_i <= '1'; else tx_wr_i <= '0'; end if; tx_data_i <= y_i; -- Zuweisung mit jeder steigenden Flanke end if; -- --> Einlesen in Transfer_Buffer erfolgt 3 clk nachdem ld_tx_shiftreg_q gesetzt wurde end process; -- Select für Output- Register process (clk_t, reset) begin if reset = '1' then so_i <= (others => '0'); we_i <= '0'; elsif rising_edge(clk_t) then if (busy_write_i = '1') then if (we_i = '0'and rx_vld_i = '1') then so_i <= rx_data_i(so_i'range); we_i <= '1'; end if; else we_i <= '0'; end if; end if; end process; process(rx_vld_i, reset) begin if reset = '1' then reg0i <= (others => '0'); reg1i <= (others => '0'); reg2i <= (others => '0'); reg3i <= (others => '0'); reg4i <= (others => '0'); rg0q <= (others => '0'); rg1q <= (others => '0'); rg2q <= (others => '0'); rg3q <= (others => '0'); elsif rising_edge(rx_vld_i) then if we_i = '1' then case so_i is when "000" => reg0i <= rx_data_i; when "001" => reg1i <= rx_data_i; when "010" => reg2i <= rx_data_i; when "011" => reg3i <= rx_data_i; when "100" => reg4i <= rx_data_i; rg0q <= reg0i; -- synchronous update of outputs 0..3 rg1q <= reg1i; -- together with output 4 rg2q <= reg2i; rg3q <= reg3i; when others => NULL; end case; end if; end if; end process; rg4q <= reg4i; end behave;