概述
预备打工人之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中呢,
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中,测试模块比较麻烦,需要两个模块,第一个模块是驱动模块产生信号,第二个模块是监视器监控输入输出信号。
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。
最后
以上就是执着树叶为你收集整理的预备打工人之SystemC学习(二)——一个全加器的例子半加器全加器测试模块顶层模块的全部内容,希望文章能够帮你解决预备打工人之SystemC学习(二)——一个全加器的例子半加器全加器测试模块顶层模块所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复