Connecting inouts

R

rbn

Hi all,

I have a question concerning connection of bidirectional signals.

Consider the code below. The attempt is to make a wrapper, which blasts
a component consisting of a std_logic_vector into separate std_logics.
Both the instantiated component's and the blasting entity's ports are
defined as inouts. The challenge now is to connect index 0 of the
std_logic_vector with the sl0 port and index 1 of the std_logic_vector
with the sl1 port in a bidrectional manner.

My first attempt was - as shown in the code - to make four concurrent
assignments utilizing an intermediate signal, slv_s. This doesn't seem
to work. It reaches the simulator's iteration limit at time 0.

I have attached two files (well, it turned out that I couldn't attach,
so they're inlined below):
fail.vhd contains the code below and some testbench that instantiates
sl. It fails.
pass.vhd is the same code with std_logic_vectors all over. It passes.

What do I do wrong in the connection, or rather, is there another - and
safe - way to connect the signals?

Any help is highly appreciated.
Thanks,
René Bøje Nielsen


entity slv is
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end slv;

entity sl is
port (
sl0_io : inout std_logic;
sl1_io : inout std_logic
);
end sl;

architecture wrapper of sl is
component slv
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end component;
signal slv_s : std_logic_vector(1 downto 0) := (others => 'Z');
begin
slv_s(0) <= sl0_io;
slv_s(1) <= sl1_io;
sl0_io <= slv_s(0);
sl1_io <= slv_s(1);
inst_slv : slv
port map (
slv_io => slv_s
);
end wrapper;


--*************************************************************--
--------------------------- fail.vhd BEGIN ----------------------
--*************************************************************--

------------------------------------------------
-- Innermost component
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity slv is
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end slv;

architecture behavioral of slv is
begin

p : process
begin
slv_io <= "ZZ";
wait for 200 ns;
slv_io <= "10";
wait for 200 ns;
slv_io <= "01";
wait for 200 ns;
slv_io <= "ZZ";
wait;
end process p;

end behavioral;

------------------------------------------------
-- Wrapper
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity sl is
port (
sl0_io : inout std_logic;
sl1_io : inout std_logic
);
end sl;

architecture wrapper of sl is
component slv
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end component;

signal slv_s : std_logic_vector(1 downto 0) := (others => 'Z');

begin

slv_s(0) <= sl0_io;
slv_s(1) <= sl1_io;
sl0_io <= slv_s(0);
sl1_io <= slv_s(1);

inst_slv : slv
port map (
slv_io => slv_s
);

end wrapper;

------------------------------------------------
-- Testbench/Top
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity top is
end top;

architecture testbench of top is

component sl
port (
sl0_io : inout std_logic;
sl1_io : inout std_logic
);
end component;

signal sl0_s : std_logic := 'Z';
signal sl1_s : std_logic := 'Z';

begin

p : process
begin
sl0_s <= 'Z';
sl1_s <= 'Z';
wait for 800 ns;
sl0_s <= '1';
sl1_s <= '0';
wait for 200 ns;
sl0_s <= '0';
sl1_s <= '1';
wait for 200 ns;
sl0_s <= 'Z';
sl1_s <= 'Z';
wait;
end process p;

inst_sl : sl
port map (
sl0_io => sl0_s,
sl1_io => sl1_s
);

end testbench;

--*************************************************************--
--------------------------- fail.vhd END ------------------------
--*************************************************************--

--*************************************************************--
--------------------------- pass.vhd BEGIN ----------------------
--*************************************************************--
------------------------------------------------
-- Innermost component
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity slv is
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end slv;

architecture behavioral of slv is
begin

p : process
begin
slv_io <= "ZZ";
wait for 200 ns;
slv_io <= "10";
wait for 200 ns;
slv_io <= "01";
wait for 200 ns;
slv_io <= "ZZ";
wait;
end process p;

end behavioral;

------------------------------------------------
-- Wrapper
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity sl is
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end sl;

architecture wrapper of sl is
component slv
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end component;

begin

inst_slv : slv
port map (
slv_io => slv_io
);

end wrapper;

------------------------------------------------
-- Testbench/Top
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity top is
end top;

architecture testbench of top is

component sl
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end component;

signal slv_s : std_logic_vector(1 downto 0) := "ZZ";

begin

p : process
begin
slv_s <= "ZZ";
wait for 800 ns;
slv_s <= "01";
wait for 200 ns;
slv_s <= "10";
wait for 200 ns;
slv_s <= "ZZ";
wait;
end process p;

inst_sl : sl
port map (
slv_io => slv_s
);

end testbench;

--*************************************************************--
--------------------------- pass.vhd END ------------------------
--*************************************************************--
 
E

Engineering Guy

rbn said:
Hi all,

I have a question concerning connection of bidirectional signals.

Consider the code below. The attempt is to make a wrapper, which blasts
a component consisting of a std_logic_vector into separate std_logics.
Both the instantiated component's and the blasting entity's ports are
defined as inouts. The challenge now is to connect index 0 of the
std_logic_vector with the sl0 port and index 1 of the std_logic_vector
with the sl1 port in a bidrectional manner.

My first attempt was - as shown in the code - to make four concurrent
assignments utilizing an intermediate signal, slv_s. This doesn't seem
to work. It reaches the simulator's iteration limit at time 0.

I have attached two files (well, it turned out that I couldn't attach,
so they're inlined below):
fail.vhd contains the code below and some testbench that instantiates
sl. It fails.
pass.vhd is the same code with std_logic_vectors all over. It passes.

What do I do wrong in the connection, or rather, is there another - and
safe - way to connect the signals?

Any help is highly appreciated.
Thanks,
René Bøje Nielsen


entity slv is
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end slv;

entity sl is
port (
sl0_io : inout std_logic;
sl1_io : inout std_logic
);
end sl;

architecture wrapper of sl is
component slv
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end component;
signal slv_s : std_logic_vector(1 downto 0) := (others => 'Z');
begin
slv_s(0) <= sl0_io;
slv_s(1) <= sl1_io;
sl0_io <= slv_s(0);
sl1_io <= slv_s(1);
inst_slv : slv
port map (
slv_io => slv_s
);
end wrapper;


--*************************************************************--
--------------------------- fail.vhd BEGIN ----------------------
--*************************************************************--

------------------------------------------------
-- Innermost component
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity slv is
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end slv;

architecture behavioral of slv is
begin

p : process
begin
slv_io <= "ZZ";
wait for 200 ns;
slv_io <= "10";
wait for 200 ns;
slv_io <= "01";
wait for 200 ns;
slv_io <= "ZZ";
wait;
end process p;

end behavioral;

------------------------------------------------
-- Wrapper
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity sl is
port (
sl0_io : inout std_logic;
sl1_io : inout std_logic
);
end sl;

architecture wrapper of sl is
component slv
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end component;

signal slv_s : std_logic_vector(1 downto 0) := (others => 'Z');

begin

slv_s(0) <= sl0_io;
slv_s(1) <= sl1_io;
sl0_io <= slv_s(0);
sl1_io <= slv_s(1);

inst_slv : slv
port map (
slv_io => slv_s
);

end wrapper;

------------------------------------------------
-- Testbench/Top
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity top is
end top;

architecture testbench of top is

component sl
port (
sl0_io : inout std_logic;
sl1_io : inout std_logic
);
end component;

signal sl0_s : std_logic := 'Z';
signal sl1_s : std_logic := 'Z';

begin

p : process
begin
sl0_s <= 'Z';
sl1_s <= 'Z';
wait for 800 ns;
sl0_s <= '1';
sl1_s <= '0';
wait for 200 ns;
sl0_s <= '0';
sl1_s <= '1';
wait for 200 ns;
sl0_s <= 'Z';
sl1_s <= 'Z';
wait;
end process p;

inst_sl : sl
port map (
sl0_io => sl0_s,
sl1_io => sl1_s
);

end testbench;

--*************************************************************--
--------------------------- fail.vhd END ------------------------
--*************************************************************--

--*************************************************************--
--------------------------- pass.vhd BEGIN ----------------------
--*************************************************************--
------------------------------------------------
-- Innermost component
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity slv is
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end slv;

architecture behavioral of slv is
begin

p : process
begin
slv_io <= "ZZ";
wait for 200 ns;
slv_io <= "10";
wait for 200 ns;
slv_io <= "01";
wait for 200 ns;
slv_io <= "ZZ";
wait;
end process p;

end behavioral;

------------------------------------------------
-- Wrapper
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity sl is
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end sl;

architecture wrapper of sl is
component slv
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end component;

begin

inst_slv : slv
port map (
slv_io => slv_io
);

end wrapper;

------------------------------------------------
-- Testbench/Top
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity top is
end top;

architecture testbench of top is

component sl
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end component;

signal slv_s : std_logic_vector(1 downto 0) := "ZZ";

begin

p : process
begin
slv_s <= "ZZ";
wait for 800 ns;
slv_s <= "01";
wait for 200 ns;
slv_s <= "10";
wait for 200 ns;
slv_s <= "ZZ";
wait;
end process p;

inst_sl : sl
port map (
slv_io => slv_s
);

end testbench;

--*************************************************************--
--------------------------- pass.vhd END ------------------------
--*************************************************************--
Your problem is here:
slv_s(0) <= sl0_io;
slv_s(1) <= sl1_io;
sl0_io <= slv_s(0);
sl1_io <= slv_s(1);

Update to sl0_io causes the event on the slv_s(0). This triggers the
assignment sl0_io <= slv_s(0); to be executed and causes an event on
the sl0_io. This triggers the assignment slv_s(0) <= sl0_io; to be
exectued and causes an event on the slv_s(0). This triggers the
assignment sl0_io <= slv_s(0); to be executed and causes an event on
the sl0_io. This triggers the assignment slv_s(0) <= sl0_io; to be
exectued and causes an event on the slv_s(0). This triggers the
assignment sl0_io <= slv_s(0); to be executed and causes an event on
the sl0_io. This triggers the assignment slv_s(0) <= sl0_io; to be
exectued and causes an event on the slv_s(0). This triggers the
assignment sl0_io <= slv_s(0); to be executed and causes an event on
the sl0_io. This triggers the assignment slv_s(0) <= sl0_io; to be
exectued and causes an event on the slv_s(0).

.... and when the iteration limit is reached, the simulator will give you
an error message.

EG
 
R

rbn

I found out that I was not the only one having this problem, so
searching in older topics revealed the solution:

The wrapper should look like:

architecture wrapper of sl is
component slv
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end component;
begin
inst_slv : slv
port map (
slv_io(1) => sl1_io,
slv_io(0) => sl0_io
);
end wrapper;

And then it works!!

/René Bøje Nielsen.
 
E

Engineering Guy

Engineering said:
Your problem is here:


Update to sl0_io causes the event on the slv_s(0). This triggers the
assignment sl0_io <= slv_s(0); to be executed and causes an event on
the sl0_io. This triggers the assignment slv_s(0) <= sl0_io; to be
exectued and causes an event on the slv_s(0). This triggers the
assignment sl0_io <= slv_s(0); to be executed and causes an event on
the sl0_io. This triggers the assignment slv_s(0) <= sl0_io; to be
exectued and causes an event on the slv_s(0). This triggers the
assignment sl0_io <= slv_s(0); to be executed and causes an event on
the sl0_io. This triggers the assignment slv_s(0) <= sl0_io; to be
exectued and causes an event on the slv_s(0). This triggers the
assignment sl0_io <= slv_s(0); to be executed and causes an event on
the sl0_io. This triggers the assignment slv_s(0) <= sl0_io; to be
exectued and causes an event on the slv_s(0).

... and when the iteration limit is reached, the simulator will give you
an error message.

EG
On the other hand, if this is the only connection updating the port, the
delta count overflow should not happen. You may want to check if your
simulator works correctly...

EG
 
E

Engineering Guy

rbn said:
I found out that I was not the only one having this problem, so
searching in older topics revealed the solution:

The wrapper should look like:

architecture wrapper of sl is
component slv
port (
slv_io : inout std_logic_vector(1 downto 0)
);
end component;
begin
inst_slv : slv
port map (
slv_io(1) => sl1_io,
slv_io(0) => sl0_io
);
end wrapper;

And then it works!!

/René Bøje Nielsen.
Well, that's compact and much faster (no need to execute the
assignments). The simple solutions work best.

EG
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top