数字IC学习:同步与异步、跨时钟域处理

摘要

  • 理解同步时钟与异步时钟的概念
  • 理解跨时钟域处理的解决方法

1. 同步与异步

1.1 同步时钟

        定义:时钟同源(即相位相同或相位差固定)且频率比为整数倍的两个时钟为同步时钟。

        同步时钟的分类:

        同频同相:此类时钟间数据传输只要满足正常的建立时间和保持时间即可,不需要特殊的同步设计。

        同频不同相(固定相位差):此类时钟可以理解为同源时钟下两个时钟因路径不同而导致的偏移,只要控制两个时钟间传输的数据延迟在合理范围内,就不会导致时序问题。

         同源不同频(整数倍频率比):此类时钟往往是时钟分频的关系,即便存在相位差也是固定的。如在该情况下单bit信号跨时钟域传输:

①慢时钟域到快时钟域:因为同源,只要满足建立时间和保持时间,快时钟域总会采集到从慢时钟域传递来的信号。

如下图所示,clk2上升沿总能采集到从clk1域传递来的信号sig1,且采集到的信号sig2高电平持续时间也是两个时钟的频率比,即2个周期。

如果需要clk2域的信号sig2只持续1个周期,则需要对sig1进行上升沿检测。

 //上升沿检测逻辑及仿真结果如下

reg[1:0] sig2_r;

always @(posedge clk2 or negedge reset) begin
    if(!reset) sig2_r<=2'b0;
    else sig2_r<={sig2_r[0],sig1};
   end
assign sig2 = sig2_r[0] && !sig2_r[1];

②快时钟域到慢时钟域:因为同源,只要慢时钟域能安全采集到从快时钟域传递来的信号,就不存在异步问题,但是如果快时钟域信号过窄,慢时钟域可能会漏掉该信号,此时就需要对快时钟域的窄脉冲信号进行展宽。

如下图所示,只要慢时钟域能安全采集到从快时钟域传递来的信号就不存在异步问题,如sig1到sig2的传输。但是如果快时钟信号过窄,慢时钟域可能会漏掉该信号,如sig11到sig22的传输。

当两个时钟频率比相对较小时,可以在快时钟域采用对信号延迟的方法进行展宽。

当两个时钟频率比相对较大时,可以在快时钟域采用计数的方法来延长单bit信号有效的时间。

//利用延迟展宽信号的逻辑及仿真结果

//clk1与clk2的频率比为2,只需要将信号在快时钟域clk1中延迟2拍,就会被慢时钟域clk2采集到
reg[1:0] sig11_r;
always @(posedge clk1 or negedge reset) begin
    if(!reset) sig11_r <= 2'b0;
    else sig11_r<= {sig11_r[0],sig11};
   end

reg[1:0] sig22_r;
always @(posedge clk2 or negedge reset) begin
    if(!reset) sig22_r <= 2'b0;
    else sig22_r <= |sig11_r;
   end
assign sig22 =sig22_r;

1.2 异步时钟

        定义:时钟不同源或者时钟同源但频率比为非整数倍的两个时钟为异步时钟。

        异步时钟的分类:

        不同源:最常见的异步时钟,即使两个时钟频率相同,也不能保证每次上电后两者的相位差是固定的,所以信号间的传输与时钟关系是不确定的。

        同源不同频(非整数倍频率比):此类同源时钟间的相位差可能会出现多个,时序难以控制,一般需要当异步时钟处理。

        同源不同频(整数倍频率比但不满足时序要求):前面介绍同步问题时有说明,当信号从快时钟域传递到慢时钟域时,只要慢时钟域能安全采集到从快时钟域传来的信号,就不存在异步问题。但是如果信号在快时钟域翻转过快,慢时钟域可能不会安全的采集到信号,这也可以认为是异步问题。(比如快时钟域信号在慢时钟域上升沿前翻转了两次,此时慢时钟域就会漏掉部分数据,而且数据的快速变化可能会导致时序违例)

2. 跨时钟域处理

        跨时钟域通俗的讲就是两个模块间有数据交互,但是模块不是用的同一个时钟驱动的(可能是同步时钟也可能是异步时钟)。

        异步信号(触发器输入端的数据变化与触发器的时钟不相关)很容易导致电路时序不满足,所以跨时钟域的信号需要进行同步处理。

2.1 慢时钟域到快时钟域

        理论上讲,快时钟域的信号总会采集到慢时钟域传输来的信号,如果存在异步可能会导致采样数据错误,所以需要进行同步处理,此类同步处理相对简单,一般采用延迟打拍法或延迟采样法。

延迟打拍法(双级触发器缓存法)

        最常见的同步方法。异步信号从一个时钟域进入另一个时钟域前,将该信号用两级触发器连续缓存两次,可有效降低因时序不满足而导致的亚稳态问题。

         一般设计中两级触发器缓存即可满足设计时序需求,大量实验表明,三级触发器缓存可解决99%以上的此类异步时序问题。

//两级触发器缓存并检测信号上升沿的逻辑描述
reg [2:0] sig2_r;  //前两级用于同步,后两级用于上升沿检测
always @(posedge clk2 or negedge reset) begin
    if(!reset) sig2_r<=3'b0;
    else    sig2_r<={sig2_r[1:0],sig1};  
   end
assign sig2 = sig2_r[1] && !sig2_r[2] ;

延迟采样法:

        此方法主要针对多位宽的数据传输。

        例如clk1和clk2时钟域频率比为1:5时,可以先采用延迟打拍的方法对数据使能信号进行2级缓存,然后再在快时钟域下对慢时钟域的数据信号采样。(解决思想:保证信号被安全采集的时刻,而不用同步多位宽的数据信号,可节省部分硬件资源)

//2级缓存同步数据使能信号din_en,并进行上升沿采样
reg [2:0] din_en_r;
wire din_en_pos;
always @(posedge clk2 or negedge reset) begin
    if(!reset) din_en_r <= 3'b0;
    else    din_en_r <= {din_en_r[1:0],din_en};
   end
assign din_en_pos = din_en_r[1] && !din_en_r[2];

//同步数据
reg [31:0] dout_r;
reg        dout_en_r;
always @(posedge clk2 or negedge reset) begin
    if(!reset) dout_r <= 32'b0;
    else if(din_en_pos)    dout_r <= din;
   end

//延迟dout_en
always @(posedge clk2 or negedge reset) begin
    if(!reset) dout_en_r <= 1'b0;
    else    dout_en_r <= din_en_pos;
   end
assign dout = dout_r;
assign dout_en = dout_en_r;

仿真结果如下:在clk2时钟域,t2时刻对数据进行采样比t1时刻安全的多。

 若是慢时钟域没有数据使能信号din_en或者数据使能信号一直有效,此时在快时钟域对数据使能信号进行上升沿检测的方法将会失效,因为除了第一个数据外,快时钟域无法检测到后续数据的传输时刻。因此,另一个解决方法是在快时钟域对慢时钟信号的边沿进行检测。

如果两个时钟的频率相差较小,可能还需要对数据进行延迟缓存,以保证采集到的是当拍时钟的数据;如果两个时钟的频率相差较大,数据采样时刻可以通过计数的方法获得,而不用对数据进行缓存。

//频率相差较大时,利用计数延迟采样的方法对慢时钟边沿进行检测的 Verilog 描述

//对clk1进行3级同步以及边沿检测
reg [3:0] edge_r;
wire edge_pos ;
always @(posedge clk2 or negedge reset) begin
    if(!reset) edge_r <= 4'b0;
    else       edge_r <= {edge_r[3:0],clk1};
   end
 assign edge_pos = edge_r[2] && !edge_r[3] ;
//延迟计数器,检测到慢时钟上升沿时开始计数
reg[5:0] cnt;
always @(posedge clk2 or negedge reset) begin
    if(!reset) cnt<=6'h3f;
    else if (edge_pos && din_en) cnt<=6'h0;
    else if (cnt!= 6'h3f) cnt<= cnt +1'b1;
   end
//同步数据
 reg [31:0]           dout_r ;
 reg                  dout_en_r ;
 always @(posedge clk2 or negedge rstn) begin
    if (!rstn)
        dout_r         <= 'b0 ;
    else if (din_en && cnt == 47) //大约在慢时钟周期中间时刻采样
        dout_r         <= din ;
   end
//数据使能信号较数据采样时刻延迟一个周期输出
 always @(posedge clk2 or negedge rstn) begin
    if (!rstn)        dout_en_r      <= 1'b0 ;
    else if (din_en && cnt==48)
                      dout_en_r      <= 1'b1 ;
    else              dout_en_r      <= 1'b0 ;
   end
 assign       dout    = dout_r ;
 assign       dout_en = dout_en_r ;

仿真结果如下,快时钟采样时刻在慢时钟周期中央时刻左右,此时是非常安全的。

2.2 快时钟域到慢时钟域

        信号从快时钟域传输到慢时钟域,需要根据信号的特点来进行同步处理。

        单bit信号,一般可按电平信号和脉冲信号来区分。

        电平信号:只要快时钟的信号保持高电平或低电平的时间足够长,能被慢时钟在满足时序约束的条件下采集到,就可以认为时电平信号。既然电平信号能够被安全的采集到,所以从快时钟域到慢时钟域的电平信号采用延迟打拍的方法做同步。

        脉冲信号:当从快时钟域输出的脉冲信号的有效宽度小于慢时钟周期,此时慢时钟直接去采集这种信号有可能会漏掉。

        若这种脉冲信号脉宽是保持一致的,在知道两个时钟频率比的情况下,可以采用“快时钟脉宽扩展+慢时钟域延迟大拍”的方法进行同步。

        若这种窄脉冲信号脉宽不一致,有时候信号的有效宽度大于慢时钟周期而能被慢时钟采集到时,对此类信号进行脉冲扩展显然是不经济的,此时可以通过“握手”的方法进行同步(实质上就是通过握手机制对窄脉冲信号进行脉宽扩展)。

        多bit信号

        当多位宽数据进行同步时,如果该数据各 bit 位都可以看作电平信号,即相对一段时间内各 bit 位数据均可以保持不变以至于能被慢时钟采集到,可以消耗一些触发器资源对多位宽数据进行简单的延迟打拍同步。

        如果数据变化速率过快,则不能看作电平信号,解决此类异步问题常用方法就是采用异步FIFO

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值