IC/FPGA设计——跨时钟域处理之握手(2)

点击上方“蓝字”,学习更多干货!

上篇文章介绍了基本的握手电路,以及为了防止漏采样而设计的带输出“同步失败”信号的改进握手电路,这次我们介绍一下与”握手“相似但不同的处理单bit跨时钟域的"backpressure"机制,以及由其启发改进的更为简洁的握手电路。

最基本的握手电路及其代码在上一章(IC/FPGA设计——跨时钟域处理之握手(1)

01

"backpressure",字面意思为来自后方的压力。查阅资料后得知,"backpressure"的原理是由输出的处理速度来调节输入的速度。在电路中,backpressure机制则可实现为电路向上游提供一个"ready"信号,只有当该信号有效时上游才可发送信号到该电路。

在单bit跨时钟域同步电路基础上稍加修改,就可得到所需要的backpressure电路,电路图如下。

图1 采用backpressure机制的电路

在图1中,in_pulse为输入的待同步的脉冲信号, receive_enable为向上游电路输出的backpressure信号,只有当该信号有效时,电路才可接收输入脉冲。

从上面的电路中可以得知,backpressure的电路跟握手电路很相似,但又不同。相同的是这两个电路都有从输出到输入的反馈,而不同的是这两个电路的反馈接到了不同的地方。握手电路的反馈接到了输入端,与从输入到输出的路径共同构成了一条回路,而backpressure电路则将反馈回的电路直接作为输出信号提供给上游。

电路的不同直接导致了两种机制对于信号处理的不同。在握手机制下上游电路可以源源不断地向其输入脉冲信号,而由握手电路决定要同步哪些电路,并将同步失败的信号向上游提供一个反馈(即sync_fail),而backpressure则在电路处理不了下一个要到来的信号时及时告知上游,使上游停止输入。

有了图1电路,就可以写出代码,如下:

module sync_pulse__backpressure(
        input wire src_clk,
        input wire dst_clk,
        input wire rst,
        input wire in_pulse,
        output wire out_pulse,
        output wire receive_en
    );


    reg src_sync,dst_sync;
    reg sync_dly1,sync_dly2;


    reg sync_back_dly1,sync_back_dly2;


    always @(posedge src_clk or posedge rst )  begin
        if(rst)
            src_sync <= 0;
        else 
            src_sync <= src_sync ^ in_pulse;
    end


    always @(posedge dst_clk or posedge rst) begin
        if(rst)
            {sync_dly1,sync_dly2,dst_sync} <= 3'b000;
        else
            {sync_dly1,sync_dly2,dst_sync} <= {src_sync,sync_dly1,sync_dly2};
    end


    assign out_pulse = sync_dly2 ^ dst_sync ;


    always @(posedge src_clk or posedge rst ) begin
        if (rst)
            {sync_back_dly1,sync_back_dly2} <= 2'b00;
        else  
            {sync_back_dly1,sync_back_dly2} <= {sync_dly2,sync_back_dly1};
    end


    assign receive_en = ~(sync_back_dly2 ^ src_sync) ;


endmodule

虽然讲了这么多,但backpressure并不是今天的主角,下面开始进入正题——进一步改进的“握手”电路。

02

那么问题来了,既然两种电路都有同样的反馈,那么能不能修改backpressure电路使其变为简化版的握手电路呢?答案是可以。

经过数小时思索,终于提出了改进方案。由上述电路改为握手电路需要修改的两个关键部分:

  • 将receive_enable信号改为同步失败信号(sync_fail)。在脉冲信号到来时,若sync_fail信号同步输出1,则证明同步失败。由此看来,只需要将receive_enable信号与in_pulse进行逻辑操作,即可得到sync_fail;

  • 在上一个信号同步过程中的忙状态,若此时又一个脉冲同步信号输入,则握手电路会阻止握手回路的信号受输入的影响,而在上述backpressure电路中,一旦in_pulse有脉冲,内部信号会在下一个时钟上升沿进行翻转(见in_pulse后的异或)。

由此得到改进后的“握手”电路图,如下:

图2  进一步改进后的 “握手”电路

可以看到,这次的电路相比上一篇文章里的更为简洁。需要注意的是,为了输出sync_fail的正确性,在receive_en的后边又加了一级触发器,从而保证在空显示器输入的in_pulse不会引起sync_fail的错误输出。

03

接下来我们给出该电路的verilog描述:

module sync_pulse_fast_to_slow_handshake(
        input wire src_clk,
        input wire dst_clk,
        input wire rst,
        input wire in_pulse,
        output wire out_pulse,
        output wire sync_fail
    );


    reg src_sync,dst_sync;
    reg sync_dly1,sync_dly2;
    reg sync_back_dly1,sync_back_dly2;
    wire sync_idle;
    reg sync_idle_dly;//用于产生sync_fail信号
    wire sync_idle_1;




    always @(posedge src_clk or posedge rst )  begin
        if(rst)
            src_sync <= 0;
        else 
            src_sync <= sync_idle ? (src_sync ^ in_pulse) : src_sync;
    end


    always @(posedge dst_clk or posedge rst) begin
        if(rst)
            {sync_dly1,sync_dly2,dst_sync} <= 3'b000;
        else
            {sync_dly1,sync_dly2,dst_sync} <= {src_sync,sync_dly1,sync_dly2};
    end


    assign out_pulse = sync_dly2 ^ dst_sync ;


    always @(posedge src_clk or posedge rst ) begin
        if (rst)
            {sync_back_dly1,sync_back_dly2} <= 2'b00;
        else  
            {sync_back_dly1,sync_back_dly2} <= {sync_dly2,sync_back_dly1};
    end


    assign sync_idle = ~(sync_back_dly2 ^ src_sync) ;


    always @(posedge src_clk or posedge rst) begin
        if(rst)
            sync_idle_dly <= 0;
        else
            sync_idle_dly <= sync_idle;
    end


    assign sync_fail = in_pulse & ( ~(sync_idle | sync_idle_dly) );


endmodule

代码写完以后,便是对其进行测试,看看相比上一篇文章中提出的电路到底性能有没有提升。由于篇幅关系,testbench就不在这里贴出了,需要的同学可以留言告诉我。下图为仿真波形,其中第三条为输入的脉冲,其下蓝色的两条分别是上一篇文章中的sync_fail和输出同步脉冲,棕色的两条是本篇文章中提出的电路中的sync_fail和输出同步脉冲。

图3  仿真波形

我们姑且称上一篇中的方法为方法1,本篇为方法2。在波形图中可以看到,两种方法,均成功同步了第1个脉冲信号,但是在第2个脉冲信号到来的时候方法1提示同步失败,方法2成功了,这是因为方法1的反馈回路比方法2要长,导致了方法1同步一个信号的时间要比方法2要长一些。在后面两种环境下两种方法都成功同步了信号。由此可以看出,本文提出的方法性能有所加强,同时电路结构更加简洁。

对该部分有兴趣的,或者有问题想要探讨,欢迎点击“阅读原文”进行留言,也可以直接向公众号发送消息,欢迎大家的来信!

IC/FPGA设计之分频器设计及Verilog代码(1)

IC/FPGA设计之分频器设计及Verilog代码(2)

IC/FPGA设计之复杂序列检测

你点的每个赞,我都认真当成了喜欢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值