FPGA设计心得(2)边沿检测的问题进一步说明(仿真中一定能得到上升沿的设计)

背景

关于边沿检测,写过的博文也很多,不下于4篇了,当然都是学习过程中边学边记的,过了那么久设计的沉淀,又过了一个疫情的荒诞时光,安静下来,还谈一下这个问题,并给出一种新的写法(其实都是一个原理)。也许你觉得不值一提,但总会有点意义。

新检测方法

这种写法在Vivado中进行行为仿真时,tb文件中,即使在上升沿给0变1数据,也能检测到边沿。如下:

initial begin
    	//sys_rst = 1;
    	vio_txen = 0;
    	#7 
    	//sys_rst = 0;
    	@(posedge sys_clk) vio_txen = 1;
    	# 64 vio_txen = 0;
    	// #26

    	// @(posedge sys_clk) vio_txen = 1;
    	// # 20 vio_txen = 0;
    end // initial

李锐博恩

真正实现了边沿的检测。
对于tb文件中不在0到1时给输入数据,更不在话下:

  initial begin
    	//sys_rst = 1;
    	vio_txen = 0;
    	#7 
    	//sys_rst = 0;
    	@(negedge sys_clk) vio_txen = 1;
    	# 64 vio_txen = 0;
    	#26

    	@(posedge sys_clk) vio_txen = 1;
    	# 20 vio_txen = 0;
    end // initial

在这里插入图片描述总之,检测能力一流!

旧检测方法

我们最常用的边沿检测方式,以上升沿检测为例,大概就是对输入数据寄存一拍,然后用寄存后的数据取反,逻辑与上输入数据:

//____________________code start___________________

module rise_detect_traditionnal(
    input sys_clk,
    input sys_rst,
    
    input vio_txen,
    output vio_txen_rise

);


	reg							vio_txen_r		;
	
	
	//------------------Code Start Here-----------------//
	
	always @ (posedge sys_clk or posedge sys_rst)
		begin
			if(sys_rst)
				vio_txen_r <= 1'b0 ;
			else
				vio_txen_r <= vio_txen ;
		end
		
		assign vio_txen_rise = ~ vio_txen_r & vio_txen;

endmodule

这种方法诚然没有问题,但存在让人迷惑的地方,在vivado仿真时候,如果输入数据是在时钟上升沿从0到1的一个数据,那么就看不到检测的上升沿:
测试文件同上!
仿真图如下:
在这里插入图片描述可见,后一个上升沿没有检测到。
当然这种问题的解释也在上一篇博客的最后讲到了。

改进旧检测方法

当然对于上一种旧检测方案的改进是,首先将待检测数据同步到时钟域内,之后再寄存一拍,最后用同步数据和寄存数据取上升沿检测逻辑。也就是打两拍,保证没有问题。这也是最最标准且常见的。
如下:

module rise_detect_improved(
	input sys_clk,
    input sys_rst,
    
    input vio_txen,
    output vio_txen_rise

    );

	reg vio_txen_r1;
	reg vio_txen_r2;

	always @(posedge sys_clk) begin
	    if (sys_rst) begin    
	        vio_txen_r1 <= 0;
	        vio_txen_r2 <= 0;
	    end 
	    else begin
	        vio_txen_r1 <= vio_txen;
	        vio_txen_r2 <= vio_txen_r1;
	    end 
	end //always

	assign vio_txen_rise = (~vio_txen_r2)& vio_txen_r1;
endmodule

仿真图如下:
在这里插入图片描述可见,没有任何问题,这种也是我最喜欢用的方式。

设计介绍

背景已经把所有的基本上都讲了,这里主要提的还是今天博客的主题,就是一种新写法。可能在你眼里不是新写法,但请考虑下萌新哈。

设计代码



module rising_detect(
    input sys_clk,
    input sys_rst,
    
    input vio_txen,
    output reg vio_txen_rise

);


    wire						vio_txen			;
	reg							vio_txen_r		;
	
	
	//------------------Code Start Here-----------------//
	
	always @ (posedge sys_clk or posedge sys_rst)
		begin
			if(sys_rst)
				vio_txen_r <= 1'b0 ;
			else
				vio_txen_r <= vio_txen ;
		end
		
		always @ (posedge sys_clk or posedge sys_rst)
		begin
			if(sys_rst)
				vio_txen_rise <= 1'b0 ;
			else if((~vio_txen_r) & vio_txen)
				vio_txen_rise <= 1'b1 ;
			else
				vio_txen_rise <= 1'b0 ;
		end

endmodule

仿真情况

module rise_detect_tb();
	//______________ wire and reg definition ___________________________________


	reg sys_clk;
    reg sys_rst;
    
    reg vio_txen;
    wire vio_txen_rise;

    //____________________ simulation code start _______________________________

    //____________________generate system clock ________________________________
    initial begin
    	sys_clk  = 0;
    	forever begin
    	    # 5 sys_clk = ~sys_clk;
    	end // forever 
    	
    end // initial

    //______________________ generate input data ________________________________

    initial begin
    	sys_rst = 1;
    	vio_txen = 0;
    	#7 sys_rst = 0;
    	@(negedge sys_clk) vio_txen = 1;
    	# 64 vio_txen = 0;
    	#26

    	@(posedge sys_clk) vio_txen = 1;
    	# 20 vio_txen = 0;

    end // initial

    //_____________________ instantiation the design under test ___________________
    	rising_detect inst_rising_detect
		(
			.sys_clk       (sys_clk),
			.sys_rst       (sys_rst),
			.vio_txen      (vio_txen),
			.vio_txen_rise (vio_txen_rise)
		);
   	
endmodule

仿真图

在这里插入图片描述

最后想提出的问题

各位有没有注意到这个仿真图:
在这里插入图片描述延迟一拍的数据和原数据一致,但是为什么还可以产生正常的上升沿检测结果?
放大看看:
在这里插入图片描述
评论区留言,提出你的见解呗?

同行邀请

FPGA/IC技术交流2020

工程分享

在这里插入图片描述
链接
提取码:48ka

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李锐博恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值