`timescale 1ns/1ns
module sequence_detect(
    input clk,
    input rst_n,
    input data,
    input data_valid,
    output reg match
    );


reg [3:0] pstate,nstate;

parameter idle=4'd0,
          s1_d0=4'd1,
          s2_d01=4'd2,
          s3_d011=4'd3,
          s4_d0110=4'd4;

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        pstate<=idle;
    else
        pstate<=nstate;
end

always @(pstate or data or data_valid)
begin
    case(pstate)
        idle:
            if(data_valid && !data)
                nstate=s1_d0;            //第一位匹配
            else
                nstate=idle;
        s1_d0:
            if (data_valid)
                begin    
                    if (data) nstate = s2_d01;        //数据有效且为1,即前两位01匹配,下一状态为s2_d01
                    else nstate = s1_d0;            //数据有效但为0,即只有第一位0匹配,下一状态为s1_d0
                end
            else nstate = s1_d0;                    //数据无效,保持在s1_d0
        s2_d01:
            if (data_valid)
                begin    
                    if (data) nstate = s3_d011;        //数据有效且为1,即前三位011匹配,下一状态为s3_d011
                    else nstate = s1_d0;            //数据有效但为0,即只有第一位0匹配,下一状态为s1_d0
                end
            else nstate = s2_d01;                    //数据无效,保持在s2_d01
        s3_d011:
            if (data_valid)
                begin    
                    if (!data) nstate = s4_d0110;        //数据有效且为0,即前四位0110匹配,下一状态为s4_d0110
                    else nstate = idle;                    //数据有效但为1,即不匹配,下一状态为idle
                end
            else nstate = s3_d011;                    //数据无效,保持在s3_d011
        s4_d0110:
            if (data_valid)
                begin    
                    if (!data) nstate = s1_d0;        //数据有效且为0,即匹配目标序列的第一位0,下一状态为s1_d0
                    else nstate = idle;            //数据有效但为1,不匹配目标序列,下一状态为idle
                end
            else nstate = idle;                    //数据无效,下一状态为idle
        default:
            nstate=idle;
        endcase
end

always @(pstate or rst_n)
begin
    if(!rst_n==1)
        match=1'b0;
    else if(pstate==s4_d0110)                        //进入状态s4_d0110表示四位数据都匹配,把匹配指示信号match拉高
            match=1'b1;
         else
            match=1'b0;
end

endmodule
/*`timescale 1ns/1ns
module sequence_detect(
    input clk,
    input rst_n,
    input data,
    input data_valid,
    output reg match
    );

    parameter idle           = 6'b000000;
    parameter test_one_done       = 6'b000001;
    parameter test_two_done       = 6'b000010;
    parameter test_three_done     = 6'b000100;
    parameter test_correct   = 6'b100001;
    
    reg [5:0] c_state;
    reg [5:0] n_state;
    reg [1:0] data_cnt;
    
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            data_cnt <= 2'd0;
        else if(data_cnt == 2'd3)
            data_cnt <= 2'd0;
        else if(data_valid)
            data_cnt <= data_cnt + 1'b1;
        else
            data_cnt <= data_cnt;
    end
    
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            c_state <= idle;
        else
            c_state <= n_state;
    end
 
    always @(*) begin
        case(c_state)
            idle           : if(data_valid==1 && data==0) n_state <= test_one_done; else if(~data_valid) n_state <=idle; else n_state <= idle;
            test_one_done  : if(data_valid==1 && data==1) n_state <= test_two_done; else if(~data_valid) n_state <=test_one_done; else n_state <= idle;
            test_two_done  : if(data_valid==1 && data==1) n_state <= test_three_done; else if(~data_valid) n_state <=test_two_done; else n_state <= idle;
            test_three_done: if(data_valid==1 && data==0) n_state <= test_correct; else if(~data_valid) n_state <=test_three_done; else n_state <= idle;
            test_correct   : if(data_valid==1 && data==0) n_state <= test_one_done; else  n_state <= idle;
        endcase
    end
    
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            match <= 1'b0;
        else begin
            case(c_state)
                test_correct: match <= 1'b1;
                default:match <= 1'b0;
            endcase
        end
    end
    
endmodule*/