You can, but you should not, because in general ports should be bound outside of a module. This is not enforced, but is a common coding convention. That way a user of your module always knows what to expect: "I should bind every port of module instance to some signal"
Binding ports hierarchically (i.e. input to sub-module input) is considered OK. Since top level module still holds a contract that it's ports must be bound to "outside" signals.
Consider your buffer for example:
template <typename T>
SC_MODULE(buffer) {
sc_in <int> ip{"ip"};
sc_out <int> op{"out"};
SC_CTOR(buffer) { ip(tmp_sig); op(tmp_sig); }
private:
sc_signal <int> tmp_sig{"sig"};
};
Suppose I want to write a test-bench for this module:
int sc_main(int argc, char * argv[] ) {
sc_signal<int> in_signal{"in_signal"};
sc_signal<int> out_signal{"out_signal"};
buffer buffer1{"buffer1"};
// Error ! **ip** is already bound to tmp_sig!!
buffer1.ip(in_signal);
// How can I write to **in** ??
buffer1.ip = 1; // Error! Writing to input port is not defined
sc_start();
return 0;
}
As you can see, buffer written this way is pretty useless!
Please note that connecting input port to output port directly, as Rahul suggested, is also a bad idea:
SC_MODULE(buffer) {
sc_in <int> ip{"ip"};
sc_out <int> op{"op"};
SC_CTOR(buffer) { ip(op); }
};
int sc_main(int argc, char * argv[] ) {
sc_signal<int> in_signal{"in_signal"};
sc_signal<int> out_signal{"out_signal"};
buffer buffer1{"buffer1"};
buffer1.ip(in_signal);
// Error, **op** is already bound to in_signal !
buffer1.op(out_signal);
sc_start();
return 0;
}