这一题的重点就在于怎么把6个输入归为一组,让状态机只要检测到011100中任意一个不满足就直接跳到下一组。
解决方案也很简单:
1、计数器计数,cnt 0 1 2 3 4 5 正好6个数据,当cnt = 5的时候,就说明一串6个输入已经完整。
2、状态机中设定一个FAIL状态,当S1/S2…不能满足011100连续跳转的时候,直接跳到FAIL状态,当6个输入都完整了也就是cnt=5的时候,可以跳转到下一个6输入序列,next_state让它跳到IDLE,开始下一轮判断,否则一直保持FAIL状态。
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
output reg match,
output reg not_match
);
parameter IDLE = 7'b000_0001,
S1 = 7'b000_0010,
S2 = 7'b000_0100,
S3 = 7'b000_1000,
S4 = 7'b001_0000,
S5 = 7'b010_0000,
FAIL = 7'b100_0000;
reg [6:0]state,next_state;
reg [2:0]cnt;
//计数器
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)
cnt <= 3'b0;
else if(cnt == 3'd5)
cnt <= 3'b0;
else
cnt <= cnt + 1'b1;
end
//状态机-1
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
state <= IDLE;
else
state <= next_state;
end
//状态机-2
always@(*)
begin
if(~rst_n)
next_state <= IDLE;
else
case(state)
IDLE:next_state <= (~data)?S1:FAIL;
S1:next_state <= (data)?S2:FAIL;
S2:next_state <= (data)?S3:FAIL;
S3:next_state <= (data)?S4:FAIL;
S4:next_state <= (~data)?S5:FAIL;
S5:next_state <= (~data)?IDLE:FAIL;
FAIL:next_state <= (cnt == 3'd5)?IDLE:FAIL;
default:next_state <= IDLE;
endcase
end
//状态机-3
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)begin
match <= 1'b0;
not_match <= 1'b0;end
else if(cnt == 3'd5)
if((next_state == IDLE)&&(state == S5))
match <= 1'b1;
else
not_match <= 1'b1;
else begin
match <= 1'b0;
not_match <= 1'b0;end
end
endmodule
通过!