sc_port / sc_interface / sc_export (part 4)

总结

允许的绑定关系:

sc_port.bind(sc_port)

sc_port.bind(sc_interface)

sc_export.bind(sc_interface)

sc_port.bind(sc_export)

sc_export.bind(sc_export)

需要注意的是,前三者在 sc_port 和sc_export 代码中提供了对应的bind函数;而后两者sc_port.bind(sc_export) 和  sc_export.bind(sc_export) 需要先调用 sc_export的隐式类型转换函数,将sc_export 转换为 sc_interface,然后再调用sc_port.bind(sc_interface) 和sc_export.bind(sc_interface)

不允许的绑定关系:

sc_export.bind(sc_port)

sc_interface.bind(sc_interface)

sc_interface.bind(sc_port)

sc_interface.bind(sc_export)

需要注意,系统中所有的sc_port 和sc_export 实例 都必须进行绑定,且只能绑定一次;一个绑定链上有且只能有一个sc_interface。(1个sc_port与多个sc_interface 相连,我们认为是多条 绑定链)

sc_interface 实例 是可以单独存在和使用的。

如果报E107 的error,说明重复绑定了。

Error: (E107) bind interface to port failed: interface already bound to port: port 'top_2.mst_top.port_0' (sc_port)  In file: ../../../src/sysc/communication/sc_port.cpp:235

如果报E109 的error,说明有port或export没有绑定。

Error: (E109) complete binding failed: port not bound: port 'top_2.mst_top.port_0' (sc_port)

In file: ../../../src/sysc/communication/sc_port.cpp:235

以下为一个sc_port/sc_export/sc_interface的绑定和使用示例,其中class MyTop_1是一个sc_port绑定多个sc_interface的示例,class MyTop_2是用到sc_port/sc_export的层次化绑定的示例。

// 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 <map>
#include <systemc>

using namespace std;
using namespace sc_core;

class MyInterface : public sc_core::sc_interface, public sc_core::sc_module {
public:
  explicit MyInterface(sc_core::sc_module_name name)
      : sc_core::sc_module(name) {}
  virtual void slave_write(int addr, int data) {
    std::cout << this->name() << " write addr " << std::hex << addr << " = "
              << data << std::endl;
    m_addr_data[addr] = data;
  }
  virtual void slave_read(int addr, int &data) {
    if (m_addr_data.find(addr) != m_addr_data.end()) {
      std::cout << this->name() << " read addr " << std::hex << addr << " = "
                << m_addr_data[addr] << std::endl;
      data = m_addr_data[addr];
    } else {
      data = 0;
    }
  }
  std::map<int, int> m_addr_data;
};

// MyMaster
class MyMaster : public sc_core::sc_module {
public:
  SC_HAS_PROCESS(MyMaster);
  explicit MyMaster(sc_core::sc_module_name name) : sc_core::sc_module(name) {
    SC_THREAD(HandleThread);
  }
  ~MyMaster() override = default;

  void HandleThread() {
    for (int i = 0; i < m_port.size(); ++i) {
      cout << this->name() << " HandleThread write " << std::hex << (0x100 + i)
           << "  = " << (0x5000 + i) << endl;
      // here equal to (m_port.get_interface(i))->slave_write 
      m_port[i]->slave_write(0x100 + i, 0x5000 + i);
      wait(1, SC_NS);
    }

    // here is call operator->
    m_port->slave_write(0x5ffff, 0x1000);
    wait(1, SC_NS);

    for (int i = 0; i < m_port.size(); ++i) {
      int t_data = 0;
      cout << this->name() << " HandleThread read " << std::hex << (0x100 + i)
           << "  = " << t_data << endl;
      (m_port.get_interface(i))->slave_read(0x100 + i, t_data);
      wait(1, SC_NS);
    }
  }

  sc_core::sc_port<MyInterface, 0> m_port;
};

class MyTop_1 : public sc_core::sc_module {
public:
  MyTop_1(sc_core::sc_module_name name)
      : sc_core::sc_module(name), m_mst("mst"), m_interface("interface") {
    m_interface.init(3);
    for (int i = 0; i < 3; ++i) {
      m_mst.m_port.bind(m_interface[i]);
    }
  }
  MyMaster m_mst;
  sc_vector<MyInterface> m_interface;
};

/

// MyMasterTop
class MyMasterTop : public sc_core::sc_module {
public:
  SC_HAS_PROCESS(MyMasterTop);
  explicit MyMasterTop(sc_core::sc_module_name name)
      : sc_core::sc_module(name), m_mst("mst") {
    /*****************************************************************************
    // all port and export must to be bind, and must bind only once.

    // if you write below line twice, will lead to simulation error
    Error: (E107) bind interface to port failed: interface already bound to port x
    In file: ../../../src/sysc/communication/sc_port.cpp:235

    // if you forget to write below line, will lead to simulation error
    Error: (E109) complete binding failed: port not bound: port xxx
    In file: ../../../src/sysc/communication/sc_port.cpp:235
    ******************************************************************************/
    m_mst.m_port.bind(m_mst_top_port);    
  }
  ~MyMasterTop() override = default;

  sc_core::sc_port<MyInterface, 0> m_mst_top_port;
  MyMaster m_mst;
};

// MySlave
class MySlave : public sc_core::sc_module {
public:
  SC_HAS_PROCESS(MySlave);
  explicit MySlave(sc_core::sc_module_name name)
      : sc_core::sc_module(name), m_interface("interface") {
    m_export.bind(m_interface);
  }
  ~MySlave() override = default;

  sc_core::sc_export<MyInterface> m_export;
  MyInterface m_interface;
};

// MySlaveTop
class MySlaveTop : public sc_core::sc_module {
public:
  SC_HAS_PROCESS(MySlaveTop);
  explicit MySlaveTop(sc_core::sc_module_name name)
      : sc_core::sc_module(name), m_slv("slv") {
    /*****************************************************************************
    // here can't change the export bind export direction, 
    // if you write    m_slv.m_export.bind(m_slv_top_export); 
    // will build pass, but lead to below error in simulation
    Error: (E120) sc_export instance has no interface: top_2.slv_top.export_0
    In file: /usr/local/systemc-2.3.3/include/sysc/communication/sc_export.h:174
    ******************************************************************************/
   m_slv_top_export.bind(m_slv.m_export);

  }
  ~MySlaveTop() override = default;

  sc_core::sc_export<MyInterface> m_slv_top_export;
  MySlave m_slv;
};

class MyTop_2 : public sc_core::sc_module {
public:
  MyTop_2(sc_core::sc_module_name name)
      : sc_core::sc_module(name), m_mst_top("mst_top"), m_slv_top("slv_top") {
    // here must sc_port.bind(sc_export)
    // sc_export.bind(sc_port) will lead to build error
    m_mst_top.m_mst_top_port.bind(m_slv_top.m_slv_top_export);
  }
  MyMasterTop m_mst_top;
  MySlaveTop m_slv_top;
};

int sc_main(int argc, char **argv) {
  /*****************************************************************************
  // ports shall only be instantiated during elaboration and only from within a
  // module, so can't use port in sc_main
  // below code is error, which will lead to the below error in simulation
  Error: (E100) port specified outside of module: port 'port_0' (sc_port_base)
  In file: ../../../src/sysc/communication/sc_port.cpp:235
  ******************************************************************************/
  // sc_core::sc_port<MyInterface, 0> error_port;
  // MyInterface error_interface("error_interface") ;
  // error_port.bind(error_interface);

  MyTop_1 m_top("top_1");
  MyTop_2 m_top_2("top_2");

  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、付费专栏及课程。

余额充值