Verilog 始终具有多个灵敏度的块

Verilog 始终具有多个灵敏度的块,verilog,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中做

我正在尝试实现一个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中做到这一点

一种方法是注册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;
输入时钟;
注册A_prev、B_prev;
始终@(posedge clk)
开始

A_prev一种方法是注册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;
输入时钟;
注册A_prev、B_prev;
始终@(posedge clk)
开始

A_prev无论如何,您需要跟踪“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的附加子状态,还有阿比昂

另一方面,取决于您试图做的事情,假设您试图基于被按下的a或B构建一个状态机,那么很可能在您最初想到的状态中至少已经暗示了一些信息(例如,至少按下了一些按钮),因此,它可能不会改变那么多的复杂性


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

以这样或那样的方式,您需要跟踪“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的附加子状态,还有阿比昂

另一方面,取决于您试图做的事情,假设您试图基于被按下的a或B构建一个状态机,那么很可能在您最初想到的状态中至少已经暗示了一些信息(例如,至少按下了一些按钮),因此,它可能不会改变那么多的复杂性

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