题解 | #含有无关项的序列检测#

含有无关项的序列检测

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

题意整理

       题目要求检测a的序列,a为单bit输入,每个时刻可能具有不同的值,题目要求检测前三位和后三位,不要求检测中间三位,如果把如果把中间的XXX,分别列出:000,001,010,011,100,101,110,111,分别检测,代码过于累赘,考虑分别检测前三位和后三位,分成两个小段的序列检测。当前三位信号和后三位信号同时匹配时,把匹配信号match拉高。

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

题解主体

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

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

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

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

       reg [8:0] a_tem;

       always @(posedge clk or negedge rst_n)

              if (!rst_n)

                     begin

                            a_tem <= 9'b0;

                     end

              else

                     begin

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

                     end

然后截取数组的前三位和目标序列011对比,截取数组的后三位和目标序列110对比,分别声明两个变量表示两个子序列对比的结果。

       reg match_f;

       reg match_b;

       always @(posedge clk or negedge rst_n)

              if (!rst_n)

                     begin

                            match_f <= 1'b0;

                     end

              else if (a_tem[9:7] == 3'b011)

                     begin

                            match_f <= 1'b1;

                     end

              else

                     begin    

                            match_f <= 1'b0;

                     end

       always @(posedge clk or negedge rst_n)

              if (!rst_n)

                     begin

                            match_b <= 1'b0;

                     end

              else if (a_tem[2:0] == 3'b110)

                     begin

                            match_b <= 1'b1;

                     end

              else

                     begin    

                            match_b <= 1'b0;

                     end

当两个子序列都匹配时,拉高match信号。

       assign match = match_b && match_f;        

参考答案

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

	reg [8:0] a_tem;
	reg match_f;
	reg match_b;
	
	always @(posedge clk or negedge rst_n)
		if (!rst_n)
			begin 
				match_f <= 1'b0;
			end
		else if (a_tem[8:6] == 3'b011)
			begin
				match_f <= 1'b1;
			end
		else 
			begin	
				match_f <= 1'b0;
			end

	always @(posedge clk or negedge rst_n)
		if (!rst_n)
			begin 
				match_b <= 1'b0;
			end
		else if (a_tem[2:0] == 3'b110)
			begin
				match_b <= 1'b1;
			end
		else 
			begin	
				match_b <= 1'b0;
			end
			
	always @(posedge clk or negedge rst_n)
		if (!rst_n)
			begin 
				a_tem <= 9'b0;
			end
		else 
			begin
				a_tem <= {a_tem[7:0],a};
			end
			
	assign match = match_b && match_f;
endmodule


全部评论
match 是reg型,不能用assign赋值吧
1 回复 分享
发布于 2022-07-27 15:58
哈哈哈,和我想的一样,只不过我用的是打8拍的方式。但感觉代码有一点小问题,序列检测的第一个bit是“0”,因此复位的时候,数组或者打拍的值是不是应该置为全“1”比较合适。如果复位是全“0”的话,只输入8个bit是不是就有可能会产生match了?
5 回复 分享
发布于 2022-06-10 11:31
看我的代码,简洁 `timescale 1ns/1ns module sequence_detect( input clk, input rst_n, input a, output reg match ); reg [8:0] a_tem; always @(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) a_tem <= 'b0; else a_tem <= {a_tem[7:0], a}; end always@(posedge clk or negedge rst_n)begin if(rst_n == 1'b0) match <= 0; else if(a_tem[8:6]== 3'b011 && a_tem[2:0] == 3'b110) match <= 1; else match <= 0; end endmodule
1 回复 分享
发布于 2024-12-10 16:19 广东
为什么这两小段不可以同时检测,求问
1 回复 分享
发布于 2023-01-10 17:46 陕西
可以合并同时检测没问题,而且代码简洁很多
点赞 回复 分享
发布于 2023-01-14 21:19 重庆
为什么我的match初值总是是X 你们的代码match初值都是0,我和你们得代码几乎完全一样啊
点赞 回复 分享
发布于 2022-11-14 16:14 陕西
他把端口源代码里的match reg类型去掉了,又变成wire 所以能用assign
点赞 回复 分享
发布于 2022-08-29 16:34 山东
楼主好,题解中a_temp前三位的位截取写成[9:7]了,代码里是[8:6]没有写错
点赞 回复 分享
发布于 2022-07-11 15:16

相关推荐

11-05 10:55
中南大学 Java
要双修的猫头鹰:这面试官怕不是个m
我来点评面试官
点赞 评论 收藏
分享
评论
21
5
分享

创作者周榜

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