Порты в SystemC - это не провода, а умные указатели. В отличие от обычных указателей C ++, порты SystemC безопасны и поддерживают иерархическое связывание. Аналогично обычным указателям, по умолчанию, нельзя подключить порт к 2 каналам одновременно.
Хотя это может быть неудобно для низкоуровневого моделирования, это позволяет использовать порты с любыми высокоуровневыми каналами, такими как FIFO или каналы TLM.
Похоже, вам нужно что-то вроде широковещательной передачи. порт: при записи в такой порт сообщение должно быть записано на все подключенные каналы.
Чтобы создать порт, который можно привязать к нескольким каналам, используйте второй параметр шаблона N из sc_port:
// ----------------------------------------------------------------------------
// CLASS : sc_port
//
// Generic port class and base class for other port classes.
// N is the maximum number of channels (with interface IF) that can be bound
// to this port. N <= 0 means no maximum.
// ----------------------------------------------------------------------------
template <class IF, int N = 1, sc_port_policy P=SC_ONE_OR_MORE_BOUND>
class sc_port
Позволяет проверить его:
#include <systemc.h>
SC_MODULE(test) {
// Create broadcast_port that allows any number of binded channels
sc_port<sc_signal_inout_if<int>, 0> SC_NAMED(broadcast_port);
// create some signals
sc_signal<int> SC_NAMED(a);
sc_signal<int> SC_NAMED(b);
sc_signal<int> SC_NAMED(c);
SC_CTOR(test) {
// bind port to signals
broadcast_port(a);
broadcast_port(b);
broadcast_port(c);
SC_THREAD(test_thread);
}
void test_thread() {
// write 42 to all connected signals
for (size_t ii = 0; ii < broadcast_port.size(); ++ii) {
broadcast_port[ii]->write(42);
}
wait(SC_ZERO_TIME);
// print results
std::cout << a << "\n";
std::cout << b << "\n";
std::cout << c << "\n";
}
};
int sc_main(int, char *[]) {
test SC_NAMED(test_top);
sc_start();
return 0;
}
Это не совсем то, что мы хотели: здесь нам нужно перебирать все подключенные каналы каждый раз, когда нам нужно что-то записать в широковещательный порт.
Давайте создадим производный класс, который будет делать это автоматически:
template <typename T>
class sc_out_broadcast : public sc_port<sc_signal_inout_if<int>, 0>
{
public:
explicit sc_out_broadcast(const char *name_) : sc_port(name_) {}
// write the new value to all connected signals
void write( const T& value_ )
{
for (size_t ii = 0; ii < this->size(); ++ii) {
(*this)[ii]->write(value_);
}
}
};
Вот как мы используем его в test_thread:
void test_thread() {
broadcast_port.write(42);
wait(SC_ZERO_TIME);
std::cout << a << "\n";
std::cout << b << "\n";
std::cout << c << "\n";
}