下面是一个简单的例子:
SC_MODULE(simple_process_ex) { SC_CTOR(simple_process_ex) { SC_THREAD(my_thread_process); }
void my_thread_process(void); };
5.6 完成一个简单的设计:main.cpp
在my_instance中用了\做参数,这么做的目的是为了将实例的名字存储在其内部,以便在debug时调用。sc_module的成员函数name()可用来获取当前实例的名称。
5.7 另一种构造函数:SC_HAS_PROCESS
可以在两种情况下使用该宏:
当需要将实例名称以外的参数传给构造函数; 希望将构造函数的实现放到另一个cpp文件中。
例如,一个存储设计可以允许通过参数进行不同大小的存储选择: My_memory instance(\
(六)时间概念
6.1 sc_time
SystemC提供sc_time数据类型来衡量时间。时间由两部分构成:长度(magnitude)和单位(unit)。
时间数据类型语法如下:
时间单位有以下几种:
SystemC允许对sc_time对象进行加、减以及比例缩放等操作。 一个特殊的常量SC_ZERO_TIME,即代表sc_time(0, SC_SEC)。
6.2 sc_start()
sc_start()用于启动仿真阶段。sc_start()提供了一个sc_time类型的可选参数,用来指定最大仿真时间。如:
sc_start(60.0, SC_SEC);
6.3 sc_time_stamp () and Time Display
在SystemC中可以通过sc_time_stamp()来获得当前仿真时间。如: cout << sc_time_stamp() << endl;
6.4 wait(sc_time)
wait()被用在SC_THREAD过程中完成延迟功能。当遇到wait(),SC_THREAD过程被阻塞,并且在指定的时间返回继续执行。如:
wait(delay_sc_time); // wait specified amount of time
6.5 sc_simulation_time(), 时间分辨率和单位
有时想要用C++内建数据类型操作时间,sc_simulation_time()将以当前缺省单位返回double类型的时间。
修改缺省时间单位: sc_set_default_time_unit().缺省时间单位必须是10的幂,必须大于等于时间分辨率,只能设置一次,只能在仿真开始之前设置。 指定时间分辨率:sc_set_time_resolution().时间分辨率必须是10的幂,只能在仿真开始之前设置,且只设置1次,必须在任何的非零的sc_time声明之前设置。
(七)并发 Processes & Events
实时系统中的很多活动都是同时发生的,SystemC用processes模拟并发。
SystemC提供了两个主要的process类型:SC_THREAD,SC_METHOD,还有第三种类型,SC_CTHREAD,是SC_THREAD的变型。
7.1 sc_event
事件就是在某个特定时间点发生的事情。一个时间没有取值,也没有持续时间。事件本身没有并不做任何可以被观察到的事情,它只是激发对它敏感的过程,从而表现出作用。
SystemC中的process通过动态或者静态敏感表来等待一个事件的发生。声明一个事件的语法如下:
由于sc_event没有取值,只能对它采取两种动作:等待或导致它发生。
7.2 Simplified Simulation Engine
需要理解事件驱动模拟是怎样工作的。见5页SystemC Simulation Kernel.
7.3 SC_THREAD
过程SC_THREAD被且只被仿真器启动一次。SC_THREAD一旦被执行,就完全控制仿真过程,直到其自己将控制返回给仿真器。
SC_THREAD有两种返回控制给仿真器的方法,一种是简单退出(如return),这意味着永远结束该过程。因此,常常在SC_THREAD中使用含有至少一条wait语句的无限循环。
另一种返回控制的方法是调用wait方法,wait挂起sc_thread进程。有时候wait并不是被直接使用的,比如sc_fifo的阻塞读或写在FIFO分别为空或满的时候将隐式的激活wait。
7.4 SC_THREAD::wait()的动态敏感表
SC_THREAD依靠wait来挂起自身。当wait被执行时,当前SC_THREAD进程的状态将被保存,同时仿真内核得到控制权,启动另一个准备好的进程。当被挂起的过程重新被启动时,它将从wait后的语句开始执行。wait的语法如下:
当使用timeout时,在wait后立即调用布尔函数timed_out()来检测是否是 time out 导致进程返回。例如:
7.6 启动事件: .notify()
事件通过使用notify()来显式的发生。 面向对象的语法风格:
调用.notify() 会使任何等待该事件的进程立即由等待转为就绪。
.notify(SC_ZERO_TIME)会在当前等待被执行的所有过程完成后,才将等待该事件的过程转为等待被执行(所谓的下一个delta-cycle)。
对于.notify(time)来说,如果有多个notification,那么只有时间最近的那个是有效的。我们可以用.cancel()来取消所有notification。
7.7 SC_METHOD
SC_METHOD从不在其内部被挂起(不能直接或间接的使用wait(),否则会报runtime error的错误),SC_METHOD一旦运行便会运行到底,然后返回。仿真引擎根据动态或静态敏感表不断的调用SC_METHOD。 语法如下:
SC_METHOD(process_name); //Located inside constructor 在SC_THREAD中变量分配是永久的,即变量是永远存在的。
在SC_METHOD中,每次被调用时变量都要被声明和初始化,如果希望保存SC_METHOD中的值,那么就需要使用SC_MODULE中定义的局部变量。