【发布时间】:2017-12-23 06:35:11
【问题描述】:
在 Doulos 的 SystemC Transfer Level Model 文档中是这样写的
层次结构的顶层模块实例化一个启动器和 一个内存,并将启动器上的启动器套接字绑定到 目标内存上的目标套接字。套接字封装了一切 您需要在模块之间进行双向通信,包括端口 和双向通信的出口。一个启动器插座 始终绑定到一个目标套接字。
我对此的理解是,当你创建一个发起者和一个目标时,发起者通过调用 b_transport 开始通信,从而触发目标,目标可以回复。但是,我一直在编写一些代码,但似乎并非如此。让我们看一个例子。
我有一个非常基本的加法器实现,可以使用传输级别建模进行讨论。该模块作为目标服务器。
adder.cc
#define SC_INCLUDE_DYNAMIC_PROCESS
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
#include <iostream>
using namespace sc_core;
using namespace std;
#include "adder.h"
adder::adder(sc_module_name name)
: sc_module(name), socket("socket2")
{
socket.register_b_transport(this, &adder::b_transport);
socket.register_transport_dbg(this, &adder::transport_dbg);
}
void adder::b_transport(tlm::tlm_generic_payload& trans, sc_time& delay)
{
tlm::tlm_command cmd = trans.get_command();
sc_dt::uint64 addr = trans.get_address();
uint32_t *ptr = (uint32_t*)trans.get_data_ptr();
unsigned int len = trans.get_data_length();
unsigned char *byt = trans.get_byte_enable_ptr();
unsigned int wid = trans.get_streaming_width();
addend1 = *ptr;
addend2 = *(++ptr);
add();
cout << "addend1: " << addend1 << endl;
cout << "addend2: " << addend2 << endl;
cout << "sum: " << sum << endl;
uint32_t *return_sum_loc = ptr;
for(int i = 0; i< 2; i++) {
return_sum_loc++;
}
memcpy(return_sum_loc, (char*) &sum, sizeof(uint32_t));
cout << "New sum for return: " << *(return_sum_loc) << endl;
}
unsigned int adder::transport_dbg(tlm::tlm_generic_payload& trans)
{
return 0;
}
void adder::add()
{
sum = addend1 + addend2;
}
然后我有一个 test_bench 模块将作为启动器
test_bench.cc
#define SC_INCLUDE_DYNAMIC_PROCESS
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
using namespace sc_core;
using namespace std;
#include "test_bench.h"
#include <fstream>
#include <iostream>
test_bench::test_bench(sc_module_name name):
sc_module(name), socket("socket")
{
SC_THREAD(run_tests);
}
void test_bench::run_tests()
{
ifstream infile("./adder.golden.dat");
ofstream ofs;
ofs.open("./adder.dat");
uint32_t theoretical_sum = 0;
while(infile >> data[0] >> data[1] >> theoretical_sum)
{
tlm::tlm_generic_payload *trans = new tlm::tlm_generic_payload;
sc_time delay = sc_time(10, SC_NS);
cout << "Sending" << endl;
cout << "Data[0]: " << data[0] << endl;
cout << "Data[1]: " << data[1] << endl;
trans->set_data_ptr((unsigned char*)data);
socket->b_transport(*trans, delay);
cout << "data[2]" << data[2] << endl;
ofs << data[0] << "\t" << data[1] << "\t" << data[2] << "\n";
delete trans;
}
infile.close();
ofs.close();
printf ("Comparing against output data \n");
if (system("diff -w adder.dat adder.golden.dat"))
{
cout << "*******************************************" << endl;
cout << "FAIL: Output DOES NOT match the golden output" << endl;
cout << "*******************************************" << endl;
}
else
{
cout << "*******************************************" << endl;
cout << "PASS: The output matches the golden output!" << endl;
cout << "*******************************************" << endl;
}
}
这里是实例化和连接它们的父模块。
main.cc
#include "systemc.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
#include "tlm_utils/tlm_quantumkeeper.h"
using namespace sc_core;
using namespace sc_dt;
using namespace std;
#include "test_bench.h"
#include "adder.h"
SC_MODULE(Top)
{
test_bench *tb;
adder *ad;
sc_signal<bool> rst;
sc_signal<bool> tb_irq;
sc_signal<bool> ad_irq;
Top(sc_module_name name) :
rst("rst")
{
tb = new test_bench("test_bench");
ad = new adder("adder");
tb->socket.bind(ad->socket);
tb->irq(tb_irq);
ad->irq(ad_irq);
}
};
int sc_main(int argc, char *argv[])
{
Top *top = new Top("Top");
sc_start();
}
当我运行可执行文件时,这是我得到的输出。
1 0 1
1 1 2
2 1 3
2 2 4
2 3 5
3 3 6
4 3 7
4 4 8
5 4 9
5 5 10
失败:输出与黄金输出不匹配
所以我最初的想法是,您将此有效负载按值传递到绑定到目标的启动器的 b_transport 函数中。目标将接收并解码此有效载荷。这部分正在发生。我能够解析按值传递的 uint32_t 到数据 []。 我最终根据写入到传递的内存中的 0 返回值意识到,这实际上不是按值传递的。由于某种原因,它被创建为指针类型,然后它在通过时被取消引用。 这实质上破坏了目标操纵传递给发起者的响应的内存的能力。
所以,Aynsley 提到的整个双向沟通的事情让我有点困惑。双向是指两个模块都需要目标和启动器套接字来启用双向通信吗?
【问题讨论】:
-
adder.h 丢失