Ideas for Flexible / Generic VHDL Decoder

I want to create an address decoder that is flexible enough to use when changing the number of selector bits and decoded output signals.

So, instead of having a static (fixed I / O size) decoder that looks something like this:

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; 

Make something more flexible / general that looks like this:

  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; 

I know that this code is invalid and that the β€œwhen” test cases should be constant and that I cannot use for-generate between the case argument like this, but it shows that I am behind it: a subject smart enough to grow to my needs.

I am trying to find an elegant solution to this problem without much success, so I am open to any suggestions.

Thanks in advance, Erick

+7
source share
2 answers

Apparently you want the input to be the index of the output bit to be set.

Write it like that. Something like (assuming types from numeric_std):

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

I always thought it was easiest to keep track of when you just iterate over each bit, so that:

  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; 
+1
source

All Articles