EDAboard.com | EDAboard.eu | EDAboard.de | EDAboard.co.uk | RTV forum PL | NewsGroups PL

Multiplex 2 external I2C signals to one FPGA internal signal

elektroda.net NewsGroups Forum Index - VHDL Language - Multiplex 2 external I2C signals to one FPGA internal signal

hhanff
Guest

Wed Jul 14, 2010 6:27 pm   



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

Michael Kellett
Guest

Wed Jul 14, 2010 6:27 pm   



"hhanff" <hendrik.hanff_at_googlemail.com> wrote in message
news:3fec1133-6279-4142-86fc-b9476179220c_at_u26g2000yqu.googlegroups.com...
Quote:
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

Might be irrelevant but where is I2C_1 defined ?

Michael Kellett

Tricky
Guest

Wed Jul 14, 2010 7:11 pm   



On 14 July, 16:27, hhanff <hendrik.ha...@googlemail.com> wrote:
Quote:
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

Are these tristates signals connected to pins, or are they meant to be
internal signals?
You cannot use internal tri-states. They get converted to muxes.

Andy
Guest

Wed Jul 14, 2010 8:18 pm   



On Jul 14, 10:27 am, hhanff <hendrik.ha...@googlemail.com> wrote:
Quote:
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

As far as I can see, you only have an output mux (for signal flow from
i2c_wrapper to the two external i2c interfaces.)

What about the intput mux? How is i2c_wrapper going to receive clock
and data from the external interfaces?

Andy

hhanff
Guest

Thu Jul 15, 2010 10:13 am   



On 14 Jul., 18:11, Tricky <trickyh...@gmail.com> wrote:
Quote:
On 14 July, 16:27, hhanff <hendrik.ha...@googlemail.com> wrote:



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

Are these tristates signals connected to pins, or are they meant to be
internal signals?
You cannot use internal tri-states. They get converted to muxes.

These signalse are connected to pins:
-- 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;

The signals
sda : inout std_logic;
scl : inout std_logic;
are internal signals and thus converted to muxes.
It is OK for me if they are converted to muxes and the whole design is
fully functional as long as I do not manually multiplex the external
i2c signals to the i2c_wrapper.

In other words:
If I would avoid the manual multiplexing of the two external ic2
signals by using two i2c_wrapper components there wouldn't be any
problem.

Or:
If I would only have one external i2c signal and connect this to the
i2c_wrapper, there would also be no problem.

Why???

hhanff
Guest

Thu Jul 15, 2010 10:16 am   



On 14 Jul., 18:38, "Michael Kellett" <nos...@nospam.com> wrote:
Quote:
"hhanff" <hendrik.ha...@googlemail.com> wrote in message

news:3fec1133-6279-4142-86fc-b9476179220c_at_u26g2000yqu.googlegroups.com...



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

Might be irrelevant but where is I2C_1 defined ?

Michael Kellett

Sorry! Both I2C_1 and I2C_2 are defined in a package which I didn't
include in this thread for reasons of simplicity.

I2C_1 = '1' and I2C_2 = '0'...

hhanff
Guest

Thu Jul 15, 2010 10:19 am   



On 14 Jul., 19:18, Andy <jonesa...@comcast.net> wrote:
Quote:
On Jul 14, 10:27 am, hhanff <hendrik.ha...@googlemail.com> wrote:



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

As far as I can see, you only have an output mux (for signal flow from
i2c_wrapper to the two external i2c interfaces.)

What about the intput mux? How is i2c_wrapper going to receive clock
and data from the external interfaces?

Andy

For my understanding the synthesis tool should insert muxes for
resolving input and output signals automatically during synthesis.
The mux that was inserted by me has the intention to multiplex the two
external i2c signals to one internal i2c component. Reason: I would
like to save resources...

hhanff
Guest

Thu Jul 15, 2010 10:29 am   



On 14 Jul., 17:27, hhanff <hendrik.ha...@googlemail.com> wrote:
Quote:
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

Yesterday I found an article which seems to adress my problem:
http://cdserv1.wbut.ac.in/81-312-0257-7/Xilinx/files/Xcell%20Journal%20Articles/xcell_47/xc_synpro47.pdf

The paragraph "Mapping to Spartan-3 without TBUF" adresses what I'm
trying to implement... unfortunately I do not understand what is
described... can anybody help me???

Rob Gaddi
Guest

Thu Jul 15, 2010 5:40 pm   



On 7/15/2010 12:19 AM, hhanff wrote:

[snip]
Quote:

For my understanding the synthesis tool should insert muxes for
resolving input and output signals automatically during synthesis.
The mux that was inserted by me has the intention to multiplex the two
external i2c signals to one internal i2c component. Reason: I would
like to save resources...

How many "resources" are you talking about. Specifically, how many
LUTs, how many flops, are you trying to save? Out of how many in your chip?

Frankly, if the resource cost of an extra I2C interface is blowing your
design budget, you'll never place and route anyhow. And if it's not,
then just instantiate two I2C interfaces and be done with it.

Also, I personally HATE the use of internal tristates that the
synthesizer "figures out" into muxes. It means that your code is
downright lying to you about what hardware is being generated.

--
Rob Gaddi, Highland Technology
Email address is currently out of order

Andy
Guest

Thu Jul 15, 2010 8:15 pm   



Synthesis' job is to produce hardware that will act like the source
code simulates (within limitations). If you simulate your code (highly
recommended!), you will see that anything externally driving your two
I2C interfaces will not get back to the i2c_wrapper component.
Continuous signal assignments are not bidirectional relationships.
(not to be confused with port assignments on inout ports) You won't
get a bidirectional HW interface from a single continuous assignment.

If you want the synthesis tool to implement something, you have to
describe the behavior you want implemented.

One more hint: do not use "clk = '1' and clk'event" for detecting a
rising clock edge. Use "rising_edge(clk)" instead. It reliably handles
transitions like '0' -> 'H', which might be critical in this design.
Both implement the same hardware, but the former does not simulate
correctly.

Andy

hhanff
Guest

Fri Jul 23, 2010 2:48 pm   



Just for completeness: I changed my design and removed all internal
tristates. Now it's fine.

elektroda.net NewsGroups Forum Index - VHDL Language - Multiplex 2 external I2C signals to one FPGA internal signal

Arabic versionBulgarian versionCatalan versionCzech versionDanish versionGerman versionGreek versionEnglish versionSpanish versionFinnish versionFrench versionHindi versionCroatian versionIndonesian versionItalian versionHebrew versionJapanese versionKorean versionLithuanian versionLatvian versionDutch versionNorwegian versionPolish versionPortuguese versionRomanian versionRussian versionSlovak versionSlovenian versionSerbian versionSwedish versionTagalog versionUkrainian versionVietnamese versionChinese version
RTV map EDAboard.com map News map EDAboard.eu map EDAboard.de map EDAboard.co.uk map Opony