I have a component, which is added several times by a generate command:

Gen_RayMemory: for i in 0 to RayCount-1 generate
    Mem: RayMemory
    generic map(
        length_data => Data_length,
        length_ray => RayLength,
        direction => '1'
    port map(
        clk => clk,
        i_start => i_user,
        i_data => i_data,
        i_store => Rays_save(i),
        i_invalid => Rays_invalid(i),

        r_rd => select_ray(i),
        r_data => data_out(i) --    <- Fix here (std_logic_vector)
end generate Gen_RayMemory;

Lets have a look a the ports starting with r_ only. Always only one of the components is enable by the r_rd signal. The enabled component will put its data to r_data.

Is there a elegant way, to combine these outputs to a single data_out? They could be OR-ed or multiplexed by select_ray(i).

  • \$\begingroup\$ So you want a better solution then OR-ing the outputs together or multiplex them based on select_ray? \$\endgroup\$ – Martin Zabel Mar 23 '16 at 14:39
  • \$\begingroup\$ I could store them in an Array and write some logic to select them again (or merge them by OR). I am looking for a more direct (inline) way. \$\endgroup\$ – Botnic Mar 23 '16 at 14:40
  • 1
    \$\begingroup\$ In a synthesisable design, you need either multiplexers or OR logic. In my opinion, anything that didn't simply show this logic in the code in a plain way would just make the code harder to read. \$\endgroup\$ – scary_jeff Mar 29 '16 at 12:27

You can describe it using a high-impedance output of your RAM. All RAMs, which are de-selected, output all 'Z' on the data signal. Only the selected RAM actually outputs the requested value. Then, the outputs of all RAMs can be connected together without creating a short-circuit. That means, all RAMs "write" to the same signal. Some tools can even synthesize it, by replacing the 3-state driver by appropriate logic gates of the target architecture if required (e.g. ISE 14.7).

Example design:

library ieee;
use ieee.std_logic_1164.all;

entity RAM is
  generic (
    CONTENT : std_logic_vector(7 downto 0));

  port (
    read_enable : in  std_logic;
    read_data   : out std_logic_vector(7 downto 0));
end entity RAM;

architecture rtl of RAM is
  read_data <= CONTENT when read_enable = '1' else (others => 'Z');
end architecture rtl;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity top is
  generic (
    N : positive);          -- number of RAMs

  port (
    read_enable : in  std_logic_vector(N-1 downto 0);
    read_data   : out std_logic_vector(7 downto 0));
end entity top;

architecture rtl of top is

begin  -- architecture rtl

  gRAMs: for i in 0 to N-1 generate
    RAM_inst: entity work.RAM
      generic map (
        CONTENT => std_logic_vector(to_unsigned(i, 8)))
      port map (
        read_enable => read_enable(i),
        read_data   => read_data);
  end generate gRAMs;

end architecture rtl;

If you simulate it using this testbench:

library ieee;
use ieee.std_logic_1164.all;

entity top_tb is
end entity top_tb;

architecture sim of top_tb is
  constant N : positive := 4;
  signal read_enable : std_logic_vector(N-1 downto 0) := (others => '0');
  signal read_data   : std_logic_vector(7 downto 0);

begin  -- architecture sim
  DUT: entity work.top
    generic map (
      N => N)
    port map (
      read_enable => read_enable,
      read_data   => read_data);

  Stimuli: process
    wait for 10 ns;
    for i in 0 to N-1 loop
      read_enable(i) <= '1';
      wait for 10 ns;
      read_enable(i) <= '0';
    end loop;
  end process;
end architecture sim;

then you get the following result:

simulation output

|improve this answer|||||
  • \$\begingroup\$ "Some tools can even synthesize it": important point ;-) \$\endgroup\$ – Botnic Mar 23 '16 at 15:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.