输入序列连续的序列检测

描述

        请编写一个序列检测模块,检测输入信号a是否满足01110001序列,当信号满足该序列,给出指示信号match。

        模块的接口信号图如下:    

        模块的时序图如下:

请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能

输入描述

        clk:系统时钟信号

        rst_n:异步复位信号,低电平有效

        a:单比特信号,待检测的数据

输出描述

        match:当输入信号a满足目标序列,该信号为1,其余时刻该信号为0

解题分析

        题目要求检测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

方法二:

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

 reg [7:0] areg;

always @(posedge clk or negedge rst_n)
	begin
		if(~rst_n)
			begin
				match <= 0;
			end
		else
			begin
				if(areg == 8'b01110001)
					match <= 1;
				else
					match <= 0;
			end

	end


always @(posedge clk or negedge rst_n)
	begin
		if(~rst_n)
			begin
				areg <= 0;
			end
		else
			begin
				areg <= {areg[6:0],a};
			end
	end


endmodule

注:解题分析来源于网友,如有侵权,请告删之。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值