题解主体
1、确定题目要求
首先,存在S0~S4的四个态,需要注意的是S4到S0的转换和S4到S1的转换,发现对于S4输出flag为1的时候输入是什么无所谓,说明最后的输出控制是由现态单独控制的,因此是摩尔机。
1 |
0 |
|
现态代号 |
次态代号 |
次态代号 |
S0 |
S1 |
S0 |
S1 |
S2 |
S1 |
S2 |
S3 |
S2 |
S3 |
S4 |
S3 |
S4 |
S1 |
S0 |
蓝色代表输出,摩尔机最后添加了状态S4,从状态转移上看输出节拍会晚一拍,但由于是组合逻辑输出,因此实际上并没有晚一拍
知识补充:
一般来说,两段式和三段式的描述方法主要是针对摩尔机来讲的,个人认为,写硬件代码不需要纠结于具体是哪一种状态机和哪一种段式分布,而应该注意实际需求:1、是否要求检测到后同步输出结果(否则结果晚一拍) 2、是否需要寄存器输出
二段式包含二个进程:
第一个进程(同步时序always),描述次态到现态的转移
第二个进程(组合逻辑always),描述状态转移条件的判断,组合逻辑输出
2、按照状态转移写出二段式状态机
parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 ,S4 = 'd4 ;
reg [2:0] current_state;
reg [2:0] next_state;
always@(posedge clk or negedge rst)begin
if(rst == 1'b0)begin
current_state <= S0;
end
else begin
current_state <= next_state;
end
end
always@(*)begin
case(current_state)
S0:begin
next_state = data ? S1 : S0;
flag = 1'b0;
end
S1:begin
next_state = data ? S2 : S1;
flag = 1'b0;
end
S2:begin
next_state = data ? S3 : S2;
flag = 1'b0;
end
S3:begin
next_state = data ? S4 : S3;
flag = 1'b0;
end
S4:begin
next_state = data ? S1 : S0;
flag = 1'b1;
end
default:begin
next_state = S0;
flag = 1'b0;
end
endcase
end
endmodule
参考答案
`timescale 1ns/1ns module fsm2( input wire clk , input wire rst , input wire data , output reg flag ); parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 ,S4 = 'd4 ; reg [2:0] current_state; reg [2:0] next_state; always@(posedge clk or negedge rst)begin if(rst == 1'b0)begin current_state <= S0; end else begin current_state <= next_state; end end always@(*)begin case(current_state) S0:begin next_state = data ? S1 : S0; flag = 1'b0; end S1:begin next_state = data ? S2 : S1; flag = 1'b0; end S2:begin next_state = data ? S3 : S2; flag = 1'b0; end S3:begin next_state = data ? S4 : S3; flag = 1'b0; end S4:begin next_state = data ? S1 : S0; flag = 1'b1; end default:begin next_state = S0; flag = 1'b0; end endcase end endmodule