题解 | #输入序列连续的序列检测#

输入序列连续的序列检测

http://www.nowcoder.com/practice/d65c2204fae944d2a6d9a3b32aa37b39

`timescale 1ns/1ns
module sequence_detect(
    input clk,
    input rst_n,
    input a,
    output reg match
    );
//0111_0001
//------Solution 1 finite state machine
    parameter   IDLE = 3'd0 ;  //
    parameter   S0   = 3'd1 ;  //0
    parameter   S1   = 3'd2 ;  //01
    parameter   S2   = 3'd3 ;  //011
    parameter   S3   = 3'd4 ;  //0111
    parameter   S4   = 3'd5 ;  //0111_0
    parameter   S5   = 3'd6 ;  //0111_00
    parameter   S6   = 3'd7 ;  //0111_000

    reg [2:0]   state , next_state ;
    reg         match_pre ;

    always @( posedge clk or negedge rst_n) begin
      if( !rst_n ) begin
          state <= IDLE ;
      end
      else begin
          state <= next_state ;
      end
    end      

    always @(*) begin
        case (state)
            IDLE : next_state = ~a ? S0 : IDLE ; 
            S0   : next_state =  a ? S1 : S0   ;     
            S1   : next_state =  a ? S2 : S0   ;
            S2   : next_state =  a ? S3 : S0   ;
            S3   : next_state = ~a ? S4 : IDLE ;
            S4   : next_state = ~a ? S5 : S1   ;
            S5   : next_state = ~a ? S6 : S1   ;
            S6   : next_state =  a ? IDLE : S0 ;
           
        default : next_state = IDLE ;
        endcase
    end

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            match_pre <= 1'b0 ;
        else if (state == S6 && a)  //0111_0001
            match_pre <= 1'b1 ;
        else 
            match_pre <= 1'b0 ;
    end
// 本来意图是使用3个触发器完成序列检测,所以就没有用S7=0111_0001这个状态,但好像从时序来看这么做会让match提前一拍拉起来,所以再打一拍就好了
//一直有疑惑像序列检测能不能不要用IDLE这个状态,这样就可以节省一个触发器,希望能有大佬看到后解惑
    
    always @( posedge clk or negedge rst_n) begin
      if( !rst_n ) begin
          match <= 1'b0 ;
      end
      else begin
          match <= match_pre ;
      end
    end      
//------Solution 2 shift resister-----------------
//    reg [7:0] shift;
//
//    always @(posedge clk or negedge rst_n) begin
//        if (!rst_n)
//            shift <= 8'd0;
//        else 
//            shift <= {shift , a};
//    end
//    
//    
//  always @( posedge clk or negedge rst_n) begin
//    if( !rst_n ) begin
//       match <= 1'b0 ;
//    end
//    else  if (shift == 8'b0111_0001)begin
//       match <= 1'b1 ;
//    end
//    else
//    match <= 1'b0 ;
//  end      

endmodule
全部评论

相关推荐

真烦好烦真烦:牛友太有实力了
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务