2
\$\begingroup\$

When an inout port is used for read and write simultaneously it is necessary to use the "?:" operator with the HiZ to assign the port.

inout   [7:0]some_port;
wire    [7:0]port_in;
reg     [7:0]port_out;
reg     is_output;
...
assign port_in  = some_port;
assign some_port= is_output ? 8'bz : port_out;

Suppose that the design contains several levels of modules and the bottom module has a number of ports. Some of these ports are used by middle level modules. The other ports are directly used as inout of the FPGA. Must I to drag inout ports through all hierarchy of modules as a separated port_in / port_out / is_output and then assign it in the top level module to the inout port? Can I assign somehow an inout port in the bottom module and then forward this port through all levels to the top? If I can't, do the professional SV programmers uses some macros to do this action with minimum strings of code?

\$\endgroup\$
3
\$\begingroup\$

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.

An example:

// Top level module inout represents a tri-state buffer
module topLevel(
    inout [1:0] tlBidir
);
// inout can be fed entirely into one module, or shared between multiples
subModule first (
    .bidir(tlBidir[0])
);
subModule second (
    .bidir(tlBidir[1])
);
// This one is **not** a tristate buffer as used internally
// It will infer a multiplexer/demultiplexer structure.
wire internalWire;
subModule third (
    .bidir(internalWire)
);
assign internalWire = ctrl ? 1'b0 : 1'bz;

endmodule

// A submodule which describes tristate buffer behaviour.
// Can be at any level
module subModule(
    inout bidir
);

wire ctrl;
wire outVal;
wire inVal;

assign bidir = ctrl ? 1'bz : outVal;
assign inVal = bidir;

...

endmodule
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.