Verilog 始终具有多个灵敏度的块
我正在尝试实现一个FSM,它会对按下两个按钮中的任何一个做出反应。让我们把这些按钮称为A和B。我想要的是: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中做
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构建一个状态机,那么很可能在您最初想到的状态中至少已经暗示了一些信息(例如,至少按下了一些按钮),因此,它可能不会改变那么多的复杂性
(请注意,如果您担心同时按下或释放两个按钮的可能性,这也会使此实现更加复杂。)