Seleccione la salida de Generar en VHDL

1

Tengo un componente, que se agrega varias veces mediante un comando de generación:

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;

Veamos los puertos que comienzan con r_ solamente. Siempre solo uno de los componentes está habilitado por la señal r_rd. El componente habilitado pondrá sus datos a r_data.

¿Existe una forma elegante de combinar estas salidas en un solo data_out? Podrían ser OR-ed o multiplexados por select_ray (i).

    
pregunta Botnic

1 respuesta

1

Puede describirlo usando una salida de alta impedancia de su RAM. Todas las RAM, que están deseleccionadas, emiten toda la "Z" en la señal de datos. Solo la RAM seleccionada en realidad genera el valor solicitado. Luego, las salidas de todas las RAM se pueden conectar juntas sin crear un cortocircuito. Eso significa que, todas las RAM "escriben" a la misma señal. Algunas herramientas pueden incluso sintetizarlo, reemplazando el controlador de 3 estados por puertas lógicas apropiadas de la arquitectura de destino si es necesario (por ejemplo, ISE 14.7).

Diseño de ejemplo:

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
begin
  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;

Si lo simulas usando este banco de pruebas:

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
  begin
    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;
    wait;
  end process;
end architecture sim;

entonces obtienes el siguiente resultado:

    
respondido por el Martin Zabel

Lea otras preguntas en las etiquetas