admin 管理员组文章数量: 1184232
2024年1月18日发(作者:编程的主要内容)
SystemC中的SC_METHOD、SC_THREAD和SC_CTHREAD
2008-12-23 14:38
现实系统中很多活动都是同时发生的。SystemC用过程(Process)来模拟并发性。了解SystemC仿真器如何处理并发性,能使设计者写出高效的仿真模型。SystemC提供两种主要的过程类型:SC_THREAD和SC_METHOD。另外还有第三种,SC_CTHREAD,是SC_THREAD的变型。SystemC官方的Language Reference Manual不推荐在一般情况下使用SC_CTHREAD。
一、事件sc_event:
事件(Event)是SystemC这种事件驱动的仿真器的关键之处。事件就是在某个特定时间点发生的事情。一个时间没有取值,也没有持续时间。事件本身没有并不做任何可以被观察到的事情,它只是激发对它敏感的过程,从而表现出作用。SystemC中的过程通过动态或者静态敏感表来等待一个事件的发生。声明一个事件的语法如下:
sc_event name;
二、过程SC_THREAD:
过程SC_THREAD被且只被仿真器启动一次。SC_THREAD一旦被启动就完全控制仿真过程,直到其自己将控制返回给仿真器。SC_THREAD有两种返回控制给仿真器的方法,一种是简单退出(如return),这意味着永远结束该过程。因此,常常在SC_THREAD中使用含有wait语句的无限循环。
另一种返回控制的方法是使用wait来挂起过程。有时候wait并不是被直接使用的,比如sc_fifo的阻塞读和写在FIFO分别为空或满的时候将隐式的激活wait。
三、SC_THREAD::wait()的动态敏感表(dynamic sensitivity):
SC_THREAD依靠wait来挂起自身。当wait被执行时,当前SC_THREAD过程的状态将被保存,同时仿真内核得到控制权,接着启动另一个准备好的过程。当被挂起的过程重新被启动时,它将从wait后的语句开始执行。wait的语法如下:
wait(time);
wait(event);
wait(event1 | event2); // any of these events
wait(event1 & event2); // all of these events
wait(timeout, event1 | event2); // any of these events with timeout
wait(timeout, event1 & event2); // all events with timeout
wait(); // static sensitivity
带有timeout的wait将timeout值设为最大的等待时间,超过这个时间即使事件没有发生,过程同样也会被重新启动。我们可以在timeout的wait后面用布尔函数time_out()来
检测到底是不是timeout使得过程返回,例如:
...
sc_event ack_event, bus_error_event;
...
wait(t_MAX_DELAY, ack_event | bus_error_event);
if(time_out()) break; // test for timeout
...
四、启动事件-.notify():
事件通过notify()来显式的发生。notify()有以下两种语法风格,由于C++是面向对象的语言,因此建议使用前一种语法风格:
// Object-oriented style (preferred)
event_(); //immediate notification
event_(SC_ZERO_TIME); //delayed notification
event_(time); //timed notification
// Functional-call style
notify(event_name); //immediate notification
notify(event_name, SC_ZERO_TIME); //delayed notification
notify(event_name, time); //timed notification
上面最难理解的是.notify()和.notify(SC_ZERO_TIME)两种的区别。.notify()会立即使等待该事件的过程转为等待被执行。而.notify(SC_ZERO_TIME)会在当前等待被执行的所有过程完成后,才将等待该事件的过程转为等待被执行(所谓的下一个delta-cycle)。
对于.notify(time)来说,如果有多个notification,那么只有时间最近的那个是有效的。我们可以用.cancel()来取消所有notification。
五、过程SC_METHOD:
SC_METHOD与SC_THREAD的主要不同,是SC_METHOD不能在其内部被挂起,即不能直接或间接的使用wait(),否则会报runtime error的错误。SC_METHOD一旦运行便会运行到底,然后返回。仿真引擎根据动态敏感表不断的调用SC_METHOD。某种程度上,SC_METHOD很像Verilog中的always块。注册SC_METHOD过程的语法如下:
SC_METHOD(process_name); //Located inside constructor
SC_METHOD中的变量在其每次被调用时都要被声明和初始化。这和SC_THREAD中变量是永远存在的不一样。如果希望保存SC_METHOD中的值,那么就需要使用
SC_MODULE中定义的局部变量。
六、SC_METHOD::next_trigger()的动态敏感表:
SC_METHOD过程通过next_trigger()来处理动态敏感表。next_trigger()和wait()有着同样的语法。next_trigger不会阻碍当前SC_METHOD的执行,它会改变下一次调用该SC_METHOD的敏感表。如果没有静态敏感表,那么SC_METHOD的所有执行分支都应当有next_trigger,否则可能导致该SC_METHOD不再被调用。
七、过程的静态敏感表(Static Sensitivity):
前面说的动态敏感表示在仿真阶段的建立的,并且可以在仿真中被改变。静态敏感表是在仿真开始前建立的,在仿真过程中不能被改变。静态敏感表的申明有两种语法:
sensitive< sensitive(event [, event]...); // functional style 同样建议选择类似于C++流的第一种语法风格。静态敏感表的申明必须紧跟在其过程的注册语句后面。 八、dont_initialize: SystemC的仿真引擎将在开始时初始化执行所有的过程,然后有时候某些过程不需要在一开始就执行。可以在静态敏感表后面加上dont_initialize()来阻止初始化执行。 九、sc_event_queue: 正如前面讲的,sc_event只能被安排一次,如果多个notification只有时间最近的那个会被执行。sc_event_queue使得一个事件能够被安排多次,甚至是在同一个时间点。sc_event_queue的语法和sc_event类似。
版权声明:本文标题:SC_THREAD等进程使用 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1705565520a490193.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论