在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 6064|回复: 8

[原创] 关于SystemC中 sc_event_finder 类的使用

[复制链接]
发表于 2014-11-4 22:34:46 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 asic_wang 于 2014-11-5 09:35 编辑

之前在读SC LRM的时候看到这个地方一带而过,没太看明白,可以说SC基本库里的各种port,export以及channel对一般的应用来说已经非常够用了,所以当时也没太细细思考,直到今天工作中碰到一个和这个有关的问题,在晚上的班车上再次结合RLM中有关的描述思考了一下,觉得有必要在此mark一下,记录自己的思考过程,更希望这里有朋友在此之前有过这个class的深入使用经历也能分享交流一下。
      1、一些基本的SC的观点
           a、interface是一个纯虚类,描述的是channel的用户界面,如read,write等;
           b、channel继承interface,并且实现interface中的界面函数;
           c、port用来传递来自诸如module内部的用户访问需求至channel,可以在逻辑上认为port是channel的指针;
           实际上port是一个模版类,以interface为模版参数。
      2、sc sensitive的4个重载函数版本
                                                                                                                                                                        
[size=10.000000pt]              class [size=10.000000pt]sc_sensitive[size=8.000000pt]†[size=10.000000pt]{                                       
[size=10.000000pt]                    public:
                            [size=10.000000pt]sc_sensitive[size=8.000000pt]&#8224;[size=10.000000pt]& [size=10.000000pt]operator<< [size=10.000000pt]( const sc_event& );[size=10.000000pt]/////版本1
[size=10.000000pt]                            sc_sensitive[size=8.000000pt]&#8224;[size=10.000000pt]& [size=10.000000pt]operator<[size=10.000000pt]< ( const sc_interface& );//////版本2
[size=10.000000pt]                            sc_sensitive[size=8.000000pt]&#8224;[size=10.000000pt]& [size=10.000000pt]operator<< [size=10.000000pt]( const sc_port_base& );////////版本3
[size=10.000000pt]                            sc_sensitive[size=8.000000pt]&#8224;[size=10.000000pt]& [size=10.000000pt]operator<< [size=10.000000pt]( sc_event_finder& );////////版本4                                       
[size=10.000000pt]                            // Other members[size=10.000000pt] implementation-defined                                       
[size=10.000000pt]               };



[size=10.000000pt]               在所有的我们设定SC_METHOD、SC_THREAD、SC_CTHREAD的sensitive列表中,都逃不过这四种之一!
[size=10.000000pt]               版本1最直接,无需多说;
[size=10.000000pt]               版本2、3、4有一个共同特点就是:如果实际传递的参数对象定义了有效的default_event()函数,那么实际上
[size=10.000000pt]               sensitive列表最终加入的该函数返回的sc event对象。
[size=10.000000pt]               当我们使用如下情形时实际上会使用版本2:
[size=10.000000pt]               a、sensitive  << 某一个channel,例如 sensitive << sc_fifo<int>对象
[size=10.000000pt]               b、sensitive  << 某一个interface,例如 sensitive << sc_fifo_in_if<int>对象
[size=10.000000pt]               c、sensitive  << 某一个export,例如 sensitive << sc_export<sc_fifo_in_if<int> >对象
[size=10.000000pt]               需要说明一下的是c情形,之所以能这样是因为export class定义中实现了类型转换函数,它能将该export类型

[size=10.000000pt]               转换成与之对应的interface类型,如下所示:

                                                                                                
[size=10.000000pt]                         template<class IF>

[size=10.000000pt]                         class [size=10.000000pt]sc_export[size=10.000000pt]: public sc_export_base{                                       
[size=10.000000pt]                             public:
                           ........
[size=10.000000pt]                            operator IF& [size=10.000000pt]();
                            [size=10.000000pt]operator const IF& [size=10.000000pt]() const;
[size=10.000000pt]                            ...........
[size=10.000000pt]                         }
[size=10.000000pt]               当使用一个port对象作为sensitive对象并且该port对象提供了有效的default_event()函数时可以调用版本3;
[size=10.000000pt]               当使用一个port对象最为sensitive对象并且该port对象没有提供有效的default_event()函数时很可能需要版本4;
                                
                        
               
        
[size=10.000000pt]       3、当我们需要版本4的时候,我们需要在此之前做一些工作,而该工作需要sc event finder来完成
[size=10.000000pt]            根本原因是:当我们使用sensitive << port对象;或者 sensitive << port对象的一个函数,而该函数返回一个
            sc event类型[size=10.000000pt]时,port对象还没有完成和与之对应的channel的binding工作,所以此时可以想象成这个port还是一个NULL指针。
           但是一旦binding完成之后,这些sensitive操作就没有任何问题了,所以需要推迟sensitive <<操作,此时
           sc event finder派上用场!

         具体举例来说就是,
         假如我们有一个sc_fifo_in类型的port 对象,叫做 fifo_port_in, 那么我们可以如下写:
         sensitive << fifo_port_in.data_written();
         但是我们不能如下写:
         sensitive << fifo_port_in.data_written_event();  
         如果你这样写,编译的时候没有问题,但是在systemc elaboration的会报如下的error:
         Error:(E112)get interface failed: port is not bound .......
         根本原因就是如上述分析的那样,使用data_written()之所以没有问题就是因为它返回的是sc event finder对象,
         它会defer这个操作直到port binding完成之后进行。
 楼主| 发表于 2014-11-4 23:05:26 | 显示全部楼层
那么data_written()函数在data_written_event()函数上做了些什么工作就是的这个Error可以消失而且使程序可以正常工作了呢?如果库没有提供data_written()函数,由我们来fix这个Error,我想无非是如下两行程序:
sc_event_finder& data_written() const{
      return *(new sc_event_finder_t<sc_fifo_in_if<Type> >(*this, &sc_fifo_in_if<Type>::data_written_event) );
}
如此一来我们就利用普通的data_written_event()函数来达到了我们想要的目的。在我们自己构造自己的interface、channel以及port的时候,我们需要特别关注这些,否则你提供给用户的界面很可能是及其容易被用户误用的,甚至不能正常使用!
发表于 2014-12-26 13:46:41 | 显示全部楼层
还没有细看,总结得不错,有空再来讨论下
发表于 2014-12-26 14:07:53 | 显示全部楼层
你是某为员工?interface是一种虚拟基类,只包含纯虚函数,不用直接使用,目的是用于不同通道扩展用。基于port实现的api调用,称为接口方法调用。关于这几个敏感列表参数类型,没有研究过,但是你提到sensitive<<port在没有完成绑定的时候,会出现error,那么试下在参数列表中绑定,而不是在构造函数体内部试下?有空我也研究下,私聊
发表于 2014-12-27 13:22:17 | 显示全部楼层
还有一种解决方法,就如同楼上所说的那样,不放在构造函数体内,放在end of elaboration()中~
Another possible solution to this issue is to write an end_of_elaboration() callback for the module containing the SC_METHOD, and within the callback register the method and the sensitivity, instead of within the ctor.

方法一:
http://www.accellera.org/Discussion_Forums/systemc-forum/archive/summary_form/msg?list_name=systemc-forum&monthdir=200603&msg=msg00045.html
方法二:
http://www.accellera.org/Discussion_Forums/systemc-forum/archive/summary_form/msg?list_name=systemc-forum&monthdir=200603&msg=msg00046.html
发表于 2014-12-27 13:28:23 | 显示全部楼层
本帖最后由 yucaoxilin 于 2014-12-27 13:29 编辑

正如楼上所说,另外一种方法是不在构造函数中定义,而是在end_of_elaboration()中~

write an end_of_elaboration() callback for the module containing the SC_METHOD, and within the callback register the method and the sensitivity, instead of within the ctor:

void end_of_elaboration() {
  SC_METHOD( my_method );
  sensitive << fifo_port.data_written_event();
}
发表于 2014-12-27 17:54:00 | 显示全部楼层
放在参数列表进行一些初始化与在ctor内部一般情况下是没有多大差别,但是当初始化变量之间有关联时或一个变量的初始化依赖于另外一个时,就应该采用前者。回到topic,既然问题是关于绑定,那么在进程登记前就做好相关事情,就可能能解决问题。至于楼上解决的办法也比较通用,现在大部分各种建模验证方法学都将系统的运行的细分,可以在执行某些阶段前就做好对应的准备
 楼主| 发表于 2014-12-31 17:42:48 | 显示全部楼层
回复 4# 744160354peter


    难道只有“某为”的员工才能研究这些或者懂这些?
发表于 2015-1-5 19:32:53 | 显示全部楼层
因为“某为”是国内使用sc较多的单位。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条

×

小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-22 15:02 , Processed in 0.322659 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表