0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Verilog時鐘分頻知識總結

冬至子 ? 來源:數(shù)字IC與好好生活的兩居室 ? 作者:除夕之夜啊 ? 2023-05-30 17:21 ? 次閱讀

偶數(shù)分頻

采用觸發(fā)器反向輸出端連接到輸入端的方式,可構成簡單的 2 分頻電路。

以此為基礎進行級聯(lián),可構成 4 分頻,8 分頻電路。

電路實現(xiàn)如下圖所示,用 Verilog 描述時只需使用簡單的取反邏輯即可。

圖片

如果偶數(shù)分頻系數(shù)過大,就需要使用對分頻系數(shù) N 循環(huán)計算的方法進行分頻。在計數(shù)達到分頻系數(shù)中間數(shù)值 N/2 時進行時鐘翻轉,可保證分頻后時鐘的占空比為 50%。因為是偶數(shù)分頻,也可以對分頻系數(shù)中間數(shù)值 N/2 進行循環(huán)計數(shù)。

兩種偶數(shù)分頻的 Verilog 描述如下。

module even_divisor
  # (parameter DIV_CLK = 10 )
    (
    input               rstn ,
    input               clk,
    output              clk_div2,
    output              clk_div4,
    output              clk_div10
    );


   //2 分頻
   reg                  clk_div2_r ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         clk_div2_r     <= 'b0 ;
      end
      else begin
         clk_div2_r     <= ~clk_div2_r ;
      end
   end
   assign       clk_div2 = clk_div2_r ;


   //4 分頻
   reg                  clk_div4_r ;
   always @(posedge clk_div2 or negedge rstn) begin
      if (!rstn) begin
         clk_div4_r     <= 'b0 ;
      end
      else begin
         clk_div4_r     <= ~clk_div4_r ;
      end
   end
   assign clk_div4      = clk_div4_r ;


   //N/2 計數(shù)
   reg [3:0]            cnt ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         cnt    <= 'b0 ;
      end
      else if (cnt == (DIV_CLK/2)-1) begin
         cnt    <= 'b0 ;
      end
      else begin
         cnt    <= cnt + 1'b1 ;
      end
   end


   //輸出時鐘
   reg                  clk_div10_r ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         clk_div10_r <= 1'b0 ;
      end
      else if (cnt == (DIV_CLK/2)-1 ) begin
         clk_div10_r <= ~clk_div10_r ;
      end
   end
   assign clk_div10 = clk_div10_r ;
endmodule

testbench 中只需給入激勵時鐘等信號即可,這里不再列出。

仿真結果如下。

圖片


奇數(shù)分頻

奇數(shù)分頻如果不要求占空比為 50%,可按照偶數(shù)分頻的方法進行分頻。即計數(shù)器對分頻系數(shù) N 進行循環(huán)計算,然后根據(jù)計數(shù)值選擇一定的占空比輸出。

如果奇數(shù)分頻輸出時鐘的高低電平只差一個 cycle ,則可以利用源時鐘雙邊沿特性并采用“與操作”或“或操作”的方式將分頻占空比調整到 50%。

◆或操作調整占空比

采用“或操作”產(chǎn)生占空比為 50% 的 3 分頻時序圖如下所示。

利用源時鐘上升沿分頻出高電平為 1 個 cycle、低電平為 2 個 cycle 的 3 分頻時鐘。

利用源時鐘下降沿分頻出高電平為 1 個 cycle、低電平為 2 個 cycle 的 3 分拼時鐘。

兩個 3 分頻時鐘應該在計數(shù)器相同數(shù)值、不同邊沿下產(chǎn)生,相位差為一個時鐘周期。然后將 2 個時鐘進行“或操作”,便可以得到占空比為 50% 的 3 分頻時鐘。

圖片

同理,9 分頻時,則需要在上升沿和下降沿分別產(chǎn)生 4 個高電平、5 個低電平的 9 分頻時鐘,然后再對兩個時鐘做“或操作”即可。Verilog 描述如下。

module odo_div_or
  #(parameter DIV_CLK = 9)
   (
    input               rstn ,
    input               clk,
    output              clk_div9
    )


   //計數(shù)器
   reg [3:0]            cnt ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         cnt    <= 'b0 ;
      end
      else if (cnt == DIV_CLK-1) begin
         cnt    <= 'b0 ;
      end
      else begin
         cnt    <= cnt + 1'b1 ;
      end
   end


   //在上升沿產(chǎn)生9分頻
   reg                  clkp_div9_r ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         clkp_div9_r <= 1'b0 ;
      end
      else if (cnt == (DIV_CLK>>1)-1 ) begin //計數(shù)4-8位低電平
        clkp_div9_r <= 0 ;
      end
      else if (cnt == DIV_CLK-1) begin //計數(shù) 0-3 為高電平
        clkp_div9_r <= 1 ;
      end
   end

   //在下降沿產(chǎn)生9分頻
   reg                  clkn_div9_r ;
   always @(negedge clk or negedge rstn) begin
      if (!rstn) begin
         clkn_div9_r <= 1'b0 ;
      end
      else if (cnt == (DIV_CLK>>1)-1 ) begin 
        clkn_div9_r <= 0 ;
      end
      else if (cnt == DIV_CLK-1) begin 
        clkn_div9_r <= 1 ;
      end
   end


   //或操作,往往使用基本邏輯單元庫
   // or (clk_div9, clkp_div9_r, clkn_div9_r) ;
   assign clk_div9 = clkp_div9_r | clkn_div9_r ;


endmodule

仿真結果如下。

圖片

◆與操作調整占空比

采用“與操作”產(chǎn)生占空比為 50% 的 3 分頻時序圖如下所示。

利用源時鐘上升沿分頻出高電平為 2 個 cycle、低電平為 1 個 cycle 的 3 分頻時鐘。

利用源時鐘下降沿分頻出高電平為 2 個 cycle、低電平為 1 個 cycle 的 3 分拼時鐘。

兩個 3 分頻時鐘應該在計數(shù)器相同數(shù)值、不同邊沿下產(chǎn)生,相位差為一個時鐘周期。然后將 2 個時鐘進行“與操作”,便可以得到占空比為 50% 的 3 分頻時鐘。

圖片

同理,9 分頻時,則需要在上升沿和下降沿分別產(chǎn)生 5 個高電平、4 個低電平的 9 分頻時鐘,然后再對兩個時鐘做“與操作”即可。Verilog 描述如下。

module odo_div_and
   #( parameter DIV_CLK = 9 )
   (
    input               rstn ,
    input               clk,
    output              clk_div9
    );


   //計數(shù)器
   reg [3:0]            cnt ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         cnt    <= 'b0 ;
      end
      else if (cnt == DIV_CLK-1) begin
         cnt    <= 'b0 ;
      end
      else begin
         cnt    <= cnt + 1'b1 ;
      end
   end


   //在上升沿產(chǎn)生9分頻
   reg                  clkp_div9_r ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         clkp_div9_r <= 1'b0 ;
      end
      else if (cnt == (DIV_CLK>>1) ) begin //計數(shù)5-8位低電平
        clkp_div9_r <= 0 ;
      end
      else if (cnt == DIV_CLK-1) begin //計數(shù) 0-4 為高電平
        clkp_div9_r <= 1 ;
      end
   end


   //在下降沿產(chǎn)生9分頻
   reg                  clkn_div9_r ;
   always @(negedge clk or negedge rstn) begin
      if (!rstn) begin
         clkn_div9_r <= 1'b0 ;
      end
      else if (cnt == (DIV_CLK>>1) ) begin 
        clkn_div9_r <= 0 ;
      end
      else if (cnt == DIV_CLK-1) begin 
        clkn_div9_r <= 1 ;
      end
   end


   //與操作,往往使用基本邏輯單元庫
   //and (clk_div9, clkp_div9_r, clkn_div9_r) ;
   assign clk_div9 = clkp_div9_r & clkn_div9_r ;


endmodule

仿真結果如下。

圖片


半整數(shù)分頻

利用時鐘的雙邊沿邏輯,可以對時鐘進行半整數(shù)的分頻,但是無論再怎么調整,半整數(shù)分頻的占空比不可能是 50%。半整數(shù)分頻的方法有很多,這里只介紹一種和計數(shù)分頻調整占空比類似的方法。

(1) 例如進行 3.5 倍分頻時,計數(shù)器循環(huán)計數(shù)到 7,分別產(chǎn)生 4 個和 3 個源時鐘周期的分頻時鐘。從 7 個源時鐘產(chǎn)生了 2 個分頻時鐘的角度來看,該過程完成了 3.5 倍的分頻,但是每個分頻時鐘并不是嚴格的 3.5 倍分頻。

(2) 下面對周期不均勻的分頻時鐘進行調整。一次循環(huán)計數(shù)中,在源時鐘下降沿分別產(chǎn)生 4 個和 3 個源時鐘周期的分頻時鐘。相對于第一次產(chǎn)生的 2 個周期不均勻的時鐘,本次產(chǎn)生的 2 個時鐘相位一個延遲半個源時鐘周期,一個提前半個源時鐘周期。

(3) 將兩次產(chǎn)生的時鐘進行“或操作”,便可以得到周期均勻的 3.5 倍分頻時鐘。分頻波形示意圖如下所示。

圖片

3.5 倍時鐘分頻的 Verilog 描述如下。

module half_divisor(
    input               rstn ,
    input               clk,
    output              clk_div3p5
    );


   //計數(shù)器
   parameter            MUL2_DIV_CLK = 7 ;
   reg [3:0]            cnt ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         cnt    <= 'b0 ;
      end
      else if (cnt == MUL2_DIV_CLK-1) begin //計數(shù)2倍分頻比
         cnt    <= 'b0 ;
      end
      else begin
         cnt    <= cnt + 1'b1 ;
      end
   end


   reg                  clk_ave_r ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         clk_ave_r <= 1'b0 ;
      end
      //first cycle: 4 source clk cycle
      else if (cnt == 0) begin
         clk_ave_r <= 1 ;
      end
      //2nd cycle: 3 source clk cycle
      else if (cnt == (MUL2_DIV_CLK/2)+1) begin
         clk_ave_r <= 1 ;
      end
      else begin
         clk_ave_r <= 0 ;
      end
   end


   //adjust
   reg                  clk_adjust_r ;
   always @(negedge clk or negedge rstn) begin
      if (!rstn) begin
         clk_adjust_r <= 1'b0 ;
      end
      //本次時鐘只為調整一致的占空比
      else if (cnt == 1) begin
         clk_adjust_r <= 1 ;
      end
      //本次時鐘只為調整一致的精確分頻比
      else if (cnt == (MUL2_DIV_CLK/2)+1 ) begin
         clk_adjust_r <= 1 ;
      end
      else begin
         clk_adjust_r <= 0 ;
      end
   end


   assign clk_div3p5 = clk_adjust_r | clk_ave_r ;
endmodule

仿真結果如下。

圖片


小數(shù)分頻

◆基本原理

不規(guī)整的小數(shù)分頻不能做到分頻后的每個時鐘周期都是源時鐘周期的小數(shù)分頻倍,更不能做到分頻后的時鐘占空比均為 50%,因為 Verilog 不能對時鐘進行小數(shù)計數(shù)。和半整數(shù)分頻中第一次分頻時引入的“平均頻率”概念類似,小數(shù)分頻也是基于可變分頻和多次平均的方法實現(xiàn)的。

例如進行 7.6 倍分頻,則保證源時鐘 76 個周期的時間等于分頻時鐘 10 個周期的時間即可。此時需要在 76 個源時鐘周期內進行 6 次 8 分頻,4 次 7 分頻。再例如進行 5.76 分頻,需要在 576 個源時鐘周期內進行 76 次 6 分頻,24 次 5 分頻。

下面闡述下這些分頻參數(shù)的計算過程。

當進行 7 分頻時,可以理解為 70 個源時鐘周期內進行 10 次 7 分頻。在 76 個源時鐘周期內仍然進行 10 次分頻,相當于將多余的 6 個源時鐘周期增加、分配到 70 個源時鐘周期內,即完成了 7.6 倍分頻操作。分頻過程中必然有 6 個分頻時鐘是 8 分頻得到的,剩下的 4 個分頻時鐘則仍然會保持原有的 7 分頻狀態(tài)。

很多地方給出了計算這些分頻參數(shù)的兩元一次方程組,如下所示。其原理和上述分析一致,建議掌握上述計算過程。

7N + 8M = 76

N + M = 10

其中 7 為整數(shù)分頻,N 整數(shù)分頻的次數(shù);8 與 M 為整數(shù)加一的分頻系數(shù)及其分頻次數(shù)。

◆平均原理

以 7.6 倍分頻為例,7 分頻和 8 分頻的實現(xiàn)順序一般有以下 4 種:

(1) 先進行 4 次 7 分頻,再進行 6 次 8 分頻;

(2) 先進行 6 次 8 分頻,再進行 4 次 7 分頻;

(3) 將 4 次 7 分頻平均的插入到 6 次 8 分頻中;

(4) 將 6 次 8 分頻平均的插入到 4 次 7 分頻中。

前兩種方法時鐘頻率不均勻,相位抖動較大,所以一般會采用后兩種平均插入的方法進行小數(shù)分頻操作。

平均插入可以通過分頻次數(shù)差累計的方法實現(xiàn),7.6 分頻的實現(xiàn)過程如下:

(1) 第一次分頻次數(shù)差值為 76-10*7 = 6 < 10,第一次進行 7 分頻。

(2) 第二次差值累積結果為 6+6=12 > 10,第二次使用 8 分頻,同時差值修改為 12-10=2。

(3) 第三次差值累積結果為 2+6=8 < 10,第三次使用 6 分頻。

(3) 第四次差值累積結果為 8+6=14 > 10,第四次使用 8 分頻,差值修改為 14-10=4。

以此類推,完成將 6 次 8 分頻平均插入到 4 次 7 分頻的過程。

下表展示了平均插入法的分頻過程。

1.jpg

◆設計仿真

基于上述分析實現(xiàn)方法的 Verilog 描述如下。

module frac_divisor
  #(
   parameter            SOURCE_NUM = 76 , //cycles in source clock
   parameter            DEST_NUM   = 10  //cycles in destination clock
   )
   (
    input               rstn ,
    input               clk,
    output              clk_frac
    );

   //7分頻參數(shù)、8分頻參數(shù)、次數(shù)差值
   parameter    SOURCE_DIV = SOURCE_NUM/DEST_NUM ; 
   parameter    DEST_DIV   = SOURCE_DIV + 1; 
   parameter    DIFF_ACC   = SOURCE_NUM - SOURCE_DIV*DEST_NUM ;


   reg [3:0]            cnt_end_r ;  //可變分頻周期
   reg [3:0]            main_cnt ;   //主計數(shù)器
   reg                  clk_frac_r ; //時鐘輸出,高電平周期數(shù)為1
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         main_cnt    <= 'b0 ;
         clk_frac_r  <= 1'b0 ;
      end
      else if (main_cnt == cnt_end_r) begin
         main_cnt    <= 'b0 ;
         clk_frac_r  <= 1'b1 ;
      end
      else begin
         main_cnt    <= main_cnt + 1'b1 ;
         clk_frac_r  <= 1'b0 ;
      end
   end
   //輸出時鐘
   assign       clk_frac        = clk_frac_r ;
   //差值累加器使能控制
   wire         diff_cnt_en     = main_cnt == cnt_end_r ;


   //差值累加器邏輯
   reg [4:0]            diff_cnt_r ;
   wire [4:0]           diff_cnt = diff_cnt_r >= DEST_NUM ?
                                   diff_cnt_r -10 + DIFF_ACC : 
                                   diff_cnt_r + DIFF_ACC ;                                
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         diff_cnt_r <= 0 ;
      end
      else if (diff_cnt_en) begin
         diff_cnt_r <= diff_cnt ;
      end
   end


   //分頻周期變量的控制邏輯
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         cnt_end_r      <= SOURCE_DIV-1 ;
      end
      //差值累加器溢出時,修改分頻周期
      else if (diff_cnt >= 10) begin
         cnt_end_r      <= DEST_DIV-1 ;
      end
      else begin
         cnt_end_r      <= SOURCE_DIV-1 ;
      end
   end


endmodule

仿真結果如下。

圖片


分頻小結

◆偶數(shù)分頻不使用時鐘雙邊沿邏輯即可完成占空比為 50% 的時鐘分頻,是最理想的分頻狀況。

◆奇數(shù)分頻如果要產(chǎn)生 50% 占空比的分頻時鐘,則需要使用時鐘的雙邊沿邏輯。如果不要求占空比的話,實現(xiàn)方法和偶數(shù)分頻類似。

◆半整數(shù)分頻屬于特殊的小數(shù)分頻,可以用雙邊沿邏輯進行設計。通過一定邏輯將兩個雙邊沿時鐘信號整合為最后的一路輸出時鐘時,建議不要使用選擇邏輯。因為容易出現(xiàn)毛刺現(xiàn)象,電路中又會增加一定的不確定性。例如下面描述是不建議的。

assign clk_div3p5 = (cnt == 1 || cnt ==2) ? clk_ave_r 
                                          : clk_adjust_r ;

◆小數(shù)分頻的基本思想是,輸出時鐘在一段時間內的平均頻率達到分頻要求即可。但是考慮到相位抖動,還需要對可變的分頻邏輯進行平均操作。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 邏輯電路
    +關注

    關注

    13

    文章

    491

    瀏覽量

    42503
  • Verilog
    +關注

    關注

    28

    文章

    1335

    瀏覽量

    109848
  • 計數(shù)器
    +關注

    關注

    32

    文章

    2248

    瀏覽量

    94179
  • 觸發(fā)器
    +關注

    關注

    14

    文章

    1992

    瀏覽量

    60976
  • 累加器
    +關注

    關注

    0

    文章

    50

    瀏覽量

    9434
收藏 人收藏

    評論

    相關推薦

    利用Verilog實現(xiàn)奇數(shù)倍分頻

    時鐘下降沿變成了上升沿,則計數(shù)值n-1只保持了半個時鐘周期,由于時鐘翻轉下降沿變成上升沿,因此計數(shù)值變?yōu)?。因此,每產(chǎn)生一個n+0.5分頻時鐘
    發(fā)表于 06-14 06:30

    如何利用Verilog實現(xiàn)奇數(shù)倍分頻

    時鐘下降沿變成了上升沿,則計數(shù)值n-1只保持了半個時鐘周期,由于時鐘翻轉下降沿變成上升沿,因此計數(shù)值變?yōu)?。因此,每產(chǎn)生一個n+0.5分頻時鐘
    發(fā)表于 07-09 09:11

    基于verilog的數(shù)字時鐘程序

    基于verilog的數(shù)字時鐘程序,時鐘芯片基礎——60進制計數(shù)器設計目的讓nexys 4板上的7段碼LED顯示時鐘信息,其中包括時鐘的小時,
    發(fā)表于 07-22 07:37

    STM32時鐘分頻系數(shù)的知識點匯總,絕對實用

    STM32時鐘分頻系數(shù)的知識點匯總,絕對實用
    發(fā)表于 12-15 07:01

    時鐘分頻及定時變換電路

    時鐘分頻及定時變換電路
    發(fā)表于 10-11 10:35 ?2200次閱讀
    <b class='flag-5'>時鐘</b><b class='flag-5'>分頻</b>及定時變換電路

    基于Verilog的FPGA分頻設計

    給出了一種基于FPGA的分頻電路的設計方法.根據(jù)FPGA器件的特點和應用范圍,提出了基于Verilog分頻方法.該方法時于在FPGA硬件平臺上設計常用的任意偶數(shù)分頻、奇數(shù)
    發(fā)表于 11-09 09:49 ?355次下載
    基于<b class='flag-5'>Verilog</b>的FPGA<b class='flag-5'>分頻</b>設計

    Verilog實現(xiàn)基于FPGA的通用分頻器的設計

    Verilog實現(xiàn)基于FPGA 的通用分頻器的設計時鐘分頻包括奇數(shù)和偶數(shù)分頻
    發(fā)表于 07-14 11:32 ?46次下載

    MSP430G2553時鐘系統(tǒng)要點總結

    MSP430G2553時鐘系統(tǒng)要點總結時鐘總覽時鐘源的選用默認狀態(tài)控制寄存器例程個人總結的MSP430G2553各個模塊功能要點,主要側重于
    發(fā)表于 12-16 16:55 ?10次下載
    MSP430G2553<b class='flag-5'>時鐘</b>系統(tǒng)要點<b class='flag-5'>總結</b>

    分頻分頻器與飲料售貨機控制器verilog代碼

    分頻分頻器與飲料售貨機控制器verilog代碼分享
    發(fā)表于 09-01 15:35 ?0次下載

    通過Verilog實現(xiàn)對一個頻率的任意占空比的任意分頻

    verilog程序設計中,我們往往要對一個頻率進行任意分頻,而且占空比也有一定的要求這樣的話,對于程序有一定的要求,現(xiàn)在我在前人經(jīng)驗的基礎上做一個簡單的總結,實現(xiàn)對一個頻率的任意占空比的任意
    的頭像 發(fā)表于 01-05 09:33 ?2350次閱讀

    verilog時鐘分頻時鐘使能

    時鐘使能電路是同步設計的基本電路,在很多設計中,雖然內部不同模塊的處理速度不同,但由于這些時鐘是同源的,可以將它們轉化為單一時鐘處理;在ASIC中可以通過STA約束讓分頻始終和源
    的頭像 發(fā)表于 01-05 14:00 ?1559次閱讀

    時鐘的相關知識

    幾乎稍微復雜的數(shù)字設計都離不開時鐘。時鐘也是所有時序邏輯建立的基礎。前面介紹建立時間和保持時間時也涉及過時鐘偏移的概念。下面將總結時鐘的相
    的頭像 發(fā)表于 03-28 13:56 ?1749次閱讀
    <b class='flag-5'>時鐘</b>的相關<b class='flag-5'>知識</b>

    偶數(shù)分頻、奇數(shù)分頻、半整數(shù)分頻和小數(shù)分頻詳解

    初學 Verilog 時許多模塊都是通過計數(shù)與分頻完成設計,例如 PWM 脈寬調制、頻率計等。而分頻邏輯往往通過計數(shù)邏輯完成。本節(jié)主要對偶數(shù)分頻、奇數(shù)
    的頭像 發(fā)表于 03-29 11:38 ?4514次閱讀
    偶數(shù)<b class='flag-5'>分頻</b>、奇數(shù)<b class='flag-5'>分頻</b>、半整數(shù)<b class='flag-5'>分頻</b>和小數(shù)<b class='flag-5'>分頻</b>詳解

    基于Verilog的分數(shù)分頻電路設計

    上一篇文章時鐘分頻系列——偶數(shù)分頻/奇數(shù)分頻/分數(shù)分頻,IC君介紹了各種分頻器的設計原理,其中分
    的頭像 發(fā)表于 04-25 14:47 ?1587次閱讀
    基于<b class='flag-5'>Verilog</b>的分數(shù)<b class='flag-5'>分頻</b>電路設計

    利用FPGA的高頻時鐘扇出電路的分頻和分配設計

    基于FPGA的高頻時鐘分頻分頻設計
    發(fā)表于 08-16 11:42 ?1次下載