在systemc编程中,如果程序run过程中出现以下两种报错,则说明系统中有port没有正确绑定。
Error: (E126) sc_export instance already bound: xxxxxx
In file: xxxx/sysc/sysc/communication/sc_export.h:188 (systemc 2.3.3)
In file: xxxx/sysc/sysc/communication/sc_export.h:179 (systemc 2.3.1)
Error: (E120) sc_export instance has no interface: init.init_socket_export_0
In file: xxxxx/sysc/communication/sc_export.h:174 (systemc 2.3.3)
In file: xxxxx/sysc/communication/sc_export.h:166 (systemc 2.3.1)
查看systemC spec,发现port绑定时确实有一些限制,16.1.1.2 章节有如下描述。
同时,在13.1 章节 P462 有以下绑定示例。此实例中,由于Initiator 和Target 类中都是 tlm socket,故struct Parent_of_initiator中进行绑定时,initiator->init_socket.bind( init_socket ); 也可以写成 init_socket.bind(initiator->init_socket)。但 如果Initiator类中定义的是 simple socket,则必须采用上述表格中的bind方式。
如下给出一个自己写的实例,并给出错误的写法
// 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 <systemc>
#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
using namespace sc_core;
using namespace std;
//Initiator
class Initiator : public sc_core::sc_module {
public:
tlm_utils::simple_initiator_socket<Initiator> init_socket;
SC_HAS_PROCESS(Initiator);
explicit Initiator(sc_core::sc_module_name name);
~Initiator() override = default;
};
Initiator::Initiator(sc_core::sc_module_name name)
: sc_core::sc_module(name), init_socket("dummy_initiator_socket") {}
//Target
class Target : public sc_core::sc_module {
public:
tlm_utils::simple_target_socket<Target> targ_socket;
SC_HAS_PROCESS(Target);
explicit Target(sc_core::sc_module_name name);
~Target() override = default;
};
Target::Target(sc_core::sc_module_name name)
: sc_core::sc_module(name), targ_socket("dummy_target_socket") {}
// Parent of initiator
struct Parent_of_initiator: sc_module // Showing hierarchical socket binding
{
// here can't use simple socket, will lead to simulation error
// (E126) sc_export instance already bound:xxxxxxxxx
// tlm_utils::simple_initiator_socket<Initiator> init_socket; //error use
tlm::tlm_initiator_socket<32> init_socket;
Initiator* initiator;
SC_CTOR(Parent_of_initiator) : init_socket("init_socket") {
initiator = new Initiator("initiator");
// here MUST use simple init socket.bind(tlm init socket)
// if use tlm init socket.bind (simple init socket) may lead to simulation error
// Error: (E120) sc_export instance has no interface: xxxxxxx
// init_socket(initiator->init_socket); //error use
initiator->init_socket.bind( init_socket ); // Bind initiator socket to parent initiator socket
}
};
// Parent of target
struct Parent_of_target: sc_module
{
// here can't use simple socket, will lead to simulation error
// (E126) sc_export instance already bound:xxxxxxxxx
// tlm_utils::simple_target_socket<Initiator> targ_socket; //error use
tlm::tlm_target_socket<32> targ_socket;
Target* target;
SC_CTOR(Parent_of_target) : targ_socket("targ_socket") {
target = new Target("target");
// here MUST use tlm target socket.bind(simple target socket)
// if use simple target socket.bind (tlm target socket) may lead to simulation error
// Error: (E120) sc_export instance has no interface: xxxxxxx
// target->targ_socket(targ_socket); //error use
targ_socket.bind( target->targ_socket ); // Bind parent target socket to target socket
}
};
//main
int sc_main(int argc, char ** argv)
{
Parent_of_initiator *init;
Parent_of_target *targ;
init = new Parent_of_initiator("init");
targ = new Parent_of_target("targ");
init->init_socket.bind(targ->targ_socket); // Bind initiator socket to target socket at top level
std::cout<<"test pass"<<std::endl;
return 0;
}