预备打工人之SystemC学习
- 半加器
- 全加器
- 测试模块
- driver模块
- monitor负责监控
- 顶层模块
这是一个全加器的例子。
这个全加器是由两个半加器构成,这样可以学习一下层次的连接与描述。
半加器
一位的半加器就是输入a,b,输出进位符号c和结果sum。由于和c++一样的描述,所以将module定义写在.h文件中,将具体函数写在.c中。
1、首先是.h中
1
2
3
4
5
6
7
8
9
10
11#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。函数里是输出与输入的关系。
1
2
3
4
5
6#include "half_add.h" void half_add::prc_half_add(){ sum=a*b; carry=a&b; }
全加器
由半加器组成全加器,主要就是调用半加器来构成。和半加器的一样,分为.h和.cpp两个文件。
1、.h文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#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中呢,
1
2half1_ptr= new half_add("half1");
指针分指向新建的创建的半加器,括号里的是自己取的名称。
1
2half1_ptr->a(a);
并且使用了上述语句将半加器模块的端口与全加器端口连接,两个半加器中模块的连接使用信号。
值得注意的是,因为创建了指针,所以需要析构函数进行释放。
2、.cpp文件
1
2
3
4
5#include "full_add.h" void full_add::prc_or(){ carry=c1|c2; }
测试模块
测试模块就是verilog中的test bench。
但是SystemC中,测试模块比较麻烦,需要两个模块,第一个模块是驱动模块产生信号,第二个模块是监视器监控输入输出信号。
driver模块
驱动将产生信号给全加器的输出
1、driver.h驱动
1
2
3
4
5
6
7
8
9#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驱动
1
2
3
4
5
6
7
8
9
10
11
12
13#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中
1
2
3
4
5
6
7
8
9
10#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来进行输出
1
2
3
4
5
6
7
8#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; }
顶层模块
刚刚每个模块都已经完成,最后需要一个顶层模块全部串起来。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#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学习(二)——一个全加器内容请搜索靠谱客的其他文章。
发表评论 取消回复