SystemC/TLM: sc_fifo 的简单使用

sc_core::sc_fifo可以设置深度,默认深度为16。

    explicit sc_fifo( int size_ = 16 )
      : sc_prim_channel( sc_gen_unique_name( "fifo" ) ),
        m_data_read_event( sc_event::kernel_event, "read_event" ),
        m_data_written_event( sc_event::kernel_event, "write_event" )
      { init( size_ ); }

    explicit sc_fifo( const char* name_, int size_ = 16 )
      : sc_prim_channel( name_ ),
        m_data_read_event( sc_event::kernel_event, "read_event" ),
        m_data_written_event( sc_event::kernel_event, "write_event" )
      { init( size_ ); }

Sc_fifo的read 、write 函数都提供了non-block 和block两种形式,其中non-block 函数有一个bool类型的返回值,比如nb_read(),当fifo为empty的时候,返回false,read到一个entry的时候返回true;nb_write()如果返回值为false,则说明full了。

Read和write则是阻塞型的,没有返回值,也就是说函数中会自动进行wait。

sc_fifo的最大问题在于没有时序,write的当拍就可以read到。而这个feature跟实际的硬件设计肯定是不一致的,因为RTL 的fifo往往从push到pop至少花费1拍时间。

peq (payload event queue) 带时序,但没有full / empty的概念。故一般情况下,需要设置一个depth的成员变量进行配合,来模拟RTL中FIFO的时序功能。 peq 的使用方法可参考之前的博客: systemC/TLM:peq的简单用法_123axj的博客-CSDN博客

在SystemC编码过程中,可能会遇到这样的场景:Thread A push fifo1,Thread B push fifo2, Thread C 根据fifo 1 和fifo2的状态进行仲裁。由于SystemC调度影响,假设同一拍的调用顺序是Thread A --> Thread B --> Thread C,则C在仲裁时可以看到fifo1和fifo2都有request;但假设调用顺序是Thread C --> Thread A --> Thread B,则C在仲裁时看到的就是 fifo1和fifo2没有request。这样就会导致相同的测试条件下,前后两次的测试结果可能不一致,给debug工作带来了麻烦。

为消除SystemC调度对仿真结果的影响,可以让Thread A /B push fifo的内容always只能下一拍才能看到,这样0T Thread A/B push fifo,1T Thread C 看到两个request,ThreadC 的状态就是固定的了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

123axj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值