2011-01-24 8 views
7

Quiero crear un decodificador de dirección que sea lo suficientemente flexible como para que lo use cuando cambie el número de bits del selector y de las señales de salida descodificadas.Ideas para un decodificador flexible/genérico en VHDL

Así, en lugar de tener una estática (entrada fija/tamaño de salida) del decodificador que se ve algo como esto:

entity Address_Decoder is 
Generic 
(
    C_INPUT_SIZE: integer := 2 
); 
Port 
(
    input : in STD_LOGIC_VECTOR (C_INPUT_SIZE-1 downto 0); 
    output : out STD_LOGIC_VECTOR ((2**C_INPUT_SIZE)-1 downto 0); 
    clk : in STD_LOGIC; 
    rst : in STD_LOGIC 
); 
end Address_Decoder; 

architecture Behavioral of Address_Decoder is 

begin   
     process(clk) 
      begin 
       if rising_edge(clk) then 
        if (rst = '1') then 
        output <= "0000"; 
        else 
        case <input> is 
         when "00" => <output> <= "0001"; 
         when "01" => <output> <= "0010"; 
         when "10" => <output> <= "0100"; 
         when "11" => <output> <= "1000"; 
         when others => <output> <= "0000"; 
        end case; 
        end if; 
       end if; 
      end process; 

end Behavioral; 

tener algo que es más flexible/en general, que se ve así:

entity Address_Decoder is 
    Generic 
    (
     C_INPUT_SIZE: integer := 2 
    ); 
    Port 
    (
     input : in STD_LOGIC_VECTOR (C_INPUT_SIZE-1 downto 0); 
     output : out STD_LOGIC_VECTOR ((2**C_INPUT_SIZE)-1 downto 0); 
     clk : in STD_LOGIC; 
     rst : in STD_LOGIC 
    ); 
    end Address_Decoder; 

    architecture Behavioral of Address_Decoder is 

    begin   

DECODE_PROC: 
    process (clk) 
    begin 

     if(rising_edge(clk)) then 
     if (rst = '1') then 
      output <= conv_std_logic_vector(0, output'length); 
     else 
      case (input) is 
      for i in 0 to (2**C_INPUT_SIZE)-1 generate 
      begin 
       when (i = conv_integer(input)) => output <= conv_std_logic_vector((i*2), output'length);   
      end generate; 
      when others => output <= conv_std_logic_vector(0, output'length); 
      end case; 
     end if; 
     end if; 
    end process; 

    end Behavioral; 

Sé que este código no es válido y que los casos de prueba "cuándo" deben ser constantes y que no puedo usar el for-generate entre el enunciado de casos así, pero muestra qué es lo que busco : una entidad lo suficientemente inteligente como para crecer a mis necesidades.

He estado tratando de encontrar una solución elegante para este problema sin mucho éxito, por lo tanto, estoy abierto para cualquier sugerencia.

Gracias de antemano, Erick

+1

'numeric_std' proporciona una función que desplaza un vector por un número especificado. De modo que podría presumiblemente cambiar el vector '0 => '1', otros => '0'' a la izquierda por (número de entrada - 1). –

Respuesta

13

Al parecer desea que la entrada sea el índice del bit de salida que debe ser ajustado.

Escríbelo así. Algo así como (asumiendo tipos de numeric_std):

output <= (others => '0'); -- default 
output(to_integer(input)) <= '1'; 
+2

Corto y efectivo (¡y funcionó muy bien!). Esto me hace darme cuenta de que a veces querer ir un poco "más abajo" en la descripción del hardware (tratando de definir la lógica más cercana a cómo se verá su implementación de hardware), puede cegarlo soluciones que ponen parte de la carga de diseño en el software en lugar de usted. Gracias por la solución Jan. –

+2

Me alegro de que hayas recibido el metamensaje :-) ¡Felicidades con esa idea, que es sorprendentemente poco común en el mundo del diseño HDL! –

1

Siempre he encontrado este tipo de cosas más fáciles de seguir cuando se acaba de bucle sobre cada bit, así que algo como:

 if (rst = '1') then 
     output <= (others=>'0'); 
    else 
     for i in 0 to (2**C_INPUT_SIZE)-1 generate 
     begin 
     if (i = conv_integer(input)) then 
      output(i) <= '1'; 
     else 
      output(i) <= '0'; 
     end if; 
     end generate; 
    end if;