If known about at the time of implementation, using SystemVerilog Interfaces Section 3.5 and 25 of IEEE 1800-2012 can solve this issue.
An interface is a named bundle of nets, so if everything in the path connects to the interface, adding an extra net to the interface means all instances of that interface get the extra wire.
Adding signals to the interface allows low level modules to be instantly connected to everything else (top level) using that bus, without any additional port work to connect once the interface is connected through the hierarchy.
Interfaces vs Structs has been discussed previously.
A Doulos Tutorial on interfaces.
For a slightly more complete answer I include the example given in 25.3.3 IEEE 1800 showing to modules connected via an interface:
// memMod and cpuMod can use any interface
module memMod (interface a, input logic clk);
...
endmodule
module cpuMod(interface b, input logic clk);
...
endmodule
interface simple_bus; // Define the interface
logic req, gnt;
logic [7:0] addr, data;
logic [1:0] mode;
logic start, rdy;
endinterface: simple_bus
module top;
logic clk = 0;
simple_bus sb_intf(); // Instantiate the interface
// Reference the sb_intf instance of the simple_bus
// interface from the generic interfaces of the
// memMod and cpuMod modules
memMod mem (.a(sb_intf), .clk(clk));
cpuMod cpu (.b(sb_intf), .clk(clk));
endmodule
Using modports (Section 25.5 of IEEE 1800) you can specify master slave sections of the interface to define port directions.
As Tim has mentioned I avoid using this as it becomes very difficult to debug. I have worked on one project where interfaces were heavily used. The connections were not one to one, but propagated everywhere through the hierarchy. Imagine register writes happening over LBUS, using WiredOR bus or tristate for the readback. The tools we had at the time would not let you see which module was driving the bus. Therefore if it went X from multiple drives it was a guessing game as to what was causing it.
We were not using interfaces only for standard protocols like LBUS but new ones which were being altered on the fly, which meant modules that had not been fixed for protocol changes corrupted the bus. Using interfaces greatly sped up the implementation as extra signal were quick to integrate. The cost was almost impossible to debug as the source of issues on the interface could not be traced.