始终阻止多种敏感性

时间:2015-04-18 19:09:52

标签: verilog

我正在尝试实现一个FSM,它对正在按下的两个按钮中的任何一个做出反应。让我们调用这些按钮A和B.我想要的是:

always@(posedge A or posedge B) begin
    if(A) begin **do one thing**
      end else if (B) begin **do another**
    end
end

我害怕的情况是,例如,用户按住按钮A然后按B. if语句将检测到A为高,当我想要反应的实际敏感参数是B.我怎样才能在Verilog中做到这一点?

2 个答案:

答案 0 :(得分:2)

一种方法是注册A和B的值,并将它们与当前值进行比较。这需要某种系统时钟,但您可能已经使用了一个FSM。

举个例子:

input A, B;
input clk;
reg A_prev, B_prev;

always @(posedge clk)
begin
    A_prev <= A;
    B_prev <= B;
end

always @(*)
begin
    if (A && !A_prev) **do whatever**
    else if (B && !B_prev) **do whatever**
end

由于A和B已注册,第二个always块将检测A(或B)在前一个时钟周期是否为低电平且现在为高电平。

答案 1 :(得分:2)

无论如何,你需要跟踪“A已被压低但尚未被释放”等状态。您可以在状态机外部跟踪该状态,如@ wilcroft的回答,或作为状态机的一部分。要将其作为状态机的一部分来处理,您需要更改灵敏度列表以响应按下或释放(即不仅仅是posedge),并包括其中一个或两个按钮的状态信息:

always @(A or B) begin
    if (state == NONE_ON) begin
        if(A) begin next_state = A_ON; **do one thing**
          end else if (B) begin next_state = B_ON; **do another**
        end
    end
    else if (state == A_ON) begin
        if (!A) begin next_state = NONE_ON; 
          end else if (B) begin next_state = AB_ON; **do the B things***
        end
    end
    else if (state == B_ON) begin
        if (!B) begin next_state = NONE_ON; 
          end else if (A) begin next_state = AB_ON; **do the A things***
        end
    end
    else if (state == AB_ON) begin
        if (!A) begin next_state = B_ON;
          end else if (!B) begin next_state = A_ON;
        end
    end 
end

在某种意义上,跟踪这样的状态是状态机的重点,这就是你所说的你想要构建的,这是建立状态机的一个共同动机。

但是,如果您打算构建的状态机完全复杂,那么将更多的A / B信息添加到状态表可能会显着增加您的状态,并使整个状态机变得更加复杂和意大利面条状,因为您的预期状态可能最终成为A_ON,B_ON和AB_ON的附加子状态。

另一方面,根据您尝试做的事情,鉴于您尝试构建基于A或B的状态机被按下,似乎很可能已经隐含了至少部分此类信息(例如,至少某些按钮被按下了)在您最初想到的状态中,因此它可能不会更改复杂性。

(请注意,如果您担心处理同时按下或释放两个按钮的可能性,也会使此实现更加复杂。)