Я предлагаю вам опубликовать это на форумах поддержки 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
}