tlm::tlm_analysis_port & tlm::tlm_analysis_if

在SystemC/TLM建模中,我们经常需要加一些payload monitor来进行performance counter的统计,或者使用data checker来进行unit test。很多情况下,为了保持代码的整洁和提高仿真速度,我们不希望将monitor和checker的代码直接写在module内部。此时,就可以使用tlm提供的analysis port,然后根据需求来添加特定的monitor或checker。一个tlm::tlm_analysis_port可以绑定0个 /1个或多个tlm::tlm_analysis_if。

具体实现为:

monitor或checker (如下图的module B和C)继承于tlm::tlm_analysis_if,同时对write 函数进行改写,在函数内部进行 performance counter的统计计算,或test check。

在module内部(如下图的module A)定义一个tlm::tlm_analysis_port的成员变量,在module 内部 调用这个成员变量的write 函数。

在top中,对tlm::tlm_analysis_port 和多个tlm::tlm_analysis_if进行bind。这样module内call write函数时,所有bind的tlm::tlm_analysis_if 子类模块中的write函数 都会被调用一次。

 在SystemC spec中给出了一个analysis port的示例,以下代码是在此基础上的一个完整使用,其中class parent和 child都定义了一个tlm::tlm_analysis_port;child->ap.bind(parent_ap);是两个tlm_analysis_port的层次间绑定,在top module中的两个bind是 tlm_analysis_port和tlm_analysis_if的绑定。

// execute:
//     g++ -g -Wall -lsystemc -m64 -pthread main.cpp
//         -L/$(your systemc path)/lib-linux64
//         -I/$(your systemc path)/include  -I/$(your systemc
//         path)/src/tlm_utils -o sim

#include "tlm"
#include <systemc>

using namespace std;

struct Trans // Analysis transaction class
{
  int i;
};
struct Subscriber : sc_core::sc_module, tlm::tlm_analysis_if<Trans> {
  Subscriber(sc_core::sc_module_name name) : sc_core::sc_module(name) {}
  virtual void write(const Trans &t) {
    cout << this->name() << " Hello, got " << t.i
         << "\n"; // Implementation of the write method
  }
};

class Child : public sc_core::sc_module {
public:
  tlm::tlm_analysis_port<Trans> ap;
  SC_HAS_PROCESS(Child); // must have this line
  explicit Child(sc_core::sc_module_name name)
      : sc_core::sc_module(name), ap("ap") {
    SC_THREAD(thread);
  }
  void thread() {
    Trans t = {999};
    ap.write(
        t); // Interface method call to the write method of the analysis port
  }
};
class Parent : public sc_core::sc_module {
public:
  tlm::tlm_analysis_port<Trans> parent_ap;
  Child *child;

  explicit Parent(sc_core::sc_module_name name)
      : sc_core::sc_module(name), parent_ap("ap") {
    child = new Child("child");
    child->ap.bind(
        parent_ap); // Bind analysis port of child to analysis port of parent
  }
};

class Top : public sc_core::sc_module {
public:
  Parent *parent;
  Subscriber *subscriber1;
  Subscriber *subscriber2;
  explicit Top(sc_core::sc_module_name name) : sc_core::sc_module(name) {
    parent = new Parent("parent");
    subscriber1 = new Subscriber("monitor");
    subscriber2 = new Subscriber("checker");
    parent->parent_ap.bind(
        *subscriber1); // Bind analysis port to two separate subscribers
    parent->parent_ap.bind(
        *subscriber2); // This is the key feature of analysis ports
  }
};

int sc_main(int argc, char **argv) {
  Top m_top("top");

  sc_core::sc_start();
  return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

123axj

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

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

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

打赏作者

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

抵扣说明:

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

余额充值