SoC系統(tǒng)描述與SystemC
摘 要:隨著VLSI工藝技術(shù)的發(fā)展,為了縮短開發(fā)周期,提高設(shè)計的可預(yù)見性,SoC設(shè)計已經(jīng)成為迫切需求。本文將比較C++、VHDL和SystemC,說明SystemC是一種非常好的系統(tǒng)描述語言。同時利用C++和VHDL的語法來深入介紹SystemC的語法。
引言
在早期的集成電路設(shè)計過程中,由于低抽象層次的設(shè)計問題比高抽象層次的設(shè)計問題手工處理更難,這迫使研究者首先把注意力集中到低層次設(shè)計問題上。例如:電路仿真、布局、布線和布局規(guī)劃。隨著低層次設(shè)計問題變得易于處理,邏輯仿真與綜合取得了成功的發(fā)展,并引進(jìn)到設(shè)計過程中。隨著現(xiàn)代系統(tǒng)復(fù)雜性的日益增加和緊迫的上市時間的壓力,特別是SoC技術(shù)的發(fā)展,利用上面的工具和設(shè)計方法已遇到了巨大的挑戰(zhàn)。工業(yè)界和學(xué)術(shù)界開始把注意力集中到系統(tǒng)設(shè)計。因為在系統(tǒng)級可以大大減少設(shè)計者需要考慮的對象的數(shù)目,這樣就可以在短時間內(nèi)完成復(fù)雜系統(tǒng)的設(shè)計。
用自然語言來描述一個系統(tǒng),通常是模糊和不完備的,缺乏詳細(xì)說明任務(wù)的能力。因此,設(shè)計者需要用一些精確的語言來描述系統(tǒng)的功能。隨著與SoC有關(guān)的設(shè)計復(fù)雜性的增加,設(shè)計者非??释幸粋€可執(zhí)行的系統(tǒng)描述語言,能在綜合執(zhí)行之前就能表示和驗證系統(tǒng)的中間實現(xiàn)。但是目前出現(xiàn)的很多語言都不能作為系統(tǒng)描述語言,因為每一種語言只能描述系統(tǒng)的一部分特性,不具備描述全部系統(tǒng)特性的能力。本文介紹的系統(tǒng)描述語言SystemC則較好地解決了上述問題。
系統(tǒng)特性
隨著功能需求的增加,現(xiàn)在的系統(tǒng)越來越復(fù)雜,并且具有許多特性。
并發(fā)性:任何系統(tǒng)都可分解成許多稱為行為的功能塊。每一個功能塊通??梢杂眠M(jìn)程、子程序或狀態(tài)機的形式來描述。大部分情況下,系統(tǒng)的功能都能很容易地概述成并發(fā)行為的集合。因為用順序結(jié)構(gòu)來描述將產(chǎn)生復(fù)雜的、難于理解的描述。
層次性:在面對大的系統(tǒng)時,一個突出的問題就是系統(tǒng)太復(fù)雜而不能以整體來考慮。在這種情況下,人們只能以層次模型來分析。首先,層次模型允許系統(tǒng)概述成更小子系統(tǒng)的集合。這種分解系統(tǒng)的建模方式可以大大簡化系統(tǒng)的開發(fā)。而且,一旦得到了系統(tǒng)的概念概述,層次模型將大大促進(jìn)設(shè)計者對系統(tǒng)功能的理解。
時序:在系統(tǒng)說明中必須詳細(xì)說明時序關(guān)系。當(dāng)一個部件在指定的時間范圍收到或產(chǎn)生一個事件時,必須能以實際的時間單位來測量。協(xié)議通??捎脮r序圖表來表示。時序信息對實時系統(tǒng)非常重要,它的性能通常根據(jù)實現(xiàn)滿足時序限制的程度來度量。
通信:系統(tǒng)由一些相互作用的行為組成。這些行為必須與它們相互協(xié)作的行為進(jìn)行通信。這樣一個通信模型對系統(tǒng)描述是必需的。
進(jìn)程同步:在一個可以概述為一些并發(fā)進(jìn)程的系統(tǒng)中,進(jìn)程很少完全與其它進(jìn)程相互獨立。每個進(jìn)程通常產(chǎn)生被其它進(jìn)程考慮的數(shù)據(jù)和事件。當(dāng)進(jìn)程需要交換數(shù)據(jù)或者當(dāng)某個操作同時要被不同的進(jìn)程執(zhí)行時,必須采取某種方式來使進(jìn)程同步。
當(dāng)然,現(xiàn)代系統(tǒng)還有許多特性,如異常處理、行為完備性、編程結(jié)構(gòu)等。
傳統(tǒng)語言的缺陷
傳統(tǒng)的C++語言是順序語言,不能處理硬件系統(tǒng)固有的并發(fā)性。它也缺少時間概念,不能描述時間順序,但是硬件系統(tǒng)必須以時間順序來進(jìn)行操作。同時它缺少硬件類型的通信,缺少重啟機制,不支持各種硬件數(shù)據(jù)類型:例如Bit類型、多值邏輯類型、定點數(shù)據(jù)類型等。
傳統(tǒng)的VHDL語言是專用的硬件描述語言,缺少描述各種機制的支持,因此不能作為系統(tǒng)描述語言。
怎樣才能得到系統(tǒng)描述語言呢?目前有兩種方案,一種方案是以硬件描述語言為基礎(chǔ),增加類C語言的結(jié)構(gòu)來描述系統(tǒng),如ICL Design Automation的VHDL+、Co-Design的Superlog;另一種方案是以軟件語言C++為基礎(chǔ),增加對硬件特性的描述類庫,如Synopsys、Co-Ware等提出的SystemC語言。SystemC采用了源碼公開的形式,得到了很多設(shè)計公司和用戶的支持。
SystemC語言
SystemC使用C++面向?qū)ο蟮木幊烫攸c, 在沒有對C++增加新的語言構(gòu)件的基礎(chǔ)上,利用類的概念對C++進(jìn)行了擴充,加入了一個類庫和仿真核,用以支持硬件的建模和仿真概念。設(shè)計者能利用它有效地創(chuàng)建軟件算法、硬件結(jié)構(gòu)、SoC接口和系統(tǒng)設(shè)計模型。可以用SystemC和標(biāo)準(zhǔn)的C++開發(fā)工具來創(chuàng)建一個系統(tǒng)級模型,通過快速地仿真來驗證和優(yōu)化設(shè)計,探索各種各樣的算法,并且提供給軟硬件開發(fā)隊伍一個可執(zhí)行的系統(tǒng)說明。一個可執(zhí)行的說明本質(zhì)上是一個C++程序,能展示與系統(tǒng)相同的行為。
SystemC支持協(xié)同設(shè)計和由軟硬件部件組成的復(fù)雜系統(tǒng)的結(jié)構(gòu)描述。在C++環(huán)境中,它支持軟件、硬件和接口描述。
模塊
模塊是SystemC中用來劃分設(shè)計的基本塊。模塊允許設(shè)計者把復(fù)雜的系統(tǒng)劃分成更小的、可以管理的塊。模塊能在一個設(shè)計隊伍中劃分復(fù)雜的系統(tǒng),允許設(shè)計者隱藏內(nèi)部數(shù)據(jù)和算法,迫使設(shè)計者采用公開接口與其它模塊進(jìn)行通信,并且整個系統(tǒng)更容易測試和維護。
模塊用SystemC的關(guān)鍵字:SC_MODULE來聲明。
SC_MODULE(transmit)
{......}
這個模塊的名字為transmit。一個模塊可以包含端口(Ports)、局部信號(Local Signals)、局部數(shù)據(jù)(Local Data)、其它模塊、進(jìn)程(Processes)和構(gòu)造函數(shù)(Constructors)。這些元素實現(xiàn)了模塊要求的功能。
模塊的端口用來傳遞模塊進(jìn)程的數(shù)據(jù)。端口的模式有:sc_in、sc_out、sc_inout。端口的數(shù)據(jù)類型可以是C++的數(shù)據(jù)類型、SystemC的數(shù)據(jù)類型或者用戶定義的數(shù)據(jù)類型。端口的模式已經(jīng)預(yù)定義在SystemC的類庫中。
SystemC的模塊對應(yīng)C++語言的類。模塊中的端口、局部信號、局部數(shù)據(jù)、其它模塊對應(yīng)C++類的成員變量,模塊中的進(jìn)程對應(yīng)類的成員函數(shù)。
SystemC的模塊也對應(yīng)VHDL中的設(shè)計實體。模塊的端口、局部信號、局部數(shù)據(jù)部分對應(yīng)實體說明。端口模式對應(yīng)實體說明部分中的類屬和端口說明。模塊的進(jìn)程對應(yīng)設(shè)計實體的結(jié)構(gòu)體。
進(jìn)程
進(jìn)程是SystemC中基本的運行單元,調(diào)用進(jìn)程可以仿真目標(biāo)設(shè)備或系統(tǒng)的行為。SystemC的進(jìn)程有三種類型可以使用:method process、thread process、clocked thread process。有些進(jìn)程的行為與函數(shù)相似,進(jìn)程調(diào)用時開始運行,完成之后把結(jié)果返回到調(diào)用機制。其它的進(jìn)程僅僅在仿真開始時調(diào)用一次,然后或者運行,或者掛起,等待一個條件變成真。進(jìn)程不是層次的,因此進(jìn)程不能直接調(diào)用其它進(jìn)程,進(jìn)程可以調(diào)用不是進(jìn)程的方法或函數(shù)。
進(jìn)程有敏感列表,也就是能激活進(jìn)程的信號列表。一個進(jìn)程被觸發(fā),進(jìn)程的列表肯定有事件發(fā)生。
方法進(jìn)程(Method Process):當(dāng)一個進(jìn)程的敏感信號上發(fā)生事件時,進(jìn)程就要被執(zhí)行。一個方法執(zhí)行并且把控制返回到仿真核中。方法進(jìn)程不能被掛起或包含無窮循環(huán),當(dāng)一個方法進(jìn)程被激活,它將一直執(zhí)行直到結(jié)束。
線程(Thread process):它能被掛起或重新激活,包含wait()函數(shù)。一個時間將重新激活線程,從上次掛起時的語句開始,繼續(xù)執(zhí)行直到下一個wait()函數(shù)。敏感列表是在模塊的構(gòu)造函數(shù)中說明。線程是最一般的進(jìn)程,幾乎可以用來建模一切事物。一個方法進(jìn)程用來建模同樣的設(shè)計,但要求更多的語句,并且難于理解和維護。
線程是作為co-routines來實現(xiàn)的。這種實現(xiàn)比方法進(jìn)程慢。如果提高仿真速度是當(dāng)前的主要目的,那么應(yīng)該限制線程的使用,而去維護最高的仿真速度。
時鐘線程(Clocked thread process):它是線程中的一個特殊情形,它能更好地綜合結(jié)果,幫助設(shè)計者描述他們的設(shè)計。時鐘線程僅僅能被一個時鐘的邊沿所觸發(fā),這與硬件用綜合工具實現(xiàn)的方式匹配。時鐘線程能用來創(chuàng)建隱式狀態(tài)機。這種設(shè)計所以創(chuàng)建的形式簡單且容易理解。一個顯式狀態(tài)機將在聲明中定義狀態(tài)機,并且用case語句從一個狀態(tài)移到另一個狀態(tài)。
時鐘線程與線程在許多方面不同。首先,時鐘線程說明了一個時鐘對象,它不能與其它進(jìn)程一樣有分開的敏感列表。敏感列表僅僅是特定的時鐘邊沿。無論什么時候到達(dá)了特定的時鐘邊沿,時鐘線程都會被激活。
Wait Until
在一個時鐘線程中,wait until()能用來控制進(jìn)程的執(zhí)行。wait until()將停止進(jìn)程的執(zhí)行,直到一個特定的事件發(fā)生。這個特定的事件是被wait until()的表達(dá)式所指定的。wait until()函數(shù)僅僅與sc_signal<bool>類型的表達(dá)式一起工作。
Watching
線程與時鐘線程中有無窮循環(huán)。一個典型設(shè)計需要某些方式來初始化循環(huán)行為,或者當(dāng)某個條件發(fā)生時跳出循環(huán)。這些通過watching construct的使用來完成。watching construct將監(jiān)控一個特定的條件。當(dāng)這個條件發(fā)生時,控制從當(dāng)前的執(zhí)行點轉(zhuǎn)移到進(jìn)程的開始點。那里需要處理watched condition,被watch的對象必須是布爾類型。
Local Watching允許精確地說明進(jìn)程的哪一個部分正觀察哪一個信號和事件處理者所定位的位置。它的功能用四個特定的宏來定義。
W_BEGIN // put the watching declarations here.
watching (......);
watching (......);
W_DO // This is where the process functionality goes.
..................;
W_ESCAPE // This is where the handler for the watched events go.
if (...) {.............};
W_END
W_BEGIN宏標(biāo)記Local watching塊的開始。在W_BEGIN與W_DO宏之間放所有的watching聲明。這些聲明與全局watching事件看起來一樣。在W_DO與W_ESCAPE之間放入進(jìn)程的功能,只要沒有watching事件發(fā)生,就會執(zhí)行這些代碼。在W_ESCAPE與W_END之間放事件處理者。事件處理者將確保相關(guān)事件已發(fā)生,然后去執(zhí)行這個事件的必要行動。W_END結(jié)束local watching塊。
對于local watching,下面的情形需要注意:
在聲明塊中,所有事件有相同的優(yōu)先級。如果需要不同的優(yōu)先級,Local watching塊將需要被嵌套(nested)。
Local watching僅僅在時鐘線程中工作。
在watching表達(dá)式中的信號僅僅在進(jìn)程的活動邊沿取樣。在時鐘線程中,這僅僅意味著進(jìn)程敏感塊什么時候改變。全局watched事件比局部watched 事件有更高的優(yōu)先級。
時鐘(Clocks)
時鐘對象是SystemC中的特別對象,它產(chǎn)生時間信號,用來同步仿真中的事件。時鐘按時間順序排列,以致硬件上并行的時間能在順序計算機上適當(dāng)?shù)乇环抡嫫鹘!r鐘對象有許多數(shù)據(jù)成員來存儲時鐘環(huán)境和執(zhí)行時鐘動作的方法。
舉個例子:sc_clock clock1(“clock1”,20,0.5,2,true)。這個聲明將創(chuàng)建一個名字為clock1的時鐘對象,它的周期為20個時間單位,占空比為50%,第一條時鐘邊沿在第二個時間單位,第一個值為真。除了時鐘的名字,所有的變量都有缺省值:周期為1,占空比為0.5,第一條時鐘邊沿為0,第一個值為真。
事件(Events)
事件類型sc_event是SystemC中基本的同步對象。一個進(jìn)程能通知一個事件,也就是說導(dǎo)致一個事件發(fā)生,以致所有等待這個事件的進(jìn)程將被激活。一個事件對象通常在模塊中聲明,并且被模塊中的進(jìn)程使用。為了實現(xiàn)模塊重用,通過模塊的端口,應(yīng)該總是能訪問一個外部時間對象。
sc_event類型提供下列功能:
構(gòu)造函數(shù):sc_event mu_event。
通知:my_event.notify(0);sc_time t(10,sc_ps);my_event.notify(t)。
Wait()方法
wait()函數(shù)接收它等待的事件參數(shù)列表,能有多個wait()語句。它們有不同的參數(shù)。這意味著進(jìn)程的敏感性能可以動態(tài)地改變。wait()方法能在線程執(zhí)行的任何地方被調(diào)用。當(dāng)它被調(diào)用時,指定的事件臨時覆蓋線程的靜態(tài)敏感列表。當(dāng)一個或所有的時間被通知時,等待的線程被重新開始,調(diào)用的線程再一次對靜態(tài)敏感列表敏感。當(dāng)wait()沒有參數(shù)時,這與以前一樣:當(dāng)事件發(fā)生在線程的靜態(tài)敏感列表上時,wait()被激醒。
主從通信庫
主從通信庫的目標(biāo)是利用主從總線通信協(xié)議的系統(tǒng)。由一個或多個CPU核、DSP、外圍設(shè)備和通過總線集進(jìn)行通信的定制ASIC組成的系統(tǒng)特別適合這個庫。這個庫提供了一個從功能級可執(zhí)行說明到RTL級的路徑,并且可以使用通信綜合的界面綜合工具。這個庫介紹了一個順序執(zhí)行和進(jìn)程之間的通信協(xié)議。這非常好地適合順序軟件-軟件通信的抽象功能級建模、硬件-軟件的界面和硬件-硬件的界面。
利用這個庫,復(fù)雜的系統(tǒng)模型能被建模。作為一個順序通信功能塊的相互連接體,它允許快速模型開發(fā)、軟硬件劃分的權(quán)衡分析和資源分配決定。在設(shè)計過程的后期,功能通信被精煉到循環(huán)精確總線協(xié)議通信,然后通過在塊內(nèi)的功能行為通信,到循環(huán)精確可綜合的形式。這個模型的一個重要特性是:功能級抽象通信能被精煉到循環(huán)精確總線協(xié)議通信,而保持順序通信和功能級的執(zhí)行順序。這個特性是界面綜合工具的一個關(guān)鍵因素。這個庫也允許把模塊的通信從它的內(nèi)部行為分開到一個大的程序,當(dāng)然完全的分開是不可能的。
結(jié)語
系統(tǒng)描述是一個非常復(fù)雜的過程。為了能有效地描述一個系統(tǒng),合適的系統(tǒng)描述語言是必不可少的。SystemC利用流行的C++編譯器,通過擴展類庫的方法,實現(xiàn)了硬件的高級語言描述。利用流行的C++編譯器,保證SystemC在語法上完全兼容標(biāo)準(zhǔn)C++,為系統(tǒng)開發(fā)者提供了統(tǒng)一的開發(fā)平臺。擴展類庫是SystemC的核心。它實現(xiàn)了硬件描述的并發(fā)性和模塊化的本質(zhì)特點。通過使用面向?qū)ο蟮姆椒ǎ梢苑奖愕貙崿F(xiàn)硬件的描述和IP核的復(fù)用。隨著芯片系統(tǒng)規(guī)模日益擴大,軟件工程的思想日益滲透到芯片的設(shè)計過程中,使用成熟的軟件工程方法,可以有力地支持芯片系統(tǒng)的設(shè)計。采用高級語言的芯片系統(tǒng)設(shè)計,將是未來的發(fā)展方向?!?/P>
評論