上一篇文章,介绍了SystemC事务级建模01之最简单的模块间数据传输
现在我们对以下情形进行事务级建模:CPU
发送一个数据给GPU
,GPU
中的子模块GM
(GPU Manager)负责接收并打印出接收到的信息。
GPU
并不需要接收和处理CPU
的数据,而可以直接让GM
模块全权处理。
还是老样子,先分别给CPU
、GPU
、GM
建模,
-
CPU
:包含一个initiator socket
,即事务发起的socket -
GPU
:包含一个target socket
,即事务接收的socket -
GM
:包含一个target socket
,即事务接收的socket
#include <systemc.h>
#include <tlm.h>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
class Cpu : public sc_module {
public:
SC_HAS_PROCESS(Cpu);
Cpu(sc_module_name name) : sc_module(name) {
}
public:
tlm_utils::simple_initiator_socket<Cpu> initiator_socket_gpu;
};
class GpuManager : public sc_module {
public:
SC_HAS_PROCESS(GpuManager);
GpuManager(sc_module_name name) : sc_module(name) {
}
public:
tlm_utils::simple_target_socket<GpuManager> target_socket_cpu;
};
class Gpu : public sc_module {
public:
SC_HAS_PROCESS(Gpu);
Gpu(sc_module_name name) : sc_module(name) {
}
public:
tlm::tlm_target_socket<> target_socket_cpu;
private:
GpuManager gm{"GpuManager"};
};
然后,把他们连接起来。首先连接GPU
和GM
,
class Gpu : public sc_module {
public:
SC_HAS_PROCESS(Gpu);
Gpu(sc_module_name name) : sc_module(name) {
target_socket_cpu.bind(gm.target_socket_cpu);
// gm.target_socket_cpu.bind(target_socket_cpu);
}
public:
tlm::tlm_target_socket<> target_socket_cpu;
private:
GpuManager gm{"GpuManager"};
};
注意端口绑定的顺序,反了就会报错(注释掉的那一行,initiator socket
反而应该这样):
Error: (E120) sc_export instance has no interface: gpu.tlm_base_target_socket_0
In file: C:/Users/adam/Downloads/systemc-2.3.3/src/sysc/communication/sc_export.h:174
接下来,让CPU
发送一个消息给GPU
,
class Cpu : public sc_module {
public:
SC_HAS_PROCESS(Cpu);
Cpu(sc_module_name name) : sc_module(name) {
SC_METHOD(send);
}
void send() {
auto payload = new tlm::tlm_generic_payload{};
auto data = std::string{"Hello, I am CPU"};
payload->set_data_ptr((unsigned char *) data.c_str());
auto delay = SC_ZERO_TIME;
initiator_socket_gpu->b_transport(*payload, delay);
}
public:
tlm_utils::simple_initiator_socket<Cpu> initiator_socket_gpu;
};
因为GPU
的target socket
是直接连接到了GM
的target socket
,所以,我们不需要再给GPU
的target socket
注册接收消息的方法,给GM
注册即可,
class GpuManager : public sc_module {
public:
SC_HAS_PROCESS(GpuManager);
GpuManager(sc_module_name name) : sc_module(name) {
target_socket_cpu.register_b_transport(this, &GpuManager::recieve);
}
void recieve(tlm::tlm_generic_payload &payload, sc_time &delay) {
std::cout << payload.get_data_ptr() << std::endl;
}
public:
tlm_utils::simple_target_socket<GpuManager> target_socket_cpu;
};
编译,运行,
C:\Users\adam\CLionProjects\untitled\cmake-build-debug\untitled.exe
SystemC 2.3.3-Accellera --- Mar 10 2021 20:59:57
Copyright (c) 1996-2018 by all Contributors,
ALL RIGHTS RESERVED
Hello, I am CPU
Process finished with exit code 0
搞定!
网友评论