我正在尝试用verilog设计这个状态机:
我有:
`timescale 1ns/1ns
module labEightMachine(y, x,clk,clr)
output y;
input [1:2] x;
input clk, clr;
reg [1:2] q;
reg y;
reg nX;
always @ (posedge clk)
begin
if(clr)
{q}<=2'b00;
else
q<= {nX}
end
always @(y,x)
begin
if(q==2'b00)
if(x==2'b00)
q<=2'b00;
else
q<=2'b01;
y<=1;
if(q==2'b01)
if((x==2'b00)||(x==2'b01))
q<=2'b00;
y<=0;
else
q<=2'b11;
y<=0;
if(q==2'b11)
if(x==2'b10)
q<=2'b10;
y<=1;
else
q<=2'b00;
y<=0;
if(q==2'b10)
q<=2'b00;
y<=0;
end
endmodule
如果任何人可以通过告诉我哪里不正确而提供帮助,那将非常感激。国家机器让我感到困惑,我不确定我是否正确地重新分配了一切。
答案 0 :(得分:1)
应用刺激始终是检查代码的更好方法。留下分号/开头的语法错误以及所有这些,我可以看到几个直接的逻辑错误如下所示。
声明reg nX
声明了一个单位宽度的变量。相反,q
被声明为reg [1:2] q
,两位宽度。
其次,q
来自两个始终阻止。如果clr
为低,则q
由nX
驱动。虽然,nX
永远不会受到任何信号的驱动。因此,输出将是x
的大多数时间(留下那些竞争条件)。多个驱动程序问题。
第三,最好使用if--else if--else
阶梯而不是多个if
。这将使 next_state逻辑清除。
更好的FSM,可能有两个always
块和一个输出逻辑块。一个用于顺序逻辑,另一个用于组合逻辑。顺序块用于通过next_state值更新current_state值。同时,组合块用于根据输入更新下一个状态值。输出逻辑必须具有单独的连续分配块或程序块。
此外,对next_state逻辑使用case
语句可能会很方便。当太多状态在单个FSM中相互交互时,这将非常有用。在case语句中使用default
是不可避免的。
有关高效FSM编码样式的更多信息,请参阅CummingsSNUG1998SJ_FSM论文和CummingsSNUG2000Boston_FSM论文。