2011-01-24 11 views
7

Chcę utworzyć adres Dekoder, który jest wystarczająco elastyczny, aby używać go podczas zmiany liczby bitów selektora i dekodowanych sygnałów wyjściowych.Pomysły na elastyczny/ogólny dekoder w VHDL

Więc zamiast statycznego (stałe wejście rozmiar/wyjście) Dekoder, który wygląda mniej więcej tak:

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; 

mieć coś, co jest bardziej elastyczny/ogólny, który wygląda tak:

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; 

Wiem, że ten kod jest niepoprawny i że przypadki testowe "kiedy" muszą być stałe i że nie mogę używać for-generate pomiędzy tymi przypadkami, ale pokazuje, po co to jest : podmiot wystarczająco sprytny, aby sprostać moim potrzebom.

Próbowałem znaleźć eleganckie rozwiązanie tego problemu bez większego sukcesu, więc jestem otwarty na wszelkie sugestie.

Dzięki z góry, Erick

+1

'numeric_std' zapewnia funkcja przesuwająca wektor o określoną liczbę. Można więc przypuszczalnie przesunąć wektor '0 => '1', pozostałe =>" 0 "pozostawione przez (numer wejścia - 1). –

Odpowiedz

13

Najwyraźniej chcesz być wejście do indeksu bitu wyjściowego, które należy ustawić.

Napisz to tak. Coś jak (przy założeniu, że typy z numeric_std):

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

Krótka i skuteczna (i działała świetnie!) Daje mi to do zrozumienia, że ​​czasami chęć pójścia trochę "niżej" w opisie sprzętu (próba zdefiniowania logiki bliżej do tego, jak będzie wyglądała jego implementacja sprzętowa), może oślepić cię od oczywistości rozwiązania, które kładą część obciążenia projektowego na oprogramowanie zamiast na ciebie. Dzięki za rozwiązanie Jan. –

+2

Cieszę się, że dostałeś meta-wiadomość :-) Gratulacje z tego wglądu, co jest zaskakująco rzadkie w świecie projektowania HDL! –

1

Zawsze uważałem tego rodzaju rzeczy łatwiejsze do naśladowania, kiedy po prostu pętlę nad każdym kroku, więc coś takiego:

 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;