练习状态图如图所示
真值表
stata | y1 y2 y3 (格雷码) | 00 | 01 | 10 | 11 |
0 | 000 | 000/0 | 111/1 | 001/1 | 011/1 |
1 | 001 | 000/0 | 001/0 | 011/0 | 001/0 |
2 | 011 | 011/0 | 011/0 | 010/1 | 010/1 |
3 | 010 | 010/1 | 111/1 | 010/1 | 111/1 |
4 | 111 | 000/0 | 000/0 | 000/1 | 111/1 |
注:米勒状态机不能用一段式完成
1)一段式verilog代码
//one always
//built module
module one_fsm (clk , ina, reset,out);
input clk, ina,reset;
wire [1:0] ina;
output out;
reg out;
reg [2:0] state; nextstate;
parameter s0 = 3'b000, s1 = 3b'001, s2 = 3b'011, s3 = 3b'010, s4 = 3b'110;
//kaishimiaoshu
always @ (posedge clk or reset);
begin
if(reset)
state <= s0;
else
state <= nextstate;
end
//选择状态、每一状态所包含的信息
case(state)
s0:begin
case(ina)
ina = 2b'00:begin
nextstate <= s0; out = 0;
end
ina = 2'b10:begin
nextstate <= s1; out = 1;
end
ina = 2'b01:begin
nextstate <= s4; out = 1;
end
ina = 2'b11:begin
nextstate <= s2; out = 1;
end
endcase
s1:begin
case(ina)
ina[0] = 1:begin
nextstate <= s1; out = 0;
end
ina = 2'b00:begin
nextstate <= s0; out = 0;
end
ina = 2'b10:begin
nextstate <= s2; out = 0;
end
endcase
s2:begin
case(ina)
ina[1] = 1:begin
nextstate <= s3; out = 1;
end
ina[1] = 0 :begin
nextstate <= s1; out = 0;
end
endcase
s3:begin
case(ina)
ina[0] = 0:begin
nextstate <= s3; out = 1;
end
ina[1] = 1:begin
nextstate <= s4; out = 1;
end
endcase
s4:begin
case(ina)
ina[2] = 0:begin
nextstate <= s0; out = 0;
end
ina = 2'b10:begin
nextstate <= s0; out = 1;
end
ina = 2'b11:begin
nextstate <= s4; out = 1;
end
endcase
endcase
end
endmodule
2.三段式
//三段式always
module three_fsm (clk, reset, ina, out)
input clk, reset, ina;
wire[1:0] ina;
output out;
reg out;
reg[2:0] state, nextstate;
//格雷码代表每一个阶段
paratemer s0 = 3b'000, s1 = 3b'001, s2 = 3b'011, s3 = 3b'010, s4 = 3b'110;
//第一个always,判断选择哪一个state
always @ (posedge clk or posedge reset) //用非阻塞赋值
begin
if (reset)
state <= s0;
else
state <= nextstate;
end
//第二个always,根据输入信号Ina决定下一个state是什么
always @ (state or ina)
begin
case (state)
s0:begin
if (ina == 2'b00)
nextstate = s0;
else if (ina == 2b'01)
nextstate = s4;
else if (ina == 2b'10)
nextstate = s1;
else if (ina == 2b'11)
nextstate = s2;
end
s1:begin
if(ina == 2b'00)
nextstate = s0;
else if (ina == 10)
nextstate = s2;
else if (ina[0] == 1)
nextstate = s1;
end
s2:begin
if (ina[1] == 0)
nextstate = s1;
else if (ina[0] == 1)
nextstate = s3;
end
s3:begin
if (ina[0] == 0)
nextstate = s3;
else if (ina == 1)
nextstate = s4;
end
s4:begin
if(ina[1] == 0 or ina == 2b'10)
nextstate = s0;
else if(ina == 11)
nextstate = s4;
end
endcase
end
//第三个always由ina决定输出结果
alwas @(posedge clk)
begin
case(state)
s0:begin
if(ina == 2b'00 )
out = 0;
else if (ina == 2b'10 or ina == 2b'01 or ina == 2b'11)
out = 1;
end
s1:out = 0;
s2:begin
if(ina[1] == 0)
out = 0;
else if (ina[1] == 1)
out =1;
end
s3:out = 1;
s4:begin
if (ina[1] == 0)
out = 0;
else if (ina == 2b'10 or ina ==2b'11)
out =1
end
endcase
end
endmodule
tb
`timescale 1 ns/1 ns
module three_fsm_tb();
reg clk;
reg reset;
reg ina;
wire out;
FSM_SequDetection U1(
.clk(clk),
.reset(reset),
.ina(ina),
.out(out)
);
initial
begin
clk = 0;
reset = 1;
#15;
reset = 0;
ina = 2'b01;#10;
ina = 2'b11;#10;
ina = 2'b10;#10;
ina = 2'b00;#10;
ina = 2'b01;#10;
ina = 2'b11;#10;
ina = 2'b10;#10;
ina = 2'b01;#10;
ina = 2'b01;#10;
ina = 2'b11;#10;
ina = 2'b00;#10;
ina = 2'b01;#10;
#50;
$stop; //停止仿真
end
always #5 clk = ~clk;
endmodule