微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 微电子和IC设计 > IC验证交流 > 第一章 SystemC基础知识(二)

第一章 SystemC基础知识(二)

时间:10-02 整理:3721RD 点击:

2 进程

CtoS中使用的进程是SC_CTHREAD和SC_METHOD。这两个进程的区别在于SC_METHOD进程不能调用wait因此必须在零时间内返回,而SC_CTHREAD进程,不需要返回,相反地SC_CTHREAD进程必须调用wait将自身挂起并且允许其他进程执行。

在设计中选择哪种类型的进程完全取决于我们将要建模的逻辑:

·纯组合逻辑应该使用带上该逻辑对所有输入敏感的静态敏感列表的SC_METHOD建模;即组合SC_METHOD进程;

·带显式状态控制的时序进程应该用带由时钟事件或者异步复位事件组成的静态敏感表的SC_MATHOD进程;即时钟SC_METHOD进程;

·带隐式控制状态的时序状态机应该用SC_CTHREAD进程建模,这种建模风格最适合行为描述。


2.1 SC_CTHREAD 进程
2.1.1 SC_CTHREAD的基本概念

如下代码段给出了如何定义SC_CTHREAD进程的方法:



在构造函数中,我们声明了用SC_CTHREAD宏将main方法声明为进程,该进程对clk时钟上升沿敏感,即每次进程调用wait时都会挂起直到clk从0跳变到1然后从wait之后继续执行。reset_signal_is函数指明了该进程有一个同步复位信号rst,该信号低有效,在clk从0到1跳变的时刻,如果采样到rst为低,那么该进程将重新启动;类似地,我们也可以为该进程指定一个异步复位信号,如将rst指定为异步复位,低有效调用async_reset_signal_is函数。reset_signal_is函数和async_reset_signal_is函数的第一个参数是module的sc_in<bool>或sc_in<sc_logic>类型的成员成员,如果复位信号是在module内部产生的,那么第一个参数也可以是sc_signal<bool>或sc_signal<sc_logic>类型。

SC_CTHREAD宏的第二个参数指定了时钟事件,时钟事件必须是包含该进程的module的sc_in<bool>或者sc_in_clk成员的上升沿(用pos表示)或者下降沿(用neg表示)事件。而对于复位条件需要注意的几点就是:SC_CTHREAD进程可以指定多个复位条件,但是最多只能一个异步复位条件,而对于大多数的线程进程而言,指定一个复位条件足矣[1]。我们的建议是为每一个线程进程指定一个复位条件,当然如果进程只有一个控制状态那么不指定复位条件也是可以的。

那么复位行为如何在进程中体现出来?如下面的代码实现了SC_CTHREAD进程main,复位行为由main的函数体开始到遇到的第一个wait之间的语句描述,即out.write(0)复位后端口out输出低电平。



如果一个线程进程没有指定复位,那么在验证时应该特别注意在仿真开始时综合模型中的内部信号会被初始化为不定态x,对应的SytemC中的内部变量将被初始化为0。


2.1.1 SC_CTHREAD进程函数

前一目讨论到了用SC_CTHREAD宏注册的进程函数,该函数必须包含该进程的成员函数,我们注意到上一目中定义的main其参数列表为空而且没有返回值,事实上所有的SC_CTHREAD进程函数都没有参数列表,且返回值都为void。

上一目实现的main函数中,从函数体最开始到遇到的第一个wait[2],这之间的代码描述了该进程的复位行为,在复位行为中,进程是不能读取本module最初输入或者sc_signal的值的,在复位行为发生期间唯一进行的事情就是为变量指定编译时间常量(compile-timeconstant)和为输出和signal写初值。如果进程有多个复位,则允许从复位信号读取值来决定哪个复位条件有效。

在复位行为之后就是该进程的普通操作了,我们必须将普通操作放入一个无限循环之中,而该无限循环必须直接调用wait或者通过调用其它函数来间接调用wait。

其实在复位行为和描述普通操作的无限循环之间还有可以加上可选的初始化描述,比如我们可以在一个有限循环中初始化一个数组,而这个数组的元素随后可以在普通操作中进行读写。
2.2 SC_THREAD进程

对于SC_THREAD进程,其静态敏感表由时钟事件组成,一个代码示例如下:



这其实SC_CTHREAD的另外一种写法,CtoS对两种写法不加以区分,所有SC_CTHREAD进程的限制同样适用于SC_THREAD进程。


2.3 组合SC_METHOD进程

组合SC_METHOD进程用于建模组合逻辑,一旦输入改变那么进程就会重新计算输出;与组合SC_METHOD相关的函数不能调用wait,且必须立即返回;一旦静态敏感表中任意输入改变时,该函数就会被调用。

在CtoS中对使用组合SC_METHOD有一些限制,在讨论这些限制之前,我们先给出一个组合SC_METHOD进程的例子。

#include “systemc.h”

class mux2x8 :public sc_module {

public:

mux2x8(sc_module_name name);

~mux2x8();

SC_HAS_PROCESS(mux2x);

sc_in<sc_uint<8> >in0;

sc_in<sc_uint<8> >in1;

sc_in<bool>sel;

sc_out<sc_uint<8> > out;

private:

void proc();

};


mux2x8::mux2x8(sc_module_namename) : sc_moudle(name), in0(“in0”), in1(“in1”),

sel(“sel”), out(“out”)

{

SC_METHOD(proc);

sensitive << in0 << in1<< sel;

}


voidmux2x8::proc() {

out = sel ? in1 : in0;

}


在上面给出的例子中,SC_MATHOD方法进程在构造函数中进行指定,我们注意到使用了sensitive,该关键字可以为SC_METHOD方法进程指定静态敏感表:在SC_METHOD方法进程的静态敏感表中必须进程所有输入的value_changed_vent事件,默认情况下value_changed_event针对sc_in端口和sc_signal,我们只需要按照上面例子在静态敏感表中给出sc_in端口或sc_signal的名字即可。

我们注意到在上面的静态敏感表中没有边沿事件(edge event),是否在SC_METHOD方法进程的静态敏感表中不允许有边沿事件呢?答案是肯定的!SC_METHOD的仿真语义在于当进程中的输入(通常列于静态敏感表中)发生改变时会立即对输出进行重新计算,所以要使此类进程的仿真结果与综合后硬件的行为保持一致,我们必须保证:

·进程的每个输入建模为sc_signal或sc_in端口;

·进程的每个输出建模为sc_signal或sc_out端口;

·进程的静态敏感表包含进程的所有输入。


再次强调,SC_METHOD方法进程函数没有任何参数,返回值一定为void,函数体中不能包含任何延迟语句,包括wait语句,也不能包含无限循环。





[1]并不是所有版本的INCISIV仿真器都支持多复位,且如果指定多个复位条件那么最终实现的电路将会更复杂并且QoR更差,所以如非确实必要不要使用多复位,本书也不深入讨论多复位问题。

[2]如果调用wait时不带参数,这表示等待直到下一个时钟事件,如果wait带正整常数n则表示等待n个时钟事件,在SC_CTHREAD进程中,使用wait时只能使用以上提到的两种调用方式,不能使用wait(some_sc_event)等形式的调用。

学习了..这是哪本书中的?还是自己写的哇,厉害

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top