• Verilog-异步脉冲同步:双握手法



    参考博客:https://www.cnblogs.com/littleMa/p/10701576.html

    一、前言

      上一篇文章中(https://www.cnblogs.com/wt-seu/p/12489174.html)已经描述了简单的脉冲同步器,它可以实现简单应用场景下的同步功能,同时也存在不少应用限制或缺陷,例如:

      (1) 对src_clk域dst_clk关系较为敏感,当src_clk与dst_clk时钟频率差别很大时可能不适应;

      (2) 由于没有完整的握手机制,当多个src_pulse之间间隔较短时,可能存在脉冲同步丢失情况。

      (3) 当dst_clk时钟域出现无时钟或复位时,src_clk时钟域将丢失。

      本文将对该同步器进行改进以满足更多异步脉冲同步场景。

    二、原理

      回顾上一篇文章中的同步器的基本设计原理:

      (1)源时钟域脉冲转换为源时钟域电平信号;

      (2)对单bit电平信号进行打拍的异步处理;

      (3)在目的时钟域中进行脉冲还原。

      从以上设计原理中,我们可以发现该同步器的控制传递是单向的,即仅从源时钟域到目的时钟域,目的时钟域并没有状态反馈。假设存在如下应用:

      (1) 源时钟域中的第一个脉冲和第二个脉冲间隔过短,第一个脉冲未完成同步,第二脉冲又将状态清空,导致最终脉冲同步丢失。如下图:

      要解决以上同步问题,需要引入异步握手机制,保证每个脉冲都同步成功,同步成功后再进行下一个脉冲同步。握手原理如下:

      sync_req: 源时钟域同步请求信号,高电平表示当前脉冲需要同步;

      sync_ack: 目的时钟域应答信号,高电平表示当前已收到同步请求;

    三、代码

    `timescale 1ns / 1ps
    //--====================================================================================--
    // THIS FILE IS PROVIDED IN SOURCE FORM FOR FREE EVALUATION, FOR EDUCATIONAL USE OR FOR 
    // PEACEFUL RESEARCH.  DO NOT USE IT IN A COMMERCIAL PRODUCT . IF YOU PLAN ON USING THIS 
    // CODE IN A COMMERCIAL PRODUCT, PLEASE CONTACT JUSTFORYOU200@163.COM TO PROPERLY LICENSE 
    // ITS USE IN YOUR PRODUCT. 
    // 
    // Project      : Verilog Common Module
    // File Name    : handshake_pulse_sync.v
    // Creator(s)   : justforyou200@163.com
    // Date         : 2015/12/01
    // Description  : A handshake pulse sync 
    //
    // Modification :
    // (1) Initial design  2015-12-01
    //
    //
    //--====================================================================================--
    module Handshake_pulse_sync
        (
            src_clk         , //source clock 
            src_rst_n       , //source clock reset (0: reset)
            src_pulse       , //source clock pulse in
            src_sync_fail   , //source clock sync state: 1 clock pulse if sync fail.
            dst_clk         , //destination clock 
            dst_rst_n       , //destination clock reset (0:reset)
            dst_pulse       //destination pulse out
        );
     
    //PARA   DECLARATION
    
    
    //INPUT  DECLARATION
    input               src_clk     ; //source clock 
    input               src_rst_n   ; //source clock reset (0: reset)
    input               src_pulse   ; //source clock pulse in
    
    input               dst_clk     ; //destination clock 
    input               dst_rst_n   ; //destination clock reset (0:reset)
    
    //OUTPUT DECLARATION
    output              src_sync_fail   ; //source clock sync state: 1 clock pulse if sync fail.
    output              dst_pulse       ; //destination pulse out
    
    
    //INTER  DECLARATION
    wire                dst_pulse       ;
    wire                src_sync_idle   ;
    reg                 src_sync_fail   ;
    reg                 src_sync_req    ;
    reg                 src_sync_ack    ;
    reg                 ack_state_dly1  ;
    reg                 ack_state_dly2  ;
    reg                 req_state_dly1  ;
    reg                 req_state_dly2  ;
    reg                 dst_req_state   ;
    reg                 dst_sync_ack    ;
    
    //--========================MODULE SOURCE CODE==========================--
    
    
    //--=========================================--
    // SRC Clock :
    // 1. generate src_sync_fail; 
    // 2. generate sync req 
    // 3. sync dst_sync_ack
    //--=========================================--
    assign src_sync_idle = ~(src_sync_req | src_sync_ack );
    
    //report an error if src_pulse when sync busy ;
    always @(posedge src_clk or negedge src_rst_n)
    begin
        if(src_rst_n == 1'b0)
            src_sync_fail   <= 1'b0 ;
        else if (src_pulse & (~src_sync_idle)) 
            src_sync_fail   <= 1'b1 ;
        else 
            src_sync_fail   <= 1'b0 ;
    end
    
    //set sync req if src_pulse when sync idle ;
    always @(posedge src_clk or negedge src_rst_n)
    begin
        if(src_rst_n == 1'b0)
            src_sync_req    <= 1'b0 ;
        else if (src_pulse & src_sync_idle) 
            src_sync_req    <= 1'b1 ;
        else if (src_sync_ack)
            src_sync_req    <= 1'b0 ;
    end
    
    always @(posedge src_clk or negedge src_rst_n)
    begin
        if(src_rst_n == 1'b0)
            begin
                ack_state_dly1  <= 1'b0 ;
                ack_state_dly2  <= 1'b0 ;
                src_sync_ack    <= 1'b0 ;         
            end
            else
            begin
                ack_state_dly1  <= dst_sync_ack     ;
                ack_state_dly2  <= ack_state_dly1   ;
                src_sync_ack    <= ack_state_dly2   ;         
            end        
    end
    
    //--=========================================--
    // DST Clock :
    // 1. sync src sync req 
    // 2. generate dst pulse
    // 3. generate sync ack
    //--=========================================--
    always @(posedge dst_clk or negedge dst_rst_n)
    begin
        if(dst_rst_n == 1'b0)
            begin
                req_state_dly1  <= 1'b0 ;
                req_state_dly2  <= 1'b0 ;
                dst_req_state   <= 1'b0 ;
            end
        else
            begin
                req_state_dly1  <= src_sync_req     ;
                req_state_dly2  <= req_state_dly1   ;
                dst_req_state   <= req_state_dly2   ;
            end
    end
    
    //Rising Edge of dst_state generate a dst_pulse;
    assign dst_pulse = (~dst_req_state) & req_state_dly2 ; 
    
    //set sync ack when src_req = 1 , clear it when src_req = 0 ;
    always @(posedge dst_clk or negedge dst_rst_n)
    begin
        if(dst_rst_n == 1'b0)
            dst_sync_ack    <= 1'b0;
        else if (req_state_dly2)  
            dst_sync_ack    <= 1'b1;
        else  
            dst_sync_ack    <= 1'b0;
    end
    
    
    endmodule
    
    

    四、波形

  • 相关阅读:
    springmvc 配置多视图,返回jsp,velocity,freeMarker,tiles(模板)等等
    spring,mybatis,多数据源配置
    springMVC分页,interceptor实现
    springMVC全局Exception异常处理SimpleMappingExceptionResolver
    百度FIS入门
    如何安装nodejs
    如何高效部署前端代码,如css,js...
    javascript url几种编码方式
    【转】RBAC权限管理
    elasticsearch 之IK分词器安装
  • 原文地址:https://www.cnblogs.com/wt-seu/p/12929973.html
Copyright © 2020-2023  润新知