一般声明systemC类模块的格式为
SC_MODULE(类名){
端口声明: sc_in sc_out sc_inout
在内部链接可能需要使用的信号
声明需要使用的一般函数
声明需要使用的进程函数或者线程函数
子模块的声明或者其指针的声明
数据变量的声明
// 构造函数
SC_CTOR(类名){
注册进程或者线程函数
声明敏感量列表
}
};
一旦函数在构造函数中进行了声明,那么这个函数就不再是一个简单的方法了。
(1)在构造函数中使用SC_METHOD声明:那么这个一个进程方法,它会被敏感量所触发。触发后进入到函数执行,执行完毕后将执行权转交给仿真内核。
进程方法必须是有限循环的。
(2)在构造函数中使用SC_THREAD声明:那么这是一个线程方法,它会被敏感量触发。一般而言,触发后会停止线程方法的挂起状态,从而继续执行,直
到遇 到下一个wait语句从而再次挂起。线程函数一般是无限循环的。
接下来博主就举组合逻辑的例子-----关于数据选择器multiplexer的建模:
base.h:
#ifndef BASE
#define BASE
#include "systemc.h"
#include <iostream>
#endif
simulus.h:
#include "base.h"
#ifndef SIMULUS
#define SIMULUS
SC_MODULE(simulus){
// signal drivers
sc_out<bool> cs ;
sc_out<sc_uint<3> > select ;
void prc_simulus();
SC_CTOR(simulus){
SC_THREAD(prc_simulus); // 因为信号需要不断的生成,所以需要使用THREAD线程方法
}
};
#endif
stimulus.cpp:
#include "simulus.h"
void simulus::prc_simulus(){
// signal generates process
sc_uint<3> temp(0) ;
cs = 0 ;
for(;;){
select = temp ;
temp++ ;
wait(10,SC_NS); 每次使线程挂起10ns
}
}
monitor.h:
#include "base.h"
#ifndef MONITOR
#define MONITOR
SC_MODULE(monitor){
sc_in<bool> cs ;
sc_in<sc_uint<3> > select ;
sc_in<sc_uint<8> > mul_out;
void prc_monitor();
SC_CTOR(monitor){
SC_METHOD(prc_monitor);
sensitive<<mul_out; // 输出监视,监视multiplexer的输出
};
};
#endif
monitor.cpp:
#include "monitor.h"
void monitor::prc_monitor(){
// 在这个输出中无法使用c语言的函数进行输出,因为类型无法匹配,
// 并且systemc2.x 的版本较老了,没有办法使用其内建的to_string函数
cout<<cs.read()<<" "<<select.read()<<" "<<mul_out.read()<<std::endl ;
}
dut.h(Design under test ----- multiplexer ):
#include "../base.h"
#ifndef DUT
#define DUT
SC_MODULE(multiplexer){
sc_in<bool> cs_n ;
sc_in<sc_uint<3> >select ;
sc_out<sc_uint<8> > mul_out ;
void prc_mul();
SC_CTOR(multiplexer){
SC_METHOD(prc_mul);
sensitive<<cs_n<<select ;
};
};
#endif
dut.cpp:
#include "dut.h"
void multiplexer::prc_mul() // 数据选择器的内部逻辑实现
{
sc_uint<8> temp = 0 ;
temp = ~temp ;
if( cs_n )
mul_out = temp ;
else {
temp[select.read()] = 0 ;
mul_out = temp ;
}
}
最后的总测试文件main.cpp:
#include "simulus.h"
#include "dut/dut.h"
#include "monitor.h"
int sc_main(int argc , char * argv[]){
// signal defination
sc_signal<sc_uint<3> > select_sig;
sc_signal<sc_uint<8> > mul_out_sig;
sc_signal<bool> cs_sig ;
sc_trace_file * vcd = sc_create_vcd_trace_file("record"); // 创立一个vcd记录文件
// istance the component
simulus sim("select");
sim(cs_sig,select_sig);
multiplexer mul("multiplexer");
mul(cs_sig,select_sig,mul_out_sig);
monitor mon("monitor");
mon(cs_sig,select_sig,mul_out_sig);
sc_trace(vcd,select_sig,"select");
sc_trace(vcd,mul_out_sig,"multiplexer"); // 将需要记录的文件加入到vcd文件中
sc_start(1000,SC_NS); // 仿真时间为1000ns
sc_close_vcd_trace_file(vcd); // 仿真结束后关闭vcd文件
return 0 ;
}
最后的仿真结果:
转载于:https://blog.51cto.com/13824643/2137092