• 单bit脉冲信号跨时钟域处理——展宽信号 + 握手协议


    对于单比特数据,在慢时钟域到快时钟域的数据传输中,可以使用两级触发器进行同步,以此来解决跨时钟域问题。

    但在快时钟域到慢时钟域的数据传输中,因此只有当D1 在很长一段时间内为1或0,确保一定可以被clkb采样到,才能用两级触发器同步的方式来处理;如果快时钟域的脉冲信号的宽度小于慢时钟的周期,那么慢时钟很可能无法采样到(如下图),为了防止漏采样情况的出现,采用展宽信号的方式进行处理。
    在这里插入图片描述

    方法:
    1、在clka快时钟域中,对其中的脉冲信号 pulse_ina 进行展宽 signal_a —— 通过握手来确定展宽信号时候什么拉低

    注:在握手协议中,展宽信号相当于req,signal_a_r2相当于应答ack信号,来回应展宽信号req可以拉低了。

    2、有了展宽信号signal_a 后,将其同步到clkb慢时钟域中(打两拍以防止亚稳态),最终得到signal_b_r1。(通过上升沿检测,取一个周期的pulse_outb,此时则完成了数据从快时钟到慢时钟的传递)

    到此还没结束,因为握手任务还没完成,展宽信号的拉低(下降沿)还没确定

    3、将clkb慢时钟域中的signal_b_r1信号,同步到clka快时钟域中,以此作为快时钟域的反馈回应,也就是步骤1展宽信号拉低的使能。

    4、将clkb慢时钟域采样到的脉冲展宽信号 pulse_outb 输出。

    5、将clkb慢时钟域采样到的展宽信号 signal_outb 输出,等于signal_b_r1。

    在这里插入图片描述


    verilog代码:

    module Sync_Pulse
    (
        input   clka,//快时钟
        input   clkb,//慢时钟
        input   Rst_n,
        input   Pulse_a,      //快时钟域中的脉冲信号
    	 
        output  pulse_outb,     //脉冲信号
        output  signal_outb     //电平信号
    );
    
    reg signal_a;
    reg signal_b;
    reg signal_b_r1;
    reg signal_a_r1;
    reg signal_a_r2;
    
    //展宽信号
    always @ (posedge clka or negedge Rst_n)
        if(!Rst_n)
    	      signal_a <= 1'b0;
    	  else if(Pulse_a)
    	      signal_a <= 1'b1;
    	  else if(signal_a_r2)
    	      signal_a <= 1'b0;
    	  else
    	      signal_a <= signal_a;
    			
    //将展宽信号同步到慢时钟域,两拍
    always @ (posedge clkb or negedge Rst_n)
        if(!Rst_n) begin
    	        signal_b <= 1'b0;
    			signal_b_r1 <= 1'b0;
    			end
    	  else begin
    	        signal_b <= signal_a;
    			signal_b_r1 <= signal_b;
    			end
    			
    //将慢时钟域采集到的展宽信号,同步到快时钟域中
    //作为展宽信号结束的一个反馈
    
    always @ (posedge clka or negedge Rst_n)
        if(!Rst_n) begin
    	      signal_a_r1 <= 1'b0;
    			signal_a_r2 <= 1'b0;
    			end
    	  else begin
    	        signal_a_r1 <= signal_b_r1;
    			signal_a_r2 <= signal_a_r1;
    			end	
    			
    //检测上升沿,得到慢时钟域的输出脉冲信号
    		
    assign  pulse_outb =  signal_b & ~signal_b_r1;
    
    //输出电平信号,慢时钟域的展宽信号
    
    assign  signal_outb =  signal_b_r1;
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    tb测试代码:
    tb中快时钟域为100Mhz,慢时钟域为50Mhz的展宽信号测试与波形分析,以此和上面手画波形图进行分析

    `timescale 1ns/1ns
    `define clock_period 20
    
    module Sync_Pulse_tb;
    
        reg  clka = 1;//快时钟
        reg  clkb = 1;//慢时钟
        reg  Rst_n;
        reg  Pulse_a;      //快时钟域中的脉冲信号
    	 
        wire  pulse_outb;    //脉冲信号
        wire  signal_outb;     //电平信号
    	 
    
    
     Sync_Pulse u1(
     
        .clka(clka),//快时钟
        .clkb(clkb),//慢时钟
        .Rst_n(Rst_n),
        .Pulse_a(Pulse_a),      //快时钟域中的脉冲信号
    	 
        .pulse_outb(pulse_outb),     //脉冲信号
        .signal_outb(signal_outb)     //电平信号
    );
    
    
      always #(`clock_period/4) clka = ~clka;  //时钟周期是10ns,100MHZ
      always #(`clock_period/2) clkb = ~clkb;  //时钟周期是20ns,50MHZ
      
      initial begin
    	   Rst_n=0;
    	   Pulse_a=0;
    	
      #(`clock_period*20)
       Rst_n=1;
      #(`clock_period*5)
      Pulse_a = 1 ;
      #(`clock_period/2) 
      Pulse_a = 0 ;
       #(`clock_period*30)
      $stop;
      end
      
      endmodule 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    波形仿真:

    在这里插入图片描述


    给出如下题目:300Mhz到100Mhz,考察快时钟域到慢时钟域的单时钟脉冲信号传输。

    在这里插入图片描述
    不同在于clka和clkb,仅需要修改tb中生成的时钟,其余都相同,为保证精度,选用ps单位。

    `timescale 1ps/1ps
    
      always #1666  clka = ~clka;  //时钟周期是3ns,300MHZ
      always #5000 clkb = ~clkb;  //时钟周期是10ns,100MHZ
    
    • 1
    • 2
    • 3
    • 4

    波形如下,和之前同样分析即可。
    在这里插入图片描述

    总结:

    展宽的目的?
    防止漏采样。快时钟域中脉冲信号宽度可能小于慢时钟域的周期,因为慢时钟域可能采不到该脉冲信号。

    展宽到什么时候?
    首先在快时钟域进行展宽,将输入脉冲信号拉高,下降沿需要重点分析,下降沿需要根据 应答信号signal_a_r2 来确定。

    由于快时钟域的展宽信号到了慢时钟域中,防止亚稳态打两拍,此时即采样到了慢时钟域中的展宽信号 signal_b_r1,然后即可告知快时钟域,我已经采样到了脉冲信号,于是将 signal_b_r1,同步到快时钟域中(打两拍以防止亚稳态),来作为一个反馈应答signal_a_r2,用该信号告知请求展宽可以拉低了,得到展宽信号下降沿。

    最终得到的信号?
    慢时钟域的脉冲信号:对在慢时钟域打拍的两个展宽信号进行上升沿检测,即可得到慢时钟域的脉冲信号。
    慢时钟域的电平信号:也就是signal_b_r1。


    如有错误请指正!

  • 相关阅读:
    【Unity】ABB CRB 15000 外部引导运动
    springboot之二:整合junit进行单元测试+整合redis(本机、远程)+整合mybatis
    shell流程控制
    Go 语言学习总结(10)—— Go 初学者必知的十个命令
    SAGA GIS使用教程
    QDir类【官翻】
    Oracle管理表(创建、修改、删除)
    openssl+ SM2 + linux 签名开发实例(C++)
    AWS SAA-C03 #99
    MySQL概念
  • 原文地址:https://blog.csdn.net/H19981118/article/details/126331764