当前位置: 首页 > news >正文

紫金建设公司官网太原建站seo

紫金建设公司官网,太原建站seo,做外贸需要关注的网站有什么,北京网站优化步文章目录 一、为什么要做跨时钟域处理二、单bit信号从慢时钟到快时钟处理2.1 使用同步寄存器链(打两拍)2.2 仿真代码编写2.3 仿真结果观察 三、单bit信号从快时钟域到慢时钟域处理3.1 使用脉冲展宽3.2 仿真代码编写3.3 仿真结果观察 四、在任意时钟域跨单bit信号4.1 使用握手协…

文章目录

  • 一、为什么要做跨时钟域处理
  • 二、单bit信号从慢时钟到快时钟处理
    • 2.1 使用同步寄存器链(打两拍)
    • 2.2 仿真代码编写
    • 2.3 仿真结果观察
  • 三、单bit信号从快时钟域到慢时钟域处理
    • 3.1 使用脉冲展宽
    • 3.2 仿真代码编写
    • 3.3 仿真结果观察
  • 四、在任意时钟域跨单bit信号
    • 4.1 使用握手协议传输单bit脉冲信号
    • 4.2 从快到慢仿真代码编写
    • 4.3 从快到慢仿真结果观察
    • 4.4 从慢到快仿真结果观察
  • 五、多bit数据跨时钟域


一、为什么要做跨时钟域处理

  在之前的文章《FPGA静态时序分析与约束(一)、理解亚稳态》中,我知道了什么是亚稳态以及亚稳态对系统的危害。通常我们的系统工程中不止有一个处理时钟,当不同时钟域下的信号进行交互的时候就涉及到跨时钟域的问题了。由于不同时钟的频率、相位都可能不同,所以就存在目标时钟在采集源时钟域信号时发生亚稳态情况,如下图所示:

在这里插入图片描述
  此时源时钟域下的信号变化刚好在目标时钟域的上升沿建立或保持时间范围内,因此发生了建立或保持时间违规从而造成亚稳态的输出。因此我们必须对这种情况进行处理,处理方式分为三种情况:

  1. 单bit信号从慢时钟到快时钟
  2. 单bit信号从快时钟到慢时钟
  3. 多bit信号跨时钟域

二、单bit信号从慢时钟到快时钟处理

2.1 使用同步寄存器链(打两拍)

  在快时钟域频率高于慢时钟域时,理论上一个慢时钟域周期的信号可以百分百被快时钟采集到,为了防止亚稳态的产生可以通过打两拍的方式处理,如下图所示:

在这里插入图片描述
  就算第一级寄存器产生了亚稳态,但是经过自身寄存器输出后能够使信号快速回落至稳定状态,稳定输出的概率为70%~80%左右,第二级寄存器可以稳定输出的概率为99%左右,再后面改善就不明显了,所以一般情况下进行两级寄存就能消除大多数情况下的亚稳态。代码如下:

`timescale 1ns / 1ps
module single_bit_slow2fast(input                                               i_signal_a      ,   //慢时钟域的信号input                                               i_clk_b         ,   //快时钟input                                               i_rst_b         ,   //快时钟域复位信号,高电平有效       output                                              o_signal_b      ,   //快时钟域同步后的信号output                                              o_signal_b_pos  ,   //同步后的信号上升沿output                                              o_signal_b_neg      //同步后的信号下降沿
);reg                                                 r_signal_a_d1   ;
reg                                                 r_signal_a_d2   ;
reg                                                 r_signal_a_d3   ;       //再打一拍是用最稳定的两拍检测边沿信号assign      o_signal_b      = r_signal_a_d2;
assign      o_signal_b_pos  = r_signal_a_d2 & (~r_signal_a_d3);
assign      o_signal_b_neg  = (~r_signal_a_d2) & r_signal_a_d3;always @(posedge i_clk_b or posedge i_rst_b) beginif(i_rst_b == 1'b1)beginr_signal_a_d1 <= 1'b0;r_signal_a_d2 <= 1'b0;r_signal_a_d3 <= 1'b0;endelse beginr_signal_a_d1 <= i_signal_a;r_signal_a_d2 <= r_signal_a_d1;r_signal_a_d3 <= r_signal_a_d2;end
endendmodule

2.2 仿真代码编写

  仿真代码产生两个不同快慢时钟,以及慢时钟域的信号,代码如下:

`timescale 1ns / 1ns
module tb_single_bit_slow2fast();reg                                                 i_clk_b ;reg                                                 clk_a   ;reg                                                 i_rst_b ;reg                                                 i_signal_a  ;initial begini_clk_b = 0;clk_a = 0;i_rst_b = 1;i_signal_a = 0;#300 @(posedge i_clk_b) i_rst_b = 0;
endalways #2  i_clk_b = ~ i_clk_b; 
always #15 clk_a = ~clk_a;always @(posedge clk_a) beginrepeat(20)begini_signal_a <= {$random}%2;#30i_signal_a <= 0;#200;end
endsingle_bit_slow2fast u_single_bit_slow2fast(.i_signal_a      ( i_signal_a      ),.i_clk_b         ( i_clk_b         ),.i_rst_b         ( i_rst_b         ),.o_signal_b      ( o_signal_b      ),.o_signal_b_pos  ( o_signal_b_pos  ),.o_signal_b_neg  ( o_signal_b_neg  )
);endmodule

2.3 仿真结果观察

在这里插入图片描述
  从仿真来看,慢时钟信号无论什么时候发送,快时钟依然能采集到。

三、单bit信号从快时钟域到慢时钟域处理

3.1 使用脉冲展宽

   对于快时钟域的信号让慢时钟来采集,不能使用打两拍来处理,因为快时钟信号宽度太小很可能慢时钟采集不到,如下图这种情况:

在这里插入图片描述
   在这种情况下,我们可以将快时钟下的信号进行展宽至慢时钟能采集到为止,然后再用慢时钟打两拍进行同步处理,如下所示:

在这里插入图片描述
  具体展宽多长,需要看两个时钟频率之间的比值,例如快时钟频率是175.5M,慢时钟是27M,快慢时钟之比=6.5,所以要将快时钟的脉冲展宽至7个时钟周期宽度才能确保被慢时钟采到。代码如下:

`timescale 1ns / 1ps
module single_bit_fast2slow#
(parameter CLKA_FPQ = 100_000_000,parameter CLKB_FPQ = 33_000_000
)
(input                                               i_clk_a     ,   //快时钟input                                               i_rst_a     ,   //快时钟域复位信号,高电平有效input                                               i_signal_a  ,   //快时钟脉冲信号input                                               i_clk_b     ,   //慢时钟input                                               i_rst_b     ,   //慢时钟复位信号,高电平有效output                                              o_signal_b      //慢时钟同步后的信号
);localparam                                          CLK_NUM = CLKA_FPQ / CLKB_FPQ;/***********a时钟域*******************/ reg             [7:0]                               clk_cnt         ;   //快时钟域下的计数器
reg                                                 r_i_signal_a    ;   //需要展宽的信号always @(posedge i_clk_a) beginif(i_rst_a)r_i_signal_a <= 1'b0;else if(clk_cnt == CLK_NUM)r_i_signal_a <= 1'b0;else if(i_signal_a == 1'b1)r_i_signal_a <= 1'b1;elser_i_signal_a <= r_i_signal_a;
endalways @(posedge i_clk_a) beginif(i_rst_a)clk_cnt <= 'd0;else if(clk_cnt == CLK_NUM)clk_cnt <= 'd0;else if(r_i_signal_a == 1'b1)clk_cnt <= clk_cnt + 1'b1;elseclk_cnt <= 'd0;
end/******************b时钟域**************/
reg                                                 r_signal_b1  ;
reg                                                 r_signal_b2  ;assign o_signal_b = r_signal_b2;always @(posedge i_clk_b) beginif(i_rst_b)beginr_signal_b1 <= 1'b1;r_signal_b2 <= 1'b1;endelse beginr_signal_b1 <= r_i_signal_a;r_signal_b2 <= r_signal_b1;endendendmodule

3.2 仿真代码编写

`timescale 1ns / 1nsmodule tb_single_bit_fast2slow();reg i_clk_a;
reg i_rst_a;
reg i_signal_a;
reg i_clk_b;
reg i_rst_b;initial begini_clk_a = 0;i_rst_a = 1;i_clk_b = 0;i_rst_b = 1;#150i_rst_a = 0;#100i_rst_b = 0;   
endalways#5   i_clk_a = ~i_clk_a;
always#15  i_clk_b = ~i_clk_b;always @(posedge i_clk_a) beginif(i_rst_a == 1'b1)i_signal_a <= 1'b0;else begini_signal_a <= {$random}%2;#10;i_signal_a <= 1'b0;#100;endendsingle_bit_fast2slow#(.CLKA_FPQ    ( 100_000_000 ),.CLKB_FPQ    ( 30_000_000 )
)u_single_bit_fast2slow(.i_clk_a     ( i_clk_a     ),.i_rst_a     ( i_rst_a     ),.i_signal_a  ( i_signal_a  ),.i_clk_b     ( i_clk_b     ),.i_rst_b     ( i_rst_b     ),.o_signal_b  ( o_signal_b  )
);endmodule

3.3 仿真结果观察

在这里插入图片描述
  仿真设置快时钟频率为100M,慢时钟频率为30M,因此需要将脉冲宽度展宽四个快时钟周期,然后慢时钟再打两拍同步一下,由仿真结果观察结果正确,我们下面将快时钟设置为500M,结果如下:

在这里插入图片描述
  由上面可以看出,快时钟为500M,慢时钟为30M依然也能正确的采集到快时钟的脉冲信号。

四、在任意时钟域跨单bit信号

  前面两种情况,我们实现了单bit时钟从快到慢,或者从慢到快时钟之间的传输。除了使用以上两种方式外,我们还可以通过握手信号来实现任意时钟域之间的单bit信号传输。

4.1 使用握手协议传输单bit脉冲信号

  从A时钟域向B时钟域传输脉冲信号,可以在A时钟检测脉冲信号,然后随即拉高一个valid信号,直到B时钟检测到valid信号后拉高一个周期的同步信号,同时给出ack信号,然后A时钟检测到ack信号后,拉低valid信号表示一次传输完成。

在这里插入图片描述
  代码如下:

`timescale 1ns / 1ps
module single_bit_handshake#
(parameter CLKA_FPQ = 100_000_000,parameter CLKB_FPQ = 20_000_000
)
(input                                               i_clk_a     ,   //A时钟input                                               i_rst_a     ,   //A时钟域复位信号,高电平有效input                                               i_signal_a  ,   //A时钟脉冲信号input                                               i_clk_b     ,   //B时钟input                                               i_rst_b     ,   //B时钟复位信号,高电平有效output                                              o_signal_b      //B时钟同步后的信号
);localparam                                          CLK_NUM = (CLKA_FPQ >= CLKB_FPQ) ? 1 : (CLKB_FPQ / CLKA_FPQ);/****************A时钟域*********************/
reg                                                 r_signal_a_valid    ;
reg                                                 r_ack_a1            ;
reg                                                 r_ack_a2            ;
/****************B时钟域*********************/
reg                                                 r_signal_b1         ;
reg                                                 r_signal_b2         ;
reg                                                 r_signal_b3         ;
reg                                                 r_signal_b_ack      ;
reg             [7:0]                               r_clk_cnt_b         ;assign o_signal_b   = r_signal_b3;/****************A时钟域*********************/
always @(posedge i_clk_a) beginif(i_rst_a == 1'b1)r_signal_a_valid <= 1'b0;else if(r_ack_a2 == 1'b1)r_signal_a_valid <= 1'b0;else if(i_signal_a == 1'b1)r_signal_a_valid <= 1'b1;elser_signal_a_valid <= r_signal_a_valid;
endalways @(posedge i_clk_a) beginif(i_rst_a == 1'b1)beginr_ack_a1 <= 1'b0;r_ack_a2 <= 1'b0;endelse beginr_ack_a1 <= r_signal_b_ack;r_ack_a2 <= r_ack_a1;endend/****************B时钟域*********************/
always @(posedge i_clk_b) beginif(i_rst_b == 1'b1)beginr_signal_b1 <= 1'b0;r_signal_b2 <= 1'b0; endelse if(r_signal_a_valid == 1'b1)beginr_signal_b1 <= 1'b1;r_signal_b2 <= r_signal_b1;endelse beginr_signal_b1 <= 1'b0;r_signal_b2 <= 1'b0;end
endalways @(posedge i_clk_b) beginif(i_rst_b == 1'b1)r_signal_b3 <= 1'b0;else if((r_signal_b1 ==1'b1)&&(r_signal_b2 == 1'b0))r_signal_b3 <= 1'b1;elser_signal_b3 <= 1'b0;
endalways @(posedge i_clk_b) beginif(i_rst_b == 1'b1)r_signal_b_ack <= 1'b0;else if(r_clk_cnt_b == CLK_NUM)r_signal_b_ack <= 1'b0;else if((r_signal_b1 ==1'b1)&&(r_signal_b2 == 1'b0))r_signal_b_ack <= 1'b1;elser_signal_b_ack <= r_signal_b_ack;
endalways @(posedge i_clk_b) beginif(i_rst_b == 1'b1)r_clk_cnt_b <= 'd0;else if(r_clk_cnt_b == CLK_NUM)r_clk_cnt_b <= 'd0;else if(r_signal_b_ack == 1'b1)r_clk_cnt_b <= r_clk_cnt_b + 1'b1;elser_clk_cnt_b <= 'd0;
endendmodule

4.2 从快到慢仿真代码编写

  先设置从快时钟到慢时钟

`timescale 1ns / 1ps
module tb_single_bit_handshake();reg i_clk_a;
reg i_rst_a;
reg i_signal_a;
reg i_clk_b;
reg i_rst_b;initial begini_clk_a = 0;i_rst_a = 1;i_clk_b = 0;i_rst_b = 1;#150i_rst_a = 0;#100i_rst_b = 0;   
endalways#1   i_clk_a = ~i_clk_a;
always#15  i_clk_b = ~i_clk_b;always @(posedge i_clk_a) beginif(i_rst_a == 1'b1)i_signal_a <= 1'b0;else begini_signal_a <= {$random}%2;#2;i_signal_a <= 1'b0;#100;endendsingle_bit_handshake#(.CLKA_FPQ    ( 500_000_000 ),.CLKB_FPQ    ( 30_000_000 )
)u_single_bit_handshake(.i_clk_a     ( i_clk_a     ),.i_rst_a     ( i_rst_a     ),.i_signal_a  ( i_signal_a  ),.i_clk_b     ( i_clk_b     ),.i_rst_b     ( i_rst_b     ),.o_signal_b  ( o_signal_b  )
);endmodule

4.3 从快到慢仿真结果观察

在这里插入图片描述
  由图可看出,从500M的快时钟到30M的慢时钟能成功传输。

4.4 从慢到快仿真结果观察

  将仿真代码的AB时钟互换一下,变成从30M慢时钟传输到500M快时钟,仿真代码如下:

`timescale 1ns / 1ps
module tb_single_bit_handshake();reg i_clk_a;
reg i_rst_a;
reg i_signal_a;
reg i_clk_b;
reg i_rst_b;initial begini_clk_a = 0;i_rst_a = 1;i_clk_b = 0;i_rst_b = 1;#150i_rst_a = 0;#100i_rst_b = 0;   
endalways#15   i_clk_a = ~i_clk_a;
always#1  i_clk_b = ~i_clk_b;always @(posedge i_clk_a) beginif(i_rst_a == 1'b1)i_signal_a <= 1'b0;else begini_signal_a <= {$random}%2;#30;i_signal_a <= 1'b0;#100;endendsingle_bit_handshake#(.CLKA_FPQ    ( 30_000_000 ),.CLKB_FPQ    ( 500_000_000 )
)u_single_bit_handshake(.i_clk_a     ( i_clk_a     ),.i_rst_a     ( i_rst_a     ),.i_signal_a  ( i_signal_a  ),.i_clk_b     ( i_clk_b     ),.i_rst_b     ( i_rst_b     ),.o_signal_b  ( o_signal_b  )
);endmodule

仿真结果如下:

在这里插入图片描述
  由图可以看出,从慢时钟到快时钟依然能够同步成功。值得注意的是,前面这几种单bit跨时钟处理方法不适合连续的触发信号,如果需要同步连续的脉冲信号,则需要考虑使用异步fifo或者ram。

五、多bit数据跨时钟域

  对于多bit情况,设计者必须习惯于采用例如双时钟 FIFO 这样的电路(DCFIFO)来存取数据和进行握手。FIFO 逻辑仅使用同步器传输转换两个时钟域之间的控制信号,而数据的读和写则使用双端口的存储器,具体FIFO的使用参考《详解Xilinx Native FIFO的使用以及RST复位的注意事项》。

http://www.15wanjia.com/news/6757.html

相关文章:

  • 用bootstrap做的外国网站上海做网络口碑优化的公司
  • 用ip做网站制作网页设计公司
  • 做vip兼职设计师的网站有哪些百度搜索关键词规则
  • 网站建设的销售怎么做seo的名词解释
  • 一个工程项目的整个流程石家庄seo
  • 网站如何看是哪家公司做的推广注册app赚钱平台
  • 做网站被骗了怎么办百度公司官网入口
  • 北京市工程建设信息交易网站资源优化排名网站
  • 外国做水吧设计的网站深圳网络营销模式
  • 婚纱网站模板下载百度竞价推广出价技巧
  • 网站投诉平台查权重
  • 网站客服管理系统广东云浮疫情最新情况
  • it运维公司石家庄seo优化公司
  • 网站排名不稳定seo研究所
  • 郑州做网站哪家好熊掌号旺道seo推广
  • 网站开发代做百度刷首页怎么刷
  • 做空压机网站的公司有哪些千川推广官网
  • 成都广告设计制作公司搜索引擎优化论文
  • 电商网站模板html合肥seo推广外包
  • 长宁区网站建设网站网站域名ip查询
  • 医疗网站平台建设方案网站开通
  • 如何自己做网站赚钱磁力猫官网cilimao
  • 如何做视频会员网站企业互联网推广
  • 湖北营销型网站建设价格市场营销十大经典案例
  • 网站上哪个做相片书好域名注册商
  • 专门做图片剪影的网站宁波seo排名优化哪家好
  • 网站加强阵地建设与管理全网seo优化电话
  • 2免费做网站google play下载安装
  • 丰台做网站公司常见网络营销推广方法
  • 哪些网站可以做兼职设计师深圳网站开发制作