**
状态机finite-state machine学习笔记1
**
例子来自于<Verilog数字系统设计教程>第12章,书中的例子错误较多,代码已经经过改写。
状态转移图
1.Gray编码
复制代码
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
66
67
68
69module fsm( Clock, Reset, A, K2, K1, state ); input Clock,Reset,A; output reg K1,K2; output 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)begin state <= Stop; end else begin state <= Start; end Stop:if(A)begin state <=Clear; K2 <= 1; end else begin state <=Stop; K2 = 0; K1 = 0; end Clear:if(!A)begin state <=Idle; K1 <= 1; K2 <= 0; end else begin state <= Clear; K1 <= 1; K2 <= 0; end default:state <= 2'bxx; endcase endmodule
2. one-hot code独热码编码方式
复制代码
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
59module fsm1(//finite-state machin Clock, Reset, A, K2, K1 ); input Clock,Reset,A; output reg K1,K2; reg [3:0]state; parameter Idle = 4'b1000, Start = 2'b0100, Stop = 2'b0010, Clear = 2'b0001; 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= 1; end Start:if(!A)begin state<= Stop; end else begin state<= Start; end Stop:if(A)begin state<=Clear; K2<= 1; end else begin state<=Stop; K2= 0; K1= 0; end Clear:if(!A)begin state<=Idle; K1<= 1; K2<= 0; end else begin state<= Clear; end default:state<= Idle; endcase endmodule
和第一种Gray编码相比,独热码用到的逻辑器件更多,但是用独热码电路的速度和可靠性都要比Gray编码要有显著提升,推荐用独热码方式
state
3.状态的变化和输出开关的控制分成两部分,把每一个输出开关写成一个个独立的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
56module fsm2(//finite-state machine Clock, Reset, A, K2, K1 ); input Clock,A,Reset; output reg K1,K2; reg [1:0] state,nextstate; parameter Idle = 2'b00, Start = 2'b01, Stop = 2'b10, Clear = 2'b11; always@(posedgeClock) 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 always@(state or A)//Clear---->Idle if(!Reset) K1= 0; else if((state== Clear) && (!A)) K1= 1; else K1= 0; always@(state or A)//Stop----->Clear if(!Reset) K2= 0; else if((state== Stop) && A) K2= 1; else K2= 0; endmodule
这种风格的描述比较适合大型的状态机,差错和修改比较容易
state
4.把输出直接制定为状态码,开关的时间维持必须与状态维持的时间一致
复制代码
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
43module fsm3(//finite-state machine Clock, Reset, A, K2, K1 ); input Clock,Reset,A; output K1,K2; reg [4:0] state; assign K2 = state[4]; assign K1 = state[0]; parameter Idle = 5'b0_0_0_0_0, Start = 5'b0_0_0_1_0, Stop = 5'b0_0_1_0_0, StopToClear = 5'b1_1_0_0_0, Clear = 5'b0_1_0_1_0, ClearToIdle = 5'b0_0_1_1_1; always@(posedge Clock) if(!Reset) begin state <= Idle; end else case(state) Idle:if(A) state <= Start; else state <= Idle; Start:if(!A)state = Stop; else state = Start; Stop:if(A) state<=StopToClear; else state<=Stop; StopToClear:state<=Clear; Clear:if(!A) state <= ClearToIdle; else state <= Clear; ClearToIdle:state <= Idle; default state <= Idle; 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`timescale 1ns/1ns `define clock_period 20 module fsm_tb; reg a; reg clock,rst; wire k2,k1; fsm fsm_t( .Clock(clock), .Reset(rst), .A(a), .K2(k2), .K1(k1) ); initial clock = 1'b1; always#(`clock_period/2) clock = ~clock; initial begin rst= 0; a = 0; #(`clock_period*20); rst= 1; #(`clock_period*2); repeat(50) #(`clock_period*10) a = {$random}%2; #(`clock_period*20); $stop; end endmodule
最后
以上就是温柔铃铛最近收集整理的关于状态机finite-state machine学习笔记1的全部内容,更多相关状态机finite-state内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复