前面介紹了系統級的低功耗設計,換句話說就是在系統級降低功耗可以考慮的方面。系統級的低功耗設計,主要是由系統級設計、具有豐富經驗的人員實現,雖然還輪不到我們設計,我們了解一下還是比較好的。我們前端設計人員的重點不在系統級設計上面,而是在RTL級(及綜合)上面。下面我們就來介紹RTL編碼與邏輯綜合的低功耗設計,重點是門控時鐘和操作數隔離技術。今天主要是講解操作數和一些常見的方法;門控時鐘由于內容比較多,所以寫在后面。
(1)并行與流水的選擇
對于某一個功能模塊,我們可以通過并行的方式進行實現,也可以通過流水線的方式進行實現,這兩種方法都是面積換速度,不過在一定的場合下可以降低功耗,需要靈活應用,下面就簡要地介紹一下這兩種方法(的使用)。
·并行處理常用于數字信號處理部分。采用并行處理,可以降低系統工作頻率,從而可能降低功耗。例如下圖中:
?
用兩個乘法器來取代原設計中的一個乘法器。這樣,時鐘頻率可以降低,系統的整體功耗會降低。采用這種方法,要在增加的面積與節省的功耗之間進行權衡。
·流水線技術可以將一個較長的組合路徑分成M級流水線。路徑長度縮短為原始路徑長度的1 /M。這樣,一個時鐘周期內充/放電電容變為C/M。如果在加入流水線之后,時鐘速度不變,則在一個周期內,只需要對C/M進行充/放電,而不是原來對C進行充/放電。因此,在相同的速度要求下,可以采用較低的電源電壓來驅動系統。這樣,系統的整體功耗可能會降低。例如對于下面的流水線設計:
?
?假設在一個設計中,關鍵路徑是一個32bit X 32bit的乘法器。假設該乘法器的整體電容為C,工作頻率為f。
->不加流水線時,要達到此工作頻率,工作電壓應該為V。
->當采用流水線方式時,該路徑被分成兩部分。對于每一部分,整體電容變為C/2。這樣,如果要達到原來的工作頻率f,工作電壓可以降為βV,這里β<1. ?因此,整個系統可以工作在βV電壓下,整體功耗變為原來的β^2倍,即:
????????????????????
?
?
(2)資源共享與狀態編碼
對于設計比較多算術運算的設計,如果有同樣的操作在多處使用,那我們就可以避免相應的運算邏輯在多個位置重復出現。例如下面是沒有進行共享資源的代碼:
?
進行資源共享后的代碼如下所示:
?
上述代碼中,在各分支中只使用一個比較器和一個算術比較器就可以實現相同的功能,因此極大地減少了功耗。
此外,對于一些變化非常頻繁的信號,我們利用數據編碼來降低開關活動(例如,用格雷碼比用二進制碼翻轉更少,功耗更低)。
?
?
(3)操作數隔離
下面我們重點介紹另外一種常用的方法——操作數隔離(operand isolation,簡稱OI)的方法。
①操作數隔離的原理
我們先來看一個電路,如下所示:
?
上面的電路圖中,當SEL_0≠1,SEL_1≠0時,加法器Add_0的運算結果并不能通過mux_0和mux_1到達寄存器reg_0的輸入端口,也就是說寄存器reg_0將不會保存加法器Add_0的運算結果,這就意味著加法器Add_0的運算是不必要的。為了節省功耗,我們可以用操作數分離的方法,在某些條件下,使加法器不工作,保持靜態,進行操作隔離之后的電路如下所示:
?
因此,操作數隔離的原理就是:如果在某一段時間內,數據通路的輸出是無用的,則將它的輸入置成個固定值,這樣,數據通路部分沒有翻轉,功耗就會降低。
下面我們再舉一個例子,對于下面的電路:
?
上圖所示的乘法器中,如果知道乘法操作延遲超過半個時鐘周期,則將乘法器的輸出與反相時鐘進行與操作,可以保證在時鐘前半周期乘法器的輸出不會導致加法器的翻轉。這就是操作數隔離技術的基本思想。不過需要注意的是,采用這種方法,會增加面積,并影響到DFT,所以在使用前應該對它的利弊進行權衡。
?
②OI的物體選擇
OI并不是什么時候都可以進行使用的(也就是說不是所有的對象(物體)都符合操作數隔離的要求)。此外操作數隔離主要是:滿足一定條件下,通過指定操作數隔離的物體來實現的;指定操作數隔離的物體可以通過EDA工具自動執行(我們一般使用這種方法),也可以通過我們手動進行。下面我們就分別介紹一下這兩種方式。
·EDA工具自動指定操作數隔離的物體
默認情況下,如果操作數隔離的物體滿足下列條件,Power Compiler自動選擇它(們):
1.OI物體是算術運算器或層次組合單元。
2.OI物體的輸出是選擇性地使用。
3.運算器必須有非零的翻轉率。
4.僅當工具進行功耗估算后,用操作數隔離具有潛在的功耗可節省,才把它(們)作為OI物體。
自動進行操作數隔離的腳本如下:
set ?do_operand_isolation ???true
set_operand_isolation_style
read_saif ?
……
compile
?
·手動指定操作數隔離的物體
除了使用EDA工具自動選擇IO物體,我們也可以手動進行指定,然后進行操作數隔離。手動完成操作數隔離大致可以分為兩步:
A:設定操作數隔離的風格為手動(用戶自定義模式):
在約束腳本中加入下面的命令,說明是使用手動的方式指定IO物體:
set_operand_isolation_style ?-user_directives
?
B:手動指定IO物體:
手動指定IO物體有下面兩種方式:
1.用命令指定OI物體:set_opreand_isolation_cell,例如:
set_operand_isolation_cell ?[get_cells ??U1]
2.在RTL代碼中加綜合指引(pragma)
例如:下面的RTL中加入了綜合指令“//synopsys_isolate_operands":
if(c2 == 1’b1)
o ?= a + b ;
else
o ?= c + d ;?//synopsys_isolate_operands
?
完成前面A、B兩步的設置之后,在使用compile命令進行綜合時,如果手動指定的IO物體滿足前面的三點:
1.OI物體是算術運算器或層次組合單元。
2.OI物體的輸出是選擇性地使用。
3.運算器必須有非零的翻轉率。
那么綜合器就會進行操作數隔離。
?
③操作數隔離的范圍
有些時候,我們需要在整個設計中指定某些模塊要做操作數隔離,某些模塊不要做操作數隔離。這時候我就可以使用set_operand_isolation_scope命令來實現了。例如下面的分層模塊中:
?
我們只對SUB2模塊中的操作數做隔離,其他的模塊不做操作數隔離,那么就可以使用下面的示例腳本:
set_operand_isolation_scope ??[get_designs ??tops] ??false
set_operand_isolation_scope ??[get_designs ??sub1] ??false
set_operand_isolation_style
······
?
④隔離邏輯的設置
實現操作數隔離需要插入相應的隔離邏輯,比如與門或者或門之類的。這些邏輯可以由EDA自動選擇,也可以由我們自己手動指定。下面就來介紹這兩種方式。
·默認的EDA工具選擇
默認情況下,隔離邏輯由工具自動選擇。工具根據輸入數據連線的靜態概率(SP)來選擇適合的隔離邏輯為“AND'’門或“OR”門。使用的命令如下所示:
set_operand_isolation_style ??-logic ??adaptive
如果SP > 0.5,選擇“OR”門作為隔離邏輯
如果SP < 0.5,選擇“AND”門作為隔離邏輯
?
·手動
我們可以手工地選擇隔離邏輯,例如下面命令指定用“AND”門作為隔離邏輯:
set_operand_isolation_style ??-logic ??AND
?
通過前面的描述,我們知道操作隔離的實現可以通過EDA全自動化實現,也可以通過我們指定OI物體的半自動化實現。完成操作數隔離后,我們可以用命令報告設計中的操作數隔離,例如:
report -operand_isolation ?-isolated ?-verb命令顯示如下的信息:
?
?
?
⑤操作數隔離的復原
?加入隔離邏輯之后,如果時序變差達到不能滿足要求的情況,我們就要復原原來的邏輯。復原的方法也是有自動和手動的方法。
·自動
一般情況下,如果加了隔離邏輯后,設計的時序變差了,即當WNS(worst negative slack)大于指定的slack時,EDA工具會使設計自動復原到原來沒有操作數隔離的狀態。例如下面的腳本適用于如果WNS大于0. 5時,設計自動復原到原來的狀態:
set_operand_isolation_slack ??0.5
compile
compile ?-inc
?
·手動
我們也可以用手工的方法復原操作數隔離。用手工的方法進行操作數隔離的復原是在指定的時序路徑上刪除OI邏輯。這時候不考慮slack。需要執行增量編輯去刪除OI邏輯。腳本如下:
remove_operand_isolation ?-from ??<starting_point> ??to ??<end_point>
compile ?-inc
······
?
?
最后,提供一個完整的加入操作數隔離的示例腳本,如下所示,使用了默認的隔離邏輯類型和操作數隔離的自動恢復:
set ??do_operand_isolation ??true
read_verilog ??mydesign.v
current_design ??top
link
create_clock -p 10 [get_ports ??clk]
set_operand_isolation_style
set_operand_isolation ??-slack 0.1
compile
report_operand_isolation -verb ?-isolated
······
(4)門控時鐘
門控時鐘在我的第一篇博客中有簡單的描述,這里就進行比較詳細的描述吧。我們主要學習門控時鐘電路是什么、什么使用門控時鐘、綜合庫里的門控時鐘、如何使用門控時鐘、對門控時鐘的一些處理、手動插入門控時鐘。我們重點介紹如何使用門控時鐘和門控時鐘的處理。
①門控時鐘概述
門控時鐘有兩種方案:一種直接針對寄存器的時鐘進行門控,一種對模塊級別的時鐘進行門控。相比之下,直接對寄存器的時鐘進行門控更為靈活。因為在很多時候,我們不能保證剛好將不需要門控的寄存器與需要門控的寄存器分配在不同的模塊。因此我們主要介紹寄存器級的門控時鐘。
=============================================================================
下圖是門控時鐘的一個簡單電路圖:
?
上述電路圖中,將控制信號(EN)直接與時鐘信號(CLK)進行與操作,以完成門控。門控后的時鐘信號GCLK送到寄存器陣列中。這樣,當EN為0時,該時鐘被關掉。相應的波形如下所示:
?
可以看出,如果EN信號不加控制,會導致門控時鐘信號出現毛刺。時鐘上的信號出現毛刺是非常危險的。所以在進行門控時,為了使門控時鐘不產生毛刺,使能信號必須滿足條件:它是寄存器的輸出,該寄存器的時鐘信號與要門控的時鐘信號是相同的。由于上述原因,雖然采用這種門控方式最直接,但在實際中很少采用。
==============================================================================
為了解決這種問題,引入基于鎖存器的門控時鐘方案,如下圖所示:
?
對應的時序圖如下所示:
?
可以看到,這種方式消除了EN與CLK組合產生的毛刺對門控時鐘的影響。該方法的原理在于:鎖存器在CLK為低時透明。這樣,EN 信號上的毛刺僅出現在CLK的低電平處,EN1與CLK進行與操作,可以將這部分毛刺消除掉。這樣,GCLK上就沒有毛刺了。
? 不過需要注意的是,如果在電路中,鎖存器與與門相隔很遠,到達鎖存器的時鐘與到達與門的時鐘有較大的延遲差別,則仍會出現毛刺,下面就來分析一下:
?
上述的右上圖中,B點的時鐘比A時鐘遲到,并且Skew > delay,這種情況下,產生了毛刺。為了消除毛刺,要控制Clock Skew,使它滿足Skew >Latch delay(也就是鎖存器的clk-q的延時)。上述的右下圖中,B點的時鐘比A時鐘早到,并且|Skew| ?> ENsetup 一 (D->Q),這種情況下,也產生了毛刺。為了消除毛刺,要控制Clock Skew,使它滿足|Skew|< ENsetup一(D->Q)。
常見的是第一種毛刺,不過我們可以將這個邏輯做成一個單元,這樣就基本上能消除上面的那兩種毛刺了,即:
?
============================================================================
通常情況下,時鐘樹由大量的緩沖器和反相器組成,時鐘信號為設計中翻轉率最高的信號,時鐘樹的功耗可能高達整個設計功耗30%。加入門控時鐘電路后,由于減少了時鐘樹的開關行為,節省了開關功耗。同時,由于減少了時鐘引腳的開關行為,寄存器的內部功耗也減少了。采用門控時鐘,可以非常有效地降低設計的功耗,一般情況下能夠節省20%~60%的功耗。
此外,由于門控時鐘不需要用到MUX單元,加入門控時鐘電路后,設計的面積也減少了。門控時鐘電路的扇出越大,減低功耗和面積的效能越好。當然,扇出太大了,又會產生時序等的問題。
門控時鐘電路非常容易實現,用工具自動插入門控時鐘,不需要修改RTL代碼,門控時鐘與工藝無關。
這些優點本來應該放在總結處說的,這里提前進行敘述是為了能夠給大家一個印象。其中低功耗的優點是通篇進行講解的,然后降低面積和實現的問題,我們會在后面的具體實現進行講解。
?
②綜合庫中的門控時鐘模型
前面我們說了,門控時鐘可以以三種方式實現:一個與門(即不帶鎖存的門控時鐘)、分散的鎖存器+與門、集成的鎖存器+與門。在綜合庫中,與門、鎖存器是基本邏輯單元,因此可以構成門控時鐘。此外,綜合庫中還專門提供了集成的門控單元。一般情況下,我們使用的是集成的門控單元,因為這個門控單元是對Skew作了控制,不存在前面描述的毛刺問題。
一個示例的 ?綜合庫中的時鐘門控單元描述如下所示:
(該綜合庫模型中,E為門控信號;CK為時鐘信號;ENL是鎖存器輸出;ECK為對輸出門控后的時鐘信號;statetable描述了該門控單元中內部鎖存器的功能。該單元的其他內容描述就不具體描述了,我在Tcl與Design Compiler這個分類的博客里面有對綜合庫進行具體的介紹。)
?
?
?
?
③門控時鐘實現
我們要實現門控時鐘,首先就得從RTL代碼中進行設置。在RTL代碼中將需要門控的寄存器寫成“載入-使能”的形式,如下所示:
always ?@(posedge CLK)
?? if (EN)
Q <=D;
上述代碼中,如果EN有效,則寄存器在時鐘上升沿采樣數據,否則保持原值。一般情況下,綜合會得到下圖右上角的電路,而插入門控時鐘的電路為下圖右下角的電路:
?
上圖的典型綜合結果中(即不使用門控時鐘的情況),在每個受EN使能控制的寄存器之前加入了一個MUX,當EN信號有效時,寄存器鎖存輸入信號D;否則保持原值。這種方法也能減少寄存器上的翻轉,因而節省翻轉功耗。然而,這種“載入一使能”結構中,每個寄存器都有一個MUX,假設MUX面積為4,則8位寄存器需要增加的面積為32。面積越大,意味著芯片成本越高,而且整體的功耗也會增加。另外,這種方式不能消除時鐘樹上的功耗。
對于右下角的門控時鐘形式的綜合電路,假設一個門控邏輯的面積為10,一個門控時鐘信號可以驅動8位寄存器,則在門控時鐘電路中,對每8個寄存器需增加一個門控邏輯,增加的面積為10。由此可以看到,門控時鐘的電路比普通綜合結果的面積更小、功耗更低。
=============================================================================
鑒于門控時鐘的優點,我們需要把普通的綜合結果“轉換”為門控時鐘的結果,我們主要是通過DC的power compiler來自動實現的。我們主要通過命令來設置門控時鐘的風格和通過命令“啟動”插入門控時鐘。綜合工具根據我們所設置的時鐘門控的風格,插入相應的門控邏輯。因此,門控時鐘的實現主要有兩步,一步是設置門控時鐘的風格,通過命令set_clock_gating_stale 及其選項來實現;另一步就是在網表中加入門控時鐘,通過命令insert_clock_gating來實現。下面我們就來介紹一下這兩個設置,由于命令在不同版本的DC中有所不同,命令的具體選項就可能不一樣,這里就只介紹一些常用或者說是可能用到的選項。
==============================================================================
在執行insert_clock_gating命令前,我們一般先使用set_clock_gating_style命令來指定要插入門控時鐘電路的結構(或者說是插入門控時鐘的風格)。下面我們就來介紹一下使用這個set_clock_gating_style命令可以進行插入哪些門控時鐘電路結構。
·-sequential_cell?選項設置是否采用基于鎖存器的風格。因為我們的門控時鐘有三種形式(不適用鎖存器的與門,基于鎖存器+離散與門,集成的鎖存器+與門),因此就要指定使用哪一種形式:
A:基于鎖存器的離散門控單元是默認值,可以通過下面的命令來設置:
set_clock_gating_style ??-sequential_cell ?latch
B:不使用鎖存器的門控單元,可以通過下面的命令來設置:
set_clock_gating_style ??-sequential_cell ?none
C:使用集成的門控單元則不需要使用這個-sequential_cell來設置了,因為-sequential_cell 選項設置是否采用基于鎖存器的風格。使用集成的門控單元直接設置參數就可以了,例如可以通過下面的命令來設置使用集成的門控單元:
set_clock_gating_style ???“integrated”
一般推薦使用集成門控這種方式。
?
·-positive_edg_logic選項(簡寫為-positive或-pos)設置在RTL代碼中用上升沿鎖存的寄存器(也就是上升沿沿觸發的寄存器)采用何種門控邏輯。
?????-negative_edg_logic選項(簡寫為-negative或-neg)設置在RTL代碼中用下降沿鎖存的寄存器(也就是下降沿觸發的寄存器)采用何種門控邏輯。
例如下面的命令:
set_clock_gating_style ?-sequential_cell ?none ?-pos ?“or”
該命令設置了不適用鎖存器的風格,然后對于上升沿觸發的寄存器,其門控單元使用或門邏輯構成。
?
set_clock_gating_style ?-neg “integrated”
該命令置在RTL代碼中用下降沿鎖存的寄存器(也就是下降沿觸發的寄存器)使用集成門控時鐘單元。
?
set_clock_gating_style -positive ?“integrated”??-negative “integrated”
該命令設置RTL代碼中,無論你的寄存器是上升沿觸發還是下降沿觸發,控制該寄存器的時鐘單元都是使用集成門控時鐘單元。
?
·-minimum_bitwidth?選項用于設置進行時鐘門控的寄存器陣列的最小寬度。對于寬度小于該設置的寄存器陣列,不進行時鐘門控;然而當電路由有公共使能時,會對電路進行分解進行集體門控。例如下面的命令作用與下面的電路:
set_clock_gating_style ?-minimum_bitwidth ?4
上述命令意味著一個門控時鐘至少要觸發4個寄存器。左圖中有3個寄存器組,每組只有3個寄存器,不能滿足至少要有4個寄存器的要求。因此,對于每個組的寄存器,不能用門控時鐘。然而,所有的3個寄存器組,都有1個公共的使能信號”a”,我們可以把它分解出來作為控制時鐘的門控信號。這樣一來,信號“a”控制9個寄存器,它滿足最少要觸發4個寄存器的要求。因此將上面的命令約束上面左邊的電路時,綜合得到結果就會成為右邊有門控時鐘的電路。
?
·-num_stages選項用于設置一個多級門控的級數。在有些設計中,頂層的門控信號會分解成不同的子門控信號。在缺省情況下,僅對跟寄存器陣列相連的門控制信號生成門控邏輯。例如對于下面的電路圖:
?
在這個例子中,全局門控信號EN分別跟a,b,c信號組合,然后驅動不同的寄存器陣列。缺省情形下(set_clock_gating_style命令的默認設置為“num_stages”等于“1",缺省時也為1),跟寄存器陣列相連的門控信號 ??由門控單元給出。
由于所有的3個寄存器組都有1個公共使能“a",它可以被分解出來產生1個額外(級)的門控時鐘單元。在set_clock_gating_style命令加選項“-num_stages 2",就可以產生下圖所示的兩級門控時鐘:
?
?
使用多級門控時鐘,時鐘綜合器可以盡量地擺放門控時鐘單元,使它靠近時鐘源,從而最大限度地降低時鐘樹的功耗。
?
·-control_point與-control_signal選項跟DFT有關,用于設置該門控單元在DFT時是否可控,DFT控制信號是scan-enable還是test-mode,以及DFT控制信號與EN信號的組合邏輯是放在門邏輯中的鎖存器之前還是之后。通常,將DFT控制信號與EN信號進行或操作,這樣在DFT時,可以控制該門控邏輯。例如下面的命令約束:
set_clock_gating_style ?-control_point ?before ?-control_signal test_mode
設置得到下面的電路結構:
?
上圖給出了在門控邏輯中插入控制點的示例。在這個例子中,DFT控制信號為test_mode,控制點位于鎖存器之前。
?
·-observation_point選項跟DFT有關,用于設置是否要插入觀測邏輯,以便在DFT時能看到門控邏輯內部的信號。
例如下面的約束命令:
set_clock_gating_style ??-observation_point ?true
則設置插入觀測,邏輯,如下圖所示:
?
除了上述選項外,該命令還有一些其他的選項設置,比如-setup選項設置建立時間約束。-hold選項設置保持時間約束。-observation_logic_depth選項用于設置觀察電路中異或門的數目。-max_fanout選項設置一個門控單元所驅動的最大負載數目,定義CG單元最大扇出的一個目的是減少CG后面的時鐘延遲,門控時鐘單元的扇出越大,它到達寄存器的延遲越長;此外,還有用來約束重新平衡(后面會有對重新平衡進行介紹)。"set_clock_gating_style"命令有很多選項,我們可以在Power Compiler用"man ?set_clock_gating_style"命令來查看其詳細的使用方法。
==============================================================================
設置了門控時鐘的加入風格之后,我們就可以設置在門級網表電路中加入門控時鐘。在Power Compile:里,用insert_clock_gating命令可在GTECH網表上加入門控時鐘。這個命令可以單獨使用,也可以配合一些選項,設置一些功能,我們下面主要介紹一下-global選項。
我們來看一下下面這段代碼:
always @ (posedge clk)begin
?? ??if (a && b) q=d;
end
當有多個模塊都有這段代碼時,單單利用insert_clock_gating命令就會得到下面的帶門控時鐘的電路:
?
上述電路中,有兩個模塊都有門控時鐘,都是同一個控制信號。那么我們就可以使用insert_clock_gating ?-global選項,讓門控時鐘可以穿越層次結構,插入到設計中。這樣一來,既可以省門控時鐘,又可以省面積。使用該選項后,綜合得到的帶門控時鐘的電路如下所示:
?
因此使用insert_clock_gating加選項“-global",可以使門控時鐘穿越層次結構。如果不用選項“-global",在每個模塊里有一個門控時鐘單元。
實現門控時鐘的方法就如前面所示,主要是設置門控時鐘的風格和加入門控時鐘這兩個命令以及他們的一些選項。
?
④門控時鐘的處理
我們在門級網表中加入門控時鐘之后,有時候需要對門控時鐘進行修修改改,比如說刪除一些門控時鐘之類的。下面我們就來介紹一下常見的一些門控時鐘處理。
·重新連接門控時鐘
如下圖所示:
?
上面的左邊圖中,寄存器A由CG1觸發(也就是原來由上面的門控單元CG1進行控制)。由于寄存器A距離門控時鐘單元CG2更接近,我們更想讓寄存器A與門控單元CG2進行連接來減少連線的長度,因此我們需要進行重新連接。重新連接后,寄存器A由CG2觸發,如上面右邊的圖所示。上面重新連接所使用的命令如下所示:
rewire_clock_gating???-gating_cell ?CG2 ?-gated_objects ?{reg_A}
此外,我們可以使用rewire_clock_gating的-proximity選項,使用這個選項后,Power Compiler會自動重新連接寄存器,使時鐘門控單元CG到寄存器的連線最短:
rewire_clock_gating ?-proximity
?
·重新平衡門控時鐘的扇出
如下圖所示:
?
左圖是原來的設計。當我們對電路進行優化時(比如使用compiler_utral -retiming 或者 optimize_registers命令),設計中的寄存器可能被移動或刪除,如中圖所示。
寄存器優化后,門控時鐘的扇出不平衡。而門控時鐘有最小和最大扇出的約束,對于每一個單獨的CG單元(如中圖所示)最小扇出的條件不能滿足。Power Compiler就需要相關的命令重新平衡門控時鐘的扇出,使用的命令如下所示:
rewire_clock_gating ??-balance_fanout
使用上述命令后,Power Compiler將CG單元合并,以滿足最小/最大扇出的約束。重新平衡后的設計如右圖所示。
?
?
·合并門控時鐘
如果兩個或以上的門控時鐘單元的輸人邏輯相等,它們可以被合并。合并只能在一個層次內部進行。合并后,冗余的邏輯被刪除。如下圖所示:
?
合并的命令為"merge_clock_gating_cells"
?
·刪除門控時鐘
有時候,我們需要刪除某些門控時鐘,這個時候我可以使用remove_clock_gating命令。該命令即一些選項如下所示:
remove_clock_gating
[-gating_cells ???CG_cells_list]
[-gated_registers ??gated_register_list]
[-all] ?[hier]
如下圖所示:
?
?
上圖上半部分是使用了-gated_registers這個選項,將原來的門控單元刪除,換成“使能-載入”模式;上圖的下半部分是使用了-gating_cells這個選項,原來的一個門控時鐘刪除。
因此我們可以通過指定門控時鐘單元或通過指定寄存器刪除門控時鐘。如果在使用刪除門控時鐘命令時用了開關選項“-all",當前設計中的所有門控時鐘都會被刪除。
?
?
⑤手動插入門控時鐘
上面介紹的是使用EDA工具,配合代碼自動生成門控時鐘。我們也可以以手工的方式設計門控時鐘,下面是一個手動設計門控時鐘的的代碼例子:
assign Gated_Clock ?= ?Clock&Enable ?;
always@(posedge Gated_Clock or negedge Reset)begin
????if(!Reset)
??????????Data_ Out<=8’b0;
????else
Data Out<=Data Out+8'b1
end
對于手工門控時鐘,Power Compiler將不插入時鐘門控單元,也不能對它進行操作(比如重新平衡之類的)。
?
手工門控時鐘可以被取代,取代的腳本如下:
······
create_clock ??-period ??5 ??[get_ports ??clk]
set_clock_gating_style ??...
replace_clock ??-gating_cells
······
取代前后的電路如下所示:
?
?
取代手工門控時鐘的好處在于:取代后,它可以避免產生潛在的毛刺(glitch),也可以允許在它上使用其他的CG命令。例如我們可以使用remove_clock_gating命令去掉門控時鐘或使用rewire_clock_gating命令重新連接門控時鐘。
門控時鐘的低功耗設計到這里就介紹完了,關于門控的STA、DFT和CTS的問題我們就不進行介紹了。
?
?
(5)其他
有的時候,我們不經意間就會引入多余的翻轉,多余翻轉就引起的多余的功耗。下面是多余翻轉的例子(類似于操作數隔離):
?
?
上圖中,當load_out無效時,如果laod_op有效,那么數據就會進行操作,也就是存在相應的翻轉。因為輸出是無效的,所以這些翻轉是多余的,消耗了功耗,但卻沒有輸出。因此我們就要注意,當load_out無效時,load_op也要設置為無效,這樣就可以節省部分功耗。
對于上面的多余翻轉,可以進行相應的壓縮來節省功耗,如下所示:
?
sel_in同時控制了數據輸入和多路選擇器的輸出。SEL=0時,讀入A和B,選通操作1;SEL=1時,讀入C和D,選通操作2;這時候就可以減少另一半操作引起的翻轉,從而減少了功耗。
對于這種數據輸入,然后進行操作選擇性輸出的,可以進行相應的門控來減少多余的翻轉,從而減少功耗。
?
結合綜合進行RTL級的低功耗就如上所述了,重點是門控時鐘的使用和操作數隔離技術,這是我們前端設計人員需要懂的。