Connecting inouts

Discussion in 'VHDL' started by rbn, Apr 15, 2005.

  1. rbn

    rbn Guest

    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 ------------------------
    --*************************************************************--
     
    rbn, Apr 15, 2005
    #1
    1. Advertisements

  2. 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
     
    Engineering Guy, Apr 15, 2005
    #2
    1. Advertisements

  3. rbn

    rbn Guest

    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.
     
    rbn, Apr 15, 2005
    #3
  4. 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
     
    Engineering Guy, Apr 15, 2005
    #4
  5. Well, that's compact and much faster (no need to execute the
    assignments). The simple solutions work best.

    EG
     
    Engineering Guy, Apr 15, 2005
    #5
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.