题解 | #不重叠序列检测#----序列缓存法
不重叠序列检测
https://www.nowcoder.com/practice/9f91a38c74164f8dbdc5f953edcc49cc
思想
序列检测题目通常有两种办法:状态机法和序列缓存法。
状态机法明天再写,今天写序列缓存法。
先来分析题目:
要求是不重叠的检测序列,且仔细观察波形图,每隔6个clocl cycle,match或者not_match就会有一个为1。
这正好可以用序列缓存法,把每次的data缓存下来。可能有小伙伴会有疑问:题目要求不重叠检测呀,若每次把data缓存下来,那就变成重叠的序列啦!其实这样想是对的,把序列缓存下来后,下一个clk上升沿的检测就会用到上一个clk的data1,但是,它是每隔6个周期检测一次,缓存下来的正是之前6个周期的data。【这里我可能表达不清楚,可以想一想重叠检测的序列缓存法怎么做,不重叠检测的序列缓存法又怎么做,比较比较就知道了】
所以接下来的工作显而易见,首先有一个模6计数器,然后需要把data给缓存下来,当计数器计数6次时,比较一下缓存下来的序列是否是目标序列。
代码
`timescale 1ns/1ns module sequence_detect( input clk, input rst_n, input data, output reg match, output reg not_match ); reg [2:0]cnt; reg [5:0]data_temp; //持续计数 计数到5就归0 always @(posedge clk or negedge rst_n) begin if (!rst_n)begin cnt<=3'b0; end else begin if (cnt<3'd5)cnt<=cnt+1'b1; else begin cnt<=3'b0; data_temp<=6'b0; end end end //把data放到data_temp的低位 always @(posedge clk or negedge rst_n) begin if (!rst_n)data_temp<=6'b0; else begin data_temp<={data_temp[4:0],data}; end end //判断,当计数到5时,看data_temp是否满足序列 always @(posedge clk or negedge rst_n)begin if(!rst_n)begin match<=1'b0; not_match<=1'b0; data_temp<=6'b0; end else begin //如果计数到5 if (cnt==5)begin if ({data_temp[4:0],data}==6'b011100)begin match<=1'b1; not_match<=1'b0; end else begin not_match<=1'b1; match<=1'b0; end end //如果没有计数 else begin match<=1'b0; not_match<=1'b0; end end end endmodule
代码的注意事项
代码中有几个需要注意的地方,接下来我将详细讲解:
- 第17行,是cnt<3'd5不是cnt<3'd6
- 之前我把第42,43行写成:
match<=1'b1; not_match<=!match;
然后波形图错误了,本该match和not_match不一样的,波形图显示两个都为1.这是因为<=是非阻塞赋值
3.在always语句块中,可以对reg类型变量赋值,但不能对wire类型的赋值。
4. 第41行为什么是if ({data_temp[4:0],data}==6'b011100)begin而不是if (data_temp==6'b011100)?【这个问题我也在纠结中。。。。。】