常用時序收斂方法

結構調整

結構調整是提高時域性能的一種方法,它是在不改變原有組合邏輯功能的前提下,通過調整其內部邏輯門之間的連接關係,來達到減少邏輯門級數的目的,進而提高時域性能的方法。舉例如下:
現在有同步輸入總線A、B、C、D,需要在下一時鐘週期就能以寄存的方式輸出它們的和SUM。那麼通常來說,你可能會將HDL代碼寫成這樣:

--VHDL example
--all inputs are scalar type
PROCESS (clk)
BEGIN
    IF clk'event AND clk = '1' THEN
        SUM <= A + B + C + D;
    END IF;
END PROCESS;
// Verilog example
// all inputs are bus type
always@(posedge clk)
begin
    SUM<=A+B+C+D;
end

對於上述代碼,編譯器通常會將它翻譯成如圖所示的電路。

由此可見,該電路中從“輸入A~D”到“輸出SUM的寄存器輸人”之間,最長的邏輯路徑依次經過了3個加法器,也就是說上述電路中的組合邏輯部分有3級加法器,如果一個加法器的時間延遲爲T,那麼整個組合邏輯的時間延遲就是3T.
編譯器之所以會給出如此結構的電路,主要是因爲在HDL語言中,“+”運算符號對應的運算優先關係爲從左至右,因此A、B先參與運算,而其結果再和C一起送人下一個加法器運算,而這次的結果再和D一起送人第三個加法器進行運算,至此纔得到組合形式輸出的和。
通過進一步分析上述電路可以發現,當A、B進行運算時,C、D其實閒着沒事幹(雖然事實不是這樣,但是此時第二、第三個加法器進行的運算都是無效的),因爲第一、第二個加法器的輸出還沒有穩定;而當A、B或C參與有效運算時,D其實一直是閒着沒事幹的(解釋類似同前),因爲第二個加法器的輸出還沒有穩定。由此可見,上述電路中的邏輯結構不是很合理,因爲我們更希望編譯器得出的電路是同時使用兩個加法器分別處理A、B和C、D的求和,然後再使用一個加法器處理這兩個加法器的結果即可。爲了達到這種效果,可以對上例進行一些修改,結果如下:

--VHDL example
--all inputs are scalar type
PROCESS (clk)
BEGIN
    IF clk'event AND clk = '1' THEN
        SUM <= (A + B) + (C + D);
    END IF;
END PROCESS;

可見,我們僅僅通過添加了兩個小括號,就調整了原有算式中不太合理的運算優先級關係,這便是“小括號的妙用”。對應上述代碼,編譯器給出的電路結構如圖所示。

 

1、插入寄存器

將計算邏輯分成多個時鐘週期實現,這是常用的時序優化方法,可以減少過多的組合邏輯層數,但會增加延時。

這裏以一個多路輸入求和計算爲例

module sum(
    input        clk,
    input  [15:0] data_A,
    input  [15:0] data_B,
    input  [15:0] data_C,
    input  [15:0] data_D,
    output [17:0] sum_o);

    always @(posedge clk) begin
        sum_o <= data_A + data_B + data_C + data_D;
     end

endmodule

增加寄存器後,改爲

module sum(
    input        clk,
    input  [15:0] data_A,
    input  [15:0] data_B,
    input  [15:0] data_C,
    input  [15:0] data_D,
    output [17:0] sum_o);

    reg [16:0] sum0, sum1;

    always @(posedge clk) begin
        sum0 <= data_A + data_B;
        sum1 <= data_C + data_D;
     end

    always @(posedge clk) begin
        sum_o <= sum0 + sum1;
     end

endmodule

2、邏輯展平設計

優化代碼中優先級譯碼電路邏輯,主要出現在IF/ELSE結構語句中,這樣邏輯結構被展平,路徑延遲得以縮短。

IF ELSE結構語句存在明顯的優先級,建議儘量用CASE語句來替代。

3、防止變量被優化

HDL綜合佈線軟件會根據實際情況,自動優化代碼邏輯,可能存在將多個不同寄存器變量合併成一個寄存器變量的情況。

對於不希望被優化的變量,可以在變量定義前,添加(* keep = "ture" *)

高扇出

高扇出問題,原因是一個寄存器驅動後級數超過了它本身的驅動能力,導致延遲時間過大,不滿足時序。

1、使用max_fanout
在變量定義前,可以添加(* max_fanout = n *),來設置變量的最大扇出數n,超過這個扇出數,綜合軟件會自動複製多份變量。

2、復位信號高扇出
復位信號是常見的高扇出問題,主要解決辦法有:

(1)減少復位信號的使用,能使用使能信號控制的,就用使能信號。

(2)對於大型模塊,復位信號可以使用BUFG來驅動復位信號,可以增加復位信號的驅動能力

資源消耗

FPGA器件的整個工程資源消耗,不管是LUT還是BRAM等資源,建議不超過80%。

一旦資源消耗超過80%,在佈線綜合時,就出現佈線資源不夠,導致出現佈線擁塞,從而出現了時序不收斂的情況。

佈線擁塞也分爲全局擁塞和局部擁塞,可能是高扇出信號過多,也可能是局部佈線資源不夠用,導致時序路徑過長。

1、優化代碼邏輯,減少資源消耗。

在資源不夠用的情況下,建議檢查代碼是否可優化,設置的RAM大小是否過大等等。

2、使用替代資源實現

在FPGA中實現RAM時,可以根據整個資源的使用情況,考慮使用Distributed RAM、URAM等資源來減少BRAM的消耗。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章