Verilog有限状态机(7)

HDLBits链接


前言

今天继续更新状态机小节的习题。


题库

Q3a:FSM

题目里说当s为0时,进入B状态,然后会检查w的值,如果在接下来的三个周期中w值恰好有两个周期都为1,那么z输出1,否则z输出0。注意,由示例的波形图看应该是不重叠检测。

1

2

Solution

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
module top_module (
input clk,
input reset, // Synchronous reset
input s,
input w,
output z
);
parameter S0 = 1'd0, S1 = 1'd1;
reg current_state, next_state;
reg [1:0] counter,num_one;

always @(*) begin
case(current_state)
S0: next_state = s ? S1 : S0;
S1: next_state = S1;
default:next_state = S0;
endcase
end

always @(posedge clk) begin
if(reset)begin
current_state <= S0;
end
else begin
current_state <= next_state;
end
end

always @(posedge clk) begin
if(reset)begin
counter <= 2'd0;
end
else if(counter == 2'd2) begin
counter <= 2'd0;
end
else if(current_state == S1) begin
counter <= counter + 1'd1;
end
end

always @(posedge clk) begin
if(reset) begin
num_one <= 1'd0;
end
else begin
if(counter == 2'd0)begin
num_one <= w ? 1'd1 : 1'd0;
end
else if(current_state == S1) begin
num_one <= w ? (num_one+1'd1) : num_one;
end
end
end

assign z = (current_state == S1 && num_one == 2'd2 && counter == 2'd0);

endmodule

此题中我用了两个计数器来完成,需特别注意的是,在满足哪种条件时计数器清零或者自加,一定注意!

Q3b:FSM

该题让实现下图所示的状态机,其中复位信号让状态转移至000;

3

Solution

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
module top_module (
input clk,
input reset, // Synchronous reset
input x,
output z
);

parameter S0 = 3'b000, S1 = 3'b001, S2 = 3'b010;
parameter S3 = 3'b011, S4 = 3'b100;
reg [2:0] current_state, next_state;

always @(*) begin
case(current_state)
S0: next_state = x ? S1 : S0;
S1: next_state = x ? S4 : S1;
S2: next_state = x ? S1 : S2;
S3: next_state = x ? S2 : S1;
S4: next_state = x ? S4 : S3;
default:next_state = S0;
endcase
end

always @(posedge clk) begin
if(reset)begin
current_state <= S0;
end
else begin
current_state <= next_state;
end
end

always @(posedge clk) begin
if(reset)begin
z <= 1'b0;
end
else begin
case(next_state)
S3: z <= 1'b1;
S4: z <= 1'b1;
default:z <= 1'b0;
endcase
end
end

endmodule

心得:第三段状态机输出用到next_state做条件时,记得要将reset条件加上,因为reset影响的是current_state,不影响next_state

Q3c:FSM logic

由下面的状态转移表将Y[0]与z表示出来。

4

Solution

1
2
3
4
5
6
7
8
9
10
11
12
module top_module (
input clk,
input [2:0] y,
input x,
output Y0,
output z
);

assign Y0 = ((~y[2]&y[0])|(y==3'b100))&~x | (~y[2]&~y[0])&x;
assign z = (y == 3'b011) | (y == 3'b100);

endmodule

Q6b:FSM next-state logic

通过下面的状态转移表将Y[2]的下一状态表示出来,其中w为输入。

5

6

Solution

1
2
3
4
5
6
7
8
module top_module (
input [3:1] y,
input w,
output Y2);

assign Y2 = (y == 3'b001 | y == 3'b101) & ~w | (y == 3'b001 | y == 3'b010 | y == 3'b100 | y == 3'b101) & w;

endmodule

按上面我列的状态转移表将Y2表示出来即可。

Q6c:FSM one-hot next-state logic

这里使用了one-hot编码,将Y2和Y4输出出来,思路与上题类似,这里不再赘述。

Solution

1
2
3
4
5
6
7
8
9
10
module top_module (
input [6:1] y,
input w,
output Y2,
output Y4);

assign Y2 = ~w & y[1];
assign Y4 = (w & y[2])|(w & y[3])|(w & y[5])|(w & y[6]);

endmodule

Q6:FSM

这是个正宗的FSM题,照着图列状态即可。

7

Solution

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
module top_module (
input clk,
input reset, // synchronous reset
input w,
output z);

parameter A = 3'd0, B = 3'd1, C=3'd2;
parameter D = 3'd3, E = 3'd4, F=3'd5;
reg [2:0] current_state, next_state;

always @(*) begin
case(current_state)
A: next_state = w ? A : B;
B: next_state = w ? D : C;
C: next_state = w ? D : E;
D: next_state = w ? A : F;
E: next_state = w ? D : E;
F: next_state = w ? D : C;
default:next_state = A;
endcase
end

always @(posedge clk) begin
if(reset)begin
current_state <= A;
end
else begin
current_state <= next_state;
end
end

assign z = (current_state == E | current_state == F);

endmodule

结语

今天先更新这几题吧,FSM这部分题目都算比较基础的题目,代码有不足之处还望指正,状态机部分的题终于要结束了。