跨时钟域传输和Verilog代码


前面我们谈到了 亚稳态的产生与处理,在异步信号进行跨时钟域传输时,很大概率会产生亚稳态的问题,那么该如何解决跨时钟域信号传输的问题呢?跨时钟域信号分为单bit控制信号、多比特控制信号和多bit数据流传输,依照这个进行分类处理。

基本概念

同步电路:即电路中所有受时钟控制的单元(寄存器和触发器)全部由一个统一的全局时钟控制。

异步电路:电路中数据传输可以在任何时间发生,电路中没有一个全局或局部的控制时钟。

时钟域:所谓的同一个时钟域和跨时钟域都是针对时钟源点来说的。

同步时钟:如果有好几个时钟,它们都是从同一个锁相环(PLL)出来的,那么这些时钟之间的相位和倍数都是确定的,这些时钟称为同步时钟。

异步时钟:不是从同一个PLL出来的时钟,它们之间的相位和倍数都不可控,称为异步时钟。

一、单bit信号

单bit控制信号在传输时,需要两种情况讨论:快时钟域信号同步到慢时钟域、慢时钟域信号同步到快时钟域。为什么要进行这两种分类呢?因为快时钟是肯定可以采样到慢时钟信号的有效边沿,而慢时钟却可能没办法采集到快时钟域的信号边沿,因此需要做另外的处理。

1.慢时钟域信号同步到快时钟域

慢时钟域的单bit控制信号在同步快时钟域时,只需要使用边沿检测同步器即可,用两级触发器打两拍同步信号。
在这里插入图片描述

module asy_1bit_slow2fast(
	input  clk1, //慢时钟
	input  clk2, //快时钟
	input  rstn,
	input  data,
	output dout
);
reg       q1,q2,q3;

assign dout = q2 & (~q3);
//------同步打拍-------
always@(posedge clk2 or negedge rstn) begin
	if(!rstn)begin
		{q3,q2,q1} <= 3{1'b0};
    end
	else begin
		{q3,q2,q1} <= {q2,q1,data};
	end
end
endmodule

上图中,data是来自慢时钟域的单比特信号,clk2是快时钟域的时钟。时序图如下所示,经过两级触发器同步两拍后,会产生一个AND(A)信号波形,再经过后一级触发器同步,会产生一个AND(B)的信号,两个信号经过逻辑电路处理,产生一个Output信号脉冲,信号宽度为快时钟域一个时钟周期宽度。
在这里插入图片描述

总结:单比特信号在经过边沿检测同步器同步后,会将慢时钟域下宽频的信号脉冲搬移并缩小为快时钟域下一个时钟周期的同步脉冲。
使用条件:使用边沿检测同步器进行单比特信号的跨时钟同步是有一定的条件,只有满足条件,才能进行有效同步。

  • 慢时钟域下的单比特信号的脉冲宽度,必须要大于或等于快时钟域下2个时钟周期。这样才能保证慢时钟域的脉冲信号是足够保持到被快时钟域的同步器拿到。

2.快时钟域信号同步到慢时钟域

由于快时钟域信号频率变化快,导致慢时钟域的时钟信号可能采样不到快时钟域下有效的信号的边沿。这时,就需要使用脉冲同步器进行同步。
脉冲同步器的结构和时序图如下:
在这里插入图片描述

module asy_1bit_fast2slow(
	input  clk1, //快时钟
	input  clk2, //慢时钟
	input  rstn,
	input  din,
	output dout
);
reg       toggle;
reg       q1,q2,q3;
//------产生Toggle信号------
always@(posedge clk1 or negedge rstn) begin
	if(!rstn)begin
		toggle <= 1'b0;
    end
	else if(din) begin
		toggle <= ~toggle;
	end
	else begin
		toggle <= toggle;
	end
end

//------同步打拍-------
assign dout = q2 ^ q3; //输出同步后的脉冲信号
always@(posedge clk2 or negedge rstn) begin
	if(!rstn)begin
		{q3,q2,q1} <= 3{1'b0};
    end
	else begin
		{q3,q2,q1} <= {q2,q1,toggle};
	end
end

endmodule

在这里插入图片描述
解释一下上面两张图:

  1. 首先,脉冲同步器的作用就是:在快时钟域取出一个单时钟周期宽度的脉冲,然后在经过慢时钟域两级同步和后一级触发器打拍,逻辑异或后产生一个慢时钟下单时钟周期宽度的同步脉冲。
  2. 因为慢时钟很有可能采样不到快时钟,所以需要通过快时钟域下的翻转电路,将快时钟域下前后间隔较多个周期的两个有效脉冲进行标定,形成上图所示的Toggle信号脉冲。
  3. 然后,先通过同步电路将Toggle信号进行同步,形成上图所示的A、B信号波形。
  4. 最后用组合电路做A^B,得到慢时钟域下两个有效的单周期脉冲。

脉冲同步器同步信号的使用限制

  • 快时钟域下的两个输入脉冲的间隔必须大于或等于慢时钟域2个时钟周期。换做图中的Toggle信号来说,就是Toggle信号脉冲必须要维持两个慢时钟域周期。

为什么要对间隔有严格要求?

  • 因为如果快时钟域下的两个输入脉冲过近,则会使慢时钟域中同步后的两个输出脉冲紧密相连,输出时钟的宽度会比慢时钟域的单时钟宽度要宽。

3.结绳法处理单bit信号跨时钟域

上面所介绍的无论是慢时钟域到快时钟域,还是快时钟域到慢时钟域的处理方式,都具有比较严格的要求。而结绳法是一种适合任何时钟域的过渡的方式,下面将简单介绍一下结绳法来处理单比特信号的从快时钟域到慢时钟域。

原理:将快时钟域的信号脉冲展宽,等到慢时钟域的同步器采样后,再解绳将信号脉冲还原为原来的周期宽度。

如下,是典型的结绳法的电路结构:在这里插入图片描述
PS:以下代码参考:单比特跨时钟域一文。

module pusle_extend(
    input   clka,     //快时钟域
    input   clkb,	  //慢时钟域
    input   rstn,
    input   din,      //输入信号
    output  dout,     //输出信号
);
//--------------------------------------------------------
reg         din_reg;
reg			a1,a2; //同步到快时钟域
reg         q1,q2; //同步到慢时钟域

/**********************************************
*    慢时钟域内对信号脉冲展宽
**********************************************/
always @(posedge clka or negedge rst_n)begin
    if(!rst_n)begin
        din_reg <= 1'b0;
    end
    else if(din) begin     //检测信号有效
        din_reg <= 1'b1;   //信号展宽
    end
    else if(a2) begin      //同步到b后同步回a
        din_reg <= 1'b0;   //拉低,展宽使命完成
    end
end

/**********************************************
*    展宽信号同步到慢时钟域,再同步回快时钟域
**********************************************/
   //1.将展宽信号同步到慢时钟域
always @(posedge clkb or negedge rst_n)begin
    if(!rst_n)
        {q2,q1} <= 2{1'b0};
    else 
        {q2,q1} <= {q1,din_reg};
end
   //2.慢时钟域收到后,再把展宽结束的信号同步回快时钟域
always @(posedge clkb or negedge rst_n)begin
    if(!rst_n)
        {a2,a1} <= 2{1'b0};
    else 
        {a2,a1} <= {a1,q2};
end

/**********************************************
*   慢时钟域内同步的脉冲信号
**********************************************/
assign dout = ~q2 & q1;

endmodule

解释:

  1. 数据信号Din_clkA作为触发器的时钟,当数据信号脉冲的上升沿到来时,DFF1的输出将会稳定在高电平,此时等待慢时钟clkB的采样同步。
  2. 当clkB采样同步完成后,DFF4会输出高电平。若在DFF4输出高电平期间,此时Din_clkA为低电平,经过组合逻辑会给DFF1复位,开始下一次采样等待。

总结

  • 结绳法适合采样数据少(信号脉冲间隔大)的信号;
  • 脉冲间隔应该大于3个慢时钟域时钟周期(因为要同步打三拍);
  • 等待3拍后,才能完成复位,允许下一个输入脉冲同步。

这里解释一下为什么要大于3个慢时钟域时钟周期?当数据上升沿来临时,慢时钟clkB需要等待3拍才会在DFF4上输出高电平,并完成输入端触发器的复位。所以如果快时钟域下的数据信号Din_clkA 变化太快,持续时间短语3个clkB,那么Din_clkA 的变化就无法被采样到,同步出错。

二、多bit控制信号跨时钟域同步

多比特信号的跨时钟域传输不能通过简单的同步器同步打拍解决。比如下图,要想另一个时钟域同时传递两个信号(b_load和b_en),因为考虑到时钟偏斜(skew)的可能,将会导致两个信号在另一个时钟域出现一个时间差,这就与原来的逻辑不匹配了。
在这里插入图片描述
处理方法:

  • 如果两个信号可以合并,可以在原来的时钟域先将两个信号合并成一个脉冲信号,再进行跨时钟域传输。
  • 如果两个信号不能合并,如译码信号,可以加一个控制信号,在两个信号都稳定后,再通知另一个时钟域采样。

三、多bit数据流跨时钟域同步

数据流与多比特控制信号不同,因为数据流具有连续性(及背靠传输)。所以一般直接使用异步FIFO,调节上下游的数据吞吐量。

  • 38
    点赞
  • 258
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小verifier

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值