跨时钟域相关的知识点

模块之间有数据交互,但是用的不是一个时钟进行驱动,存在相位与频率的不同,由于电路本身的特性(中间态存在时间长),在同一时刻不同元器件对同一信号的判断出现不一致现象,称为亚稳态。这就需要同步器进行同步,减小亚稳态传播下去的概率。

跨时钟域:模块之间有数据交互,但是用的不是同一个时钟进行驱动。

在跨时钟处理单bit信号时,慢时钟域到快时钟域下的处理方式比较简单,将在慢时钟域下的信号在快时钟域下打三拍处理,取二拍与三拍信号进行处理,将慢时钟域的信号分解为在快时钟域下的上升沿脉冲信号与下降沿脉冲信号。

//将慢时钟域下的信号能在快时钟域下采集
//clka为快时钟、clkb为慢时钟
module slow2quick (
                  // input
                  input rst_n              , // system reset
                  input clka               , // clockA
                  input clkb               , // clockB
                  input level_a_in         , // pulsee input from clka
                  // output
                  output pulse_b_neg     , // pulsee output in clkb
                  output pulse_b_pos     , // pulsee output in clkb
                  output level_b_out        // level output in clkb
                  );
 
parameter         DLY      =  1   ; //
 
reg level_b_d1, level_b_d2, level_b_d3;
 

//
always @ (posedge clka or negedge rst_n)
begin
    if (!rst_n) begin
       level_b_d1 <= #DLY 1'b0;
       level_b_d2 <= #DLY 1'b0;
       level_b_d3 <= #DLY 1'b0;
    end
    else begin
       level_b_d1 <= #DLY level_a_in;
       level_b_d2 <= #DLY level_b_d1;
       level_b_d3 <= #DLY level_b_d2;
    end
end
 
assign pulse_b_pos = level_b_d2 & (~level_b_d3);
assign pulse_b_neg = level_b_d3 & (~level_b_d2);
assign level_b_out  = level_b_d2;
 
endmodule

在跨时钟域处理单bit信号时,快时钟域的信号由于频率较快,信号的脉宽如果不足,就不会被慢时钟采样到,因此需要将快时钟产生的信号进行展宽,然后在进行打两拍来处理亚稳态。具体处理方式如下:

快到慢时钟域

//目的:使在clka下的脉冲信号pluse_a_in也能在clkb下采集到
module quick2slow (
                  // input
                  input rst_n              , // system reset
                  input clka               , // clockA
                  input clkb               , // clockB
                  input pulse_a_in          , // pulsee input from clka
                  // output
                  output pulse_b_out        , // pulsee output in clkb
                  output level_b_out        // level output in clkb
                  );
 
parameter         DLY      =  1   ; //模拟真实电路加入DLY
 
reg signal_a;
reg signal_b;
reg signal_b_b1;
reg signal_b_b2;
reg signal_b1_a1;
reg signal_b1_a2;
 //对脉冲信号进行展宽处理
//引入signsl_a作为展宽信号,脉冲信号为1时拉高signal_a,signal_b1_a2为1时拉低signal_a,
//signal_b1_a2在后边进行定义
always @ (posedge clka or negedge rst_n)
begin
    if (rst_n == 1'b0)
        signal_a <= # DLY 1'b0 ;
    else if (pulse_a_in)
        signal_a <= # DLY 1'b1 ;
    else if (signal_b1_a2)
        signal_a <= # DLY 1'b0 ;
    else ;
end
//将展宽后的信号signal_a引入到clkb下,定义为signal_b
always @ (posedge clkb or negedge rst_n)
begin
    if (rst_n == 1'b0)
        signal_b <= # DLY 1'b0 ;
    else
        signal_b <= # DLY signal_a ;
end
 //在clkb下对signal_b打一拍得到signal_b_b1,
//在clkb下对signal_b打二拍得到signal_b_b2,
always @ (posedge clkb or negedge rst_n)
begin
    if (rst_n == 1'b0) begin
        signal_b_b1 <= # DLY 1'b0 ;
        signal_b_b2 <= # DLY 1'b0 ;
    end
    else begin
        signal_b_b1 <= # DLY signal_b ;
        signal_b_b2 <= # DLY signal_b_b1 ;
    end
end
//确定signal_a的信号下降沿
//选取 signal_b_b1作为signal_a的下降沿,但是他是在clkb下的信号,而signal_a是clka下的信号,可能存在踩不到的现象,因此对signal_b_b1在clka下同步打两拍得到signal_b1_a2
always @ (posedge clka or negedge rst_n)
begin
    if (rst_n == 1'b0) begin
        signal_b1_a1 <= # DLY 1'b0 ;
        signal_b1_a2 <= # DLY 1'b0 ;
    end
    else begin
        signal_b1_a1 <= # DLY signal_b_b1 ;
        signal_b1_a2 <= # DLY signal_b1_a1 ;
    end
end
 
assign pulse_b_out = signal_b_b1 & (~signal_b_b2) ;
assign level_b_out = signal_b_b1 ;
 
endmodule

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值