题解主体
1、确定题目要求
首先,序列为1011,因此存在5个态,命名为S0~S4
题目要求:
1 重叠检测,因此在状态转移中,判断非将不会直接返回S0
2 要求寄存器输出但延迟一拍输出结果,因此如果使用三段式描述,需要使用现态作为输出判断标准
两段式和三段式的描述方法主要是针对摩尔机来讲的,个人认为,写硬件代码不需要纠结于具体是哪一种状态机和哪一种段式分布,而应该注意实际需求:1、是否要求检测到后同步输出结果(否则结果晚一拍) 2、是否需要寄存器输出
三段式包含三个进程:
第一个进程(同步时序always),描述次态到现态的转移
第二个进程(组合逻辑always),描述状态转移条件的判断
第三个进程(同步时序always),描述状态的寄存器输出
摩尔机和米勒机的区别:主要区别在于状态机的输出与当前的状态是否有关,下面用两段式来描述两者的区别。
需要注意的是,如果使用三段式描述法,两者的区别主要聚焦于第三段的判断是基于现态还是次态。
摩尔状态机要比米勒状态机少一个状态,摩尔状态机慢一个周期;米勒状态机使用当前输入和当前状态共同判断,摩尔状态机不需要当前输入。
米勒机
2、画出状态转移
画一下状态转移表
现态 |
N=0 |
N=1 |
|||
现态值 |
现态代号 |
次态值 |
次态代号 |
次态值 |
次态代号 |
0 |
S0 |
00 |
S0 |
01 |
S1 |
1 |
S1 |
10 |
S2 |
11 |
S1 |
10 |
S2 |
100 |
S0 |
101 |
S3 |
101 |
S3 |
1010 |
S2 |
1011 |
S4 |
1011 |
S4 |
10110 |
S2 |
10111 |
S1 |
3、按照状态转移写出三段式状态机
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;
end
S1:begin
next_state = data? S1 : S2;
end
S2:begin
next_state = data ? S3 : S0;
end
S3:begin
next_state = data ? S4 : S2;
end
S4:begin
next_state = data ? S1 : S2;
end
default:begin
next_state = S0;
end
endcase
end
always@(posedge clk or negedge rst)begin
if(rst == 1'b0)begin
flag <= 1'b0;
end
else begin
if(current_state == S4)begin
flag <= 1'b1;
end
else begin
flag <= 1'b0;
end
end
end
endmodule
参考答案
`timescale 1ns/1ns module sequence_test2( 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; end S1:begin next_state = data? S1 : S2; end S2:begin next_state = data ? S3 : S0; end S3:begin next_state = data ? S4 : S2; end S4:begin next_state = data ? S1 : S2; end default:begin next_state = S0; end endcase end always@(posedge clk or negedge rst)begin if(rst == 1'b0)begin flag <= 1'b0; end else begin if(current_state == S4)begin flag <= 1'b1; end else begin flag <= 1'b0; end end end endmodule