System C是一種軟/硬件協同設計語言,一種新的系統級建模語言。它包含了一系列C++的類和宏,并且提供了一個事件驅動的模擬核,使得系統的設計者能夠用C++的詞法模擬并行的進程,特別是在SoC系統中。
簡介
近年來Synopsys 公司, CoWare 公司和Frontier 設計公司合作開發了SystemC。在1999 年9 月27 日四十多家世界上著名的EDA 公司, IP 公司,半導體公司和嵌入式軟件公司宣布成立”開放式SystemC 創始社” (Open SystemC Initiative) 這些公司包括ARM, CoWare, Cygnus Solution, Ericsson, Frontier Design, 富士通株式會社, Infineon, Lucent Technologies,索尼, 意法半導體, Synopsys, Taxas Instruments 等
這些公司認為SystemC 是一種很好的硬件軟件聯合設計語言。愛立信 公司微電子部主任Jan-Olof Kismalm 說:“通信系統的復雜性在不斷地增加而新的系統卻要求以更短的時間推向市場為了以最短的時間開發出復雜的產品,需要我們采用單一的語言描述復雜的行為和 IP,我們相信SystemC 可以幫助我們以更好的方法描述我們的系統并在設計過程的初始階段進行有效的硬件軟件聯合設計這可以大大縮短我們開發產品的時間Kismalm 先生的話表達了世界上眾多公司歡迎SystemC 的原因。”
研究表明,具有較高的抽象能力,同時能體現出硬件設計中的信號同步、時間延遲、狀態轉換等物理信息的語言,才能給工程師提供一個系統級設計的公共基礎平臺。在我們常用的設計語言中,C、C++ 和Java等高級編程語言有較高的抽象能力,但由于不能體現硬件設計的物理特性,硬件模塊部分需重新用硬件描述語言設計,使得后續設計缺乏連貫性;而vhdl,Verilog最初目的并不是進行電路設計,前者是用來描述電路的,而后者起源于板級系統仿真,因此它們并不適合進行系統級的軟件和算法設計,特別是現在系統中的功能越來越多的由軟件來完成時。
SystemC是在C++的基礎上擴展了硬件類和仿真核形成的,由于結合了面向對象編程和硬件建模機制原理兩方面的優點,這可以使SystemC在抽象層次的不同級進行系統設計。系統硬件部分可以用SystemC類來描述,其基本單元是模塊(modul)模塊內可包含子模塊、端口和過程,模塊之間通過端口和信號進行連接和通訊。
隨著通訊系統復雜性的不斷增加,工程師將更多的面對使用單一的語言來描述復雜的IP和系統,而SystemC,語言良好的軟硬件協同設計能力這一最大特點,將會使其應用更加廣泛。
基本語法
C++和SystemC任務的執行
C++:任務的執行是串行的;SystemC:可以做到并行。
SystemC的基本進程
進程是程序在并發環境中的執行過程, SystemC的基本進程包括:
SC_METHOD, SC_THREAD, SC_CTHREAD
①SC_METHOD:當敏感列表上有事件發生時,才被調用,(用法很像Verilog中描述組合邏輯)調用后迅速返回;
②SC_THREAD:能夠被掛起和重新激活,當敏感表上有事件發生,線程被重新激活運行到新的wait()語句再重新掛起,(主要用于對程序的驗證);
③SC_CTHREAD:繼承于線程進程,只能在時鐘的上升沿或者下降沿被觸發或者激活,(用于時鐘精確的建模)。
Systemc的時鐘模型
在Systemc程序設計中,時鐘(sc_clock)被作為一個特殊的對象處理。
sc_clock共有六個重載的構造函數。
sc_clock(“clk1”,20,0.5,5,ture)?
模塊
模塊是SystemC的 最基本單元,模塊內部可以包括 端口,內部信號,內部數據,進程等
模塊本質上是 類,使用 SC_MODULE聲明:
SC_MODULE(mmu)
{…..//details of the 設計}
等價于:
Class mmu :public sc_module
{…..//details of the design}
實例
SC_METHOD??實例
?
#ifndef_FULLADDER_H
#define_FULLADDER_H
#include
SC_MODULE(FullAdder)
{
sc_in
sc_out
void do_add()
{
S=(A.read())^ (B.read())^(Ci.read());
Co= (A.read())&(B.read())|
(B.read())&(Ci.read())|
(A.read())&(Ci.read());
};
SC_CTOR(FullAdder) //systemc的構造函數
{
SC_METHOD(do_add); //表示do_add對A,B,Ci敏感
含羞草< } }; #endif SC_THREAD實例 #ifndef_MONITOR_H #define_MONITOR_H #include SC_MODULE(Monitor) { sc_in void pre_monitor() { while⑴{ cout< wait(); //當執行到時程序被掛起,當敏感列表被觸發時程序繼續執行 cout< } }; SC_CTOR(Monitor) { SC_ THREAD(pre_monitor); //表示當變量發生變化時, pre_monitor被激活或者重新激活; sensitive< }; #endif SC_CTHREAD實例 #ifndef_DRⅣER_H #define_DRⅣER_H #include”systemc.h” SC_MODULE(Drive){ sc_in_CLK clk; sc_out void prc_drive(); SC_CTOR(Drive){ //表示prc_drive對時鐘上升沿敏感 SC_CTHREAD(prc_drive,clk.pos()); } } ; #endif 接口:集合一組固定的通信方法 存儲器寫接口: Class mem_read_if: public sc_interface {public: virtual transfer_status read(…)=0;//讀虛函數(沒有數據) } 存儲器讀接口: Class mem_write_if: public sc_interface {public: virtual transfer_status write(…)=0;//寫虛函數(沒有數據) } 存儲器接口(將讀接口與寫接口封裝): Class ram_if: public mem_read_if,mem_write_if{ … } 通道實現了接口的內容,即它是一個實現通信功能的“模塊”,只不過它僅完成通信功能。 例子:Ram通道: Class ram :public sc_module,ram_if{ … Transfer_status read(…)//定義讀函數(需要用戶自己定義具體功能) { … } Transfer_status write(…)//定義寫函數(需要用戶自己定義) { … } } 端口:模塊通過端口與通道連接 模塊的端口的定義要與接口同一類才能連接 SC_MASTER(Master){ sc_in_CLK clk; sc_port Int data; Unsigned int address; … void main_action{ //需要用戶自己定義 … Transfer_statusstatus=ram_port->write(address,data);//在功能函數中通過端口 … ;調用通道函數 Transfer_statusstatus=ram_port->read(address,data);//通過端口調用功能函數 … } … } 接口(interface):是C++抽象類,它以純虛數的方式定義了一組抽象的方法? 通道(channel):通道實現一個或者多個接口(接口中定義的虛函數必須在通道中實現) 端口(port):端口定義在模塊中,通過端口,模塊中的進程就能夠連接到一定的接口 Systemc支持業界很多設計方法學,OSCI的思路是定義一個小的語言子集以完成最基本的語言構架,具體的設計方法學有一些專用庫來實現,如可以使用Master-Slave庫來實現IP復用; Master-Slave庫使得通信與模塊的行為在一定程度上分離,從而可以方便的向SoC中集成IP模塊。 Void generate_data(int &out){ for(int i=0;i<10;i++){ accumlate(out); } } Void accumlate(int &in1){ sum +=in1; cout<<;“sum =”< } SC_MODULE(producer){ Sc_outmaster 表示作為主機輸出out1 Sc_in Void generate_data(){ For(int i+0;i<10;i++){ Out1=i; } } SC_CTOR(producer){ SC_METHOD(generate_data); sensitive< } } SC_MODULE(consumer){ Sc_inslave Int sum; Void accumulate(){ Sum+=int1; Cout<<;“sum=”< } SC_CTOR(consumer){ sc_slave(accumulate,in1); // systemc中master-slave通信庫內表示從機中accumulate函數對in1敏感 sum=0; } } SC_MODULE(top){ Producer *A1; Consumer *B1; Sc_link_mp SC_CTOR(top){ A1=new producer(“A1”); A1->out1(link1); B1=new consumer(“B1”); B1->in1(link1); } } 參考資料 >接口
通道
端口
行為建模
通信庫