Ideas for a flexible/generic decoder in VHDL

混江龙づ霸主 提交于 2020-01-02 02:48:06

问题


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

So, instead of having a static (fixed input/output 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;

Have something that is 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 this code is not valid and that the "when" test cases must be constants and that I can't use the for-generate in between the case statement like that, but it shows what it is that I am after: an entity smart enough to grow to my needs.

I have been trying to find an elegant solution for this problem without much success, so, I'm open for any suggestions.

Thanks in advance, Erick


回答1:


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

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

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



回答2:


I have always found this sort of thing easier to follow when you just loop over each bit, so something like:

     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;


来源:https://stackoverflow.com/questions/4787966/ideas-for-a-flexible-generic-decoder-in-vhdl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!