Verilog有限状态机(3)

HDLBits链接


前言

今天继续更新状态机小节的习题,本章主要编写Lemmings Game部分。


题库

题目描述10:

Game Lemmings1:有个小人左右走,它只有两种状态:向左走和向右走;左边碰到东西之后它就向右走,右边碰到东西之后它就向左走,两边都碰到东西就跟当前方向的反方向走;复位时小人向左走

1

Solution10:

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
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
output walk_left,
output walk_right); //

parameter LEFT=1'b0, RIGHT=1'b1;
reg state, next_state;
wire [1:0] bump;
assign bump = {bump_left,bump_right};

always @(*) begin
case(state)
LEFT:begin
if((bump == 2'b10) || (bump == 2'b11))begin
next_state = RIGHT;
end
else begin
next_state = LEFT;
end
end
RIGHT:begin
if((bump == 2'b01) || (bump == 2'b11))begin
next_state = LEFT;
end
else begin
next_state = RIGHT;
end
end
endcase
end

always @(posedge clk, posedge areset) begin
if(areset)begin
state <= LEFT;
end
else begin
state <= next_state;
end
end

// Output logic
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);

endmodule

题目描述11:

Game Lemmings2:有个小人左右走,它只有两种状态:向左走和向右走;左边碰到东西之后它就向右走,右边碰到东西之后它就向左走,两边都碰到东西就跟当前方向的反方向走;复位时小人向左走;

添加ground信号,ground=1时规则与上述规则相同;ground=0时,记录当前走的方向,并将aaah信号置1,直到ground=1时,走与掉落之前相同的方向。

Solution11:

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
69
70
71
72
73
74
75
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
output walk_left,
output walk_right,
output aaah );

parameter LEFT = 2'b0;
parameter RIGHT = 2'b1;
parameter AH_LEFT = 2'b10;
parameter AH_RIGHT = 2'b11;
reg [1:0] state,next_state;
wire [1:0] bump;
assign bump = {bump_left,bump_right};

always @(*)begin
case(state)
LEFT:begin
if(ground == 1'b0)begin
next_state = AH_LEFT;
end
else if((bump == 2'b10) || (bump == 2'b11))begin
next_state = RIGHT;
end
else begin
next_state = LEFT;
end
end
RIGHT:begin
if(ground == 1'b0)begin
next_state = AH_RIGHT;
end
else if((bump == 2'b01) || (bump == 2'b11))begin
next_state = LEFT;
end
else begin
next_state = RIGHT;
end
end
AH_LEFT:begin
if(ground == 1'b0)begin
next_state = AH_LEFT;
end
else begin
next_state = LEFT;
end
end
AH_RIGHT:begin
if(ground == 1'b0)begin
next_state = AH_RIGHT;
end
else begin
next_state = RIGHT;
end
end
endcase
end

always@(posedge clk,posedge areset)begin
if(areset)begin
state <= LEFT;
end
else begin
state <= next_state;
end
end

assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = ((state == AH_LEFT) | (state == AH_RIGHT));

endmodule

题目描述12:

Game Lemmings3:有个小人左右走,它只有两种状态:向左走和向右走;左边碰到东西之后它就向右走,右边碰到东西之后它就向左走,两边都碰到东西就跟当前方向的反方向走;复位时小人向左走;

添加ground信号,ground=1时规则与上述规则相同;ground=0时,记录当前走的方向,并将aaah信号置1,直到ground=1时,走与掉落之前相同的方向。

添加dig信号,ground=1时一直挖,ground=0时,进入aaah状态,直到ground再次为1,方向与dig开始的方向相同。

优先级:fall>dig>switch direction

2

Solution12:

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
input dig,
output walk_left,
output walk_right,
output aaah,
output digging );

parameter LEFT = 3'b0;
parameter RIGHT = 3'b1;
parameter DIG_LEFT = 3'b10;
parameter DIG_RIGHT = 3'b11;
parameter FALL_LEFT = 3'b100;
parameter FALL_RIGHT = 3'b101;

reg [2:0] state,next_state;
wire [1:0] bump;
assign bump = {bump_left,bump_right};

always @(*)begin
case(state)
LEFT:begin
if(ground == 1'b0)begin
next_state = FALL_LEFT;
end
else if(dig == 1'b1)begin
next_state = DIG_LEFT;
end
else if((bump == 2'b10) || (bump == 2'b11))begin
next_state = RIGHT;
end
else begin
next_state = LEFT;
end
end
RIGHT:begin
if(ground == 1'b0)begin
next_state = FALL_RIGHT;
end
else if(dig == 1'b1)begin
next_state = DIG_RIGHT;
end
else if((bump == 2'b01) || (bump == 2'b11))begin
next_state = LEFT;
end
else begin
next_state = RIGHT;
end
end
DIG_LEFT:begin
if(ground == 1'b0)begin
next_state = FALL_LEFT;
end
else begin
next_state = DIG_LEFT;
end
end
DIG_RIGHT:begin
if(ground == 1'b0)begin
next_state = FALL_RIGHT;
end
else begin
next_state = DIG_RIGHT;
end
end
FALL_LEFT:begin
if(ground == 1'b0)begin
next_state = FALL_LEFT;
end
else begin
next_state = LEFT;
end
end
FALL_RIGHT:begin
if(ground == 1'b0)begin
next_state = FALL_RIGHT;
end
else begin
next_state = RIGHT;
end
end
endcase
end

always @(posedge clk,posedge areset)begin
if(areset)begin
state <= LEFT;
end
else begin
state <= next_state;
end
end

assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign digging = ((state == DIG_LEFT) | (state == DIG_RIGHT));
assign aaah = ((state == FALL_LEFT) | (state == FALL_RIGHT));

endmodule

题目描述13:

Game Lemmings4:小人行动规则与上述规则相同,添加小人会die的规则:

如果小人fall超过20cycles,则当其接触地面时直接die(未接触地面时不会die)。dig,fall,left和right输出全部置零,直到reset信号来临。

3

手绘状态转移图:(Dead状态少个自己到自己的状态)

4

Solution13:

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
input dig,
output walk_left,
output walk_right,
output aaah,
output digging );

parameter LEFT = 3'b0;
parameter RIGHT = 3'b1;
parameter DIG_LEFT = 3'b10;
parameter DIG_RIGHT = 3'b11;
parameter FALL_LEFT = 3'b100;
parameter FALL_RIGHT = 3'b101;
parameter DEAD = 3'b110;
parameter SPLATTER = 3'b111;

reg [2:0] state,next_state;
reg [4:0] Cycle_Count;

wire [1:0] bump;
assign bump = {bump_left,bump_right};

always @(*)begin
case(state)
LEFT:begin
if(ground == 1'b0)begin
next_state = FALL_LEFT;
end
else if(dig == 1'b1)begin
next_state = DIG_LEFT;
end
else if((bump == 2'b10) || (bump == 2'b11))begin
next_state = RIGHT;
end
else begin
next_state = LEFT;
end
end

RIGHT:begin
if(ground == 1'b0)begin
next_state = FALL_RIGHT;
end
else if(dig == 1'b1)begin
next_state = DIG_RIGHT;
end
else if((bump == 2'b01) || (bump == 2'b11))begin
next_state = LEFT;
end
else begin
next_state = RIGHT;
end
end

DIG_LEFT:begin
if(ground == 1'b0)begin
next_state = FALL_LEFT;
end
else begin
next_state = DIG_LEFT;
end
end

DIG_RIGHT:begin
if(ground == 1'b0)begin
next_state = FALL_RIGHT;
end
else begin
next_state = DIG_RIGHT;
end
end

FALL_LEFT:begin
if((ground == 1'b0) && (Cycle_Count < 5'd20))begin
next_state = FALL_LEFT;
end
else if((ground == 1'b0) && (Cycle_Count >= 5'd20))begin
next_state = SPLATTER;
end
else begin
next_state = LEFT;
end
end

FALL_RIGHT:begin
if((ground == 1'b0) && (Cycle_Count < 5'd20))begin
next_state = FALL_RIGHT;
end
else if((ground == 1'b0) && (Cycle_Count >= 5'd20))begin
next_state = SPLATTER;
end
else begin
next_state = RIGHT;
end
end

SPLATTER:begin
if(ground == 1'b1)begin
next_state = DEAD;
end
else begin
next_state = SPLATTER;
end
end

DEAD:begin
next_state = DEAD;
end

endcase
end

always @(posedge clk,posedge areset)begin
if(areset)begin
state <= LEFT;
end
else begin
state <= next_state;
end
end

always @(posedge clk,posedge areset)begin
if(areset)begin
Cycle_Count <= 5'd0;
end
else if((next_state == FALL_LEFT) || (next_state == FALL_RIGHT)) begin
Cycle_Count <= Cycle_Count + 1'b1;
end
else begin
Cycle_Count <= 5'd0;
end
end

assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = ((state == FALL_LEFT) || (state == FALL_RIGHT) || (state == SPLATTER));
assign digging = ((state == DIG_LEFT) || (state == DIG_RIGHT));

endmodule

结语

今天更新的几道旅鼠题非常有意思,大家可以先自己尝试。代码若有问题的话可以与我交流。