【 FPGA 】跨时钟域处理以及边沿检测

举报
李锐博恩 发表于 2021/07/15 03:11:40 2021/07/15
【摘要】 本文转载自:跨时钟域处理 题目:多时钟域设计中,如何处理跨时钟域 单bit:两级触发器同步(适用于慢到快)多bit:采用异步FIFO,异步双口RAM加握手信号格雷码转换 题目:编写Verilog代码描述跨时钟域信号传输,慢时钟域到快时钟域 reg [1:0] signal_r;//-----------------------------------------...

本文转载自:跨时钟域处理


题目:多时钟域设计中,如何处理跨时钟域

  1. 单bit:两级触发器同步(适用于慢到快)
  2. 多bit:采用异步FIFO,异步双口RAM
  3. 加握手信号
  4. 格雷码转换

题目:编写Verilog代码描述跨时钟域信号传输,慢时钟域到快时钟域


  
  1. reg [1:0] signal_r;
  2. //-------------------------------------------------------
  3. //
  4. always @(posedge clk or negedge rst_n)begin
  5. if(rst_n == 1'b0)begin
  6. signal_r <= 2'b00;
  7. end
  8. else begin
  9. signal_r <= {signal_r[0], signal_in};
  10. end
  11. end
  12. assign signal_out = signal_r[1];

 


题目:编写Verilog代码描述跨时钟域信号传输,快时钟域到慢时钟域

跨时钟域处理从快时钟域到慢时钟域,如果是下面第一个图,clkb则可以采样到signal_a_in,但是如果只有单脉冲,如第二个图,则不能确保采样到signal_a_in。这个时候用两级触发器同步是没有用的。


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

 

慢到快,单脉冲

慢到快,长信号传递

快到慢,单脉冲

单脉冲,长信号传递

 

   上述代码可以实现快到慢,慢到快时钟域任意转换,pulse_outb会输出单个脉冲,signal_outb输出信号时间长度最少为clkb的四个周期,当signal_a_in的信号长度大于clkb的四个周期,signal_outb输出与signal_a_in时间长度相同。


题目:边沿检测


  
  1. reg [1:0] signal_r;
  2. //-------------------------------------------------------
  3. //
  4. always @(posedge clk or negedge rst_n)begin
  5. if(rst_n == 1'b0)begin
  6. signal_r <= 2'b00;
  7. end
  8. else begin
  9. signal_r <= {signal_r[0], signal_in};
  10. end
  11. end
  12. assign singal_posedge = ~signal_r[1] & signal_r[0];//检测上升沿
  13. assign singal_negedge = signal_r[1] & ~signal_r[0];//检测下降沿

 记忆:上升沿之前是0,现在变成1,所以上个周期传输到的signal_r[1]是0所以取反。反之亦然。

 

 

 

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

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

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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