本文內容摘自《advanced FPGA design》對應中文版是 《高級FPGA設計,結構,實現,和優化》第一章中的內容
FPGA中改善時序,我相信也是大家最關心的話題之一,在這本書中列舉了一些方法供給大家參考。
1,插入寄存器(Add Register Layers),在中文版中被翻譯成:添加寄存器層次。即,在關鍵路徑中插入寄存器。
這種方式會增加設計的時滯(clock latency)。插入了幾個寄存器,結果輸出就會延長幾個周期,在不違反設計規格(對clock latency有要求)以及功能沒有影響的時滯情況之下可以這么做。
2,並行結構。把串行改成並行。最典型的就是乘法器了。
作為一個16bit的乘法器,最省資源的就是等待16個clock出結果,也可以是設計成面積最大但是出來結果速度最快的,只需要一個周期就可以出來結果。
3,邏輯展開(Flatten Logic Structures)。中文版同樣翻譯的很保守:展平邏輯結構。
仔細看了看,覺得里面應該包含了連個知識點。第一是邏輯復制,特別是針對大扇出(詳情在altera的官方視頻資料中有提到),通常使用generate或者是在綜合器中設定。第二個是消除代碼中的優先級。這里需要多說一句:現在的工具很智能,就算你寫成if else 有優先級的結構,有時候也能綜合出並行結構。如果並行也符合你的設計要求,為了安全起見,最好還是寫成case這種並行結構比較好。
4,寄存器平衡 (Register Balancing)。
寄存器平衡就是在你的關鍵路徑中移動你的寄存器。第一就是你手動移動 —— 改代碼。第二就是設定綜合器讓它自己移動 —— 不到萬不得已不這么干,因為這么多導致代碼移植性變差。
5,路徑重組
這是最有意思的一個方法,也是體現你的設計水平的方式。結果書中給出的例子確實讓我驚訝了一下。為啥呢,先貼出代碼
第一版:
1 module randomlogic_1( 2 output reg [7:0] Out, 3 input [7:0] A, B, C, 4 input clk, 5 input Cond1, Cond2); 6 always @(posedge clk) 7 if(Cond1) 8 Out <= A; 9 else if(Cond2 && (C < 8)) 10 Out <= B; 11 else 12 Out <= C; 13 endmodule
第二版:
1 module randomlogic_2( 2 output reg [7:0] Out, 3 input [7:0] A, B, C, 4 input clk, 5 input Cond1, Cond2); 6 7 wire CondB = (Cond2 & !Cond1); 8 9 always @(posedge clk) 10 if(CondB && (C < 8)) 11 Out <= B; 12 else if(Cond1) 13 Out <= A; 14 else 15 Out <= C; 16 endmodule
從代碼上來看2版好像還比第一版路徑更長,因為 out <= B,的路徑從 Cond2 && (C < 8) 變成了 (Cond2 & !Cond1) && (C < 8)。似乎還變長了,怎么叫優化了呢?實際上,如果我們不看下面的圖,自己模仿RTL Viewer,發現2版的關鍵路徑真的比1短。書中給出的圖示也是如此,這是第一版的視圖,關鍵路徑經歷了4個器件
這是第二版的視圖,關鍵路徑居然少了一個器件。
這就是我驚訝的地方,因為這種做法從代碼上看不出來。所以需要更高的硬件知識才能駕馭啊。
歡迎加入: FPGA廣東交流群:162664354
FPGA開發者聯盟: 485678884