5408|13

6892

帖子

0

TA的资源

五彩晶圆(高级)

楼主
 

FPGA设计经验之边沿检测 [复制链接]

在同步电路设计中,边沿检测是必不可少的!
    例如:在一个时钟频率16MHz的同步串行总线接收电路里,串行总线波特率为1Mbps。在串行总线的发送端是在同步时钟(1MHz)的上升沿输出数据,在接收端在同步时钟的下降沿对输入数据进行接收采样。在这个接收电路里检测同步时钟的下降沿是必不可少的。假设主时钟-clk,同步时钟-rck,同步数据-data。
  有些人在边沿检测的时候就喜欢这样做:代码
  1. signal rck_dly: std_logic;   --定义一个触发器   
  2. signal data_buf: std_logic;  --数据缓冲器   
  3. RCK_Delay:process(clk,rst_n)   
  4. begin   
  5.     if rst_n='0' then   
  6.        rck_dly <= '0';   
  7.     elsif rising_edge(clk) then   
  8.        rck_dly <= rck;   
  9.     end if;   
  10. end process;   
  11.   
  12. Data_Receivee:process(clk,rst_n)   
  13. begin   
  14.   if rst_n='0' then   
  15.      data_buf <= '0';   
  16.   elsif rising_edge(clk) then   
  17.      if (rck_dly='1' and rck='0') then   --RCK下降沿(但这个条件是否总会出现?)   
  18.          data_buf <= data;   
  19.      end if;   
  20.   end if;   
  21. end process;  

   但是大家忽略了一种情况,就是clk与rck之间比没有必然的同步关系,当rck的下降沿刚好略滞后于clk的上升沿(大概几个ns),这样就会使高电平 保持时间不足,就会发现在本时钟上升沿时还是rck_dly='1' and rck='1',而在下一个时钟的上升沿来的时候,就会出现rck_dly='0' and rck='0',所以就不会有rck_dly='1' and rck='0'的情况出现!! 从而导致丢失数据。
  如果用下面的方法就可以避免上面的情况,并且可以做到正确无误地接收数据:

代码
  1. signal rck_dly: std_logic_vector(1 downto 0);   
  2. signal data_buf: std_logic;   
  3. RCK_Delay:process(clk,rst_n)   
  4. begin   
  5.   if rst_n='0' then   
  6.      rck_dly <= (others=>'0');   
  7.   elsif rising_edge(clk) then   
  8.      rck_dly <= rck_dly(0) & rck;   
  9.   end if;   
  10. end process;   
  11.   
  12. Data_Receiver:process(clk,rst_n)   
  13. begin   
  14.   if rst_n='0' then   
  15.      data_buf <= '0';   
  16.   elsif rising_edge(clk) then   
  17.      if rck_dly="10" then   
  18.         data_buf <= data;   
  19.      edn if;   
  20.   end if;   
  21. end process;  

  至于以上电路为什么就可以克服上面出现的情况,就留给大家分析了。
  不得不承认后一种方法所耗的资源要比前一种方法多(一个触发器),但是就可以大大提高可靠性,这绝对是物有所值!!

此帖出自FPGA/CPLD论坛

最新回复

貌似咱俩观点是一样的,我是以一楼为参照的 第一种:rck_dly   详情 回复 发表于 2011-4-26 08:38
点赞 关注
 

回复
举报

6892

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

顶!

此帖出自FPGA/CPLD论坛
个人签名一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
 
 

回复

255

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
此帖出自FPGA/CPLD论坛
 
 
 

回复

6892

帖子

0

TA的资源

五彩晶圆(高级)

4
 

边沿检测实际FPGA设计中比较常用的技巧!

此帖出自FPGA/CPLD论坛
个人签名一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
 
 
 

回复

732

帖子

0

TA的资源

纯净的硅(高级)

5
 
input  sck;
reg     sck_r;

always (poseedge clk or negedge rst_b)
    begin
        if(!rst_b)
            sck_r <= 1'b0;
        else
            sck_r <= sck;
    end

always @(*)
    begin
        if((sck_r = 1'b1) && (sck = 1'b0)) // 检测边沿
    end
此帖出自FPGA/CPLD论坛
个人签名学习的乐趣在于分享。
 
 
 

回复

6892

帖子

0

TA的资源

五彩晶圆(高级)

6
 

回复TX_XY:

   兄弟你写的表达方法, 就是常用检测边沿的方法,但该方法存在我上面分析的问题哦

此帖出自FPGA/CPLD论坛
个人签名一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
 
 
 

回复

202

帖子

0

TA的资源

一粒金砂(高级)

7
 

碰到这样输入状况

我用双端口或FIFO跨时钟域处理数据。当然资源更多,反正我不做CPLD
此帖出自FPGA/CPLD论坛
 
 
 

回复

732

帖子

0

TA的资源

纯净的硅(高级)

8
 
原帖由 eeleader 于 2011-4-22 16:57 发表 回复TX_XY:    兄弟你写的表达方法, 就是常用检测边沿的方法,但该方法存在我上面分析的问题哦


我这么写 前提条件有两个:
1. 单独的检测边沿;
2. 快时钟去采慢时钟域的信号的沿。

你原帖里面提到的多打一拍 其实不是去采信号的沿,严格来说是利用一个握手信号把异步总线同步,把异步总线同步如果仅仅只是打一拍,其实您的做法还是有问题滴。HOHO 。。

可以继续讨论 。。。
此帖出自FPGA/CPLD论坛
个人签名学习的乐趣在于分享。
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(中级)

9
 
把2个过程中的程序写进同一个过程中就没问题吧
此帖出自FPGA/CPLD论坛
 
 
 

回复

6892

帖子

0

TA的资源

五彩晶圆(高级)

10
 

回复8楼兄弟:回帖

我这么写 前提条件有两个:
1. 单独的检测边沿;
2. 快时钟去采慢时钟域的信号的沿。

你原帖里面提到的多打一拍 其实不是去采信号的沿,严格来说是利用一个握手信号把异步总线同步,把异步总线同步如果仅仅只是打一拍,其实您的做法还是有问题滴。HOHO 。。

可以继续讨论 。。。

 

当然,异步总线同步只是利用一个D触发器去检测信号,确实也不能避免亚稳态传递; 但是这样的设计的电路更符合电路原理,理由如下:

 

  1. signal rck_dly: std_logic_vector(1 downto 0);   
  2. signal data_buf: std_logic;   
  3. RCK_Delay:process(clk,rst_n)   
  4. begin   
  5.   if rst_n='0' then   
  6.      rck_dly <= (others=>'0');   
  7.   elsif rising_edge(clk) then   
  8.      rck_dly <= rck_dly(0) & rck;   
  9.   end if;   
  10. end process;   
  11.   
  12. Data_Receiver:process(clk,rst_n)   
  13. begin   
  14.   if rst_n='0' then   
  15.      data_buf <= '0';   
  16.   elsif rising_edge(clk) then   
  17.      if rck_dly="10" then   
  18.         data_buf <= data;   
  19.      edn if;   
  20.   end if;   
  21. end process;  

上面表达方式生成电路如下:

 

       上面电路是两个D触发器串联+一个比较电路结构, 没有环回结构,从电路角度理解,该电路是稳定台,抗干扰性能强!

下面在看TX_XY表达电路:

  1. Data_Receivee:process(clk,rst_n)   
  2. begin   
  3.   if rst_n='0' then   
  4.      data_buf <= '0';   
  5.   elsif rising_edge(clk) then   
  6.      if (rck_dly='1' and rck='0') then   --RCK下降沿(但这个条件是否总会出现?)   
  7.          data_buf <= data;   
  8.      end if;   
  9.   end if;   
  10. end process;  
其生成电路结构如下:
该电路结构, 依赖于rclk,clk之间周期关系,且与逻辑容易产生冒险,导致后面电路误触发!
此帖出自FPGA/CPLD论坛
个人签名一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
 
 
 

回复

198

帖子

0

TA的资源

纯净的硅(初级)

11
 

回复 楼主 eeleader 的帖子

认为第二种写法更为妥当,而且我见过的“抓沿”代码都是第二种写法。
个人认为,原因是:不要再process的条件语句(if、case等)的输入端,出现FPGA外部的信号。否则有可能出现竞争冒险。
这个我遇到过。
此帖出自FPGA/CPLD论坛
 
 
 

回复

6892

帖子

0

TA的资源

五彩晶圆(高级)

12
 

回复qd0090:

  你提到的办法,解决输入信号的同步问题,与第一种方法一样.

 但是抓沿判断的话,还是第一种可靠些. 原因是:

 

第一种方法: 两个D触发器的输出信号与一个常数进行比较, 不易产生竞争关系;

第二种方法: 两个D触发器的输出信号与逻辑, 这个地方容易产生生竞争关系;

此帖出自FPGA/CPLD论坛
个人签名一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
 
 
 

回复

198

帖子

0

TA的资源

纯净的硅(初级)

13
 

回复 12楼 eeleader 的帖子

貌似咱俩观点是一样的,我是以一楼为参照的
第一种:rck_dly <= rck;
第二种:rck_dly <= rck_dly(0) & rck;   
我认为第二种好。
此帖出自FPGA/CPLD论坛
 
 
 

回复

6892

帖子

0

TA的资源

五彩晶圆(高级)

14
 

回复qd0090:

 

看来咱们同道中人啊!幸会幸会!

此帖出自FPGA/CPLD论坛
个人签名一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表