4种FPGA序列检测【附源码】:1.连续序列;2.含有无关项的序列;3.不重叠序列;4.不连续的序列;

题目来源于牛客网,完整工程源码:https://github.com/ningbo99128/verilog


目录

1、VL25 输入序列连续的序列检测

题目介绍

思路分析

代码实现

仿真文件

2、VL26 含有无关项的序列检测

题目介绍

思路分析

代码实现

仿真文件

3、VL27 不重叠序列检测

题目介绍

思路分析

代码实现

仿真文件

4、VL28 输入序列不连续的序列检测

题目介绍

思路分析

代码实现

仿真文件


1、VL25 输入序列连续的序列检测

题目介绍

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

 模块的时序图如下:

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

输入描述:

        clk:系统时钟信号

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

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

输出描述:

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

思路分析

        由状态图可以看出,在s5、s6状态为1时,其状态分别为011101、0111001,不满足序列条件,从而跳转到s2状态继续执行检测;其余状态均为跳转到s2状态;最后在s8状态时,满足序列01110001条件,输出信号match为1。

代码实现

//第一段 状态转移
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
		curr_state <= s0;
	else
		curr_state <= next_state;
	end

//第二段 转移状况
always @(*)begin
	case(curr_state)
		s0:	begin
				if(a==0) 	next_state = s1;
				else 		next_state = s0;	
			end
		s1:	begin
				if(a==1) 	next_state = s2;
				else 		next_state = s0;	
			end
		s2:	begin
				if(a==1) 	next_state = s3;
				else 		next_state = s0;	
			end
		s3:	begin
				if(a==1) 	next_state = s4;
				else 		next_state = s0;	
			end
		s4:	begin
				if(a==0) 	next_state = s5;
				else 		next_state = s0;	
			end
		s5:	begin
				if(a==0) 	next_state = s6;
				else 		next_state = s2;	
			end
		s6:	begin
				if(a==0) 	next_state = s7;
				else 		next_state = s2;	
			end
		s7:	begin
				if(a==1) 	next_state = s8;
				else 		next_state = s0;	
			end
		s8:	begin next_state = s0; end			
		default: begin next_state = s0;end
	endcase	   
end
	
/********* 第三段 状态输出 moore FSM ************/

//标志信号
always @(posedge clk or negedge rst_n)begin 
	if(!rst_n)
		match <= 1'b0;	
	else if(curr_state == s8)    //注意此处是curr_state 
		match <= 1'b1;					
	else
		match <= 1'b0;	
end  

仿真实现

        注意match的变化,是在a序列结束后的1个时钟周期,而不是在a序列最后一位刚开始就产生变化。

2、VL26 含有无关项的序列检测

题目介绍

请编写一个序列检测模块,检测输入信号a是否满足011XXX110序列(长度为9位数据,前三位是011,后三位是110,中间三位不做要求),当信号满足该序列,给出指示信号match。

程序的接口信号图如下:

时序图如下:

请使用Verilog HDL实现以上功能,并编写testbench验证模块的功能。 要求代码简洁,功能完整。

输入描述:

clk:系统时钟信号

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

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

输出描述:

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

思路分析

状态转移图如下:

        有一个疑惑是,在s6状态时,011xxx后面有2个状态分别为011xxx0、011xxx1;如果是011xxx1那没问题,继续跳转下一个状态,那如果是011xxx0,应该返回哪个状态呢?要不要识别一下x的值,如果前3个x恰好是011,那应该返回到s3状态,而不是s0状态。这样好像把题目想的太复杂了。最后按照最简单的思路来,就好了。

代码实现

//第二段 转移状况
always @(*)begin
	case(curr_state)
		s0:	begin
				if(a==0) 	next_state = s1;
				else 		next_state = s0;	
			end
		s1:	begin
				if(a==1) 	next_state = s2;
				else 		next_state = s0;	
			end
		s2:	begin
				if(a==1) 	next_state = s3;
				else 		next_state = s0;	
			end
		s3:	begin next_state = s4; end
		s4:	begin next_state = s5; end
		s5:	begin next_state = s6; end
		s6:	begin
				if(a==1) 	next_state = s7;
				else 		next_state = s0;	
			end
		s7:	begin
				if(a==1) 	next_state = s8;
				else 		next_state = s0;	
			end
		s8:	begin
				if(a==0) 	next_state = s9;
				else 		next_state = s0;	
			end		
		s9:	begin next_state = s0; end			
		default: begin next_state = s0;end
	endcase	   
end

仿真文件

        直接运行成功了,就没用vivado仿真。

3、VL27 不重叠序列检测

题目介绍

        请编写一个序列检测模块,检测输入信号(a)是否满足011100序列, 要求以每六个输入为一组,不检测重复序列,例如第一位数据不符合,则不考虑后五位。一直到第七位数据即下一组信号的第一位开始检测。当信号满足该序列,给出指示信号match。当不满足时给出指示信号not_match。

模块的接口信号图如下:

模块的时序图如下:

请使用Verilog HDL实现以上功能,要求使用状态机实现,画出状态转化图。并编写testbench验证模块的功能。

输入描述:

clk:系统时钟信号

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

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

输出描述:

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

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

思路分析

代码实现

自己仿真没啥问题,但是牛客网的提交总是通过不了。有大佬不怕麻烦的话,帮我看看提出问题。

module sequence_detect(
	input clk,
	input rst_n,
	input data,
	output reg match,
	output reg not_match
	);

//*************code***********//
parameter [2:0]	s0 = 3'b000,
				s1 = 3'b001,		
				s2 = 3'b010,
				s3 = 3'b011,
				s4 = 3'b100,	
				s5 = 3'b101,
				s6 = 3'b110,
				s7 = 3'b111;
						
reg [2:0] curr_state;
reg [2:0] next_state;
reg [2:0] cnt;

always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
		cnt <= 3'd0;
	else if(cnt == 3'd6)
		cnt <= 3'd1;
	else	
		cnt <= cnt + 1'b1;
end


//第一段 状态转移
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
		curr_state <= s0;
	else if(cnt == 3'd6)
		curr_state <= s1;		
	else
		curr_state <= next_state;
	end

//第二段 转移状况
always @(*)begin

	
	case(curr_state)
		s0:	begin next_state = s1;end	
		s1:	begin
				if(data==0) 	next_state = s2;
				else 			next_state = s1;	
			end
		s2:	begin
				if(data==1) 	next_state = s3;
				else 			next_state = s1;	
			end
		s3:	begin
				if(data==1) 	next_state = s4;
				else 			next_state = s1;	
			end
		s4:	begin
				if(data==1) 	next_state = s5;
				else 			next_state = s1;	
			end
		s5:	begin
				if(data==0) 	next_state = s6;
				else 			next_state = s1;	
			end
		s6:	begin
				if(data==0) 	next_state = s7;
				else 			next_state = s1;	
			end
		s7:	begin next_state = s1;end			
		default: begin next_state = s1;end
	endcase	   
end
	
/********* 第三段 状态输出 moore FSM ************/

//标志信号
always @(posedge clk or negedge rst_n)begin 
	if(!rst_n)begin
		match <= 1'b0;	
		not_match <= 1'b0;	
	end
	else if(next_state == s7 && cnt == 3'd6)begin
		match <= 1'b1;	
		not_match <= 1'b0;	
	end
	else if(next_state != s7 && cnt == 3'd6)begin
		match <= 1'b0;	
		not_match <= 1'b1;	
	end	
	else begin
		match <= 1'b0;
		not_match <= 1'b0;			
	end
end  

//*************code***********//
  
endmodule

仿真文件

仿真代码

//2、产生激励
always #5 clk = ~clk;
	
initial begin
	#15;
	rst_n = 1'b1;
	
	#10;            
	@(posedge clk); data=1'b1;	//1
	#10;            
	@(posedge clk); data=1'b1;	//1
	#10;            
	@(posedge clk); data=1'b1;	//1
	#10;            
	@(posedge clk); data=1'b0;	//0
	#10;            
	@(posedge clk); data=1'b0;	//0
		
	#10;            
	@(posedge clk); data=1'b0;	//0
	#10;            
	@(posedge clk); data=1'b1;	//1
	#10;            
	@(posedge clk); data=1'b0;	//0
	#10;            
	@(posedge clk); data=1'b0;	//0
	#10;            
	@(posedge clk); data=1'b1;	//1
	#10;            
	@(posedge clk); data=1'b1;	//1
	
	
	#10;            
	@(posedge clk); data=1'b1;	//1
	#60;            
	@(posedge clk); data=1'b0;	//0		
			
	#60;                       
	@(posedge clk); data=1'b0;	//0	
	#10;            
	@(posedge clk); data=1'b1;	//1
	#10;            
	@(posedge clk); data=1'b1;	//1
	#10;            
	@(posedge clk); data=1'b1;	//1
	#10;            
	@(posedge clk); data=1'b0;	//0
	#10;            
	@(posedge clk); data=1'b0;	//0
	
	#60;            
	@(posedge clk); data=1'b0;	//0	
	
	
	#10;            
	@(posedge clk); data=1'b0;	//0	
	#10;            
	@(posedge clk); data=1'b1;	//1
	#10;            
	@(posedge clk); data=1'b1;	//1
	#10;            
	@(posedge clk); data=1'b1;	//1
	#10;            
	@(posedge clk); data=1'b0;	//0
	#10;            
	@(posedge clk); data=1'b0;	//0	
	
end	

波形图

4、VL28 输入序列不连续的序列检测

题目介绍

        请编写一个序列检测模块,输入信号端口为data,表示数据有效的指示信号端口为data_valid。当data_valid信号为高时,表示此刻的输入信号data有效,参与序列检测;当data_valid为低时,data无效,抛弃该时刻的输入。当输入序列的有效信号满足0110时,拉高序列匹配信号match。

接口信号图:

 模块的时序图:

         请使用状态机实现以上功能,画出状态转移图并使用Verilog HDL编写代码实现以上功能,并编写testbench验证模块的功能.

输入描述:

        clk:系统时钟信号

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

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

        data_valid:输入信号有效标志,当该信号为1时,表示输入信号有效

输出描述:

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

思路分析

        本题和其他序列检测没有本质区别,还是使用3段式状态机,在序列检测的状态跳转部分加一个控制条件。如下:if(data==0 && data_valid)    next_state = s1;

代码实现

//*************code***********//

parameter [2:0]	s0 = 3'b000,
				s1 = 3'b001,		
				s2 = 3'b010,
				s3 = 3'b011,
				s4 = 3'b100;
						
reg [2:0] curr_state;
reg [2:0] next_state;

//第一段 状态转移
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
		curr_state <= s0;
	else
		curr_state <= next_state;
	end

//第二段 转移状况
always @(*)begin
	case(curr_state )
		s0:	begin
				if(data==0 && data_valid) 	
					next_state = s1;
				else 			
					next_state = s0;	
			end
		s1:	begin
				if(data==1 && data_valid) 	
					next_state = s2;
				else 			
					next_state = s0;	
			end
		s2:	begin
				if(data==1 && data_valid) 	
					next_state = s3;
				else 			
					next_state = s0;	
			end
		s3:	begin
				if(data==0 && data_valid) 	
					next_state = s4;
				else 			
					next_state = s0;	
			end			
		s4:	begin next_state = s0;end
		default: begin next_state = s0;end
	endcase	   
end
	
/********* 第三段 状态输出 moore FSM ************/

//标志信号
always @(posedge clk or negedge rst_n)begin 
	if(!rst_n)
		match <= 1'b0;	
	else if(next_state == s4)
		match <= 1'b1;					
	else
		match <= 1'b0;	
end  

//*************code***********//

仿真文件


有发现的错误,欢迎交流奥~

猜你喜欢

转载自blog.csdn.net/qq_40528849/article/details/128486297