有些时候,我们会发现有这样的用法:
A 模块定义了一个 sc_port<sc_signal<bool> > m_port_in ; 且在 一个sc_thread 中 进行 read
B 模块定义了一个 sc_signal<bool> m_signal ;且在 一个sc_thread 中 进行 write
然后在顶层进行绑定 m_port_in.bind(m_signal)
这跟我们常见的 信息传输方向 不太一样:常见的sc_port 一般作为 initiator,而此处用法中 感觉 sc_port 被当做了一个 target。
编写以下测试程序进行测试
// 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>
class TestScPort : public sc_core::sc_module {
public:
SC_HAS_PROCESS(TestScPort);
explicit TestScPort(sc_core::sc_module_name name):sc_core::sc_module(name) {
SC_THREAD(WriteThread);
SC_THREAD(ReadThread);
m_port_in.bind(m_signal);
}
~TestScPort() override = default;
void WriteThread(){
m_signal.write(true);
std::cout<<"m_signal write 1 " <<std::endl;
sc_core::wait(1,sc_core::SC_NS);
m_signal.write(false);
std::cout<<"m_signal write 0 " <<std::endl;
sc_core::wait(1,sc_core::SC_NS);
m_signal.read();
}
void ReadThread(){
while(1){
// here must use ->read() , can't use .read(), because sc_port have no read function
// operator-> will call the read() function of sc_signal.
bool t_sig = m_port_in->read();
std::cout<<"m_port_in read " << t_sig <<std::endl;
sc_core::wait(1,sc_core::SC_NS);
}
}
sc_core::sc_port<sc_core::sc_signal<bool> > m_port_in ;
// sc_core::sc_inout<bool> m_port_in;
sc_core::sc_signal<bool> m_signal ;
};
int sc_main(int argc, char ** argv)
{
TestScPort m_test_sc_port ("test");
sc_core::sc_start(10,sc_core::SC_NS);
return 0;
}
然后gdb 发现,在 m_port_in->read(); 时,调用了 sc_port中的以下代码,然后就调用了 sc_signal 中的read 函数。所以到这里,我们就知道了 上述做法的原理: sc_core::sc_port<sc_core::sc_signal<bool> > 跟sc_core::sc_signal<bool> 绑定后,sc_core::sc_port 通过 -> 直接就获取了bind对方sc_signal的变化。sc_core::sc_port 本身是没有read 函数的,所以此处必须要用 ->read() 。
进而,sc_core::sc_port<sc_core::sc_signal<bool> > 也可以改为 sc_core::sc_export <sc_core::sc_signal<bool> > ,也就是这种用法 已经无所谓是 sc_port 和sc_export 了,两边都是 调用的sc_signal的函数 (write or read)。
template <class IF>
inline
IF*
sc_port_b<IF>::operator -> ()
{
if( m_interface == 0 ) {
report_error( SC_ID_GET_IF_, "port is not bound" );
}
return m_interface;
}
个人理解,这样做 可以实现 signal的write /read 在两个模块间解耦,且 双向 都可以write /read 。如果是这个原因,其实是可以用sc_core::sc_inout<bool> m_port_in; 的。