VHDL - 增加一个(未签名)

时间:2014-11-12 19:35:23

标签: encoding vhdl counter increment fpga

我试图制作一个代码,用一个增加输入位。我想使用两段代码样式,但这里的问题是这些位不能达到输出。任何的想法?谢谢!

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;


entity increment1 is
    port(
        from_ASMD_State_reg : in std_logic_vector(7 downto 0);
        reset, clk : in std_logic;
        to_mux : out std_logic_vector(7 downto 0)
    );
end increment1;

architecture Behavioral of increment1 is
--signal count : unsigned(7 downto 0);
signal r_reg : unsigned(7 downto 0);
signal r_next : unsigned(7 downto 0);
begin
process(clk, reset)
begin
    if(reset = '1') then
        to_mux <= (others => '0');
    elsif(clk'event and clk = '1') then
        r_reg <= r_next;
    end if;
end process;

r_next <= r_reg + 1;

to_mux <= std_logic_vector(r_reg);

end Behavioral;

经过一些代码调整后,它现在似乎正在运作!

architecture Behavioral of increment1 is
signal r_reg : unsigned(7 downto 0);
signal r_inc : unsigned(7 downto 0);
begin
process(clk, reset, r_reg)
begin
    r_reg <= unsigned(from_ASMD_State_reg);

    if(reset = '1') then
        r_reg <= (others => '0');
    elsif(clk'event and clk = '1') then
        r_reg <= r_inc;
    end if;
end process;

r_inc <= r_reg + 1;

to_mux <= std_logic_vector(r_inc);

end Behavioral;

2 个答案:

答案 0 :(得分:2)

您的更新代码几乎正确,但不完全正确。如果您只想增加并注册一个值,那么您只需要:

architecture Behavioral of increment1 is
begin

  r_inc <= unsigned(from_ASMD_State_reg) + 1;

  process (clk, reset)
  begin
    if(reset = '1') then
        r_reg <= (others => '0');
    elsif(clk'event and clk = '1') then
        r_reg <= r_inc;
    end if;
  end process;

  to_mux <= std_logic_vector(r_reg);

end Behavioral;

(注意:编辑以上内容以修复分配错误并重新排序语句以使所需的“两段式”更明显)

你确定它在你的进程中r_reg的赋值“工作”但在if块之外吗?你有没有试过合成,或者只是模拟?

优化:

  • 您可以通过将增量语句直接放入流程中的r_inc作业中来摆脱r_reg
  • 您可以通过在流程和类型转换中将r_reg替换为to_mux来摆脱to_mux <= std_logic_vector(unsigned(from_ASMD_State_reg) + 1);

此操作不需要所有这些中间信号。如果您需要添加其他功能,请随时保留它们,但请注意端口可用于这些操作 - 您无需先将它们分配给其他信号。

您的流程中的简化分配将是:

{{1}}

要做到这一点几乎不值得制作一个单独的组件,但当然可以。

答案 1 :(得分:0)

当你创建一个触发器(存储一个值)时,只将reset和clock放在灵敏度列表中:

process(clk, reset)
begin

    if(reset = '1') then
       r_reg <= (others => '0');
    elsif(clk'event and clk = '1') then
       r_reg <= r_inc;
    end if;
end process;

如果from_ASMD_State_reg在重置为1时取值,则可以直接将其作为重置值插入:

process(clk, reset)
begin

    if(reset = '1') then
       r_reg <= unsigned(from_ASMD_State_reg);
    elsif(clk'event and clk = '1') then
       r_reg <= r_inc;
    end if;
end process;

否则,你必须用另一种方式写。在您需要知道何时退出复位之前:只有在复位信号未复位from_ASMD_State_reg信号时才能写入。     r_reg&lt; =

signal finish_reset    : std_logic;
signal finish_reset_d  : std_logic;

process(clk, reset)
begin

    if (reset = '1') then
       finish_reset   <= '0';
       finish_reset_d <= '0';
    elsif (clk'event and (clk = '1')) then
       finish_reset_d <= finish_reset;
       finish_reset   <= '1';
    end if;

end process;

然后使用此新信号初始化您的计数器:

 process(clk, reset)
 begin

     if (reset = '1') then
        r_reg <= (others => '0');
     elsif (clk'event and (clk = '1')) then

         if ((finish_reset = '1') and (finish_reset_d = '0')) then
            r_reg <= unsigned(from_ASMD_State_reg);
         else
            r_reg <= r_inc;
         end if;

     end if;

 end process;

你在怎么写r_inc:

r_inc <= r_reg + 1;

to_mux <= std_logic_vector(r_inc);

最后一件事:通常复位为低电平有效(当复位='0'时复位,而当复位为'1'时复位)。