我是靠谱客的博主 执着树叶,这篇文章主要介绍预备打工人之SystemC学习(二)——一个全加器的例子半加器全加器测试模块顶层模块,现在分享给大家,希望可以做个参考。

预备打工人之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
2
half1_ptr= new half_add("half1");

指针分指向新建的创建的半加器,括号里的是自己取的名称。

复制代码
1
2
half1_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学习(二)——一个全加器内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(113)

评论列表共有 0 条评论

立即
投稿
返回
顶部