2011-01-24 15 views
7

Desidero creare un decodificatore di indirizzo che sia abbastanza flessibile da utilizzare per la modifica del numero di bit del selettore e dei segnali di uscita decodificati.Idee per un decodificatore flessibile/generico in VHDL

Così, invece di avere una statica (ingresso fisso/formato di output) Decoder che sembra qualcosa di simile:

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; 

avere qualcosa che è più flessibile/generale, che assomiglia a questo:

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; 

So che questo codice non è valido e che i casi di test "quando" devono essere costanti e che non posso usare il for-generate tra la dichiarazione del caso in questo modo, ma mostra cosa sono dopo : un'entità abbastanza intelligente da crescere secondo i miei bisogni.

Ho cercato di trovare una soluzione elegante per questo problema senza molto successo, quindi sono aperto a qualsiasi suggerimento.

Grazie in anticipo, Erick

+1

'numeric_std' offre invece una funzione che sposta un vettore di un numero specificato. Quindi potresti presumibilmente spostare il vettore '0 => '1', altri => '0'' lasciato da (numero di input - 1). –

risposta

13

A quanto pare si vuole l'ingresso sia l'indice del bit di uscita che dovrebbe essere impostato.

Scrivilo così. Qualcosa di simile (assumendo tipi da numeric_std):

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

Breve ed efficace (e ha funzionato benissimo!). Questo mi fa capire che a volte volendo andare un po '"in basso" nella descrizione dell'hardware (cercando di definire la logica più vicina a come sarà l'implementazione hardware), potrebbe impedirti di vedere soluzioni che caricano parte del design del software al posto tuo. Grazie per la soluzione Jan. –

+2

Sono felice che tu abbia ricevuto il meta-messaggio :-) Complimenti per questa intuizione, che è sorprendentemente rara nel mondo del design HDL! –

1

ho sempre trovato questo tipo di cose più facili da seguire quando si è solo un ciclo su ogni bit, in modo da qualcosa come:

 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;