Menu
Coddy logo textTech

Inout Ports

Part of the Fundamentals section of Coddy's Verilog journey — lesson 32 of 90.

An inout port is a bidirectional port that can both send and receive signals. It can act as an input or an output at different times.

Most ports are either input (data flows in) or output (data flows out). An inout port can do both — it can drive data out or receive data in, depending on the situation.

Think of it like a two-way street instead of a one-way road.

Inout ports are used for:

  • Shared buses — multiple devices connected to the same wires
  • Memory data buses — data can be read or written
  • Bidirectional communication — I2C, SPI, etc.

Only one device drives the bus at a time. Other devices must be in high-impedance state (Z).

Declaring an Inout Port

inout [7:0] data_bus;   // 8-bit bidirectional bus
inout ready;             // Single-bit bidirectional signal

How Inout Works

An inout port requires a control signal to decide whether it is acting as an input or output:

module bidir (
  inout [7:0] bus,
  input [7:0] data_out,
  input enable,
  output [7:0] data_in
);
  
  assign bus = (enable) ? data_out : 8'bZ;  // Drive bus when enabled, else Z
  assign data_in = bus;                     // Always read the bus
  
endmodule
  • When enable = 1, the module drives the bus (output mode)
  • When enable = 0, the module releases the bus (input mode, high-Z)

Important Rules for Inout

RuleWhy
Must be declared as wireCannot be reg
Cannot be read and written at same timeWould create conflict (X)
Use Z to release the busAllows other devices to drive
Only one driver at a timePrevents bus contention

Inout vs Input vs Output

Port TypeDirectionCan DriveCan Read
inputOne way (in only)NoYes
outputOne way (out only)YesNo
inoutTwo way (both)Yes (when enabled)Yes (always)

Common Mistake

// WRONG: Cannot assign to inout inside always block
always @(posedge clk) begin
  data_bus <= something;   // Error! Use assign with condition
end
// CORRECT: Use assign with enable condition
assign data_bus = (enable) ? something : 8'bZ;
challenge icon

Challenge

Add the missing inout port and the assign statements to make this bidirectional buffer work.

What to do:

  1. Add an 8-bit inout port called io_bus
  2. Add an assign statement that drives io_bus with send_value when send_enable is 1, otherwise Z
  3. Add an assign statement that reads io_bus into receive_value

Cheat sheet

inout is a bidirectional port that can both drive and receive signals. Only one device drives the bus at a time; others must output high-impedance (Z).

module bidir (
  inout [7:0] bus,
  input [7:0] data_out,
  input enable,
  output [7:0] data_in
);
  assign bus = (enable) ? data_out : 8'bZ; // Drive when enabled, else release
  assign data_in = bus;                    // Always read the bus
endmodule

Key rules:

  • Must be wire (not reg)
  • Use assign with a ternary condition — never assign inside an always block
  • Release with Z when not driving to avoid bus contention

Try it yourself

module bidir_buffer (
  // Task 1: Add an 8-bit inout port called io_bus here
  
  
  input [7:0] send_value,
  input send_enable,
  output [7:0] receive_value
);

  // Task 2: Add an assign statement that drives io_bus with send_value when send_enable is 1, otherwise Z
  
  
  // Task 3: Add an assign statement that reads io_bus into receive_value
  

endmodule
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Fundamentals