There is no requirement for
inout ports to be placed only in the top level. That being said, an FPGAs typically don't support internal tri-state buffers, so the use of them in internal modules is not necessarily representing a bidirectional signal.
In your case where you wish to feed a tristate signal from a lower level module up to the top level, this is perfectly acceptable. Just connect the
inout signal to the port connection list of your submodule. As long as each
inout pin connects ultimately to only one tristate buffer design at any level in the hierarchy, a proper tristate buffer will inferred. Remember, wires have no concept of direction until one is specified by an assignment, so feeding a bidirectional wire through the hierarchy is acceptable.
Where things get a bit more interesting is when you connect two
inout signals inside the FPGA. Typical FPGAs don't have internal tristates, so instead the synthesis tool has to infer multiplexing/demultiplexing logic (usually with some form of priority to avoid bus contention). This can cause differences between simulation and synthesis - sim might show
x for bus contention, but in synthesis one of the signals will take priority due to the multiplexer structure.
// Top level module inout represents a tri-state buffer
inout [1:0] tlBidir
// inout can be fed entirely into one module, or shared between multiples
subModule first (
subModule second (
// This one is **not** a tristate buffer as used internally
// It will infer a multiplexer/demultiplexer structure.
subModule third (
assign internalWire = ctrl ? 1'b0 : 1'bz;
// A submodule which describes tristate buffer behaviour.
// Can be at any level
assign bidir = ctrl ? 1'bz : outVal;
assign inVal = bidir;