SystemC在1999年正式推出,並由Open SystemC Initiative (OSCI) 負責支持、維護和發展。這個組織包含了范圍廣泛的公司、研究機構、大學和個人成員。被選舉出OSCI理事會成員(Board Member Coreporations)包括:ARM Ltd.,Cadence Design Systems, Inc.,CoWare,Fujitsu,Mentor Graphics,Motorola,NEC,Synopsys,Inc. [1],涵蓋了系統廠商、半導體廠商、EDA工具廠商、IP供應商等。
SystemC是建立C++基礎上的開放的系統級設計語言。實際上SystemC由一系列用來進行系統描述的C++類構成,並包含了一個用來對系統行為進行模擬的仿真核。SystemC語言的發展大致經歷了兩個大的階段:SystemC1.0和SystemC2.0。SystemC1.0可以用來進行硬件描述。SystemC2.0的推出使SystemC成為真正的系統級設計語言,能夠用來對SoC體系結構進行更加自然和有效的描述。這樣就使SystemC語言涵蓋了從系統概念直到實現的針對系統軟、硬件建模的能力。
SystemC的以下特性使它能夠支持RTL或行為級的硬件描述[2]。
● 數據類型 標准C/C++語言不提供可以用來進行硬件設計所需要的數據類型。SystemC語言支持所有的C/C++數據類型,同時SystemC所定義的以下數據類型可以用來進行定點或硬件設計和描述:sc_bit, sc_logic, sc_int, sc_uint, sc_bigint, sc_biguint, sc_lb, sc_lv, sc_fixed, sc_ufixed, sc_fix, sc_ufix 等。例如使用sc_int<8>可以表示一個8比特的有符號整數,或使用sc_uint<8>表示一個8比特的無符號整數。sc_(u)fix, sc_(u)fixed是定點數據類型,HDL語言不?支持類似的數據類型。豐富的數據類型使得SytemC可以支持從算法描述直到可綜合的RTL描述。
● 設計描述 SC_MODULE是一個基本的用來進行設計描述的SystemC類。它類似與VHDL的ENTITY或VERILOG的MODULE。在SC_MODULE中可以定義輸入、輸出管腳,內部信號等,或實例化另外一個SystemC MODULE。設計的行為可以使用SC_METHOD或SC_THREAD進行描述。SC_METHOD或SC_THREAD在SC_MODULE的構造函數中進行聲明,並可以指定相應的敏感信號列表。
下面簡單的例子給出了使用SystemC描述一個加法器的代碼。更普遍的描述會使用一個頭文件定義模塊的接口及所包含方法、函數等的聲明,而在一個或幾個C++文件中實現所定義的方法、函數。實際上上面的例子是一個加法器的RTL描述,所定義的方法myadd_method()在時鐘clk的上升沿被執行。現在已經有這樣的工具支持對RTL的SystemC代碼進行綜合優化,並使用FPGA、ASIC或SoC完成硬件實現的設計流程[3]。
#i nclude
SC_MODULE(myadd)
{
//interface define
sc_in
sc_in
sc_in
sc_out
void myadd_method()
{
out1 = in1.read() + in2.read();
};
// default constructor
SC_CTOR(myadd)
{
SC_METHOD(myadd_method);
//sensitive list for the process
sensitive_pos << clk;
}
}; // end module myadd
2 SYSTEMC2.0
SystemC2.0語言發布的一個主要目的是使用戶可以在(相對於RTL)更高的層次對SoC系統進行描述。SystemC2.0引入了新的特性、概念以支持更方便、有效地對系統進行建模,包括:channel, interface, event等。HDL語言的RTL模型很適合於對一個特定的硬件模塊進行建模,但通常很難高效率的對構成整個SoC的各模塊之間的通信、同步機制進行描述。主要基於這個原因,Transaction Level(TL) 的建模思想被引入到了SoC設計流程之中[4]。TLM(Transaction Level Model)主要用來對整個SoC的體系結構進行描述,進而對系統結構進行仿真、分析、優化。同時TLM使得設計者在系統硬件的RTL描述完成之前就可以對SoC所包含的大量軟件進行驗證。使用SystemC2.0提供的channel、interface等概念以及基於此的Interface Method Call(IMC)的思想可以對SoC系統的TL模型進行描述,建立SoC虛擬平台。
為了更自然、更容易的對整個SoC體系結構進行描述,SystemC2.0引入了一些新的概念[5]:
●Interface interface是一組通信或同步方法的定義,使用這些方法可以對其對象進行訪問。但interface本身並不包含這些方法的具體實現描述。
●Channel channel是一個對象,它具體的實現了一個或幾個interface。同時一個interface也可以由多個channel在不同的抽象層次來實現。
實際上interface和channel的引入起到了對方法的封裝的作用,是面向對象的設計思想在SoC描述上的具體應用,類似的思想在另一個新的硬件設計和驗證語言SystemVerilog[6]中也有反映。這樣使用了某一interface作為其管腳(port)類型的SoC模塊可以通過方法調用的方式使用在interface中定義的方法,即interface method call。
圖1是一個非常簡化的SoC系統模型。
在這個簡單的SoC系統中包含若干master模塊,在真實的系統中,他們可以是CPU或DSP核或專有的硬件等。這個系統還包含若干slave模塊,在真實的系統中他們可以是memory,buffer等。這些模塊通過一個總線連結起來。總線協議中定義了各種總線訪問方法,這些方法描述了基於這個總線的各SoC模塊之間的通信、同步方法,例如read, write, burst_read, burst_write、direct_read、direct_write等。我們可以使用SystemC的interface來定義這個總線所提供的各種方法。然後可以由一個channel具體地實現所定義的方法。例如右面的代碼分別給出定義了這個總線所支持的direct_read、direct_write的方法、實現這些interface的channel的部分代碼。定義了一個interface之後,一個模塊可以聲明一個以這個interface為“類型”的管腳(port),並通過這個port調用在interface中所定義的方法。右面的代碼也包含一個采用simple_bus_direct_if接口的master的例子。
SoC的設計者在使用SystemC描述interface所具有的基本的訪問方法外還可以定義一些其他的方法用以對例如總線狀態、訪問沖突等進行統計、分析的方法,這樣可以通過仿真對這些重要的系統性能數據進行統計、分析,並在此基礎上對整個系統結構進行優化。一些商業工具在這方面可以提供更多的幫助[1]。
SoC是一個完整的系統,包含了硬件及運行於其中的軟件。由於RTL代碼的仿真速度的問題,在RTL代碼的基礎上進行軟件的驗證會耗費難以想象的時間。同時期待整個系統的RTL描述完成之後再進行軟硬件的聯合驗證會延長整個開發周期[7]。SoC的TL模型則提供了一個進行軟件驗證的虛擬平台。 ?
●Interface:方法的定義
#i nclude
class simple_bus_direct_if
: public virtual sc_interface
{
public:
// direct BUS/Slave interface
virtual bool direct_read(int *data, unsigned int address) = 0;
virtual bool direct_write(int *data, unsigned int address) = 0;
}; // end class simple_bus_direct_if
●Channel:interface的實現
class simple_bus// Simple Bus
: public simple_bus_direct_if,
public simple_bus_non_blocking_if,
public simple_bus_blocking_if,
public sc_module
{
public: ?
…
bool direct_read (
int *data,
unsigned int address
)
{
if (address%4 != 0) {
// address not word alligned
fprintf(stdout, “BUS ERROR→
address %04X not word
alligned\n?address);
return false;
} ?
return slave→direct_read(data, address);
… ?
} ?
●Port和interface method call
#i nclude
#i nclude “simple_bus_direct_if.h?
// Simple Bus Master Direct
class simple_bus_master_direct
: public sc_module
{
…
//This port connects to the bus interface.
sc_port
…
void main_action()
{
int mydata[4];
while (true)
{
//interface method call
bus_port->direct_read(&mydata[0],
m_address);
…
wait(m_timeout, SC_NS);
…
}
3 基於TL模型的軟件驗證
在上面圖1的例子中,某一個master的功能可能要用軟件來實現,在得到總線、memory的RTL描述之前就可以對軟件代碼在TL的虛擬平台上進行盡可能充分的驗證。此時的軟件驗證是“一般”的代碼驗證,因為它並沒有被編譯到相應的目標CPU或DSP中,而是使用通用的C/C++開發環境對軟件代碼進行調試、分析,例如VC++和GNU的C++開發環境。
CPU或DSP的指令集仿真器(ISS: Instruction Set Simulator)和調試環境可以用來對運行於其上的軟件代碼進行仿真、調試。但這樣的調試環境通常只包含單個處理器及非常簡單的存儲系統,同時也不包含對存儲單元(包括數據存儲器和程序存儲器)的訪問接口模型。設計者基於SystemC可以開發出新的處理器的TL模型,它包含完整的仿真、調試環境以及用SystemC描述的 TL接口方法。這樣這個模型就可以與系統的其他部分緊密地整合在一起。對多處理器系統這種方法尤為重要[7]。並且如果模型是cycle-aclearcase/" target="_blank" >ccurate的,它將能提供足夠高的仿真精度。由於使用TL模型,仿真速度也將遠遠高於RTL模型。圖2是這種模型的構成示意。
這樣的TL模型可以由使用CPU或DSP的用戶開發出來,也可以由提供這些IP的供應商或其他廠家提供。
為了進行更真實的代碼驗證,可以使用相應處理器的編譯器將軟件代碼進行編譯,這樣就可以使用上述處理器的TL模型在“虛擬”的SoC平台上運行、調試軟件代碼。包括EDA、IP等公司在內的一些供應商已經開始提供這類SystemC的處理器TL模型[1]。
4 應用實例
SystemC是一種開放的系統設計語言,用戶可以在各種常見的平台中使用SystemC,例如windows平台下C++開發環境Visual C++,Linux平台下的GNU C++環境等。越來越多的商用軟件也已經提供SystemC的開發環境[1]。本文的實例(圖3)采用Synopsys提供的SystemC開發環境CoCentric System Studio。
這個實例由一個IP路由器內的AMBA總線、ARM處理器、中斷控制器、DMA控制器、程序存儲器、數據存儲器等模塊構成,這些模塊采用SystemC建立TL模型,其中的ARM處理器TL模型包含完整的ARM ADU調試環境。在這個實例裡還包含對AMBA總線進行統計和監控的模塊,使用了Synopsys在SystemC開放語言開放基礎上增添的monitor類,可以很方便的得到總線使用的統計特性以及在總線上所進行的數據傳遞、資源訪問等信息。在這個實例中,設定了存儲器大小、存儲器讀寫周期、DMA的循環寫周期等作為可以進行分析優化的參數以達到對整個系統體系結構進行分析的目的。
當這樣一個SoC的結構模型建立並分析完成之後,軟件設計人員可以在這樣一個環境下比較充分的對軟件代碼在ARM的ADU環境下進行分析、調試。由於TL模型能夠提供較RTL模型快得多的仿真速度,允許對較多數量的軟件代碼進行分析以發現可能的設計纰漏。同時硬件設計人員也可在此結構平台上進行硬件的開發。由於SystemC語言支持各種層次的抽象模型,設計人員可以采用設計“細化”[8]的方法將TL的SystemC代碼轉變為SystemC的RTL代碼,然後在同樣的測試環境下對RTL代碼進行仿真。當然用戶也可以依據TL的SystemC代碼使用HDL語言完成RTL代碼。SystemC與HDL代碼之間的聯合仿真可以通過PLI(VHPI)來實現。不過PLI的引入會增加冗余的仿真負載,降低仿真速度。為解決此問題,已經有一些公司推出了基於DKI(Direct Kernel Interface)的仿真方法,可以提高SystemC與HDL代碼之間聯合仿真的速度