控制信号(单脉冲信号)的跨时钟域传输问题

举报
李锐博恩 发表于 2021/07/15 02:19:49 2021/07/15
【摘要】   控制信号(单脉冲信号)的跨时钟域传输问题存在两种情况,一种是从快时钟域到慢时钟域传输,如果用慢时钟强行采样快时钟域内的控制信号,可能存在采样不到信号的情况,而且很大概率采不到信号;另一种情况是从慢时钟域到快时钟域的控制信号传输问题,这种情况,快时钟一定能采样到慢时钟域内的控制信号,但是可能出现亚稳态问题; 下面针对这两种情况进行处理: 快时钟到慢时钟 有...

 

控制信号(单脉冲信号)的跨时钟域传输问题存在两种情况,一种是从快时钟域到慢时钟域传输,如果用慢时钟强行采样快时钟域内的控制信号,可能存在采样不到信号的情况,而且很大概率采不到信号;另一种情况是从慢时钟域到快时钟域的控制信号传输问题,这种情况,快时钟一定能采样到慢时钟域内的控制信号,但是可能出现亚稳态问题;

下面针对这两种情况进行处理:

快时钟到慢时钟

有两个时钟域A和B,脉冲a在时钟域A中保持一个时钟周期,现要把脉冲A同步到时钟域B中,试用D触发器、与门、或门、非门以及异或门画出电路图实现这个功能。(某发科IC现场笔试题)


先考虑从快时钟域到慢时钟域进行信号传输的问题(脉冲宽度小于一个时钟):

先通过Verilog来实现:(参考链接


  
  1. module Sync_Pulse(
  2. input clka,
  3. input clkb,
  4. input rst_n,
  5. input pulse_ina,
  6. output pulse_outb,
  7. output signal_outb
  8. );
  9. //-------------------------------------------------------
  10. reg signal_a;
  11. reg signal_b;
  12. reg signal_b_r;
  13. reg signal_b_rr;
  14. reg signal_a_r;
  15. reg signal_a_rr;
  16. //-------------------------------------------------------
  17. //在clka下,生成展宽信号signal_a
  18. always @(posedge clka or negedge rst_n)begin
  19. if(rst_n == 1'b0)begin
  20. signal_a <= 1'b0;
  21. end
  22. else if(pulse_ina == 1'b1)begin
  23. signal_a <= 1'b1;
  24. end
  25. else if(signal_a_rr == 1'b1)
  26. signal_a <= 1'b0;
  27. else
  28. signal_a <= signal_a;
  29. end
  30. //-------------------------------------------------------
  31. //在clkb下同步signal_a
  32. always @(posedge clkb or negedge rst_n)begin
  33. if(rst_n == 1'b0)begin
  34. signal_b <= 1'b0;
  35. end
  36. else begin
  37. signal_b <= signal_a;
  38. end
  39. end
  40. //-------------------------------------------------------
  41. //在clkb下生成脉冲信号和输出信号
  42. always @(posedge clkb or negedge rst_n)begin
  43. if(rst_n == 1'b0)begin
  44. signal_b_r <= 'b0;
  45. signal_b_rr <= 'b0;
  46. end
  47. else begin
  48. signal_b_rr <= signal_b_r;
  49. signal_b_r <= signal_b;
  50. end
  51. end
  52. assign pulse_outb = ~signal_b_rr & signal_b_r;
  53. assign signal_outb = signal_b_rr;
  54. //-------------------------------------------------------
  55. //在clka下采集signal_b_rr,生成signal_a_rr用于反馈拉低signal_a
  56. always @(posedge clka or negedge rst_n)begin
  57. if(rst_n == 1'b0)begin
  58. signal_a_r <= 'b0;
  59. signal_a_rr <= 'b0;
  60. end
  61. else begin
  62. signal_a_rr <= signal_a_r;
  63. signal_a_r <= signal_b_rr;
  64. end
  65. end
  66. endmodule

本题需要输出的信号其实是pulse_outb,这个信号在时钟域B中持续了一个时钟,通过边沿检测实现的。

经过Quartus生成的RTL原理图如下:

 

经过Vivado生成的RTL原理图如下:

rtl图

可见,大同小异。

可是到这里并没有结束,这种电路图和题目要求的还不一样,人家没要求用多路选择器呀,所以需要将反馈后的多路选择器换成需要的器件。

参考图片来源

需要画出的原理图如下:

联发科2020年提前批招聘笔试答案之一

上面电路的实现,是快时钟域到慢时钟域的问题,我们通过反馈信号进行控制信号的延时来让慢时钟域充分采样得到控制信号,本质上是也是对控制信号的延时。这个延时的具体实现,需要对控制信号的产生逻辑进行处理,来满足延时的要求。

为什么上面的电路能实现,我们来仿真看看:

pulse_ina为快时钟域的控制信号,signal_a为pulse_ina的脉冲展宽信号,signal_b为慢时钟对脉冲展宽信号的采样,signal_b_r,signal_b_rr分别为signal_b的延迟,一拍,二拍。

signal_a_r为反馈信号,同理signal_a_rr是最直接的反馈信号,它决定pulse_ina的脉冲展宽的停止。

pulse_outb为慢时钟的控制脉冲输出,也是最后需要的结果。

给出测试文件:


  
  1. `timescale 1ns/1ps
  2. module CLK_Fast2Slow_TB();
  3. reg clka;
  4. reg clkb;
  5. reg rst_n;
  6. reg pulse_ina;
  7. wire pulse_outb;
  8. wire signal_outb;
  9. initial begin
  10. clka = 0;
  11. forever
  12. #2 clka = ~clka;
  13. end
  14. initial begin
  15. clkb = 0;
  16. forever
  17. #4 clkb = ~clkb;
  18. end
  19. initial begin
  20. rst_n = 0;
  21. pulse_ina = 0;
  22. # 10
  23. rst_n = 1;
  24. #4
  25. pulse_ina = 1;
  26. #4
  27. pulse_ina = 0;
  28. end
  29. Sync_Pulse INST_CLK_Fast2Slow(
  30. .clka(clka),
  31. .clkb(clkb),
  32. .rst_n(rst_n),
  33. .pulse_ina(pulse_ina),
  34. .pulse_outb(pulse_outb),
  35. .signal_outb(signal_outb)
  36. );
  37. endmodule

慢时钟域到快时钟域

在慢时钟域到快时钟域传输的问题则不必如此麻烦,因为快时钟域总能采样到慢时钟域的脉冲信号,唯一需要注意的是,采样的信号会出现亚稳态的问题,如快时钟域信号的上升沿恰好对应慢时钟域脉冲的变化位置,导致建立时间不满足。

为了解决这个问题,我们只需要用快时钟对慢时钟域脉冲进行两级寄存器同步即可,这样基本就解决了亚稳态的问题了。

参考代码


  
  1. module Sync_Pulse(
  2. input clkb,
  3. input rst_n,
  4. input pulse_ina,
  5. output pulse_outb
  6. );
  7. reg signal_r;
  8. reg signal_rr;
  9. always @ (posedge clkb or negedge rst_n)
  10. if (!rst_n) begin
  11. signal_r <= 1'b0;
  12. signal_rr <= 1'b0;
  13. end else begin
  14. signal_r <= pulse_ina;
  15. signal_rr <= signal_r;
  16. end
  17. assign pulse_outb = signal_rr;
  18. endmodule

除了上面的参考链接外,在加几个可以参考:

https://mp.weixin.qq.com/s/QoLAV2NBi4_8mQ5bJ_4MAw

 

 

文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。

原文链接:reborn.blog.csdn.net/article/details/96714098

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。