5.2 sc_module

本文介绍了SystemC库中的sc_module类,强调了从实践出发学习的重要性,详细讲解了process、reset、wait和next_trigger等核心功能,以及如何使用宏定义SC_xxxx来简化代码。
摘要由CSDN通过智能技术生成

       sc_module

         systemc 的手册看完了,感觉还是从第五章开始讲比较好,先学会用,然后在研究底层原理。  

        sc_moduel code

class sc_module
: public sc_object
{
public:
    virtual ~sc_module();
    virtual const char* kind() const; 
    void operator() ( 
        const sc_bind_proxy†& p001,
        const sc_bind_proxy†& p002 = SC_BIND_PROXY_NIL,
        const sc_bind_proxy†& p003 = SC_BIND_PROXY_NIL,
        ... 
        const sc_bind_proxy†& p063 = SC_BIND_PROXY_NIL,
        const sc_bind_proxy†& p064 = SC_BIND_PROXY_NIL );
    virtual const std::vector<sc_object*>& get_child_objects() const;
    virtual const std::vector<sc_event*>& get_child_events() const;
protected:
    sc_module( const sc_module_name& );
    sc_module();
    void reset_signal_is( const sc_in<bool>& , bool );
    void reset_signal_is( const sc_inout<bool>& , bool );
    void reset_signal_is( const sc_out<bool>& , bool );
    void reset_signal_is( const sc_signal_in_if<bool>& , bool );
    void async_reset_signal_is( const sc_in<bool>& , bool );
    void async_reset_signal_is( const sc_inout<bool>& , bool );
    void async_reset_signal_is( const sc_out<bool>& , bool );
    void async_reset_signal_is( const sc_signal_in_if<bool>& , bool );
    sc_sensitive† sensitive;
    void dont_initialize();
    void set_stack_size( size_t );
    void next_trigger();


    void next_trigger( const sc_event& );
    void next_trigger( const sc_event_or_list & );
    void next_trigger( const sc_event_and_list & );
    void next_trigger( const sc_time& );
    void next_trigger( double , sc_time_unit );
    void next_trigger( const sc_time& , const sc_event& );
    void next_trigger( double , sc_time_unit , const sc_event& );
    void next_trigger( const sc_time& , const sc_event_or_list &);
    void next_trigger( double , sc_time_unit , const sc_event_or_list & );
    void next_trigger( const sc_time& , const sc_event_and_list & );
    void next_trigger( double , sc_time_unit , const sc_event_and_list & );
    void wait();
    void wait( int );
    void wait( const sc_event& );
    void wait( const sc_event_or_list &);
    void wait( const sc_event_and_list & );
    void wait( const sc_time& );
    void wait( double , sc_time_unit );
    void wait( const sc_time& , const sc_event& );
    void wait( double , sc_time_unit , const sc_event& );
    void wait( const sc_time& , const sc_event_or_list & );
    void wait( double , sc_time_unit , const sc_event_or_list & );
    void wait( const sc_time& , const sc_event_and_list & );
    void wait( double , sc_time_unit , const sc_event_and_list & );
    virtual void before_end_of_elaboration();
    virtual void end_of_elaboration();
    virtual void start_of_simulation();
    virtual void end_of_simulation();
private: 
    // Disabled 
    sc_module( const sc_module& ); 
    sc_module& operator= ( const sc_module& ); 
};
    void next_trigger();
    void next_trigger( const sc_event& );
    void next_trigger( const sc_event_or_list & );
    void next_trigger( const sc_event_and_list & );
    void next_trigger( const sc_time& );
    void next_trigger( double , sc_time_unit );
    void next_trigger( const sc_time& , const sc_event& );
    void next_trigger( double , sc_time_unit , const sc_event& );
    void next_trigger( const sc_time& , const sc_event_or_list & );
    void next_trigger( double , sc_time_unit , const sc_event_or_list & );
    void next_trigger( const sc_time& , const sc_event_and_list & );
    void next_trigger( double , sc_time_unit , const sc_event_and_list & );
    void wait();
    void wait( int );
    void wait( const sc_event& );
    void wait( const sc_event_or_list & );



    void wait( const sc_event_and_list & );
    void wait( const sc_time& );
    void wait( double , sc_time_unit );
    void wait( const sc_time& , const sc_event& );
    void wait( double , sc_time_unit , const sc_event& );
    void wait( const sc_time& , const sc_event_or_list & );
    void wait( double , sc_time_unit , const sc_event_or_list & );
    void wait( const sc_time& , const sc_event_and_list & );
    void wait( double , sc_time_unit , const sc_event_and_list & );
    #define SC_MODULE(name) struct name : sc_module
    #define SC_CTOR(name) implementation-defined; name(sc_module_name)
    #define SC_HAS_PROCESS(name) implementation-defined
    #define SC_METHOD(name) implementation-defined
    #define SC_THREAD(name) implementation-defined
    #define SC_CTHREAD(name,clk) implementation-defined
    const char* sc_gen_unique_name( const char* );
    typedef sc_module sc_behavior;
    typedef sc_module sc_channel;
} // namespace sc_core

 sc_module 用法

       继承

        sc_module 构造函数是private 属性,并且提供的很函数都属于protected,所以要使用第一步先继承,sc_module 不能单独使用。

        class user_module:public sc_module {};

        具体的function,逻辑算法,完全可以按照纯c++的行为实现,这一点自由度还是很高的,这也是SC最大的优势,但是同时这也是劣势。因为既不偏向软件工程师,也不偏向硬件工程师,导致很难被推广,现在已经跟SV不是一个级别,看看各家工具对SV,SC的支持度,也能感觉出来,具体SC的优缺点上一篇博文有提到。

        使用c++ 继承方式的写法,具体例子可以参考计算机体系结构研究仿真之SystemC基础(五) - 知乎 (zhihu.com)

        

       process

        process主要包括下面这三个

            #define SC_METHOD(name) implementation-defined
            #define SC_THREAD(name) implementation-defined
            #define SC_CTHREAD(name,clk) implementation-defined

        在user_module中例实现 process ,很多初学sc 的小伙伴背景都是纯软的,可以先理解为c++ 带锁的thread。有硬件背景的可以理解为D触发器,这两者的共同点都是在行为上是并行的,但是在实际运行时候是串行的。

       reset

        SC 中的reset 与rtl 中的reset 作用是一样的,可以设置边沿/电平触发,只不过根据实际场景,区分了async和非async,简单理解为同步复位,异步复位,具体使用的时候 需要结合SC的语法进行。

       reset_signal_is() 方法在指定的信号通道变为活动状态(高或低,取决于参数)时停止任何当前正在执行的进程。然后,它重置线程样式进程的上下文,以便从头开始调用它们,而不会继续延用原有的context继续执行,SC只是帮你清理了context,thread中需要清理其他动作需要自己使用if(reset_signal){xxx},去完成,这是个很大的误区,以为设置了reset 信号,那么所有端口都会自动清零,reset 只管当前的通道。

        它实际上不会重置或更改任何其他通道的值。对于方法样式的进程,它不需要这样做,因为它们不像线程那样持有任何状态。所以他只对当前的通道有效。

        async有无的区别,主要是用于SC_CHREAD上,可参考。但是三种SC process都可以用任一种方式设置reset信号。

        wait

       wait的概念不好理解,与c++  pthread 的wait 很像,但是实例上更像是是在模拟一个逻辑电路的行为,只有wait的时间或者信号变化时候,才会执行指定的动作。

        wait函数根据参数不同,具体调用需要重载函数,这些重载函数的主要集中在event和time不一样,event 指某个事件,这些事件自由度很高,包括信号变化,运行过程,计算结果等行为。time则指的是仿真时间,指定等待 n unit 的时间后,触发具体的行为。

        wait 只能放在SC_THREAD中使用。

       next_trigger

        next_trigger也是根据参数不同,具体调用需要重载函数。参数类型和wait 的参数很像,所以功能上跟wait的行为也很像,可以指定当前process 执行时候,具体触发的行为,包括event和time。

        这个功能是有悖于实际物理电路的,一个电路接好,无法改变具体的行为,但是这也是SC的优势,高自由度,高扩展性,高易用性。

       具体用法后面做专门介绍 ,next_trigger 可以用于优化CA 模型的性能。   

      

        sensitive

         关于senstitive,可以参考,下面例子。HDL4SE:软件工程师学习Verilog语言(十二)_ieee 1666-2020 system c标准-CSDN博客

Systemc语法知识总结_systemc学习-CSDN博客

 宏定义 SC_xxxx

        

         这些都是sc_module 下面,或者必选存在于sc_module(包括派生类)使用的的宏定义,主要功能还是为了简化大量冗余的代码,使代码更加简洁,最受用的群体还是硬件工程师。

       比如SC_MODULE ,SC_CTOR 就可以让你像类似于rtl的 编写一个module。

        #define SC_MODULE(name) struct name : sc_module

        #define SC_CTOR(name) implementation-defined; name(sc_module_name)

SC_MODULE(M1)

{

SC_CTOR(M1) //构造器定义

: i(0)
{}
int i;

...
};

下面这四宏定义则是配套使用的,如果 module 中需要开辟sc porcess 则应该使用以下宏定义。

#define SC_HAS_PROCESS(name) implementation-defined

#define SC_METHOD(name) implementation-defined

#define SC_THREAD(name) implementation-defined

#define SC_CTHREAD(name,clk) implementation-defined
       

        

NOTE

        NOTE 1—Because the constructors are protected, class sc_module cannot be instantiated directly but may be used as a base class.

        NOTE 2—A module should be publicly derived from class sc_module.

        NOTE 3—It is permissible to use class sc_module as an indirect base class. In other words, a module can be derived from another module. This can be a useful coding idiom.     

        example

int sc_main (int argc, char* argv[])
{
    Top_level_module top("top");
    std::vector<sc_object*> children = top.get_child_objects();
    // Print out names and kinds of top-level objects
    for (unsigned i = 0; i < children.size(); i++)
    std::cout << children[i]->name() << " " << children[i]->kind() << std::endl;
    sc_start();
    return 0;
}    

        

        

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值