问题描述
我想创建一个地址解码器,该解码器在更改选择器的位和解码输出信号的位时,该解码器足够灵活,可以使用.
所以,而不是具有看起来像这样的静态(固定输入/输出大小)解码器:
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;
具有更灵活/一般的东西,看起来像这样:
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;
我知道此代码无效,并且"何时"测试用例必须是常数,并且我不能在这样的案例语句之间使用for-enerate,但是它表明了我所追求的是什么:一个足够聪明的实体,足以满足我的需求.
我一直在尝试在没有太大成功的情况下找到一个优雅的解决方案,所以我愿意接受任何建议.
预先感谢 埃里克
推荐答案
显然您希望输入是应设置的输出位的索引.
那样写.类似(从numeric_std中假设类型):
output <= (others => '0'); -- default output(to_integer(input)) <= '1';
其他推荐答案
我总是发现当您只循环每一点时,都更容易遵循这种事情,因此类似:
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;
问题描述
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
推荐答案
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';
其他推荐答案
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;