一位的半加器就是输入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中呢,
half1_ptr= new half_add("half1");
指针分指向新建的创建的半加器,括号里的是自己取的名称。
half1_ptr->a(a);
并且使用了上述语句将半加器模块的端口与全加器端口连接,两个半加器中模块的连接使用信号。
值得注意的是,因为创建了指针,所以需要析构函数进行释放。
2、.cpp文件
#include "full_add.h"
void full_add::prc_or(){
carry=c1|c2;
}
测试模块就是verilog中的test bench。
但是SystemC中,测试模块比较麻烦,需要两个模块,第一个模块是驱动模块产生信号,第二个模块是监视器监控输入输出信号。
驱动将产生信号给全加器的输出
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也会改变
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。