FPGA基礎學習(9) -- 復位設計


一開始接觸到FPGA,肯定都知道”復位“,即簡單又複雜。簡單是因爲初學時,只需要按照固定的套路——按鍵開關復位,見寄存器就先低電平復位一次,這樣一般情況可以解決99%的問題,甚至簡單的設計,就不可能有問題。複雜是因爲復位本身是對大規模的硬件單元進行一種操作,必須要結核底層的設計來考慮問題。

1. 常見問題

自己在學習實踐過程中,以及看到網友詢問的,有關FPGA復位設計大概有以下幾類問題:

  • 我板子上沒有設計按鍵復位怎麼辦?
  • 怎麼設計上電覆位?不可能上電都要去按鍵吧
  • 同步復位還是異步復位?各自優勢是啥?
  • 高電平復位還是低電平復位?

……

歸根結底,就是怎樣設計復位,我可能給不出完美的答案,但查閱了一些資料,總結了一些設計中考慮的因素,在加上參考文獻,應該能解決99.9%的疑惑。

2. 常見的復位方式

我們習慣上通常使用的復位有三種方式:

  • 硬件開關:復位信號接一個撥碼開關或按鍵,或者RC電路

  • 電源芯片:上電時候電源芯片產生,可以長時間維持,直到穩定。

  • 控制芯片:控制芯片產生復位脈衝。

沒有專門的電源或控制芯片,甚至連按鍵都忘記設計的情況下,有人提出可不可以拿內部計數器做一個所謂的上電“軟”復位,如下代碼所示,當cnt計數到一定的值時,產生一個復位脈衝信號。

always@(posedge clk or negedge rst_n)
 begin
     if(!rst_n)
         cnt <= 0;
    else
         begin
        if(cnt < 23'd50_00000) //100ms
             cnt <= cnt+1'b1;
         else
             cnt <= cnt;
        end
 end
 always@(posedge clk or negedge rst_n)
  begin
      if(!rst_n)
          begin
          rst_nr0 <= 0;
          rst_nr1 <= 0;
          end
      else if(cnt == 23'd50_00000)
          begin
          rst_nr0 <= 1;
          rst_nr1 <= rst_nr0;
          end
      else
          begin
          rst_nr0 <= 0;
          rst_nr1 <= 0;
          end
  end

沒有設計外部硬件復位的同學又會反駁,我rst_n都沒有!去掉復位,默認上電cnt = 0,可不可以?既然默認cnt = 0了,那其他所有的寄存器不都默認爲0了嗎?接着往下分析。

3. 合理的復位設計

從參考文獻中得出有關復位設計的幾條重要結論,有助於我們明確復位設計的方向,如下:

  1. 低電平復位並不是最合理的處理方式;
  2. 建議採用異步復位同步化(異步復位同步釋放處理)
  3. 全局復位並不是最佳方式;
  4. 並不是所有時序電路都要加復位;

對上述結論分析,見後續總結。

3.1 復位電平

有關復位電平,實際上是跟FPGA芯片內部的觸發器結構有關,在之前的博文有提到過。作爲xilinx 7系列觸發器,其 R 端口既可用作同步置位/復位端口,也可用作異步預設/清除端口,但無論哪種方式,都是高電平有效。Altera的是低電平有效。

當在7系列芯片上採用低電平復位,會有什麼問題呢?如下:

如果RTL代碼採用了低電平有效的復位模式,綜合器將在復位信號驅動寄存器SR控制端之前的插入一個反相器(interver)。你必須使用一個查找表(look up table)來實現反向器,以利用LUT的輸入端口。低電平有效的控制信號帶來的額外的邏輯可能拉長了執行時間(runtime),將導致更低的FPGA資源利用率,也將影響時序和功耗。

到底我想說點什麼呢?儘可能的在HDL代碼或者實例化的模塊中使用高電平有效的控制信號。如果在設計中,你不能夠改變這些控制信號的極性,你需要在代碼的頂層文件反轉這些控制信號。採用這種方式描述電路的話,這些反向器將被吸收到I/O邏輯中,而不需要使用額外的FPGA邏輯、路徑。

所以再次強調:復位電平的選擇跟芯片結構有關!

3.2 異步復位同步化

異步復位同步化簡單的說就是將異步復位信號在相關的時鐘域模塊中進行同步化處理。單純的同步復位、異步復位以及其他的一些復位方式,都存在一些缺陷,比如抗噪聲、存在亞穩態等問題,深入學習可以查閱相關文獻。

異步復位同步化處理的結構代碼及schematic(xilinx 7系列)如下:

 module rst_signal(
    input       clk,
    input       rst,
    output      sys_rst 
 );
    reg         r1_rst,r2_rst;
  
    always@(posedge clk or posedge rst) begin
        if(rst) begin
            r1_rst <= 1'b1;
            r2_rst <= 1'b1;
        end else begin
            r1_rst <= 1'b0;
            r2_rst <= r1_rst;
        end
    end
 
    assign sys_rst = r2_rst;
    
endmodule

可以看到,模塊將系統輸入的異步復位信號進行同步,產生了一個後續邏輯使用的同步化了的異步復位,隨後即可將該復位信號sys_rst用於其他模塊的復位。爲了減少亞穩態對上述同步器中的兩個寄存器的影響,這兩個寄存器應該在FPGA中被放置的越靠近越好(相應的約束:set_property ASYNC_REG TRUE [get_cells [list r1_rst_reg r2_rst_reg]]),儘量減少佈線延遲。

以上只是一個基本原理示意,在實際使用過程中還應注意以下兩點:

  • 外部輸入異步復位信號應該增加濾波和去抖處理;
  • 在復位之前,確保由 MMCM 或PLL 生成的時鐘是穩定且被鎖定的;
  • 將異步復位信號分別引入不同的時鐘域進行同步化

綜上,復位處理的原理圖如下所示:

3.3 恰到好處的復位

看似簡單的復位,實際上不簡單,來係數復位的N宗罪:

  • 復位網絡需要佔用佈線資源;
  • 導致其餘信號的佈線信號受到影響,降低了它們佈線的自由度;
  • 增加的佈線網絡往往需要使用更高速率的芯片;
  • 復位網絡佔用大量佈線資源,使得Place&Route的時間大大增加;
  • 復位信號需要佔用大量的邏輯資源;
  • 復位信號需要使用觸發器的專用復位管腳;
  • 可操作的復位信號往往導致D觸發器的輸入前增加額外的門操作或專用的復位信號輸入;
  • 增大整個設計 的尺寸;
  • 額外的邏輯消耗降低了系統的性能;
  • 阻止了使用高效特徵,如Xilinx FPGA特有的SRL16E 移位寄存器。

簡單的說,復位的存在會對FPGA的綜合面積產生影響,主要體現在兩個方面:第一、在編寫代買的時候,習慣給所有時序電路都加上覆位信號,這樣往往會導致資源無形的浪費;第二,沒有合理的設計復位電路會產生額外的資源消耗。

什麼時候可以叫復位呢?一般判斷原則是:

類似於移位寄存器這類直通型電路,只起到一個傳輸信號的作用,本身不會對信號產生任何影響。其傳輸信號正確與否,在於其輸入端的信號是否正確。因此,此類電路自身無需加復位信號,而只需再起輸入端口加復位信號(也就是數據來源處的電路),以控制輸入數據。

4. 補充

4.1 所謂的上電初始化

當一個Xilinx的FPGA芯片被重新配置時,每一個單元都將被初始化。在某種意義上講,這是一個上電之後的“終極的”全局復位操作,因爲它不僅僅是對所有的觸發器進行了復位操作,還初始化了所有的RAM單元。隨着Xilinx FPGA芯片內部的嵌入式RAM資源越來越多,這種“終極的”全局復位操作越來越有意義。對所有的RAM單元進行預定義,在軟件仿真和實際操作中都是非常有幫助的,因爲這樣避免了在上電時採用複雜的啓動順序來清除存儲單元內容的操作。

所以在xilinx平臺,開篇的“軟”復位,實際上是沒有多大意義的。

綜上,採用以上總結的復位處理方法,應該能解決99.9%的問題了。

參考文獻

  1. 《wp272: Get Smart About Reset: Think Local, Not Global》;
  2. 《FPGA實戰演練. 高級技巧篇》——王敏志編著;
  3. DC綜合之CDC篇
  4. How do I reset my FPGA?
  5. Xilinx FPGA復位邏輯處理小結
  6. FPGA的復位方法幾種方法
  7. 在FPGA開發中儘量避免全局復位的使用?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章