Verilog 時(shí)鐘簡(jiǎn)介

2022-05-20 14:49 更新

關(guān)鍵詞:時(shí)鐘源,時(shí)鐘偏移,時(shí)鐘抖動(dòng),時(shí)鐘轉(zhuǎn)換時(shí)間,時(shí)鐘延時(shí),時(shí)鐘樹(shù),雙邊沿時(shí)鐘

幾乎稍微復(fù)雜的數(shù)字設(shè)計(jì)都離不開(kāi)時(shí)鐘。時(shí)鐘也是所有時(shí)序邏輯建立的基礎(chǔ)。前面介紹建立時(shí)間和保持時(shí)間時(shí)也涉及過(guò)時(shí)鐘偏移的概念。下面將總結(jié)下時(shí)鐘的相關(guān)知識(shí),以便更好的進(jìn)行數(shù)字設(shè)計(jì)。

時(shí)鐘源

根據(jù)時(shí)鐘源在數(shù)字設(shè)計(jì)模塊中位置的不同,可以將時(shí)鐘源分為外部時(shí)鐘源和內(nèi)部時(shí)鐘源。

外部時(shí)鐘源

RC/LC 振蕩電路:利用正反饋或負(fù)反饋電路產(chǎn)生周期性變化時(shí)鐘信號(hào)。此類時(shí)鐘源電路簡(jiǎn)單,頻率變化范圍大,但工作頻率較低,穩(wěn)定度不高。

無(wú)源/有源晶體振蕩器:利用石英晶體的壓電效應(yīng)(壓力和電信號(hào)可以相互轉(zhuǎn)換)產(chǎn)生諧振信號(hào)。此類時(shí)鐘源頻率精度高,穩(wěn)定性好,噪聲低,溫漂小。有源晶振中,往往還加入了壓控或溫度補(bǔ)償,時(shí)鐘的相位和頻率都有較好的特性。但電路實(shí)現(xiàn)相對(duì)復(fù)雜,頻帶較窄,頻率基本不能調(diào)節(jié)。


調(diào)試特定電路時(shí),往往也會(huì)使用一些搭建的特定電路(例如施密特觸發(fā)器)或信號(hào)發(fā)生器設(shè)備產(chǎn)生的時(shí)鐘源。

內(nèi)部時(shí)鐘源

鎖相環(huán)(PLL, Phase Locked Loop):

利用外部輸入的參考信號(hào)控制環(huán)路內(nèi)部振蕩信號(hào)的頻率和相位,實(shí)現(xiàn)輸出信號(hào)頻率對(duì)輸入信號(hào)頻率的自動(dòng)跟蹤,通過(guò)反饋通路將信號(hào)倍頻到一個(gè)較高的固定頻率。


一般晶振由于工藝與成本原因,做不到很高的頻率,利用 PLL 電路就可以實(shí)現(xiàn)穩(wěn)定且高頻的時(shí)鐘。PLL 集成到設(shè)計(jì)模塊的內(nèi)部,可以保證數(shù)字電路具有較好的延遲和穩(wěn)定性。

時(shí)鐘分頻

有些模塊工作頻率會(huì)低于系統(tǒng)時(shí)鐘頻率,此時(shí)就需要對(duì)系統(tǒng)時(shí)鐘進(jìn)行一定的分頻得到頻率較低的時(shí)鐘。

通過(guò)在 always 語(yǔ)句塊中計(jì)數(shù)并輸出時(shí)鐘信號(hào),是分頻器常用的方法。任意分頻比的實(shí)現(xiàn)邏輯詳見(jiàn)下一節(jié)《Verilog 時(shí)鐘分頻》

時(shí)鐘切換

系統(tǒng)或某些模塊的工作頻率有時(shí)候會(huì)在特定狀況下改變,例如低功耗模式下需要降頻,提高計(jì)算能力時(shí)需要升頻。此時(shí)系統(tǒng)往往會(huì)有多個(gè)時(shí)鐘源,以備有需求時(shí)進(jìn)行時(shí)鐘切換。

時(shí)鐘切換邏輯如果不進(jìn)行優(yōu)化,在切換的過(guò)度時(shí)間內(nèi),大概率會(huì)出現(xiàn)尖峰脈沖干擾,對(duì)電路產(chǎn)生不利影響。安全的切換邏輯,詳見(jiàn)后面章節(jié):《Verilog 時(shí)鐘切換》。

數(shù)字系統(tǒng)往往會(huì)采用外部晶振輸入、內(nèi)部 PLL 進(jìn)行倍頻的方案。再根據(jù)設(shè)計(jì)需求進(jìn)行時(shí)鐘分頻或時(shí)鐘切換。

時(shí)鐘特性

仿真時(shí),所有同步的時(shí)鐘都是理想的:時(shí)鐘的翻轉(zhuǎn)是在瞬間完成的,模塊之間的時(shí)鐘沿都是對(duì)齊的,沒(méi)有延遲,沒(méi)有抖動(dòng)。實(shí)際電路中,時(shí)鐘在傳輸、翻轉(zhuǎn)時(shí)都會(huì)有延遲。完美的數(shù)字設(shè)計(jì),也應(yīng)該考慮這些不完美的時(shí)鐘特性,否則也會(huì)造成設(shè)計(jì)時(shí)序不滿足的狀況。

下面對(duì)時(shí)鐘的一些特性進(jìn)行簡(jiǎn)單說(shuō)明。

時(shí)鐘偏移(skew)

由于線網(wǎng)的延遲,時(shí)鐘信號(hào)在到達(dá)觸發(fā)器端口時(shí),不能保證不同觸發(fā)器端口的時(shí)鐘沿是對(duì)齊的,即不同觸發(fā)器端口的時(shí)鐘相位存在差異。這種差異稱為時(shí)鐘偏移。示意圖如下:


一般時(shí)鐘偏移與時(shí)鐘頻率沒(méi)有直接的關(guān)系,與走線長(zhǎng)度、負(fù)載電容、負(fù)載數(shù)量等因素有關(guān)。

時(shí)鐘抖動(dòng)(jitter)

相對(duì)于理想時(shí)鐘沿,實(shí)際時(shí)鐘中存在的不隨時(shí)間積累的、時(shí)而超前、時(shí)而滯后的偏移稱為時(shí)鐘抖動(dòng)。可以用抖動(dòng)頻率和抖動(dòng)幅度對(duì)時(shí)鐘抖動(dòng)進(jìn)行定量描述。數(shù)字設(shè)計(jì)中,時(shí)鐘抖動(dòng)都是用時(shí)間來(lái)描述,示意圖如下。


時(shí)鐘抖動(dòng)可分為隨機(jī)抖動(dòng)和固定抖動(dòng)。

隨機(jī)抖動(dòng)的來(lái)源為熱噪聲、半導(dǎo)體工藝等。

固定抖動(dòng)的來(lái)源為開(kāi)關(guān)電源、電磁干擾或其他不合理的布局布線等。

在綜合工具 Design Compiler 中,時(shí)鐘的偏移和抖動(dòng)統(tǒng)一用不確定度 uncertainty 來(lái)統(tǒng)一表示。

轉(zhuǎn)換時(shí)間(transition)

時(shí)鐘從上升沿跳變到下降沿,或者從下降沿跳變到上升沿時(shí),并不是"直上直下"不需要時(shí)間完成電平跳變,而是"斜坡式"需要一個(gè)過(guò)渡時(shí)間完成電平跳變。這個(gè)過(guò)渡時(shí)間稱之為時(shí)鐘的轉(zhuǎn)換時(shí)間,示意圖如下。


轉(zhuǎn)換時(shí)間大小與單元庫(kù)工藝、電容負(fù)載等有關(guān)。

時(shí)鐘延時(shí)(lantency)

時(shí)鐘從時(shí)鐘源(例如晶振、PLL 或分頻器輸出端)出發(fā)到達(dá)觸發(fā)器端口的延遲時(shí)間,稱為時(shí)鐘延時(shí)。時(shí)鐘延時(shí)包括時(shí)鐘源延遲(source latency)和時(shí)鐘網(wǎng)絡(luò)延遲(network latency),如下圖所示。


時(shí)鐘源延時(shí),是時(shí)鐘信號(hào)從實(shí)際時(shí)鐘原點(diǎn)到設(shè)計(jì)模塊時(shí)鐘定義點(diǎn)的傳輸時(shí)間。上圖所示為 3ns。

時(shí)鐘網(wǎng)絡(luò)延時(shí),是從設(shè)計(jì)模塊時(shí)鐘定義點(diǎn)到模塊內(nèi)觸發(fā)器時(shí)鐘端的傳輸時(shí)間,傳輸路徑上可能經(jīng)過(guò)緩沖器(buffer)。上圖所示為 1ns。

時(shí)鐘源延時(shí)(source latency)是設(shè)計(jì)模塊內(nèi)所有觸發(fā)器共有的延時(shí),所以不會(huì)影響時(shí)鐘偏移(skew)。

時(shí)鐘樹(shù)

數(shù)字設(shè)計(jì)時(shí)各個(gè)模塊應(yīng)當(dāng)使用同步時(shí)鐘電路,同步電路中被相同時(shí)鐘信號(hào)驅(qū)動(dòng)的觸發(fā)器共同組成一個(gè)時(shí)鐘域。理想電路中,時(shí)鐘信號(hào)會(huì)同時(shí)到達(dá)同時(shí)鐘域所有觸發(fā)器的時(shí)鐘端。但是實(shí)際中因?yàn)楦鞣N延遲的存在,這種無(wú)延遲的時(shí)鐘特性是很難實(shí)現(xiàn)的。而且時(shí)鐘信號(hào)的驅(qū)動(dòng)能力有限,難以獨(dú)立的為一個(gè)包含較多的觸發(fā)器的時(shí)鐘域提供有效扇出。為解決時(shí)鐘延遲與驅(qū)動(dòng)的問(wèn)題,就需要采用時(shí)鐘樹(shù)系統(tǒng)對(duì)時(shí)鐘信號(hào)進(jìn)行管理,來(lái)確保良好的時(shí)序和驅(qū)動(dòng)能力。

時(shí)鐘樹(shù),是個(gè)由許多緩沖單元 (buffer cell) 平衡搭建的網(wǎng)狀結(jié)構(gòu)。一般由一個(gè)時(shí)鐘源點(diǎn),經(jīng)一級(jí)一級(jí)的緩沖單元搭建而成。增加 clock buffer(圖中橙色三角模塊) 的實(shí)際時(shí)鐘樹(shù)結(jié)構(gòu)如下所示。


藍(lán)色的上升沿符號(hào)表示時(shí)鐘的轉(zhuǎn)換時(shí)間(transition),紅色的實(shí)線則表示時(shí)鐘延時(shí) (latency),包含 network delay 和 source latency,綠色的虛線表示時(shí)鐘不確定度(uncertainty),包括時(shí)鐘偏移(skew)和時(shí)鐘抖動(dòng)(jitter)。

時(shí)鐘樹(shù)并不是來(lái)減少時(shí)鐘信號(hào)到達(dá)各個(gè)觸發(fā)器的時(shí)間,而是減少到達(dá)各個(gè)觸發(fā)器之間的時(shí)間差異。一般是后端設(shè)計(jì)人員通過(guò)插入 clock buffer 完成時(shí)鐘樹(shù)的設(shè)計(jì)。前端設(shè)計(jì)人員,往往需要保證時(shí)鐘方案與數(shù)字邏輯的功能正確性。

其他時(shí)鐘分類:

同步、異步時(shí)鐘

《Verilog 同步與異步》中有詳細(xì)說(shuō)明,當(dāng)時(shí)鐘同源且滿足整數(shù)倍關(guān)系是,一般可以認(rèn)為時(shí)鐘是同步的。數(shù)字設(shè)計(jì)中同步時(shí)鐘的定義比較寬泛。同時(shí)鐘域下的邏輯不需要進(jìn)行同步處理。

下面從同步電路的角度來(lái)理解同步時(shí)鐘的概念。

同步電路是由時(shí)序和組合邏輯電路構(gòu)成的電路。同步電路的特點(diǎn)是各觸發(fā)器的時(shí)鐘端全部連接在一起,并接在系統(tǒng)時(shí)鐘端。只有當(dāng)時(shí)鐘脈沖到來(lái)時(shí),電路的狀態(tài)才能改變。改變后的狀態(tài)將一直保持到下一個(gè)時(shí)鐘脈沖的到來(lái)。這期間無(wú)論外部輸入 x 有無(wú)變化,狀態(tài)表中的每個(gè)狀態(tài)都是穩(wěn)定的。

門(mén)控時(shí)鐘

門(mén)控時(shí)鐘的基本原理:使能信號(hào)有效的時(shí)候,打開(kāi)時(shí)鐘。使能信號(hào)無(wú)效的時(shí)候,關(guān)閉時(shí)鐘。


由于門(mén)控時(shí)鐘可以將工作時(shí)鐘在適合的時(shí)間關(guān)閉,所以門(mén)控時(shí)鐘在低功耗設(shè)計(jì)中有著廣泛應(yīng)用。門(mén)控時(shí)鐘最簡(jiǎn)單是實(shí)現(xiàn)邏輯是將使能信號(hào)直接與時(shí)鐘信號(hào)做"與"操作,但這樣是不安全的,容易出現(xiàn)毛刺現(xiàn)象。詳細(xì)門(mén)控時(shí)鐘介紹請(qǐng)參考《Verilog RTL 級(jí)低功耗設(shè)計(jì)(下)》。

雙邊沿時(shí)鐘

某些模塊可以在時(shí)鐘的上升沿和下降沿都進(jìn)行數(shù)據(jù)傳輸,達(dá)到速率增倍的效果。

DDR (Double Data Rate) SDRAM 是典型的采用雙邊沿傳輸數(shù)據(jù)的例子。

典型 DDR 數(shù)據(jù)傳輸示意圖如下:


下面對(duì)時(shí)鐘雙邊沿傳輸數(shù)據(jù)的行為進(jìn)行一個(gè)簡(jiǎn)單的仿真。

基本設(shè)計(jì)思路是,利用時(shí)鐘雙邊沿對(duì)數(shù)據(jù)進(jìn)行讀取,然后通過(guò)與時(shí)鐘相反的片選信號(hào)對(duì)數(shù)據(jù)進(jìn)行選擇輸出,完成數(shù)據(jù)在時(shí)鐘雙邊沿的傳輸。

Verilog 代碼描述如下 :

module double_rate(
    input               rstn ,
    input               clk,
    input               csn,

    input [7:0]         din,
    input               din_en,
    output [7:0]        dout,
    output              dout_en);

   //capture at posedge
   reg [7:0]            datap_r ;
   reg                  datap_en_r ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         datap_r        <= 'b0 ;
         datap_en_r     <= 1'b0 ;
      end
      else if (din_en) begin
         datap_r        <= din ;
         datap_en_r     <= 1'b1 ;
      end
      else begin
         datap_en_r     <= 1'b0 ;
      end
   end

   //capture at negedge
   reg [7:0]            datan_r ;
   reg                  datan_en_r ;
   always @(negedge clk or negedge rstn) begin
      if (!rstn) begin
         datan_r        <= 'b0 ;
         datan_en_r     <= 1'b0 ;
      end
      else if (din_en) begin
         datan_r        <= din ;
         datan_en_r     <= 1'b1 ;
      end
      else begin
         datan_en_r     <= 1'b0 ;
      end
   end

   assign dout = !csn ? datap_r : datan_r ;
   assign dout_en = datan_en_r | datap_en_r ;
endmodule

testbench 描述如下,其中雙邊沿?cái)?shù)據(jù)傳輸模塊的時(shí)鐘頻率為 100MHz,但輸入的數(shù)據(jù)速率為 200MHz。

`timescale 1ns/1ps

module test ;
   reg          clk_100mhz, clk_200mhz ;
   reg          rstn ;
   reg          csn ;
   reg [7:0]    din ;
   reg          din_en ;
   wire [7:0]   dout ;
   wire         dout_en ;

   always #(2.5)    clk_200mhz  = ~clk_200mhz ;
   always @(posedge clk_200mhz)
                    clk_100mhz  = ~clk_100mhz ;

   initial begin
      clk_100mhz  = 0 ;
      clk_200mhz  = 0 ;
      rstn        = 0 ;
      din         = 0 ;
      din_en      = 0 ;
      csn         = 0 ;
      //start work
      #11 rstn    = 1 ;
      @(negedge clk_100mhz) ;
      din_en      = 1 ;
      #0.2 ;
      csn         = 1 ; //csn=1 時(shí)輸出下降沿采集的數(shù)據(jù)
      //generate csn
      forever begin
         @(posedge clk_100mhz) ;
         #0.2 ;         //增加些許延遲確保數(shù)據(jù)采集正確
         csn = 0 ;      //csn=0 時(shí)輸出上升沿采集的數(shù)據(jù)
         @(negedge clk_100mhz) ;
         #0.2 ;
         csn = 1 ;      //csn=1 時(shí)輸出下降沿采集的數(shù)據(jù)
      end
   end

   always @(negedge clk_200mhz) begin
      din <= {$random()} % 8'hFF ;  //產(chǎn)生傳輸?shù)碾S機(jī)數(shù)據(jù)
   end

   double_rate u_double_rate(
     .rstn      (rstn),
     .clk       (clk_100mhz),
     .csn       (csn),
     .din       (din),
     .din_en    (din_en),
     .dout      (dout),
     .dout_en   (dout_en));

   initial begin
      forever begin
         #100;
         if ($time >= 10000)  $finish ;
      end
   end

endmodule // test

前幾個(gè)數(shù)據(jù)的仿真結(jié)果如下。

由圖可知,數(shù)據(jù)傳輸正常,且速率為時(shí)鐘頻率的 2 倍。


本次只是對(duì)時(shí)鐘雙邊沿傳輸數(shù)據(jù)進(jìn)行簡(jiǎn)單的仿真,并不是仿真 DDR 的工作原理。DDR 雙倍速率傳輸數(shù)據(jù)的工作原理遠(yuǎn)比此次仿真復(fù)雜的多。

但是一般情況下,不建議使用雙邊沿時(shí)鐘邏輯,主要有以下幾點(diǎn)原因。

always 塊中,不能同時(shí)使用上升沿和下降沿作為敏感列表,也不能在 2 個(gè)always 塊中為同一個(gè)變量賦值,例如下列描述就是錯(cuò)誤的。雖然 RTL 編譯可能不會(huì)報(bào)錯(cuò),但也不能綜合成實(shí)際電路。這就導(dǎo)致了信號(hào)間通信的難度。

   always @(posedge clk or negedge clk) begin

數(shù)據(jù)傳輸速率是數(shù)據(jù)時(shí)鐘頻率的兩倍,如果使用時(shí)鐘上升沿和下降沿邏輯進(jìn)行 RTL 建模,則還需要翻轉(zhuǎn)速率和時(shí)鐘一致的片選信號(hào);如果不使用片選信號(hào),模塊內(nèi)應(yīng)該引入數(shù)據(jù)時(shí)鐘頻率 2 倍的同源時(shí)鐘信號(hào),才可以正常對(duì)數(shù)據(jù)進(jìn)行選擇。

當(dāng)使用的雙邊沿時(shí)鐘邏輯之后,需要對(duì)上升沿和下降沿都進(jìn)行合理的約束。時(shí)鐘約束就會(huì)變得復(fù)雜,布局布線要求更加嚴(yán)格,調(diào)試難度增加。

使用時(shí)鐘雙邊沿進(jìn)行設(shè)計(jì),要求時(shí)鐘的質(zhì)量很高,設(shè)計(jì)時(shí)鐘樹(shù)時(shí)也需要考慮眾多因素。

點(diǎn)擊這里下載源碼


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)