绑定multi_passthrough_initiator_sockets是否有任何订单要求?

时间:2018-11-28 13:09:49

标签: systemc

我有一个SystemC层次结构top-> middle-> leaf,并尝试将 leaf 中的multi_passthrough_initiator_socket绑定到其父模块 middle <中的相同类型的套接字/ em>。然后将 middle 中的套接字绑定到 top 中的目标套接字。

绑定在middle::before_end_of_elaboration()中完成:

leaf->i_socket.bind(i_socket)

top::before_end_of_elaboration()

middle->i_socket.bind(t_socket)

当执行 middle 中的代码时,这会创建一个异常-我注意到 top 中的代码是在之前被调用的(似乎before_end_of_elaboration()不被称为depth)。 -第一)。

解决方法是在其构造函数中的 middle 中进行绑定,这表明存在某种排序要求。有谁知道/可以提出一个干净的解决方案吗?

1 个答案:

答案 0 :(得分:1)

我建议您将此发布到Accellera支持论坛。 http://forums.accellera.org/forum/14-systemc-tlm-transaction-level-modeling/

这是实现错误,或者是TLM库的未记录限制。

我自己已经尝试过这种情况,这就是我发现的情况:

  • 没有订购要求
  • 但是不允许您将before_end_of_elaboration()用于tlm套接字绑定

这是我的测试示例:

struct test : sc_module {
    tlm_utils::multi_passthrough_initiator_socket<test> leaf{"leaf"};
    tlm_utils::multi_passthrough_initiator_socket<test> middle{"middle"};
    tlm_utils::simple_target_socket<test>  target{"target"};
    test(sc_module_name);
protected:
    void before_end_of_elaboration();
};

选项1-有效

test::test(sc_module_name)
{
    leaf.bind(target);
    middle.bind(leaf);
}

void test::before_end_of_elaboration() {}

选项2-有效

test::test(sc_module_name)
{
    middle.bind(leaf);
    leaf.bind(target);
}

void test::before_end_of_elaboration() {}

选项3-失败,并出现错误:(E126)sc_export实例已绑定

test::test(sc_module_name)
{}

void test::before_end_of_elaboration() {
    middle.bind(leaf);
    leaf.bind(target);
}

现在,此行为的原因是TLM库使用before_end_of_elaboration回调来实现对分层绑定的支持(您自己检查multi_passthrough_initiator_socket的源代码)。因此,用户代码应在此之前完成所有套接字绑定。而且,由于before_end_of_elaboration之前没有回调,因此只能在构造函数中绑定TLM套接字。

请注意,信号端口不是这种情况,您可以使用before_end_of_elaboration以任何顺序绑定信号端口:

struct test : sc_module {
    sc_in<int> leaf0{"leaf0"};
    sc_in<int> leaf1{"leaf1"};
    sc_in<int> middle0{"middle0"};
    sc_in<int> middle1{"middle1"};
    sc_signal<int> sig{"sig"};

    test(sc_module_name);
protected:
    void before_end_of_elaboration();
};


test::test(sc_module_name)
{
}

void test::before_end_of_elaboration()
{
    leaf0(middle0); // OK
    middle0(sig);   // OK
    middle1(sig);   // OK
    leaf1(middle1); // OK
}