跨时钟域信号处理
一、场景描述:
某信号signal需要在不同的时钟域进行处理,需要同步到的不同的时钟域继续使用。
举例说明:某定时器Timer包含两个时钟域bus_clk和tmr_clk。状态寄存器STS和控制寄存器CTRL定义如下。寄存器读写访问采用bus_clk时钟,Timer功能采用tmr_clk时钟,当发生溢出时置位溢出标志,即set_tof=1,set_tof属于tmr_clk时钟域,通过对寄存器相应位写1清零清除溢出标志,即clr_tof=1,clr_tof属于bus_clk时钟域。经过跨时钟域处理之后,需要产生两个信号TOF和tof_async,TOF为寄存器标志位供用户访问属于bus_clk时钟域,tof_async用于产生异步中断属于tmr_clk时钟域,两个信号TOF和tof_async属于不同的时钟域。
| Name | STS | |||||||||||||||
| Offset | 0x00 | |||||||||||||||
| Bit | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
| Read | ||||||||||||||||
| Write | ||||||||||||||||
| Reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Bit | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Read | TOF | |||||||||||||||
| Write | W1C | |||||||||||||||
| Reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
TOF:计数器溢出标志,通过写1清零。
| Name | CTRL | |||||||||||||||
| Offset | 0x04 | |||||||||||||||
| Bit | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
| Read | ||||||||||||||||
| Write | ||||||||||||||||
| Reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Bit | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Read | IE | EN | ||||||||||||||
| Write | ||||||||||||||||
| Reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
IE:溢出中断使能。
EN:Timer计数使能。
二、代码实现:
1、cross_clk_domain模块设计
1 module cross_clk_domain( 2 3 output wire signal1, // for clk1 domain 4 output wire signal2, // for clk2 domain 5 6 input wire set_signal_condition, // siganl set condition in clk1 domain 7 input wire clk1, 8 input wire rstn1, 9 10 input wire clr_signal_condition, // signal clr condition in clk2 domain 11 input wire clk2, 12 input wire rstn2 13 ); 14 15 reg set_signal; 16 reg set_signal_d; 17 reg set_signal_dd; 18 reg clr_signal; 19 reg clr_signal_d; 20 reg clr_signal_dd; 21 22 always @(posedge clk1 or negedge rstn1)begin 23 if(!rstn1)begin 24 set_signal <= 1'b0; 25 end 26 else if(clr_signal_dd)begin 27 set_signal <= 1'b0; 28 end 29 else if(set_signal_condition)begin 30 set_signal <= 1'b1; 31 end 32 end 33 34 always @(posedge clk2 or negedge rstn2)begin 35 if(!rstn2)begin 36 set_signal_d <= 1'b0; 37 set_signal_dd <= 1'b0; 38 end 39 else begin 40 set_signal_d <= set_signal; 41 set_signal_dd <= set_signal_d; 42 end 43 end 44 45 always @(posedge clk2 or negedge rstn2)begin 46 if(!rstn2)begin 47 clr_signal <= 1'b0; 48 end 49 else if(~set_signal_dd )begin 50 clr_signal <= 1'b0; 51 end 52 else if(clr_signal_condition)begin 53 clr_signal <= 1'b1; 54 end 55 end 56 57 always @(posedge clk1 or negedge rstn1)begin 58 if(!rstn1)begin 59 clr_signal_d <= 1'b0; 60 clr_signal_dd <= 1'b0; 61 end 62 else begin 63 clr_signal_d <= clr_signal; 64 clr_signal_dd <= clr_signal_d ; 65 end 66 end 67 68 assign signal1 = set_flag; // signal1 in clk1 domain 69 assign signal2 = set_flag_dd; // signal2 in clk2 domain 70 71 endmodule
2、实例化
1 cross_clk_domain cross_clk_domain_inst( 2 signal1(tof_async), 3 signal2(tof), 4 5 set_signal_condition(set_tof), 6 clk1(tmr_clk), 7 rstn1(tmr_clk_rstn), // asynchronous reset and synchronous release 8 9 clr_signal_condition (clr_tof), 10 clk2(bus_clk), 11 rstn2(bus_clk_rstn) 12 );
注:tmr_clk_rstn和bus_clk_rstn两个复位信号不属于同一复位信号,否则会存在亚稳态问题(后期会详细探讨这个问题),一般顶层端口只提供一个复位信号bus_clk_rstn,这里的tmr_clk_rstn需要做异步复位同步释放处理。
作者:芯客栈
如果这篇文章对你有所帮助,看完心情还不错,也可以打赏一下博主😊。
本人水平有限,如表述有误,还请指正。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,如有问题, 可发送邮件咨询.

浙公网安备 33010602011771号