上一篇文章,介绍了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
搞定!










网友评论