Ideen für einen flexiblen/generischen Decoder in VHDL
Frage
Ich möchte einen Adressdecoder erstellen, der flexibel genug ist, damit ich die Anzahl der Bits des Selektors und die dekodierten Ausgangssignale ändern kann.
Anstatt einen statischen (festen Eingangs-/Ausgangsgröße) Decoder zu haben, der so aussieht:
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;
Haben Sie etwas, das flexibler/allgemeiner ist, das so aussieht:
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;
Ich weiß klug genug, um meinen Bedürfnissen zu wachsen.
Ich habe versucht, ohne viel Erfolg eine elegante Lösung für dieses Problem zu finden. Ich bin also offen für Vorschläge.
Danke im Voraus, Erick
Lösung
Anscheinend möchten Sie, dass der Eingang der Index des Ausgangsbits ist, der eingestellt werden sollte.
Schreibe es so. So etwas wie (unter der Annahme von Typen von numeric_std):
output <= (others => '0'); -- default
output(to_integer(input)) <= '1';
Andere Tipps
Ich habe so etwas immer einfacher gefunden, wenn Sie einfach jedes Stück überschreiten, also so etwas wie:
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;