Verilog 跨時鐘域傳輸:快到慢

2022-05-20 14:46 更新

信號從快時鐘域傳輸?shù)铰龝r鐘域來時,需要根據(jù)信號的特點(diǎn)來進(jìn)行同步處理。對于單 bit 信號,一般可按電平信號和脈沖信號來區(qū)分。 

電平信號同步

同步邏輯設(shè)計(jì)中,電平信號是指長時間保持不變的信號。保持不變的時間限定是相對于慢時鐘而言的。只要快時鐘的信號保持高電平或低電平的時間足夠長,以至于能被慢時鐘在滿足時序約束的條件下采集到,就可以認(rèn)為該信號為電平信號。

既然電平信號能夠被安全的采集到,所以從快時鐘域到慢時鐘域的電平信號也采用延遲打拍的方法做同步。

脈沖信號同步

同步邏輯設(shè)計(jì)中,脈沖信號是指從快時鐘域輸出的有效寬度小于慢時鐘周期的信號。如果慢時鐘域直接去采集這種窄脈沖信號,有可能會漏掉。

假如這種脈沖信號脈寬都是一致的,在知道兩個時鐘頻率比的情況下,可以采用"快時鐘域脈寬擴(kuò)展+慢時鐘域延遲打拍"的方法進(jìn)行同步。

如果有時窄脈沖信號又表現(xiàn)出電平信號的特點(diǎn),即有時信號的有效寬度大于慢時鐘周期而能被慢時鐘采集到,那么對此類信號再進(jìn)行脈沖擴(kuò)展顯然是不經(jīng)濟(jì)的。此時,可通過"握手傳輸"的方法進(jìn)行同步。

假設(shè)脈沖信號的高電平期間為有效信號期間,其基本原理如下。

  1. 快時鐘域?qū)γ}沖信號進(jìn)行檢測,檢測為高電平時輸出高電平信號 ?pulse_fast_r??;蛘呖鞎r鐘域輸出高電平信號時,不要急于將信號拉低,先保持輸出信號為高電平狀態(tài)。
  2. 慢時鐘域?qū)鞎r鐘域的信號 ?pulse_fast_r ?進(jìn)行延遲打拍采樣。因?yàn)榇藭r的脈沖信號被快時鐘域保持拉高狀態(tài),延遲打拍肯定會采集到該信號。
  3. 慢時鐘域確認(rèn)采樣得到高電平信號 ?pulse_fast2s_r ?后,再反饋給快時鐘域。
  4. 快時鐘域?qū)Ψ答佇盘?nbsp;?pulse_fast2s_r ?進(jìn)行延遲打拍采樣。如果檢測到反饋信號為高電平,證明慢時鐘域已經(jīng)接收到有效的高電平信號。如果此時快時鐘域自身邏輯不再要求脈沖信號為高電平狀態(tài),拉低快時鐘域的脈沖信號即可。

此方法實(shí)質(zhì)是通過相互握手的方式對窄脈沖信號進(jìn)行脈寬擴(kuò)展。

利用握手信號進(jìn)行同步處理的 Verilog 模型描述如下。

//同步模塊工作時鐘大約為 25MHz 的模塊
//異步數(shù)據(jù)對來自工作時鐘為 100MHz 的模塊
module pulse_syn_fast2s
  #( parameter          PULSE_INIT = 1'b0
   )
  (
   input                rstn,
   input                clk_fast,
   input                pulse_fast,
   input                clk_slow,
   output               pulse_slow);

   wire                 clear_n ;
   reg                  pulse_fast_r ;
   /**************** fast clk ***************/
   //(1) 快時鐘域檢測到脈沖信號時,不急于將脈沖信號拉低
   always@(posedge clk_fast or negedge rstn) begin
        if (!rstn)
           pulse_fast_r  <= PULSE_INIT ;
        else if (!clear_n)
           pulse_fast_r  <= 1'b0 ;
        else if (pulse_fast)
           pulse_fast_r  <= 1'b1 ;
   end

   reg  [1:0]           pulse_fast2s_r ;
   /************ slow clk *************/
   //(2) 慢時鐘域?qū)π盘栠M(jìn)行延遲打拍采樣
   always@(posedge clk_slow or negedge rstn) begin
      if (!rstn)
        pulse_fast2s_r     <= 3'b0 ;
      else
        pulse_fast2s_r     <= {pulse_fast2s_r[0], pulse_fast_r} ;
   end
   assign pulse_slow = pulse_fast2s_r[1] ;

   reg [1:0]            pulse_slow2f_r ;
   /********* feedback for slow clk to fast clk *******/
   //(3) 對反饋信號進(jìn)行延遲打拍采樣
   always@(posedge clk_fast or negedge rstn) begin
      if (!rstn)
        pulse_slow2f_r  <= 1'b0 ;
      else
        pulse_slow2f_r  <= {pulse_slow2f_r[0], pulse_slow} ;
   end
   //控制快時鐘域脈沖信號拉低
   assign clear_n = ~(!pulse_fast && pulse_slow2f_r[1]) ;


endmodule

testbench 描述如下:

`timescale 1ns/1ps

module test ;
   reg          clk_100mhz, clk_25mhz ;
   reg          rstn ;

   initial begin
      clk_100mhz = 0 ;
      clk_25mhz  = 0 ;
      rstn = 0 ;
      #11 rstn = 1 ;
   end
   always #(10/2)   clk_100mhz  = ~clk_100mhz ;
   always #(45/2)   clk_25mhz   = ~clk_25mhz ;

   reg [7:0]            cnt ;
   reg                  pulse_sig ;
   always @(posedge clk_100mhz or negedge rstn) begin
      if (!rstn) begin
         cnt     <= 'b0 ;
      end
      else begin
         cnt    <= cnt + 1'b1 ;
      end
   end

   //窄脈沖生成部分
   always @(posedge clk_100mhz or negedge rstn) begin
      if (!rstn) begin
         pulse_sig      <= 1'b0 ;
      end
      else if (cnt == 5 ||
               cnt == 40 || cnt == 42 ||
               cnt >= 75 && cnt <= 81 || cnt == 85 || cnt == 87 )
      begin
         pulse_sig      <= 1'b1 ;
      end
      else begin
         pulse_sig      <= 1'b0 ;
      end
   end

   pulse_syn_fast2s u_fast2s_pulse(
      .rstn             (rstn),
      .clk_fast         (clk_100mhz),
      .pulse_fast       (pulse_sig),
      .clk_slow         (clk_25mhz),
      .pulse_slow       ());

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

endmodule // test

仿真結(jié)果如下,由圖可知:

  1. 快時鐘域單個窄脈沖信號被慢時鐘域采集到,但是同步后的信號延遲較長,脈沖寬度較大。信號延遲是因?yàn)檠舆t打拍和反饋清零決定的,無法避免。脈寬過大問題,可以通過延遲打拍進(jìn)行邊沿檢測的方法處理。
  2. 兩個緊臨的窄脈沖信號同步后的信號脈寬與單個窄脈沖同步后的信號脈寬沒有差異,也就是說,同步電路漏掉了第二個窄脈沖的檢測。這也屬于握手傳輸處理同步問題的特點(diǎn),當(dāng)快時鐘域的脈沖信號變化速率過快時,該方法不能分辨相鄰的脈沖。
  3. 當(dāng)多個寬窄脈沖信號相鄰較近時,雖然該同步方法不能分辨多個脈沖信號,但同步后的信號脈寬可能會相對大一些。


多位寬數(shù)據(jù)同步

當(dāng)多位寬數(shù)據(jù)進(jìn)行同步時,如果該數(shù)據(jù)各 bit 位都可以看作電平信號,即相對一段時間內(nèi)各 bit 位數(shù)據(jù)均可以保持不變以至于能被慢時鐘采集到,可以消耗一些觸發(fā)器資源對多位寬數(shù)據(jù)進(jìn)行簡單的延遲打拍同步。

但如果數(shù)據(jù)變化速率過快,就不能再使用延遲打拍采樣的方法。因?yàn)榇藭r數(shù)據(jù)各 bit 位不再是電平信號,變化的時間也參差不齊,用異步時鐘進(jìn)行打拍采樣,可能會采集到因路徑延遲不同而導(dǎo)致的錯誤數(shù)據(jù)。

解決此類異步問題的常用方法是采用異步 FIFO (First In First Out)。具體請參考下一節(jié):《Verilog FIFO 設(shè)計(jì)》。

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


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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號