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

输入序列连续的序列检测

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

题意整理

       题目要求检测a的序列,a为单bit输入,每个时刻可能具有不同的值,当连续8个时钟周期中a的值依次为01110001,判断a出现目标序列,把匹配信号match拉高。

值得注意的是:当前N位数值匹配则N+1位是否匹配,当出现某一位不匹配时,注意不一定从第一位开始重新判断,例如出现前五位数值为01110,第六位数值出现1,不匹配目标序列,但第五,第六位数值符合第一,第二位数值,可以继续判断下一位是否匹配目标序列的第三位,而不需要从第一位开始。

题解主体

       对于序列检测题目,常规的解法有两种:状态机法和序列缓存对比法。

状态机法的过程类似于题意理解中提到的过程:在初始状态中,先判断第一位是否符合,若符合则进入下一个状态,判断第二位是否符合;若第一位不符合则保持在初始状态,直到第一位匹配。如前两位匹配,则判断第三位是否符合,若第一位匹配,最新输入的数值和目标序列的第二位不匹配,则根据最新一位是否匹配第一位,进入第一位匹配状态或者初始状态。依次类推。

序列缓存对比法,则是将八个时刻的数据缓存,作为一个数组,每个时刻的输入位于数组的末尾,数组其它元素左移,把最早输入的数据移出。然后将数组和目标序列对比,如果数组和目标序列相等,则说明出现目标序列。

序列缓存对比法在实现上比较简单,本题采用该方法实现。首先声明一个数组,缓存八个时刻的a输入的数值。移位可以通过位截取操作和位拼接操作实现:a_tem[6:0]表示截取a_tem的低7位,{a_tem[6:0],a}表示把a_tem[6:0]和新输入的数值a拼接,a位于低位。

       reg [7:0] a_tem;

       always @(posedge clk or negedge rst_n)

              if (!rst_n)

                     begin

                            a_tem <= 8'b0;

                     end

              else

                     begin

                            a_tem <= {a_tem[6:0],a};

                     end

然后将缓存的数组和目标序列:0111_0001相对比,如果匹配,则把match拉高,其它情况下,macth为0。

       always @(posedge clk or negedge rst_n)

              if (!rst_n)

                     begin

                            match <= 1'b0;

                     end

              else if (a_tem == 8'b0111_0001)

                     begin

                            match <= 1'b1;

                     end

              else

                     begin    

                            match <= 1'b0;

                     end

 参考答案

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

	reg [7:0] a_tem;
	
	always @(posedge clk or negedge rst_n)
		if (!rst_n)
			begin 
				match <= 1'b0;
			end
		else if (a_tem == 8'b0111_0001)
			begin
				match <= 1'b1;
			end
		else 
			begin	
				match <= 1'b0;
			end
		
	always @(posedge clk or negedge rst_n)
		if (!rst_n)
			begin 
				a_tem <= 8'b0;
			end
		else 
			begin
				a_tem <= {a_tem[6:0],a};
			end
endmodule


全部评论
赞同,我觉得这个复位值取决于要判断序列的第一个数,要和它相反,否则刚开始还没有把序列缓存填满的时候会产生假匹配
20 回复 分享
发布于 2022-07-07 23:25
是不是把a_tem复位到1更合理?
11 回复 分享
发布于 2022-04-23 20:52
各位佬,我的match直接使用组合逻辑赋值有问题吗😅
点赞 回复 分享
发布于 2024-11-19 09:20 陕西
细节细节佩服
点赞 回复 分享
发布于 2024-06-28 17:25 江苏
可以直接复位为8'zzzz_zzzz,也可以,不用考虑那么多
点赞 回复 分享
发布于 2024-06-11 16:08 天津
细节
点赞 回复 分享
发布于 2024-05-09 21:06 辽宁
细节拉满
点赞 回复 分享
发布于 2023-04-26 14:48 四川
细节啊楼上两位兄弟
点赞 回复 分享
发布于 2023-04-06 23:02 上海

相关推荐

08-05 14:05
门头沟学院 Java
Twilight_m...:你直接问他,马总能不能直聘让我进阿里
点赞 评论 收藏
分享
07-16 18:03
门头沟学院 Java
点赞 评论 收藏
分享
竟然收到了测评听说是双机位
投递拼多多集团-PDD等公司10个岗位
点赞 评论 收藏
分享
评论
76
13
分享

创作者周榜

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