首页 > 其他分享 >设计一个单比特跨时钟域传输电路?从慢到快&从快到慢

设计一个单比特跨时钟域传输电路?从慢到快&从快到慢

时间:2023-08-04 09:56:55浏览次数:37  
标签:clk 从慢 比特 rst input out reg 时钟

Clock Domain Crossing (CDC) : 跨时钟域设计中,信号adat从aclk domain传播到bclk domain;aclk与bclk之间的频率,相位没有固定关系,为asynchronous异步关系的时钟。

分为单比特跨时钟域和多比特跨时钟域。

多比特跨时钟域:采用异步FIFO。

单比特跨时钟域:分为从慢到快,和从快到慢。

从慢到快:电平信号同步方法:一级寄存器产生亚稳态并经过自身后可以稳定输出的概率为70%~80%左右,第二级寄存器可以稳定输出的概率为99%左右,再后面改善就不明显了,所以数据进来后一般选择打两拍即可。

从快到慢:脉冲信号同步方法:快时钟域脉冲展宽+慢时钟域延迟打拍。注意:在快时钟域展宽的信号宽度必须是慢时钟域周期的1.5倍以上,须满足奈克斯特采样定理。

 

从慢到快的设计代码&激励&仿真波形

module  CDC
(
input     clk_1          ,
input     clk_2          ,
input     rst_n          ,
input     in             ,
output    out       
);
//跨时钟域  单比特传输  从慢到快   
//采用打两拍 即可采样

reg         out_ff0     ;
reg         out_ff1     ;
reg         out_ff2     ;



always@(posedge  clk_1 or negedge rst_n) begin 
    if(!rst_n)
        out_ff0<=1'b0;
    else 
        out_ff0<=in;
end 



always@(posedge  clk_2 or negedge rst_n) begin 
    if(!rst_n) begin 
        out_ff1<=1'b0;
        out_ff2<=1'b0;
    end 
    else begin 
        out_ff1<=out_ff0;
        out_ff2<=out_ff1; 
    end 
end 


assign out=out_ff2 ;

endmodule 
`timescale 1ns/1ns 
module tb_CDC();
reg     clk_1   ;
reg     clk_2   ;
reg     rst_n   ;
reg     in      ;
wire    out     ;



initial  begin
    clk_1<=1'b0;
    clk_2<=1'b0;
    rst_n<=1'b0;
    in<=1'b0;
    #20
    rst_n<=1'b1;
    #15
    in<=1'b1;
    #35
    in<=1'b0;
    #300
    in<=1'b1;
    #20
    in<=1'b0;
    #450
    in<=1'b1;
    #20
    in<=1'b0;
    #250
    in<=1'b1;
    #20
    in<=1'b0;
end 

always # 5   clk_2<=~clk_2 ;    //快时钟域
always # 10  clk_1<=~clk_1 ;    //慢时钟域


CDC  CDC_inst
(
.clk_1  (clk_1)        ,
.clk_2  (clk_2)        ,
.rst_n  (rst_n)        ,
.in     (in   )        ,
.out    (out  )    
);





endmodule 

从快到慢的设计代码&激励&仿真波形

module  CDC
(
input     clk_1          ,
input     clk_2          ,
input     rst_n          ,
input     in             ,
output    out       
);
//跨时钟域  单比特传输  从快到慢   
//先在快时钟域展宽  展宽为慢时钟域至少2个时钟周期 方便慢时钟采样
reg         in_ff0      ;  // 输入打一拍
reg         in_ff1      ;  // 输入打两拍
reg         in_data     ;  // 展宽寄存
reg         in_q1       ;  // 反馈信号 取消展宽
//reg         in_q2       ;
reg         out_ff1     ;  //慢时钟域打一拍
reg         out_ff2     ;  //慢时钟域打两拍
wire        in_pos      ;  //检测输入上升沿  表示一个脉冲输入


assign  in_pos =in_ff0&&(~in_ff1);  // 输入打两拍 检测输入上升沿 

always@(posedge  clk_1 or negedge rst_n) begin 
    if(!rst_n) begin 
        in_ff0<=1'b0;
        in_ff1<=1'b0;
    end 
    else  begin 
        in_ff0<=in;
        in_ff1<=in_ff0;
    end
end 

// 在快时钟域下 对脉冲信号展宽至反馈有效有效时拉低
always@(posedge clk_1 or negedge rst_n) begin 
    if(!rst_n)
        in_data<=1'b0;
    else if(in_pos)
        in_data<=1'b1;
    else if(in_q1)
        in_data<=1'b0;
end 

// 在慢时钟域下 对脉冲信号展宽采样 即打两拍 防止亚稳态产生
always@(posedge  clk_2 or negedge rst_n) begin 
    if(!rst_n) begin 
        out_ff1<=1'b0;
        out_ff2<=1'b0;
    end 
    else begin 
        out_ff1<=in_data;
        out_ff2<=out_ff1; 
    end 
end 

//在慢时钟域下 产生反馈信号 拉低展宽信号  
always@(posedge clk_2 or negedge rst_n)  begin
    if(!rst_n) begin 
        in_q1<=1'b0;
        //in_q2<=1'b0;
    end 
    else  begin 
        in_q1<=out_ff1;  //采用in_q1 为反馈信号 输出为2个慢时钟周期
        //in_q2<=in_q1;  //采用in_q2 为反馈信号 输出为3个慢时钟周期
    end 
end 


assign out=out_ff2 ;   //得到输出



endmodule 
`timescale 1ns/1ns 
module tb_CDC();
reg     clk_1   ;
reg     clk_2   ;
reg     rst_n   ;
reg     in      ;
wire    out     ;



initial  begin
    clk_1<=1'b0;
    clk_2<=1'b0;
    rst_n<=1'b0;
    in<=1'b0;
    #20
    rst_n<=1'b1;
    #15
    in<=1'b1;
    #35
    in<=1'b0;
    #300
    in<=1'b1;
    #20
    in<=1'b0;
    #450
    in<=1'b1;
    #20
    in<=1'b0;
    #250
    in<=1'b1;
    #20
    in<=1'b0;
end 

always # 5   clk_1<=~clk_1 ;    //快时钟域
always # 10  clk_2<=~clk_2 ;    //慢时钟域


CDC  CDC_inst
(
.clk_1  (clk_1)        ,
.clk_2  (clk_2)        ,
.rst_n  (rst_n)        ,
.in     (in   )        ,
.out    (out  )    
);





endmodule 

若有不对的地方,敬请指正,万分感谢。

参考资料:

1、跨时钟传输——单比特_单bit跨时钟_carrotbanana的博客-CSDN博客

标签:clk,从慢,比特,rst,input,out,reg,时钟
From: https://www.cnblogs.com/yhm1314/p/17604356.html

相关文章

  • c++控制台时钟显示时间
    在旧电脑上刷了ubuntu的服务器版本,开着的时候旧电脑(yoga)的屏幕就处于了无用的状态。为了更好的利用这个屏幕,简单使用c++写了一个显示时间的代码。由于这台yoga的屏幕是可以360翻转的,所以给时间的显示也增加了一点翻转功能。1#include<iostream>2#include<ctime>3#......
  • 记录--canvas 复刻锤子时钟
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助介绍canvas:使用脚本(通常为JavaScript)来绘制图形的HTML元素。本人遍历了以下两份文档,学习完就相当于有了笔和纸,至于最后能画出什么,则需要在canvas应用方面进一步学习。MDN的Canvas教程1张鑫旭的Ca......
  • 拆 大屏液晶电子时钟
    配置不错功能有温湿度,夜晚荧光、micro口充电、液晶数字够大观感还不错渣渣体验开关机或者没电后所有时间要重新设置。所谓充次电用半年一年就是狗屁,一周不到就完犊子,连着充电线用才是正道,不知道实在是吃电太多还是电池垃圾,所谓床头闹钟嘛要克服不少困难吧。 拆机原因电量......
  • CM4 systick 时钟源设置
    CM4systick时钟源设置起因之前离职的同事交接给我的项目里面timer2的配置错误让我决定修改他用到的每一个时钟的配置。systick时钟源设置方法systick的时钟源可以从两个地方选择。internal源external源TheCortexSystemTimer(SysTick)externalclockisclocked......
  • Microsoft Speech SDK 5.1 微软的文字转音频 ( 8KHZ 16比特 )
    下载安装 SpeechSDK5.1下载地址: http://www.microsoft.com/en-us/download/details.aspx?id=10121详细的看这篇 https://www.cnblogs.com/hailexuexi/p/17588586.htmlC#示例直接保存到wav文件并存为8KHZ  16比特 语音格式privatevoidbtnSave_Click(objectsen......
  • 大实验2:用DS1302时钟芯片设计一个高精度时钟
    需求:1.在LCD1602上面显示年,月,日,星期,时,分,秒,并且按秒更新动态显示2.4个独立按键各有各的功能,按键1能够实现进入暂停;按键2实现数值增大;按键3实现数值减小;按键4设定为功能选择键3.具有闹钟设定以及到时报警功能,报警响起时,按任何按键均可以取消报警完成:1.根据DS1302的特性,读取DS13......
  • 05. STM32F1的时钟树
    一、STM32的时钟树二、时钟源  对于STM32F1,输入时钟源(InputClock)主要包括HSI,HSE,LSI,LSE。其中,从时钟频率来分可以分为高速时钟源和低速时钟源,其中HSI、HSE是高速时钟,LSI和LSE是低速时钟。从来源可分为外部时钟源和内部时钟源,外部时钟源就是从外部通过接晶振......
  • 【FPGA基础】时钟设计与异步复位同步撤离设计
    一、时钟设计1、时钟分频设计累加器时钟分频(32分频)always@(posedgeclkandnegedgerst_n)beginif(!rst_n)clk_cnt<=5'b0;elseclk_cnt<=clk_cnt+1'b1;end 异步时钟分频(32分频)always@(posedgeclk)clk_2<=~clk_2;alwa......
  • Si5351时钟芯片控制
    Si5351一、SI5351频率计算公式:f(out)=f(pl......
  • Azure VM (43) Azure VM时钟同步
    《WindowsAzurePlatform系列文章目录》 本文主要介绍AzureLinuxVM时钟同步问题在CentOS8.x上,默认采用chrony配置为使用PTP源同步。Chrony所选时间来源是可以配置的,你可以选择让他从Azure物理机进行时间同步(也就是通过PTP时钟)。具体可以参考:https://l......