下面是Quartus II中识别状态机的条件:
1.表现状态机的信号或变量必须为枚举类型。
2.状态转移必须由clk触发,并且是用IF语句检测的上升沿进行转移。
3.状态转移到下一个状态由CASE语句判断
4.所有信号,变量赋值都要放在状态机进程里进行。
5.状态机的状态必须多于两个状态。
自己补充:
今天编写了一个状态机,把当前状态机的状态直接作为输出端口(present_Q)输出数据,虽然这样的状态机可以用,但在State Machine Viewer中不会显示状态图。因此,后来我就取消了将当前状态(present_Q)直接输出,于是在State Machine Viewer就输出状态图了。以下是我写的代码和状态机图形:
状态机代码:
module FSM(Clk,Reset,W,Z); //module FSM(Clk,Reset,W, present_Q,Z);
input Clk,Reset,W;
output reg Z; //端口声明
reg [8:0] present_Q; //这里我曾经是写作:output reg [8:0] present_Q; 这样写可以将当前状态输出,但是在Quartus II不会显示状态图形,这样如果状态机有什么错误就不会好找了。
parameter A = 9'b000000001, //状态表编码
B = 9'b000000010,
C = 9'b000000100,
D = 9'b000001000,
E = 9'b000010000,
F = 9'b000100000,
G = 9'b001000000,
H = 9'b010000000,
I = 9'b100000000;
reg [8:0] next_state;
always @(posedge Clk,negedge Reset) //状态转换,时序电路
begin
if(Reset==0)
begin
present_Q <= A;
end
else
present_Q <= next_state; //状态赋值
end
always @(present_Q,W) //组合电路
begin
case (present_Q)
A:begin
if(!W)
next_state <= B;
else
next_state <= F;
Z <= 0;
end
B:begin
if(!W)
next_state <= C;
else
next_state <= F;
Z <= 0;
end
C:begin
if(!W)
next_state <= D;
else
next_state <= F;
Z <= 0;
end
D:begin
if(!W)
next_state <= E;
else
next_state <= F;
Z <= 0;
end
E:begin
if(!W)
next_state <= E;
else
next_state <= F;
Z <= 1;
end
F:begin
if(W)
next_state <= G;
else
next_state <= B;
Z <= 0;
end
G:begin
if(W)
next_state <= H;
else
next_state <= B;
Z <= 0;
end
H:begin
if(W)
next_state <= I;
else
next_state <= B;
Z <= 0;
end
I:begin
if(W)
next_state <= I;
else
next_state <= B;
Z <= 1;
end
default:begin
next_state <= A;
Z <= 0;
end
endcase
end
endmodule
状态机图形: