序列检测_1011(重叠&不重叠检测)Verilog实现

序列检测_1011(重叠&不重叠检测)
序列检测也是数字ic笔试中经常遇到的一类题,本篇对序列1011进行检测,其中分为重叠与不重叠检测设计,在此先简要叙述两种区别如下:
首先什么是不重叠检测?不重叠的意思是每次检测到的1011序列都是独立的组,不能够重复。例如:有一串序列1011011需要我们检测出1011的个数,而在这串序列中我们找到两个1011,但是第一个的1011和第二个的1011有一个共用的“1”,这就是重复检测了。反之当检测序列1011011中1011的个数时只会检测到有一个1011,而不是两个。具体看代码(三段式)以及仿真图。

1.不重叠检测1011
module xljc_1011(clk,rst_n,din,out);

input clk;
input rst_n;
input din; //输入要检测数据
output reg out;//检测到1011后输出标志

parameter S0=5'b0_0001,S1=5'b0_0010,S2=5'b0_0100,S3=5'b0_1000,S4=5'b1_0000;   //独热码

reg [4:0] state;
reg [4:0] c_state,n_state;
always@(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)
	     c_state<=S0;
	 else 
	     c_state<=n_state;	
end
	
always@(c_state or din)begin
	     case(c_state)      
				S0:begin
				   if(din==1'b1)
						 n_state=S1;
					else
					    n_state=S0;
					end
				S1:begin
				   if(din==1'b0)
					    n_state=S2;
					else
					    n_state=S1;
					end
				S2:begin
				   if(din==1'b1)
					    n_state=S3;
					else
					    n_state=S0;
					end
				S3:begin
				   if(din==1'b1)
					    n_state=S4;
					else 
					    n_state=S2;
					end
				S4:begin                         //
				   if(din==1'b1)
					    n_state=S1;
					else 
					    n_state=S0;
					end
				/*S4:begin                        //注释掉部分为重叠检测
				   if(din==1'b1)
					    n_state=S1;
					else
					    n_state=S2;
					end*/
				default:n_state=S0;
			endcase							  		 		 		 
	  
end
//第三段我认为有点冗长,可以考虑直接使用组合逻辑
always@(posedge clk or negedge rst_n)begin
   if(rst_n==1'b0)
	     out<=1'b0;
	 else begin
	     case(n_state)
		  S4:out<=1'b1;
		  default:out<=1'b0;	
		endcase  
	 end

end

endmodule

在这里插入图片描述
综合后状态机视图
在这里插入图片描述
详细状态转移图
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200705213717489.png
仿真结果图
在这里插入图片描述
仿真结果图局部
如上图锁定红线之间为1011011,结果只有一次输出。
2.重叠检测
代码注意:两部分代码只有最后一个状态有区别,因此只放一个代码,重叠检测代码只需把上面代码中注释部分恢复即可。直接上图:
在这里插入图片描述
综合后状态视图
在这里插入图片描述
详细状态转移图
在这里插入图片描述
重叠检测仿真结果图
在这里插入图片描述
重叠检测仿真结果局部图
由上图两锁定红线之间可以看出1011011,输出标志两次。
3.测试代码
`timescale 1ns/1ns
module xljc_1011_tb;
reg clk;
reg rst_n;
reg din;
wire out;
xljc_1011 u0(
.clk(clk),
.rst_n(rst_n),
.din(din),
.out(out)
);

 initial begin
     clk=0;
	  rst_n=0;
	  #20;
	  rst_n=1;
	  send_data;
 end
 always #10 clk=~clk;
 
task send_data;
     integer i;
	  begin
	  for(i=0;i<100;i=i+1)
	      begin
	      @(posedge clk);
			din={$random}%2;
			end
		end
 endtask

endmodule

  • 12
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值