目录
跨时钟传输中,亚稳态是如何形成的?
一、单笔特跨时钟传输_慢到快
①电平同步器
②边沿同步检测器
二、单比特跨时钟传输_快到慢
三、单比特跨时钟域的三种同步电路小结
四、握手机制
需要用到跨时钟的场景:
1.单比特:单比特慢到快的跨时钟传输(电平同步器、边沿检测同步电路)、单比特快到慢传输引起的数据丢失问题(脉冲同步/脉冲检测)。
2.多比特:数据收敛性问题。
Din在从CLOCK1时钟域变到CLOCK2时钟域时, 如下图所示,假如Din刚好在Clock2的采样窗口变化,且不满足建立保持时间,就会产生亚稳态,也就是Dout会在一个电压范围内浮动,如果在Dout浮动期间采样Dout信号,那么采样到的值可能是正确值,也可能不是。
1.采样定理:信号从源时钟域到目的时钟域后,需要在目的时钟的指挥下操作,可视为目的信号对传输过来的信号进行采集,既然是采集,就要满足奈奎斯特采样定理:目的时钟频率至少是原时钟频率的两倍。因此快时钟频率至少为慢时钟的两倍。
2.同步电路:CLK1是慢时钟,CLK2是快时钟,快时钟域一定能采样到慢时钟域信号,此外,如果两个时钟频率相差不大的话,还需要打两拍进行同步,延迟两个时钟周期,减少亚稳态发生的概率。
常用的电平同步电路如下图所示,输入信号DATA要从CLK时钟域跨到CLK2时钟域输出为output。最基本的同步器是两个串联的触发器,且触发时钟由目的时钟提供。这是一个最基础的电路,后续的脉冲边沿检测、脉冲同步都需要用到这个电路。
3.两级触发器是如何防止亚稳态传播的?
防止亚稳态传播的原理:如果同步器中第一个触发器发生了亚稳态 ,但该触发器的输出信号能在下一个触发器建立时间之前稳定下来,那么第二级触发器就不会出现亚稳态。
因此同步器的有效条件为:第一级触发器进入亚稳态后的恢复时间+第二级触发器的建立时间<=一个时钟周期。
如果不满足有效条件,那么即便使用两级同步器,信号依然会是亚稳态的,但这种情况比较罕见,一般来说,两级触发同步器可以满足大部分的应用需求。
4.为什么两个时钟域的触发器之间没有组合逻辑电路?
由于组合逻辑电路常常因为各个输入信号的不一致性以及各路延迟不一样,可能导致输出存在毛刺,所以在跨时钟信号发送到同步器前,先在源时钟域使用寄存器来寄存信号,然后再进行跨时钟同步。故两个时钟域的触发器之间没有组合逻辑电路。
5.核心代码
'timescale 1ns/1ps
module level_syc(
input clk1,
input clk2,
input rst_n,
input data_in,
output data_out
);
reg src_data; //CLK1时钟下的寄存器输出,源时钟下:source
reg des_data0; //clk2时钟下,第一级寄存器输出,目标时钟下:destination
reg des_data1; //clk2时钟下,第二级寄存器输出
always@(posedge clk1 or negedge rst_n)begin
if(!rst_n)
src_data<=0;
else
src_data<=data_in;
end
always@(posedge clk2 or negedge rst_n)begin
if(!rst_n)
des_data0<=0;
data_1<=0;
eles begin
des_data0<=src_data;
des_data1<=des_data0;
end
end
assign data_out=des_data1;
endmoudle
//clk2段的代码也可以这样写:
/**
always@(posedge clk2 or negedge rst_n)begin
if(!rst_n)
{des_data1,des_data0}<=2'b00;
eles begin
{des_data1,des_data0}<={des_data0,src_data};
end
end
**/
边沿同步检测器用于检测输入信号的上升沿,也可以检测它的下降沿。
以上升沿检测电路为例:它是在同步器的基础上增加了边沿检测电路,具体为:同步器的输出端增加一个触发器,新触发器的输出端反向后与同步器的输出端相与得到output。逻辑门的两个输入引脚相差了一个时钟周期。
对比input域output,脉冲边沿同步电路使得输入电平或脉冲转换成目标时钟的一个周期脉冲。该模块本质上是一个三级缓存。
这种脉冲边沿同步器有一个使用限制:输入脉冲的宽度要大于目标时钟周期与目标时钟的第一个触发器建立时间之和。更保险的办法是:输入脉冲的宽度要大于两个目标时钟的宽度。否则目标时钟会采样不到输入。
'timescale 1ns/1ps
module level_syc(
input clk1,
input clk2,
input rst_n,
input data_in,
output data_out_r,//上升沿检测输出
output data_out_f,//下降沿检测输出
output data_out_e //边沿检测输出
);
//由于边沿同步检测器是在电平同步器的基础上演变过来的,所以还要先写一个电平同步器。
reg src_data; //CLK1时钟下的寄存器输出
reg des_data0; //clk2时钟下,第一级寄存器输出
reg des_data1; //clk2时钟下,第二级寄存器输出
reg des_data2; //clk2时钟下,第三级寄存器的输出
always@(posedge clk1 or negedge rst_n)begin
if(!rst_n)
src_data<=0;
else
src_data<=data_in;
end
always@(posedge clk2 or negedge rst_n)begin
if(!rst_n)
des_data0<=0;
des_data1<=0;
des_data2<=0;
eles begin
des_data0<=src_data;
des_data1<=des_data0;
des_data2<=des_data1;
end
end
//边沿检测的本质就是比较最后一级输出与前一级输出
assign data_out_r = des_data1 & ~des_data2; //对应图上电路图
assign data_out_f = ~des_data1 & des_data2;
assign data_out_e = des_data1 ^ des_data2;
endmoudle
在慢到快的跨时钟传输时,提到了奈奎斯特采样定理,也就是目标时钟的采样频率要大于源时钟采样频率的两倍。然而这在快到慢的跨时钟传输中时不可能实现的。
快到慢传输除了要解决亚稳态问题,还要解决无法满足采样定理的问题,也就是采样不到数据,导致数据丢失问题。
这个问题归根结底还是源时钟的传输信号宽度太窄,导致慢时钟采样不到,基于此,将源时钟下的传输信号展宽即可。
实现快时钟到慢时钟传输的电路叫做脉冲同步器或脉冲检测器,电路图如下:总共包括三个部分,第一个部分是脉冲展宽模块,第二个是同步模块,第三个是输出模块。
输入data是一个单脉冲信号,通过该模块会将输入的单脉冲信号展宽toggle信号,然后进行跨时钟同步传输。注意输出模块是异或门,不要和脉冲边沿检测弄混,它与双边沿检测的输出模块一样。
可见:该电路实现了将源时钟下的单脉冲信号转换成目标时钟下的单脉冲信号
module pulse_sys(
input clk1,
input clk2,
input ret_n,
input data_in,
output data_out
);
reg src_dada,
reg des_data0,des_data1,des_dada2;
//脉冲展宽模块:由一个寄存器和一个二选一多路选择器构成,将脉冲信号转换成电平信号
always@(posedge clk1 or negedge rst_n)begin
if(!rst_n)
src_data<=0;
else begin
case(data_in)
1'b0:src_data<=src_dada;
1'b1:src_data<=~src_data;
endcase
end
end
//同步器模块
always@(posedge clk2 or negedge rst_n)begin
if(!rst_n)begin
des_data0<=0;
des_data1<=0;
des_data2<=0;
end
else begin
des_data0<=src_data;
des_data1<=des_data0;
des_data2<=des_data1;
end
end
//输出模块
assign data_out=des_data1^des_data2;
endmoudle
实现脉冲同步电路也有一个使用限制:源脉冲的间隔至少为两个目标时钟周期
类型 | 应用 | 输入 | 输出 | 限制 |
电平同步 | 用于同步电平信号,可以用在快到慢的跨时钟也可以用在慢到快的跨时钟传输中,主要是为了消除亚稳态。 | 电平 | 电平 | 输入电平信号的宽度至少为两个时钟周期的宽度,每次同步之后,输入信号必须恢复到无效状态。 |
边沿同步 | 用于检测输入信号的上升沿或下降沿,用在慢到快的跨时钟传输。 | 电平或脉冲 | 脉冲 | 输入信号的宽度至少为两个目标时钟周期的宽度 |
脉冲同步 | 用于同步输入过来的单脉冲信号,用在快到慢的跨时钟传输中。 | 脉冲 | 脉冲 | 输入脉冲的时间间隔至少为两个目标时钟周期。 |
可以看出,对于慢到快的跨时钟传输,只需要考虑亚稳态问题,使用电平同步器既可以解决。而对于快到慢的跨时钟传输,不仅要考虑亚稳态问题,还要考虑采样速率问题,因此要在原有的模块上再加一个脉冲展宽模块。
通过以上三种电路的对比可以发现,每一种电路都有使用限制,所以并不是一个普遍性的方法,为了保证传递成功,可以采用握手机制。
采用握手机制的跨时钟传输相比于普通的跨时钟传输多了两个信号:请求信号、应答信号。握手机制实际上是带有反馈信号的同步器。
握手过程为:
源时钟下产生请求信号。
将请求信号同步到目标时钟下,目标时钟产生应答信号。
应答信号同步到源时钟下,源时钟清除请求信号。
目标时钟检测到请求信号撤销后,清除应答信号。
握手机制不仅可以用在慢到快,也可以用在快到慢。以快到慢为例,电路结构如下:
上图是典型的握手过程来进行CDC:
源时钟域aclk下的信号adt1信号是要进行CDC的信号;
adt1先是在源时钟域aclk下被展宽,然后通过两级同步器被同步到目的时钟域bclk下,分别为bq1_dat,bq2_dat;
bq2_dat作为指示信号(反馈信号,也可以通过bq1_dat和bq2_dat来生成新的指示信号)又被反馈到了目的时钟域aclk下,并进行同步,分别为aq1_dat,aq2_dat;
aq2_dat的拉高则说明反馈信号的同步完成,此时可以将adt1拉低(结束展宽过程);
adt1拉低(结束展宽过程)后表示一次CDC操作结束。
核心代码:可以看出,带有握手机制的跨时钟传输,只需要从同步器输出反馈回输入即可,也就是只需要多一个反馈模块。
module Sync_Pulse (
aclk,
bclk,
rst_n,
data_in,
pulse_b_out,
data_out
);
/****************************************************/
input aclk;
input bclk;
input rst_n;
input data_in;
output pulse_b_out;
output data_out;
/****************************************************/
reg adat1;
reg bdat1;
reg bdat2;
reg bdat3;
reg abdat1;
reg abdat2;
reg abdat3;
/****************************************************/
//在时钟域aclk下,生成展宽信号adat1
always @ (posedge aclk or negedge rst_n)
begin
if (rst_n == 1'b0)
adta1 <= 1'b0;
else if (data_in) //检测到到输入信号data_in被拉高,则拉高adat1,使信号展宽
adat1 <= 1'b1;
else if (abdat2) //检测到反馈信号abdat2被拉高,则拉低adat1
adat1 <= 1'b0;
else;
end
//将aclk时钟下的信号adat1同步到bclk时钟
always @ (posedge bclk or negedge rst_n)
begin
if (rst_n == 1'b0)
bdat1 <= 1'b0;
bdat2 <= 1'b0;
bdat3 <= 1'b0;
else
bdat1 <= adat1;
bdat2 <= bdat1;
bdat3 <= bdat2;
end
//使用bdat2作为反馈信号,同步到aclk时钟下。用于反馈来拉低展宽信号adat1
always @ (posedge aclk or negedge rst_n)
begin
if (rst_n == 1'b0)
begin
abdat1 <= 1'b0;
abdat2 <= 1'b0;
end
else
begin
abdat1 <= bdat2;
abdat2 <= abdat1;
end
end
//输出模块,使用bdat3来组成输出模块,用来生成边沿信号或者输出信号
assign pulse_b_out = bdat2 & (~bdat3);
assign data_out = bdat3;
endmodule
参考:第三章 跨时钟域电路设计_ 单bit信号跨时钟域传输 - 知乎
跨时钟域问题(二)(单bit信号跨时钟域 1. 电平同步器 2. 边沿同步器 3. 脉冲检测器)_安静到无声的博客-CSDN博客_单bit跨时钟域
跨时钟域电路设计1--单比特信号传输 - 知乎
跨时钟域脉冲信号处理——脉冲同步器_SD.ZHAI的博客-CSDN博客_脉冲跨时钟域
跨时钟域(CDC)设计方法之单bit信号篇(一)_孤独的单刀的博客-CSDN博客_单bit信号跨时钟域
跨时钟域信号处理(一)--Verilog单比特信号_king阿金的博客-CSDN博客_verilog跨时钟域