• FPGA内部动态可重置PLL讲解(二)


      对于全局时钟的管理,涉及到关于亚稳态的知识,大家可以上网搜索相关资料,这里不再赘述。亚稳态最简单的理解形式是无法判断是处于高电平状态还是处于低电平状态,这样会导致整个系统不稳定,会出现逻辑上的错误。

      任何对时钟的管理形式,都是最大限度避免亚稳态情况的出现,从而提高MTBF(平均无故障时间)。

      对于常用的异步复位形式(之前博客有提及到),如下:

    always @(posedge clk or negedge rst_n)
    
        if(!rst_n) begin
             ......
             ......
        end
    
        else begin
        ...........
        ...........
        end

      上述得异步复位结构,正常情况下,寄存器的更新会伴随clk的上升沿进行更新,但是rst_n何时结束就不一定了,若是在寄存器的   建立时间 + 保持时间之外,那么输出是稳定的,但是若是在这之内,那么会导致输出的数据不一定正确。

      目前笔者搜索到的资料,较为合适的,能够最大限度降低亚稳态产生的逻辑电路,就是“异步复位,同步释放”。

    module rstn_ (clk,rstn,rstn_out);
        input clk ;
        input rstn;
        output rstn_out;        //所要输出的复位信号
        reg rst_out1,rst_out2;
        always@(posedge clk or negedge rstn) begin
        if(!rstn) begin
            rst_out1 <= 1'b0;
            rst_out2 <= 1'b0;
        end
        else begin
            rst_out1 <= 1'b1;
            rst_out2 <= rst_out1;
            end
    assign  rstn_out = rst_out2;
    endmodule

    RTL视图为:

    wps283.tmp

     

      通过两级缓存,使得rst_n也是伴随clk时钟下的使能信号。

      实际应用电路

      那么在实际应用中,由于电源等芯片转换需要一定的时间,FPGA稳定启动需要一定的时间,外围电路启动也需要一定的时间,人为的添加50ms的延时电路,使整个系统稳定。

      有PLL参与的时钟电路

      RTL视图

    wps9B30.tmp

      Verilog 代码

      延时模块:

    /*********************************************************
    
    //description : this module will complete function of system init delay when power on
    //author      : raymon
    //address       :  GDUT university  of technology 
    //e-mail      : 770811496@qq.com
    //contact     : 770811496
    //time          :  2015-1-31
    
    
    **********************************************************/
    `timescale 1ns/1ns
    module system_init_delay
        #(
        parameter    SYS_DELAY_TOP = 24'd2500000        //50ms system init delay
          )
    (      
    //-------------------------------------------
    //global clock
    
        input    clk,        //50MHz
        input    rst_n,
        
        //system interface
        output    delay_done
    );
    
    //------------------------------------------
    //Delay 50ms for steady state when power on
    
    reg    [23:0] delay_cnt = 24'd0;
    always@(posedge clk or negedge rst_n)
        begin
            if(!rst_n)
                delay_cnt <= 0;
            else if(delay_cnt < SYS_DELAY_TOP - 1'b1)
                delay_cnt <= delay_cnt + 1'b1;
            else
                delay_cnt <= SYS_DELAY_TOP - 1'b1;
        end
    assign    delay_done = (delay_cnt == SYS_DELAY_TOP - 1'b1)? 1'b1 : 1'b0;
    
    endmodule

      PLL

      此模块是正常的利用quartus II生成的IP核PLL,这里不再讲解。

      顶层模块:

    /*********************************************************
    
    //description : this module will complete function of system init delay when power on
    //author      : raymon
    //address       :  GDUT university  of technology 
    //e-mail      : 770811496@qq.com
    //contact     : 770811496
    //time          :  2015-1-31
    
    
    **********************************************************/
    `timescale 1ns/1ns
    module sys_control(clk, rst_n, clk_ref, sys_rst_n);
    
    //----------------------------------------------
    //globol clock
        input                clk;             //50MHz
        input                rst_n;        //reset
    
    //----------------------------------------------
    //synced signal
        output             clk_ref;       //clock output    
        output             sys_rst_n;    //system reset
     
    
    //----------------------------------
    //component instantiation for system_delay
    wire    delay_done;    //system init delay has done
    system_init_delay
    #(
        .SYS_DELAY_TOP    (24'd2500000)
    )
    u_system_init_delay
    (
        //global clock
        .clk        (clk),
        .rst_n    (1'b1),            //It don't depend on rst_n when power up
        //system interface
        .delay_done    (delay_done)
    );
    
    //注意这里因为PLL的areset复位信号是高电平复位,和平常使用的rst_n信号正好相反
    wire pll_reset = ~delay_done; //pll of ip needs high level to reset
    
    //----------------------------------
    //using IP
    wire locked;
    
            sys_pll  U1(
                .areset(pll_reset),
                .inclk0(clk),
                .c0(clk_ref),        //output 100MHz
                .locked(locked)    
                );
                
    //----------------------------------------------
    //rst_n sync, only controlled by the main clk
    reg     rst_nr1, rst_nr2;
    always @(posedge clk_ref)
    begin
        if(!rst_n)
            begin
            rst_nr1 <= 1'b0;
            rst_nr2 <= 1'b0;
            end
        else
            begin
            rst_nr1 <= 1'b1;
            rst_nr2 <= rst_nr1;
            end
    end
    assign    sys_rst_n = rst_nr2 & locked;    //active low
    
    endmodule

      无PLL参与的时钟电路

      RTL视图

    wpsBDCF.tmp

      Verilog 代码

    /*********************************************************
    
    //description : this module will complete function of system init delay when power on
    //author        : raymon
    //address      : GDUT university  of technology 
    //e-mail         : 770811496@qq.com
    //contact      : 770811496
    //time            : 2015-1-31
    
    
    **********************************************************/
    `timescale 1ns/1ns
    module system_init_delay
        #(
        parameter    SYS_DELAY_TOP = 24'd2500000        //50ms system init delay
          )
    (      
    //-------------------------------------------
    //global clock
    
        input    clk,        //50MHz
        input    rst_n,
        
        //system interface
        output    delay_done
    );
    
    //------------------------------------------
    //Delay 50ms for steady state when power on
    
    reg    [23:0] delay_cnt = 24'd0;
    always@(posedge clk or negedge rst_n)
        begin
            if(!rst_n)
                delay_cnt <= 0;
            else if(delay_cnt < SYS_DELAY_TOP - 1'b1)
                delay_cnt <= delay_cnt + 1'b1;
            else
                delay_cnt <= SYS_DELAY_TOP - 1'b1;
        end
    assign    delay_done = (delay_cnt == SYS_DELAY_TOP - 1'b1)? 1'b1 : 1'b0;
    
    endmodule

      上述是延时部分的代码。

    /*********************************************************
    
    //description :this module will complete function of system init delay when power on
    //author        : raymon
    //address      :  GDUT university  of technology 
    //e-mail         : 770811496@qq.com
    //contact      : 770811496
    //time         :  2015-1-31
    
    
    **********************************************************/
    `timescale 1ns/1ns
    module system_ctrl(clk, rst_n,  clk_ref, sys_rst_n);
    
    //----------------------------------------------
    //globol clock
        input                clk;
        input                rst_n;
    
    //----------------------------------------------
    //synced signal
        output             clk_ref;       //clock output    
        output             sys_rst_n;    //system reset
    
    //----------------------------------------------
    //rst_n sync, only controlled by the main clk
    reg     rst_nr1, rst_nr2;
    always @(posedge clk)
    begin
        if(!rst_n)
            begin
            rst_nr1 <= 1'b0;
            rst_nr2 <= 1'b0;
            end
        else
            begin
            rst_nr1 <= 1'b1;
            rst_nr2 <= rst_nr1;
            end
    end
    
    
    //----------------------------------
    //component instantiation for system_delay
    wire    delay_done;    //system init delay has done
    system_init_delay
    #(
        .SYS_DELAY_TOP    (24'd2500000)
    )
    u_system_init_delay
    (
        //global clock
        .clk        (clk),
        .rst_n    (1'b1),            //It don't depend on rst_n when power up
        //system interface
        .delay_done    (delay_done)
    );
    
    assign    clk_ref = clk;
    assign    sys_rst_n = rst_nr2 & delay_done;    //active High
    
    endmodule

    上述是实现整个模块,可以查看RTL视图。

    上面提到的最大限度降低亚稳态复位电路,在应用时,直接可以调用。目前已在多个工程中使用。

    //=======================================================================

    更多详细的资料下载可以登录笔者百度网盘:

    网址:http://pan.baidu.com/s/1bnwLaqF

    密码:fgtb

    //=======================================================================

  • 相关阅读:
    java arraylist int[] 转换
    nginx installl
    "segmentation fault " when "import tensorflow as tf"
    preprocessing MinMaxScaler
    java对集合的操作,jxl操作excel
    IPython安装过程 @win7 64bit
    JavaScript学习——创建对象
    JavaScript学习——理解对象
    JavaScript学习——Math对象
    JavaScript学习——Global对象
  • 原文地址:https://www.cnblogs.com/raymon-tec/p/5151573.html
Copyright © 2020-2023  润新知