前言

上课时讲了两段式状态机和三段式状态机,不过对于概念依旧有点模糊。自己记了一点,以便期末回顾用。

一般来说,模块内有几个always就是几段式。但是具体情况还需看代码分析。

参考资料

Verilog状态机常见三种写法

状态机的一段式、二段式、三段式的区别-电子发烧友网

Verilog实现二段式和三段式有限状态机-CSDN博客

对于经典三段式状态机的自己之前一些认识的误区-CSDN博客

一段式

顾名思义,全模块只有一个always在该模块中既描述状态转移,又描述状态的输入和输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
module fsm(Clock,Reset,A,K2,K1,state);
input Clock, Reset, A;
output K2, K1;
output [1:0] state;
reg K2, K1;
reg [1:0] state ;
parameter Idle = 2'b00,
Start = 2'b01,
Stop = 2'b10,
Clear = 2'b11;
always @(posedge Clock)
if (!Reset)
begin
state <= Idle;
K2 <=0;
K1 <=0;
end
else
case (state)
Idle:
if (A)
begin
state <= Start;
K1<=0;
end
else
begin
state <= Idle;
K2<=0;
K1<=0;
end
Start:
if (!A)
state <= Stop;
else
state <= Start;
Stop:
if (A)
begin
state <= Clear;
K2<= 1;
end
else
begin
state <= Stop;
K2<=0;
K1<=0;
end
Clear:
if (!A)
begin
state <=Idle;
K2<=0;
K1<=1;
end
else
begin
state <= Clear;
K2<=0;
K1<=0;
end
default:
state<=2'bxx;
endcase
endmodule

两段式

何谓两段式?这两段是什么?

  • 同步时序描述状态转移
  • 组合逻辑判断状态转移条件、描述状态转移规律及其输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
module fsm (
Clock,
Reset,
A,
K2,
K1
);
input Clock, Reset, A;
output K2, K1;
reg K2, K1;
reg [1:0] state, nextstate;
parameter Idle = 2'b00, Start = 2'b01, Stop = 2'b10, Clear = 2'b11;
//每一个时钟沿产生一次可能的状态变化
always @(posedge Clock)
if (!Reset) state <= Idle;
else state <= nextstate;
//------ 产生下一状态的组合逻辑 ----
always @(state or A)
case (state)
Idle:
if (A) begin
nextstate = Start;
K1 = 1;
K2 = 0;
end
else nextstate = Idle;
Start:
if (!A) begin
nextstate = Stop;
K1 = 0;
K2 = 1;
end
else nextstate = Start;
Stop:
if (A) begin
nextstate = Clear;
K2 = 1;
K1 = 0;
end
else nextstate = Stop;
Clear:
if (!A) begin
nextstate = Idle;
K2 = 0;
K1 = 0;
end
else nextstate = Clear;
default: nextstate = 2'bxx;
endcase

endmodule

三段式

三段式在两段式的基础上,将状态输出单独分离出来,使程序结构更加直观。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
module fsm (
Clock,
Reset,
A,
K2,
K1
);
input Clock, Reset, A;
output K2, K1;
reg K2, K1;
reg [1:0] state, nextstate;
parameter Idle = 2'b00, Start = 2'b01, Stop = 2'b10, Clear = 2'b11;
//每一个时钟沿产生一次可能的状态变化
always @(posedge Clock)
if (!Reset) state <= Idle;
else state <= nextstate;
//------ 产生下一状态的组合逻辑 ----
always @(state or A)
case (state)
Idle: if (A) nextstate = Start;
else nextstate = Idle;
Start: if (!A) nextstate = Stop;
else nextstate = Start;
Stop: if (A) nextstate = Clear;
else nextstate = Stop;
Clear: if (!A) nextstate = Idle;
else nextstate = Clear;
default: nextstate = 2'bxx;
endcase
//-- 产生输出K1的组合逻辑 --------------
always @(state or Reset or A)
if (!Reset) K1 = 0;
else if (state == Clear && !A)
//从Clear转向Idle
K1 = 1;
else K1 = 0;
//产生输出K2的组合逻辑
always @(state or Reset or A)
if (!Reset) K2 = 0;
else if (state == Stop && A) //转向Clear
K2 = 1;
else K2 = 0;
endmodule

组合逻辑必须使用阻塞赋值!