|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
* s5 |, ?, r" @; C0 H: o. R7 e9 K2 `
0 c0 |# H: p$ a. K7 K在同步电路设计中,边沿检测是必不可少的!
v6 X5 e' m6 L2 E 例如:在一个时钟频率16MHz的同步串行总线接收电路里,串行总线波特率为1Mbps。在串行总线的发送端是在同步时钟(1MHz)的上升沿输出数据,在接收端在同步时钟的下降沿对输入数据进行接收采样。在这个接收电路里检测同步时钟的下降沿是必不可少的。假设主时钟-clk,同步时钟-rck,同步数据-data。
0 f* U/ l2 ~3 J0 A 有些人在边沿检测的时候就喜欢这样做:代码- signal rck_dly: std_logic; --定义一个触发器
- signal data_buf: std_logic; --数据缓冲器
- RCK_Delay:process(clk,rst_n)
- begin
- if rst_n='0' then
- rck_dly <= '0';
- elsif rising_edge(clk) then
- rck_dly <= rck;
- end if;
- end process;
- Data_Receivee:process(clk,rst_n)
- begin
- if rst_n='0' then
- data_buf <= '0';
- elsif rising_edge(clk) then
- if (rck_dly='1' and rck='0') then --RCK下降沿(但这个条件是否总会出现?)
- data_buf <= data;
- end if;
- end if;
- end process;) Z( H$ r- b# V. S2 _
但是大家忽略了一种情况,就是clk与rck之间比没有必然的同步关系,当rck的下降沿刚好略滞后于clk的上升沿(大概几个ns),这样就会使高电平 保持时间不足,就会发现在本时钟上升沿时还是rck_dly='1' and rck='1',而在下一个时钟的上升沿来的时候,就会出现rck_dly='0' and rck='0',所以就不会有rck_dly='1' and rck='0'的情况出现!! 从而导致丢失数据。
) g0 l }& n! r q7 A2 F7 k 如果用下面的方法就可以避免上面的情况,并且可以做到正确无误地接收数据:
, K1 H! T6 a5 o$ e9 Y代码- signal rck_dly: std_logic_vector(1 downto 0);
- signal data_buf: std_logic;
- RCK_Delay:process(clk,rst_n)
- begin
- if rst_n='0' then
- rck_dly <= (others=>'0');
- elsif rising_edge(clk) then
- rck_dly <= rck_dly(0) & rck;
- end if;
- end process;
- Data_Receiver:process(clk,rst_n)
- begin
- if rst_n='0' then
- data_buf <= '0';
- elsif rising_edge(clk) then
- if rck_dly="10" then
- data_buf <= data;
- edn if;
- end if;
- end process;
' f" v( A/ j+ d* X 至于以上电路为什么就可以克服上面出现的情况,就留给大家分析了。& T( L' m1 \2 N
不得不承认后一种方法所耗的资源要比前一种方法多(一个触发器),但是就可以大大提高可靠性,这绝对是物有所值!!9 u. j. V3 _& F) }
~8 t s0 P+ B
|
|