繁体   English   中英

处理VHDL中的中断

[英]Handling Interrupt in VHDL

我们将OR1200用于我们的项目,并且希望将中断分配给FPGA板的第8个按钮。 这是生成中断的代码:

   inrpt: process(CLK_I, RST_I)
   begin
      if RST_I = '1' then
         butt_int_pul <= '0';
         butt_int_tmp <= '0';
      elsif rising_edge(CLK_I) then
         if(DATA_I(8) = '1' and butt_int_tmp = '0') then
            butt_int_pul <= '1';
         else 
                butt_int_pul <= '0';
         end if;

         butt_int_tmp <= DATA_I(8);
      end if;

   end process inrpt;

   process(CLK_I, RST_I)
   begin
     if RST_I = '1' then
            butt_int <= '0';
     elsif butt_int_pul = '1' then
            butt_int <= '1';
     elsif clear_int = '1' then
        butt_int <= '0';
     end if;

   end process;

我们只希望该中断只被处理一次(按住该按钮不应再次调用该中断),这就是为什么我们包含一个用于检查此中断的标志( butt_int_tmp )的原因。

问题是中断调用不稳定。 每次我们按下按钮时,它不会调用。 当我们删除该标志时,它可以工作,但是在这种情况下,它的处理量与按住按钮的次数相同。

我们做错了什么?

首先,第二个过程编写不正确。 它的结构应与第一个进程(即,除复位逻辑之外的所有进程)的if(rising_edge(CLK_I))等效。 您当前正在描述具有多个使能信号和错误灵敏度列表的锁存器。

继续前进,根本没有理由完全需要第二个过程。 您只需要一个寄存器来充当中断( butt_int ),并需要一个寄存器来跟踪按钮的先前状态( butt_prev )。 butt_prev'0'DATA_I(8)'1'时,中断被触发一个周期(即,按钮从未按下变为已按下)。

process(CLK_I, RST_I) begin
    if(RST_I='1') then
        butt_prev <= '0';
        butt_int  <= '0';
    elsif(rising_edge(CLK_I)) then
        if(DATA_I(8)='1' and butt_prev='0') then
            butt_int <= '1';
        else
            butt_int <= '0';
        end if;
        butt_prev  <= DATA_I(8);
    end if;
end process;

请注意,这仅在按钮被正确消除抖动的情况下才有效,否则当您按下(甚至释放)按钮时,您可能会触发多个中断。

最好不要考虑中断。 以FPGA为目标时,是在描述数字逻辑,而不是软件处理器。

有多种方法可以构建具有所需行为的电路。 最简单的可能是重新定时的闩锁

signal latched_button : std_logic;
signal meta_chain     : std_logic_vector(2 downto 0);

p_async_latch: process(rst_i,data(8))
begin
   if rst_i = '1' then
      latched_button <= '0';
   elsif data(8) = '1' then
      latched_button <= '1';
   end if;
end process;

p_meta_chain: process(rst_i,clk_i)
begin
   if rst_i = '1' then
      meta_chain <= (others => '0');
   elsif rising_edge(clk_i) then
      meta_chain <= meta_chain(1 downto 0) & latched_button;
   end if;
end process;

button_int <= '1' when meta_chain(2 downto 1) = "01" else '0';

这导致按钮按下被异步锁定。 然后,将锁存的信号沿移位寄存器计时,并且该中断仅在一个周期内有效,这是在时钟域上看到锁存器的第一个时钟周期。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM