systemC
軟/硬體協同設計語言
System C是一種軟/硬體協同設計語言,一種新的系統級建模語言。它包含了一系列C++的類和宏,並且提供了一個事件驅動的模擬核,使得系統的設計者能夠用C++的詞法模擬并行的進程,特別是在SoC系統中。
近年來Synopsys 公司, CoWare 公司和Frontier Design公司合作開發了SystemC。在1999 年9 月27 日四十多家世界上著名的EDA 公司, IP 公司,半導體公司和嵌入式軟體公司宣布成立”開放式SystemC 創始社” (Open SystemC Initiative) 這些公司包括ARM, CoWare, Cygnus Solution, Ericsson, Frontier Design, Fujitsu, Infineon, Lucent Technologies,Sony, STMicroelectronics, Synopsys, Taxas Instruments 等
這些公司認為SystemC 是一種很好的硬體軟體聯合設計語言。Ericsson 公司微電子部主任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的時鐘模型
sc_clock共有六個重載的構造函數。
sc_clock(“clk1”,20,0.5,5,ture)?
模塊
模塊是SystemC的 最基本單元,模塊內部可以包括 埠,內部信號,內部數據,進程等
模塊本質上是 類,使用 SC_MODULE聲明:
SC_MODULE(mmu)
{…..//details of the design}
等價於:
Class mmu :public sc_module
{…..//details of the design}
SC_METHOD??實例
?
#ifndef_FULLADDER_H
#define_FULLADDER_H
SC_MODULE(FullAdder)
{
sc_inA,B,Ci;
sc_outS,Co;
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敏感
sensitive<
}
};
#endif
SC_THREAD實例
#ifndef_MONITOR_H
#define_MONITOR_H
#include
SC_MODULE(Monitor)
{
sc_inm_a,m_b,m_cin,m_sum,m_cout;
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 d_a,d_b,d_cin;
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_portram_port; //實例化埠
Int data;
Unsigned int address;
…
void main_action{ //需要用戶自己定義
…
Transfer_statusstatus=ram_port->write(address,data);//在功能函數中通過埠
… ;調用通道函數
Transfer_statusstatus=ram_port->read(address,data);//通過埠調用功能函數
…
}
…
}
通道(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_outmasterout1; //systemc中master-slave通信庫內
表示作為主機輸出out1
Sc_in<bool>start;//啟動進程
Void generate_data(){
For(int i+0;i<10;i++){
Out1=i;
}
}
SC_CTOR(producer){
SC_METHOD(generate_data);
sensitive<
}
}
SC_MODULE(consumer){
Sc_inslavein1; //systemc中master-slave通信庫內表示作為從機輸入in1
Int sum;
Void accumulate(){
Sum+=int1;
Cout<<;“sum=”<A1=new producer(“A1”);
}
SC_CTOR(consumer){
sc_slave(accumulate,in1); // systemc中master-slave通信庫內表示從機中accumulate函數對in1敏感
sum=0;
}
}
SC_MODULE(top){
Producer *A1;
Consumer *B1;
Sc_link_mplink1; //systemc中master-slave通信庫內中間通信
SC_CTOR(top){
示意
A1->out1(link1);
B1=new consumer(“B1”);
B1->in1(link1);
}
}
目錄