跨时钟域处理(四)----脉冲展宽同步

我们知道,在单比特信号的跨时钟域传输时,如果是从慢时钟域到快时钟域,那么我们可以采用打两拍的方式。然而,这个方法在快时钟域传输到慢时钟域时并不可行,因为如果快时钟域的该信号的宽度小于慢时钟的周期,那么慢时钟很可能无法采样到,如下图所示:
在这里插入图片描述
为了解决这个问题,一个自然的想法就是将signal_a信号展宽,保证能被慢时钟域采样到,具体的方法是:每当快时钟域clka检测到Signal_a脉冲信号为高时,让wide_a信号取反,使得Signal_a的第一个脉冲变为wide_a信号的上升沿,Signal_a的第二个脉变为wide_a信号的下降沿。这样就使快速时钟域clka的脉冲信号Signal_a展宽之后在慢速时钟域clkb中能够被采集到。在接收方,慢时钟将wide_a打两拍同步到慢速时钟域clkb,再通过双边缘检测将wide_b2转换为脉冲信号。
整个过程如下图所示:
在这里插入图片描述
RTL代码实现:
发送端:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/03/08 10:38:57
// Design Name: 
// Module Name: ont_bit_sync
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module ont_bit_sync(
input logic clka,
input logic rst,
input logic pluse_a,
output logic wide_a
    );
always@(posedge clka,posedge rst)
if(rst)
    wide_a<=0;
else if(pluse_a)               
    wide_a<=~wide_a;
endmodule

接收端:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/03/08 10:41:32
// Design Name: 
// Module Name: one_bit_sync_recv
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module one_bit_sync_recv(
input logic clkb,
input logic rst,
input logic wide_a,
output logic pluse_b
    );

logic a_ff1;
logic a_ff2;
logic a_ff3;
always_ff@(posedge clkb,posedge rst)
if(rst)
    {a_ff3,a_ff2,a_ff1}<=3'b000;
else
    {a_ff3,a_ff2,a_ff1}<={a_ff2,a_ff1,wide_a};           //对wide信号打两拍同步,第三拍用于边沿检测
//边沿检测
assign pluse_b=a_ff3^a_ff2;
endmodule

测试平台

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/03/08 10:45:00
// Design Name: 
// Module Name: test_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module test_tb(

    );
logic clka;
logic clkb;
logic pluse_a;
logic pluse_b;
logic wide_a;
logic rst;
logic [31:0] cnt;
//
initial begin
    clka=0;
    forever begin
        #5 clka=~clka;
    end
end
//
initial
begin
    clkb=0;
    forever begin
        #17 clkb=~clkb;
    end
end
//rst
initial
begin
    rst=1;
    #50
    rst=0;
end
always_ff@(posedge clka,posedge rst)
if(rst)
    cnt<=0;
else
    cnt<=cnt+1;
//pluse_a
always_ff@(posedge clka,posedge rst)
if(rst)
    pluse_a<=0;
else if(cnt==13||cnt==23||cnt==31)
    pluse_a<=1;
else
    pluse_a<=0;


ont_bit_sync U1(.*
// input logic clka,
// input logic rst,
// input logic pluse_a,
// output logic wide_a
    );
//

one_bit_sync_recv U2(.*
// input logic clkb,
// input logic rst,
// input logic wide_a,
// output logic pluse_b
    );
endmodule

波形展示:
在这里插入图片描述
然而,该方法仍然存在一些问题:相邻两个输入脉冲的间隔至少是两个同步器时钟(clkb)周期才行,否则wide_a不够两个clkb周期,两个脉冲同步过来之后,中间的跳变沿就会消失,即下图中红框会消失,从而无法检测到边沿,导致最终无法区分pluse_a的两个脉冲,此时,需要采用握手信号的方法来进一步改进。
在这里插入图片描述

  • 12
    点赞
  • 92
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FPGA硅农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值