简体   繁体   中英

Is it possible to bind the output of a submodule to two different output ports?

I am trying to make a circuit which computes the carries for an addition.

In this piece of code, I would like to connect the output port rOut of the submodule pg to two output ports ( rOut and carries[0] ) of the parent module, so both get the same value.

template<>
struct Carries<1> : ::sc_core::sc_module {
    sc_vector<sc_in<bool>> a, b;
    sc_in<bool> rIn;
    sc_out<bool> p, g, rOut;
    sc_vector<sc_out<bool>> carries;

    CarryPropGen pg {"PG"};

    SC_CTOR(Carries)
        :   a {"vectA", 1}, b {"vectB", 1},
            rIn {"rIn"},
            p {"p"}, g {"g"}, rOut {"rOut"},
            carries {"vectCarries", 1} {
        pg.a(a[0]);
        pg.b(b[0]);
        pg.r(rIn);

        pg.p(p);
        pg.g(g);
        pg.rOut(rOut);
        pg.rOut(carries[0]);
    }
};

However, I get the error (E109) complete binding failed: 2 binds exceeds maximum of 1 allowed: port 'Carries.PG.port_5' (sc_out) . I also tried with a signal, with and without the writer policy SC_MANY_WRITER , as it was suggested by someone on a forum, but it didn't work either.

I am new to SystemC and while I understand the error, I don't really understand why this can't work and how to do it differently. So, is there a way to bind one submodule's output to multiple sc_out of the parent module, and how?

Ports in SystemC are not wires, but smart pointers. Unlike regular C++ pointers, SystemC ports are safe and support hierarchical binding. Similarly to a regular pointers, by default, you can't connect port to 2 channels simultaneously.

While this may be inconvenient for low-level modeling, this allows to use ports with any kind of high-level channels, like FIFOs or TLM channels.

Looks like you need something like broadcast port: when you write to such a port message should be written to all connected channels.

To create a port that can be binded to a multiple channels, use second template parameter N of 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

Lets test it:

#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;
}

This is not exactly what we wanted: here we need to iterate over all connected channels each time we need to write something into broadcast port.

Let's create a derived class that will do this automatically:

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_);
    }
  }
};

Here is how we use it in 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";
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM