题解 | #不重叠序列检测#----序列缓存法
不重叠序列检测
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)?【这个问题我也在纠结中。。。。。】
查看11道真题和解析