参考:SystemC 学习之 SystemC 基本语法(二)_systemc namespace-CSDN博客
1、systemc头文件
systemc库包含了两个最基本和最重要的命名空间,一个是sc_ocre,一个是sc_dt。
sc_core是systemc基本的内核空间,sc_dt则定义了systemc的最基本数据类型。
systemc.h则包含了除了sc_core和sc_dt外的其他方针中所需要的名字,也包含了一些c++de命名空间,比如namespace std等。
2、模块
模块是systemc设计中最基本的单元,是完成一个特定功能的基本单元。
SC_MODULE(Driver){
}
宏展开如下
SC_MODULE展开是一个宏定义
#define SC_MODULE(user_module_name) \
struct user_module_name : ::sc_core::sc_module
用宏SC_MODULE()定义的struct默认继承了sc_core命名空间的sc_module类。
类driver的构造函数定义如下
SC_CTOR(Driver) {
}
#define SC_CTOR(user_module_name) \
typedef user_module_name SC_CURRENT_USER_MODULE; \
user_module_name( ::sc_core::sc_module_name )
// the SC_HAS_PROCESS macro call must be followed by a ;
#define SC_HAS_PROCESS(user_module_name) \
typedef user_module_name SC_CURRENT_USER_MODULE
class SC_API sc_module_name
{
friend class sc_module;
friend class sc_object_manager;
public:
sc_module_name( const char* );
sc_module_name( const sc_module_name& );
~sc_module_name();
operator const char*() const;
...
}
可以看出SC_HAS_PROCESS只起了个typedef的作用,而SC_CTOR同时定义了构造函数。其中sc_module_name是一个用来管理名字的类,它可以用cons char*数据类型隐式转换而得。
这里比较奇怪的一个地方是user_module_name括号里面的::sc_core::sc_module_name,暂时还没有搞懂这个写法。(疑问)
3、端口和信号
输入端口:
sc_in<类型> 名称;
输出端口:
sc_out<类型> 名称;
双向端口:
sc_inout<类型> 名称;
systemc中信号有两种定义方式:sc_signal<类型> 和 sc_buffer<类型>。
4、类型的总结
参考:SystemC入门学习-第3章 数据类型_systemc数据类型-CSDN博客
类型名 | 描述 |
sc_bit | 位宽为1,值为0或1之一的二值信号 |
sc_bv<n> | 任意位宽的位向量 |
sc_logic | 位宽为1,值为0、1、X或Z之一的四值信号 |
sc_lv<n> | 任意位宽的逻辑向量 |
sc_int<n> | 最多可达64位的有符号整型数 |
sc_uint<n> | 最多可达64位的无符号整型数 |
sc_bigint<n> | 任意位宽的有符号整型数 |
sc_biguint<n> | 任意位宽的无符号整型数 |
4.1 sc_bit支持的操作符:
操作符 | 功能 | 用法 |
& | 按位”与“ | 表达式1 & 表达式2 |
| | 按位”或“ | 表达式1 | 表达式2 |
^ | 按位”异或“ | |
~ | 按位求反 | ~表达式 |
= | 赋值 | 值保持器=表达式 |
&= | 相“与”赋值 | |
|= | 相“或”赋值 | |
^= | 相“异或”赋值 | |
== | 相等 | |
!= | 不相等 |
4.2 sc_bv支持的操作符和方法:
4.3 逻辑类型
4.4 任意位宽的逻辑类型
4.5 有符号的整数类型
4.6 无符号的整数类型
4.7 任意精度的整数类型
4.8 判断类型
5、进程
在操作系统中,进程是程序在并发环境中的执行过程,它具有动态性、并发性、独立性、异步性和结构性五大特征。
在systemc中,进程是一个基本的执行单元,被用来仿真目标系统的行为,systemc基本进程有三种
1)SC_METHOD
2) SC_THREAD
3) SC_CTHREAD
在systemc中,进程不是层次化的,一个进程不可能包含或者直接调用其他进程,但是进程可以调用非进程的函数和方法。
5.1 方法进程SC_METHOD
SC_METHOD的特点是当敏感列表上有事件发生就会被调用,调用后立刻返回,只有该类进程返回后仿真系统的时间才有可能继续前进,因此不能使用wait这样的语句。
5.2 线程进程SC_THREAD
线程进程能够挂起和重新激活,线程进程使用wait挂起,当敏感列表中有时间发生时,或者wait时间超时时,线程进程会被重新激活,在一次方针中,线程进程一旦退出,将不能再重新进入。
5.3 钟控线程进程SC_CTHREAD
钟控线程进程是一种特殊的线程进程,它继承于线程进程,但只能在时钟的上升沿或者下降沿被触发或者激活,这种行为更接近实际硬件的行为,引入钟控线程进程是为了产生更好的行为综合。
6、通信
接口(Interface):派生自sc_interface的抽象类,包括一组虚拟函数集合。
端口(port):负责提供module写数据的方法,因此一般同具体的实例独立。
通道(channel):一个primitive channel应该实现一个或多个接口。
简单来说:
1)端口提供服务,接口定义服务,通道实现服务。
2)一个端口可以连接(绑定)到一个通道上,当且仅当该通道实现了端口要求实现的接口。
3)一个端口可视为一个通道上的一个指针。
template <class T> class sc_signal_in_if : virtual public sc_interface
template <class T> class sc_in : public sc_port<sc_signal_in_if<T>,1>
template <class T> class sc_signal_inout_if : public sc_signal_in_if<T> , public sc_signal_write_if<T>
template <class T> class sc_inout : public sc_port<sc_signal_inout_if<T>,1>
template <class T> class sc_out : public sc_inout<T>
template <class T, sc_writer_policy WRITER_POLICY = SC_ONE_WRITER>
class sc_signal : public sc_signal_inout_if<T>, public sc_prim_channel
class sc_clock : public sc_signal<bool>
typedef sc_in<bool> sc_in_clk
总之,sc_in、sc_out 和sc_inout 都属于sc_port的子类。sc_clock / sc_signal / sc_fifo / sc_mutex / sc_event_queue / sc_semaphore 都属于sc_interface 的子类。