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

序列检测一般有两种办法,一种是利用移位寄存器来实现,这种方法比较简单。另一种是利用状态机来实现,难点在于状态转移图的绘制。下面使用状态机来实现,

首先画出状态转移图

alt

然后根据状态转移图,写出三段式状态机,鉴于data_valid控制data是否有效,我采用使用data_valid来控制状态机的转移,当data_valid有效时,状态机正常跳转,否则状态机回归初始状态S0。代码如下:

`timescale 1ns/1ns
module sequence_detect(
	input clk,
	input rst_n,
	input data,
	input data_valid,
	output match
	);
    parameter    S0 = 4'd0,
                S1 = 4'd1,
                S2 = 4'd2,
                S3 = 4'd3,
                S4 = 4'd4;
    
    reg [3:0] curr_state,next_state;
    //状态跳转
    always@(posedge clk or negedge rst_n)begin
        if(rst_n == 0)
            curr_state <= S0;
        else if(data_valid) //控制状态机跳转
            curr_state <= next_state;
        else
            curr_state <= curr_state;
    end
    //状态转移逻辑
    always@(*)begin
        case(curr_state)
            S0:next_state = data ? S0 : S1 ;
            S1:next_state = data ? S2 : S1 ;
            S2:next_state = data ? S3 : S1 ;
            S3:next_state = data ? S0 : S4 ;
            S4:next_state = data ? S2 : 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 == S4);
    end*/
    assign match = (curr_state == S4);
  
endmodule
全部评论
你这个控制状态跳转的好像有问题,比如在011后无效,过段时间再有效同时data=0,这样你就检测不到了,因为你直接跳到初始状态了。
1 回复 分享
发布于 2023-08-09 21:23 上海
终于看到写法跟我一样的了!
点赞 回复 分享
发布于 2023-08-25 22:43 广东
懂了,谢谢
点赞 回复 分享
发布于 2023-04-19 21:17 陕西
你好,请问这些状态跳转是怎么规定的
点赞 回复 分享
发布于 2023-04-17 16:57 陕西

相关推荐

07-15 18:09
门头沟学院 Java
点赞 评论 收藏
分享
评论
8
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务