天天看點

預備打勞工之SystemC學習(二)——一個全加器的例子半加器全加器測試子產品頂層子產品

預備打勞工之SystemC學習

  • 半加器
  • 全加器
  • 測試子產品
    • driver子產品
    • monitor負責監控
  • 頂層子產品

這是一個全加器的例子。

這個全加器是由兩個半加器構成,這樣可以學習一下層次的連接配接與描述。

半加器

一位的半加器就是輸入a,b,輸出進位符号c和結果sum。由于和c++一樣的描述,是以将module定義寫在.h檔案中,将具體函數寫在.c中。

1、首先是.h中

#include "systemc.h"
SC_MODULE(half_add){
	sc_in<bool> a,b;
	sc_out<bool> sum,carry;
	void prc_half_add();
	SC_CTOR(half_add){
	SC_METHOD(prc_half_add);
	sensitive<<a<<b;
	}
};
           

SC_MODULE類似建立一個類(systemc模闆)

定義了兩個bool類型的輸入a和b,兩個輸出sum和carry。

定義了主要的函數prc_half_add(),這個函數将在.c中具體定義,并且是關系到輸入與輸出的。

SC_CTOR是為MODULE定義了構造函數,其中SC_METHOD是将函數加載到子產品,sensitive是指敏感清單。

2、下面是cpp内容,具體定義了half_add類下面的具體函數prc_half_add。函數裡是輸出與輸入的關系。

#include "half_add.h"
void half_add::prc_half_add(){
	sum=a*b;
	carry=a&b;
}
           

全加器

由半加器組成全加器,主要就是調用半加器來構成。和半加器的一樣,分為.h和.cpp兩個檔案。

1、.h檔案

#include "systemc.h"
#include "half_add.h"
SC_MODULE(full_add){
    sc_in<bool> a,b,c_i;
    sc_out<bool> sum,carry;
    sc_signal<bool> c1,s1,c2;
    void prc_or();
    half_add * half1_ptr,*half2_ptr;
    SC_CTOR(full_add){
        half1_ptr= new half_add("half1");
        half1_ptr->a(a);
        half1_ptr->b(b);
        half1_ptr->sum(s1);
        half1_ptr->carry(c1);
        half2_ptr= new half_add("half2");
        half2_ptr->a(s1);
        half2_ptr->b(c_i);
        half2_ptr->sum(sum);
        half2_ptr->carry(c2);     
    	SC_METHOD(prc_or);
    	sensitive<<c1<<c2;
    }
    ~full_add(){
      	delete 	half1_ptr;
        delete 	half2_ptr;
	}
};
           

SC_MODULE中定義了bool的三個輸入a,b,c_i 和兩個輸出sum和carry。

注意到設定了三個bool的信号變量,信号變量是用來連結子產品的中間量。

為了調用兩個半加器子產品,建立了兩個指針。

在SC_CTOR中呢,

指針分指向建立的建立的半加器,括号裡的是自己取的名稱。

并且使用了上述語句将半加器子產品的端口與全加器端口連接配接,兩個半加器中子產品的連接配接使用信号。

值得注意的是,因為建立了指針,是以需要析構函數進行釋放。

2、.cpp檔案

#include "full_add.h"
void full_add::prc_or(){
carry=c1|c2;
}
           

測試子產品

測試子產品就是verilog中的test bench。

但是SystemC中,測試子產品比較麻煩,需要兩個子產品,第一個子產品是驅動子產品産生信号,第二個子產品是螢幕監控輸入輸出信号。

driver子產品

驅動将産生信号給全加器的輸出

1、driver.h驅動

#include "systemc.h"
SC_MODULE(driver){
	sc_out<bool> d_a,d_b,d_cin;
	void prc_driver();
	SC_CTOR(driver){
	SC_THREAD(prc_driver);
	}
};
           

這裡的驅動子產品隻有輸出,這些輸出将用于全加器。并且在CTOR中使用的是SC_THREAD而不是SC_METHOD

2、driver.cpp驅動

#include "driver.h"
void driver::prc_driver(){
	sc_uint<3> pattern;
	pattern=0;
	while(1){
		d_a=pattern[0];
		d_b=pattern[1];
		d_cin=pattern[2];
		wait(5,SC_NS);
		pattern++;
	} 
}
           

建立了3位的變量pattern,将每一位分别賦予a,b,cin,并且過5ns後pattern也會改變

monitor負責監控

1、同樣是systemc.h中

#include "systemc.h"
SC_MODULE(monitor){
	sc_in<bool> m_a,m_b,m_cin,m_sum,m_cout;
	void prc_monitor();
	SC_CTOR(monitor){
		SC_METHOD(prc_monitor);
		sensitive<<m_a<<m_b<<m_cin<<m_sum<<m_cout;
	}
};
           

這個子產品就隻有輸入了

2、在.c檔案中具體使用cout來進行輸出

#include "monitor.h"
void monitor::prc_monitor(){
	cout<<"At time"<<sc_time_stamp()<<"::";
	cout<<"(a,b,carry_in): ";
	cout<<m_a<<m_b<<m_cin;
	cout<<"(sum,carry): "<<m_sum<<m_cout<<endl;
 }
           

頂層子產品

剛剛每個子產品都已經完成,最後需要一個頂層子產品全部串起來。

#include "driver.h"
#include "monitor.h"
#include "full_add.h"
int sc_main(int argc,char * argv[]){
	sc_signal<bool> t_a,t_b,t_cin,t_sum,t_cout;
	full_add f1("FULLADDerwithHalfadder");
	f1<<t_a<<t_b<<t_cin<<t_sum<<t_cout;
	driver d1("Generator");
	d1.d_a(t_a);
	d1.d_b(t_b);
	d1.d_cin(t_cin);
	monitor mo1("Monitor");
	mo1<<t_a<<t_b<<t_cin<<t_sum<<t_cout;
	sc_start(100,SC_NS);
	return 0;
}
           

隻要有sc_main函數,程式就會從sc_main開始。

注意,端口的連接配接隻能用信号

是以,建立了一系列的bool值用作信号。

建立了full_add的f1和driver 的d1和monitor 的mo1。

然後就調用,連接配接

最後 sc_start(100,SC_NS);表示開始仿真100ns。

繼續閱讀