ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

控制信号(单脉冲信号)的跨时钟域传输问题

2021-04-15 15:01:44  阅读:249  来源: 互联网

标签:end rr signal pulse 单脉冲 信号 rst 时钟


控制信号(单脉冲信号)的跨时钟域传输问题存在两种情况,一种是从快时钟域到慢时钟域传输,如果用慢时钟强行采样快时钟域内的控制信号,可能存在采样不到信号的情况,而且很大概率采不到信号;另一种情况是从慢时钟域到快时钟域的控制信号传输问题,这种情况,快时钟一定能采样到慢时钟域内的控制信号,但是可能出现亚稳态问题;

下面针对这两种情况进行处理:

快时钟到慢时钟
有两个时钟域A和B,脉冲a在时钟域A中保持一个时钟周期,现要把脉冲A同步到时钟域B中,试用D触发器、与门、或门、非门以及异或门画出电路图实现这个功能。(某发科IC现场笔试题)

先考虑从快时钟域到慢时钟域进行信号传输的问题(脉冲宽度小于一个时钟):

先通过Verilog来实现:(参考链接)

module Sync_Pulse(
    input           clka,
    input           clkb,
    input           rst_n,
    input           pulse_ina,
    output          pulse_outb,
    output          signal_outb
);
//-------------------------------------------------------
reg             signal_a;
reg             signal_b;
reg             signal_b_r;
reg             signal_b_rr;
reg             signal_a_r;
reg             signal_a_rr;
//-------------------------------------------------------
//在clka下,生成展宽信号signal_a
always @(posedge clka or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        signal_a <= 1'b0;
    end
    else if(pulse_ina == 1'b1)begin
        signal_a <= 1'b1;
    end
    else if(signal_a_rr == 1'b1)
        signal_a <= 1'b0;
    else 
        signal_a <= signal_a;
end
//-------------------------------------------------------
//在clkb下同步signal_a
always @(posedge clkb or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        signal_b <= 1'b0;
    end
    else begin
        signal_b <= signal_a;
    end
end
//-------------------------------------------------------
//在clkb下生成脉冲信号和输出信号
always @(posedge clkb or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        signal_b_r <= 'b0;
        signal_b_rr <= 'b0;
    end
    else begin
        signal_b_rr <= signal_b_r;
        signal_b_r <= signal_b;
    end
end
assign    pulse_outb = ~signal_b_rr & signal_b_r;
assign    signal_outb = signal_b_rr;
//-------------------------------------------------------
//在clka下采集signal_b_rr,生成signal_a_rr用于反馈拉低signal_a
always @(posedge clka or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        signal_a_r <= 'b0;
        signal_a_rr <= 'b0;
    end
    else begin
        signal_a_rr <= signal_a_r;
        signal_a_r <= signal_b_rr;
    end
end
endmodule
本题需要输出的信号其实是pulse_outb,这个信号在时钟域B中持续了一个时钟,通过边沿检测实现的。

经过Quartus生成的RTL原理图如下:

经过Vivado生成的RTL原理图如下:

可见,大同小异。

可是到这里并没有结束,这种电路图和题目要求的还不一样,人家没要求用多路选择器呀,所以需要将反馈后的多路选择器换成需要的器件。

参考图片来源

需要画出的原理图如下:

上面电路的实现,是快时钟域到慢时钟域的问题,我们通过反馈信号进行控制信号的延时来让慢时钟域充分采样得到控制信号,本质上是也是对控制信号的延时。这个延时的具体实现,需要对控制信号的产生逻辑进行处理,来满足延时的要求。

为什么上面的电路能实现,我们来仿真看看:

pulse_ina为快时钟域的控制信号,signal_a为pulse_ina的脉冲展宽信号,signal_b为慢时钟对脉冲展宽信号的采样,signal_b_r,signal_b_rr分别为signal_b的延迟,一拍,二拍。

signal_a_r为反馈信号,同理signal_a_rr是最直接的反馈信号,它决定pulse_ina的脉冲展宽的停止。

pulse_outb为慢时钟的控制脉冲输出,也是最后需要的结果。

给出测试文件:

 
`timescale 1ns/1ps
 
module CLK_Fast2Slow_TB();
    reg clka;
    reg clkb;
    reg rst_n;
    reg pulse_ina;
    wire pulse_outb;
    wire signal_outb;
    
    
    initial begin
        clka = 0;
        forever
        #2 clka = ~clka;
    
    end
    
    initial begin
        clkb = 0;
        forever 
        #4 clkb = ~clkb;
    end
    
    initial begin
    
    rst_n = 0;
    pulse_ina = 0;
    # 10 
    rst_n = 1;
    #4
    pulse_ina = 1;
    #4
    pulse_ina = 0;
    
    end
    
    Sync_Pulse INST_CLK_Fast2Slow(
    .clka(clka),
    .clkb(clkb),
    .rst_n(rst_n),
    .pulse_ina(pulse_ina),
    .pulse_outb(pulse_outb),
    .signal_outb(signal_outb)
    
    );
    
 
endmodule
 
慢时钟域到快时钟域
在慢时钟域到快时钟域传输的问题则不必如此麻烦,因为快时钟域总能采样到慢时钟域的脉冲信号,唯一需要注意的是,采样的信号会出现亚稳态的问题,如快时钟域信号的上升沿恰好对应慢时钟域脉冲的变化位置,导致建立时间不满足。

为了解决这个问题,我们只需要用快时钟对慢时钟域脉冲进行两级寄存器同步即可,这样基本就解决了亚稳态的问题了。

参考代码

module Sync_Pulse(
        input           clkb,
        input           rst_n,
        input           pulse_ina,
        output          pulse_outb
    );
    
    reg    signal_r;
    reg signal_rr;
    
    always @ (posedge clkb or negedge rst_n)
        if (!rst_n) begin
           signal_r <= 1'b0;
           signal_rr <= 1'b0;
        end else begin
           signal_r <= pulse_ina;
           signal_rr <= signal_r;
        end
    assign pulse_outb = signal_rr;
endmodule
除了上面的参考链接外,在加几个可以参考:

https://mp.weixin.qq.com/s/QoLAV2NBi4_8mQ5bJ_4MAw
 

标签:end,rr,signal,pulse,单脉冲,信号,rst,时钟
来源: https://blog.csdn.net/yundanfengqing_nuc/article/details/115724718

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有