时钟内的Rising_edge检测

时间:2012-12-13 18:15:32

标签: vhdl

我是vhdl编程的新手。我最近有一个任务是通过按下按钮来改变对时钟信号敏感的移位寄存器中std_logic_vector的值。

当我按住KEY(2)时,移位寄存器的值会改变,但除非我松开按钮,否则它不会移位。是否可以修改下面的代码,以便它对KEY(2)的上升沿敏感?或者是否有任何其他可能通过按下KEY(2)按钮来改变矢量值,即使我按住按钮它也会移动?

感谢您的回答。我会非常感激,这对我很有帮助。

抱歉我的英语不好。祝你玩得愉快。

ENTITY hadvhdl  IS PORT (
    CLOCK_50 : IN STD_LOGIC;
    KEY      : IN STD_LOGIC_VECTOR  (3 downto 0);
    LEDR     : OUT STD_LOGIC_VECTOR (15 downto 0)
);
END hadvhdl;

ARCHITECTURE rtl OF hadvhdl IS
    shared variable register : std_logic_vector(15 downto 0) := (1 downto 0=>'1', others=>'0');
    shared variable count   : integer range 1 to 4 :=1;
BEGIN

    changecount: process (KEY)
    begin    
        if rising_edge(KEY(2)) then
            if count<4 then
                count := count + 1; 
            else
                count := 1;
            end if;
        end if; 
    end process;

    shift: process (CLOCK_50, KEY)
        variable up : BOOLEAN := FALSE;
        variable reg : std_logic_vector(15 downto 0) := (1 downto 0=>'1', others=>'0'); 
    begin   
        if rising_edge(CLOCK_50) then
            if (KEY(2)='1') then
                case count is 
                    when 1 => register := (1 downto 0=>'1', others=>'0'); 
                    when 2 => register := (2 downto 0=>'1', others=>'0'); 
                    when 3 => register := (3 downto 0=>'1', others=>'0'); 
                    when 4 => register := (4 downto 0=>'1', others=>'0'); 
                end case; 
            end if;

            reg := register;
            LEDR <= reg;

            if up then
                reg := reg(0) & reg(15 downto 1); 
            else 
                reg := reg(14 downto 0) & reg(15);  
            end if;

            register := reg;

        end if;
    end process;

END rtl;

1 个答案:

答案 0 :(得分:-1)

  1. 不要使用变量! (至少作为VHDL初学者)
  2. 不要使用按钮作为时钟(例如在rising_edge中)
  3. 在您的设计中仅使用一个时钟(在您的情况下似乎是o.k.)
  4. 请记住,机械按钮会反弹。
  5. 以下是边缘检测的变体:

      -- in entity
      clk    ; in std_logic;
      sig_in : in std_logic;
    
    ...
    
    signal sig_old  : std_logic;
    signal sig_rise : std_logic;
    signal sig_fall : std_logic;
    
    ...
    
      process
      begin
        wait until rising_edge( clk);
    
        -- defaults
        sig_rise <= '0';
        sig_fall <= '0';
    
        -- shift value in
        sig_old <= sig_in;
    
        -- do some real action
        if sig_old = '0' and sig_in = '1' then
          sig_rise <= '1';
        end if;
    
        if sig_old = '1' and sig_in = '0' then
          sig_fall <= '1';
        end if;
    
      end process;