题解 | #输入序列连续的序列检测#
输入序列连续的序列检测
http://www.nowcoder.com/practice/d65c2204fae944d2a6d9a3b32aa37b39
序列检测一般有两种办法,一种是利用移位寄存器来实现,这种方法比较简单。另一种是利用状态机来实现,难点在于状态转移图的绘制。下面使用状态机来实现,
首先画出状态转移图
然后根据状态转移图,写出三段式状态机,代码如下。
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
parameter S0 = 4'd0,
S1 = 4'd1,
S2 = 4'd2,
S3 = 4'd3,
S4 = 4'd4,
S5 = 4'd5,
S6 = 4'd6,
S7 = 4'd7,
S8 = 4'd8;
reg [3:0] curr_state,next_state;
//状态跳转
always@(posedge clk or negedge rst_n)begin
if(rst_n == 0)
curr_state <= S0;
else
curr_state <= next_state;
end
//状态转移逻辑
always@(*)begin
case(curr_state)
S0:next_state = a ? S0 : S1 ;
S1:next_state = a ? S2 : S1 ;
S2:next_state = a ? S3 : S1 ;
S3:next_state = a ? S4 : S1 ;
S4:next_state = a ? S0 : S5 ;
S5:next_state = a ? S2 : S6 ;
S6:next_state = a ? S2 : S7 ;
S7:next_state = a ? S8 : S1 ;
S8:next_state = a ? S3 : S1 ;
default:next_state = S0;
endcase
end
//输出,使用时序将match延后一个周期,不延后可以用assign match = (curr_state == S8);
//注意,使用assign需将match类型改为wire。
always@(posedge clk or negedge rst_n) begin
if(rst_n == 0)
match <= 0;
else
match = (curr_state == S8);
end
endmodule