H
hhanff
Hello world!
I have a problem concerning tri-state signals. Basically I have the
folliwing design:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
library work;
use work.config.all;
entity tri_state_design is
port(
-- currently running on 18.5 Mhz clock
clk : in std_logic;
-- clock is active low
nrst : in std_logic;
-- pins for i2c signal 1
i2c_scl_1 : inout std_logic;
i2c_sda_1 : inout std_logic;
-- pins for i2c signals 2
i2c_scl_2 : inout std_logic;
i2c_sda_2 : inout std_logic;
);
end tri_state_design;
architecture behavioral of tri_state_design is
component i2c_wrapper
port (
sys_clk : in std_logic;
nrst_i : in std_logic;
sda : inout std_logic;
scl : inout std_logic);
end component;
signal sda_s : std_logic;
signal scl_s : std_logic;
signal mux_s : std_logic;
signal mux_cnt_s : natural; -- needed to multiplex the 2
different tmp sensors to one i2c mudule
i2c_wrapper_1 : i2c_wrapper
port map (
sys_clk => clk,
nrst_i => rst,
sda => sda_s,
scl => scl_s);
-- purpose: This process sets up a counter to multiplex the two
different i2c signals
-- every 500 ms to share the same i2c instance
-- type : sequential
-- inputs : clk, rst
-- outputs:
mux : process (clk, rst)
begin -- process mux
if rst = '1' then -- asynchronous reset (active
high)
mux_cnt_s <= 0;
mux_s <= I2C_1;
elsif clk'event and clk = '1' then -- rising clock edge
if to_integer(to_unsigned(mux_cnt_s, 32)) = 10000 / 2 then
case mux_s is
when I2C_1 =>
mux_s <= I2C_2;
when I2C_2 =>
mux_s <= I2C_1;
when others => null;
end case;
mux_cnt_s <= 0;
else
mux_cnt_s <= mux_cnt_s + 1;
end if;
end if;
end process mux;
-- i2c signals are multiplexed here
i2c_sda_1 <= sda_s when mux_s = I2C_1 else 'Z';
i2c_scl_1 <= scl_s when mux_s = I2C_1 else 'Z';
i2c_sda_2 <= sda_s when mux_s = I2C_2 else 'Z';
i2c_scl_2 <= scl_s when mux_s = I2C_2 else 'Z';
----purpose : Process for multiplexing the I2C signals
----type : sequential
----inputs : sys_clk, rst_s
----outputs :
--mux_p : process (clk, rst)
--begin -- process control_write_p
-- if (rst = '1') then -- asynchronous reset
(active high)
-- i2c_sda_2 <= 'Z';
-- i2c_scl_2 <= 'Z';
-- i2c_sda_1 <= 'Z';
-- i2c_scl_1 <= 'Z';
-- elsif clk'event and clk = '1' then -- rising clock edge
-- case mux_s is
-- when I2C_1 =>
-- i2c_sda_2 <= 'Z';
-- i2c_scl_2 <= 'Z';
-- i2c_sda_1 <= sda_s;
-- i2c_scl_1 <= scl_s;
-- when I2C_2 =>
-- i2c_sda_2 <= sda_s;
-- i2c_scl_2 <= scl_s;
-- i2c_sda_1 <= 'Z';
-- i2c_scl_1 <= 'Z';
-- when others =>
-- i2c_sda_2 <= 'Z';
-- i2c_scl_2 <= 'Z';
-- i2c_sda_1 <= 'Z';
-- i2c_scl_1 <= 'Z
-- end case;
-- end if;
--end process mux_p;
end behavioral;
As you can see 2 external i2c signals shall be multiplexed to one i2c
instance. I tried to implement the multiplexer in both a concurrent an
synchronous way but none of them is OK for my Spartan 3 design.
In most cases it seems that the active i2c sda line is forced to '1'
when a 'Z' is desired (e.g. during the achnowledge phase).
Can you help me?
Greetings,
Hendrik
I have a problem concerning tri-state signals. Basically I have the
folliwing design:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
library work;
use work.config.all;
entity tri_state_design is
port(
-- currently running on 18.5 Mhz clock
clk : in std_logic;
-- clock is active low
nrst : in std_logic;
-- pins for i2c signal 1
i2c_scl_1 : inout std_logic;
i2c_sda_1 : inout std_logic;
-- pins for i2c signals 2
i2c_scl_2 : inout std_logic;
i2c_sda_2 : inout std_logic;
);
end tri_state_design;
architecture behavioral of tri_state_design is
component i2c_wrapper
port (
sys_clk : in std_logic;
nrst_i : in std_logic;
sda : inout std_logic;
scl : inout std_logic);
end component;
signal sda_s : std_logic;
signal scl_s : std_logic;
signal mux_s : std_logic;
signal mux_cnt_s : natural; -- needed to multiplex the 2
different tmp sensors to one i2c mudule
i2c_wrapper_1 : i2c_wrapper
port map (
sys_clk => clk,
nrst_i => rst,
sda => sda_s,
scl => scl_s);
-- purpose: This process sets up a counter to multiplex the two
different i2c signals
-- every 500 ms to share the same i2c instance
-- type : sequential
-- inputs : clk, rst
-- outputs:
mux : process (clk, rst)
begin -- process mux
if rst = '1' then -- asynchronous reset (active
high)
mux_cnt_s <= 0;
mux_s <= I2C_1;
elsif clk'event and clk = '1' then -- rising clock edge
if to_integer(to_unsigned(mux_cnt_s, 32)) = 10000 / 2 then
case mux_s is
when I2C_1 =>
mux_s <= I2C_2;
when I2C_2 =>
mux_s <= I2C_1;
when others => null;
end case;
mux_cnt_s <= 0;
else
mux_cnt_s <= mux_cnt_s + 1;
end if;
end if;
end process mux;
-- i2c signals are multiplexed here
i2c_sda_1 <= sda_s when mux_s = I2C_1 else 'Z';
i2c_scl_1 <= scl_s when mux_s = I2C_1 else 'Z';
i2c_sda_2 <= sda_s when mux_s = I2C_2 else 'Z';
i2c_scl_2 <= scl_s when mux_s = I2C_2 else 'Z';
----purpose : Process for multiplexing the I2C signals
----type : sequential
----inputs : sys_clk, rst_s
----outputs :
--mux_p : process (clk, rst)
--begin -- process control_write_p
-- if (rst = '1') then -- asynchronous reset
(active high)
-- i2c_sda_2 <= 'Z';
-- i2c_scl_2 <= 'Z';
-- i2c_sda_1 <= 'Z';
-- i2c_scl_1 <= 'Z';
-- elsif clk'event and clk = '1' then -- rising clock edge
-- case mux_s is
-- when I2C_1 =>
-- i2c_sda_2 <= 'Z';
-- i2c_scl_2 <= 'Z';
-- i2c_sda_1 <= sda_s;
-- i2c_scl_1 <= scl_s;
-- when I2C_2 =>
-- i2c_sda_2 <= sda_s;
-- i2c_scl_2 <= scl_s;
-- i2c_sda_1 <= 'Z';
-- i2c_scl_1 <= 'Z';
-- when others =>
-- i2c_sda_2 <= 'Z';
-- i2c_scl_2 <= 'Z';
-- i2c_sda_1 <= 'Z';
-- i2c_scl_1 <= 'Z
-- end case;
-- end if;
--end process mux_p;
end behavioral;
As you can see 2 external i2c signals shall be multiplexed to one i2c
instance. I tried to implement the multiplexer in both a concurrent an
synchronous way but none of them is OK for my Spartan 3 design.
In most cases it seems that the active i2c sda line is forced to '1'
when a 'Z' is desired (e.g. during the achnowledge phase).
Can you help me?
Greetings,
Hendrik