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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
真正实现了边沿的检测。
对于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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
总之,检测能力一流!
旧检测方法
我们最常用的边沿检测方式,以上升沿检测为例,大概就是对输入数据寄存一拍,然后用寄存后的数据取反,逻辑与上输入数据:
//____________________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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
这种方法诚然没有问题,但存在让人迷惑的地方,在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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
仿真图如下:
可见,没有任何问题,这种也是我最喜欢用的方式。
设计介绍
背景已经把所有的基本上都讲了,这里主要提的还是今天博客的主题,就是一种新写法。可能在你眼里不是新写法,但请考虑下萌新哈。
设计代码
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
仿真情况
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
仿真图
最后想提出的问题
各位有没有注意到这个仿真图:
延迟一拍的数据和原数据一致,但是为什么还可以产生正常的上升沿检测结果?
放大看看:
评论区留言,提出你的见解呗?
同行邀请
工程分享
链接
提取码:48ka
文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。
原文链接:reborn.blog.csdn.net/article/details/106028122
- 点赞
- 收藏
- 关注作者
评论(0)