【问题标题】:Implementing SystemC TLM Testbench Build Fail实施 SystemC TLM 测试平台构建失败
【发布时间】:2018-04-16 01:08:37
【问题描述】:

我正在尝试为使用基本 simple_initiator_socketsimple_target_socket 创建的加法器模块实现 SystemC 基本 TLM 测试平台。

目前构建失败,我无法诊断原因。

这里是三个主要模块的实现,加法器、测试台和实例化两者并启动数据流的主模块。

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;

    Top(sc_module_name name) :
        rst("rst")
    {
        tb = new test_bench("test_bench");
        ad = new adder("adder");

        tb->socket.bind(ad->socket);

    }
};

int sc_main(int argc, char *argv[])
{
    Top *top = new Top("Top");


}

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;
using namespace sc_dt;

#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", ofstream::out | ofstream::app);

    while(infile >> data[0] >> data[1])
    {   
        tlm::tlm_generic_payload *trans = new tlm::tlm_generic_payload;
        sc_time delay = sc_time(10, SC_NS);

        trans->set_data_ptr((unsigned char*)data);

        socket->b_transport(*trans, delay);

        ofs << data[0] << data[1] << data[2];       

        delete trans;
    }
    infile.close();
    ofs.close();

    printf ("Comparing against output data \n");
    if (system("diff -w sha1.dat sha1.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;
    }

}

adder.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 "adder.h"

adder::adder(sc_module_name name)
    : sc_module(name), socket("socket")
{
    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();

    memcpy(ptr + sizeof(uint32_t) * 2, (char*) &sum, sizeof(uint32_t));
}

unsigned int adder::transport_dbg(tlm::tlm_generic_payload& trans)
{
    return 0;
}

void adder::add()
{
    sum = addend1 + addend2;
}

这是我在编译时看到的错误。

在包含的文件中 /home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/include/sysc/kernel/sc_module.h:35:0, 来自/home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/include/systemc:74, 来自/home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/include/tlm:23, 来自/home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/include/tlm_utils/simple_initiator_socket.h:23, 来自/home/test_benches/adder/test_bench.cc:3: /home/test_benches/adder/test_bench.cc:

在构造函数“test_bench::test_bench(sc_core::sc_module_name)”中: /home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/include/sysc/kernel/sc_module.h:463:29: 错误:“SC_CURRENT_USER_MODULE”尚未声明 SC_CURRENT_USER_MODULE,\

/home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/include/sysc/kernel/sc_process.h:151:46:注意:在宏“SC_MAKE_FUNC_PTR”的定义中 static_cast(&callback_tag::func)

/home/epi/jfrye_xilinx/SystemC/systemc-2.3.2/include/sysc/kernel/sc_module.h:461:5: 注意:在宏“declare_thread_process”的扩展中 declare_thread_process(func ## _handle, \

/home/test_benches/adder/test_bench.cc:17:2: 注意:在扩展中

宏'SC_THREAD' SC_THREAD(run_tests);

制作:*** [/home//test_benches/adder/obj/test_bench.o] 错误 1

我最好的猜测是我没有正确设置套接字。测试台有一个simple_initiator_socket,加法器有一个simple_target_socket。我需要为模块注册simple_target_socketb_transport 方法吗?我在启动器中这样做了,但在下面的教程中,我没有看到目标需要这样做。我的猜测是数据流是这样的:

  1. simple_initiator_sockettest_bench 的成员)注册到模块的 b_transport 方法和另一个模块的 simple_target_socket(在顶部模块中)
  2. Initiator 模块 (test_bench) 设置 tlm_generic_payload 需要发送到目标 (adder) 的数据
  3. b_transportsimple_initiator_socket 方法(test_bench 的成员)在传递 tlm_generic_payload 的情况下被调用(加法器的加数)
  4. 目标套接字(目标)接收并解码传递的tlm_generic_payload(加值)。
  5. 目标套接字 (adder) 执行操作(添加解码的加数)并修改 tlm_generic_payload(按值传递)(通过将计算的总和写回有效负载内存)
  6. 发起者 (test_bench) 查看修改后的 tlm_generic_payload(现在包含总和)并执行一些过程(检查理论总和)

我试图遵循这个例子。

https://www.doulos.com/knowhow/systemc/tlm2/tutorial__1/

更新

test_bench.h

class test_bench:
    public sc_core::sc_module
{
public: 
    tlm_utils::simple_initiator_socket<test_bench> socket;
    sc_out<bool> irq;

    test_bench(sc_core::sc_module_name name);
    void run_tests();

private:
    uint32_t data[3];
};

【问题讨论】:

  • 你应该发布你的“test_bench.h”。您似乎没有使用 SC_MODULE 宏声明 test_bench 模块。它的声明方式应与声明 Top 模块的方式相同。
  • 我在继承。 adder.cc 编译成具有相同范式的对象

标签: c++ compiler-errors systemc


【解决方案1】:

在 SystemC 中有两种声明模块的方法。

第一个是通过使用SC_MODULE宏:

SC_MODULE(mymodule) {
    SC_CTOR(mymodule)
    {
    }
};

第二个没有它:

class mymodule : public sc_core::sc_module {
    SC_HAS_PROCESS(mymodule);
public:
    mymodule(sc_core::sc_module_name)
    { }
};

我更喜欢第二个,因为:

  • 它尽可能地避免了那些讨厌的宏。
  • 它允许您从另一个模块继承。

现在为什么需要 SC_MODULESC_HAS_PROCESS 宏。原因是宏 SC_METHODSC_THREAD 需要知道它们被用来完成工作的模块类型。由于 SystemC 基于 1998 年发布的 C++ 语言的旧版本,因此无法自动执行此操作。所以辅助宏SC_HAS_PROCESS被定义为:

#define SC_HAS_PROCESS(user_module_name) typedef user_module_name SC_CURRENT_USER_MODULE

这允许SC_METHODSC_THREAD 使用SC_CURRENT_USER_MODULE 作为它们正在使用的模块的同义词。宏SC_MODULE 已经在幕后使用SC_HAS_PROCESS


另一个建议 - 如果您使用 C++11 兼容的编译器,您可以为自己声明一个辅助宏:

#define DECL(name, ...) name{#name, __VA_ARGS__}

这可以帮助您声明命名对象而无需输入两次名称:

sc_in<bool> DECL(clk);

任何提及此端口的错误消息都包含它的正确名称。

也可以在构造函数中用于初始化成员字段:

mymodule(sc_core::sc_module_name)
    : DECL(clk)
{
}

【讨论】:

  • 所以它构建了,如果您不介意,作为一个快速的单独问题:当我运行可执行文件时,test_bench 类的 run_tests() 方法似乎没有运行。有什么方法可以触发 SC_THREAD。它如何先进行实例化和 tlm 绑定,然后再触发方法。我是否需要使线程敏感并从顶部模块触发 test_bench 的端口?
  • 一旦模拟开始,所有线程进程都会被调度执行。你不需要做任何事情。你打电话给sc_start了吗?也许它确实被调用了,但在 b_transport 中被阻止了?
  • 不,我没有。这确实引发了回应。实际上,现在我得到了一个奇怪的响应,这可以追溯到我最初对连接 tlm 的担忧 --- 错误:(E109)完全绑定失败:端口未绑定:端口'Top.adder.port_0'(sc_out)
  • @JohnFrye 你需要绑定它。建议为每个对象命名,以便阅读错误消息。我已经更新了我的答案,并就命名对象提出了一些小建议。
  • 我更改了加法器上的端口名称,以便套接字具有不同的名称,但我仍然收到相同消息的相同错误。该错误清楚地表明,加法器中的 simple_target_socket 存在问题。这是进出加法器的唯一端口。我感觉问题出在那儿,但我不知道它到底是什么
猜你喜欢
  • 1970-01-01
  • 2015-05-29
  • 2014-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多