Menu
Coddy logo textTech

Puertos Inout

Parte de la sección Fundamentos del Journey de Verilog de Coddy — lección 32 de 90.

Un puerto inout es un puerto bidireccional que puede tanto enviar como recibir señales. Puede actuar como una entrada o una salida en diferentes momentos. La mayoría de los puertos son input (el flujo de datos entra) u output (el flujo de datos sale). Un puerto inout puede hacer ambas cosas: puede enviar datos hacia afuera o recibir datos hacia adentro, dependiendo de la situación.

Piensa en ello como una calle de doble sentido en lugar de una calle de sentido único.

Los puertos inout se utilizan para:

  • Buses compartidos — múltiples dispositivos conectados a los mismos cables
  • Buses de datos de memoria — los datos se pueden leer o escribir
  • Comunicación bidireccional — I2C, SPI, etc.

Solo un dispositivo controla el bus a la vez. Los otros dispositivos deben estar en estado de alta impedancia (Z).

Declaración de un puerto Inout

inout [7:0] data_bus;   // bus bidireccional de 8 bits
inout ready;             // señal bidireccional de un solo bit

Cómo funciona Inout

Un puerto inout requiere una señal de control para decidir si está actuando como entrada o salida:

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
  • Cuando enable = 1, el module drives el bus (modo salida)
  • Cuando enable = 0, el module release el bus (modo entrada, alta impedancia/high-Z)

Reglas importantes para Inout

ReglaPor qué
Debe declararse como wireCannot ser reg
No se puede leer y escribir al mismo tiempoCrearía un conflicto (X)
Usar Z para liberar el busPermite que otros dispositivos manejen la señal
Solo un Drive a la vezEvita la contención del bus

Inout vs Input vs Output

Tipo de puertoDirecciónPuede DrivePuede leer
inputUnidireccional (solo entrada)No
outputUnidireccional (solo salida)No
inoutBidireccional (ambos)Sí (when enabled)Sí (always)

Error común

// WRONG: No se puede asignar a inout dentro de un bloque always
always @(posedge clk) begin
  data_bus <= something;   // ¡Error! Usa assign con condición
end

// CORRECT: Usa assign con condición de enable
assign data_bus = (enable) ? something : 8'bZ;
challenge icon

Desafío

Agrega el puerto inout que falta y las declaraciones assign para hacer que este buffer bidireccional funcione.

Qué hacer:

  1. Agrega un puerto inout de 8 bits llamado io_bus
  2. Agrega una declaración assign que maneje io_bus con send_value cuando send_enable sea 1, de lo contrario Z
  3. Agrega una declaración assign que lea io_bus en receive_value

Pruébalo tú mismo

module bidir_buffer (
  // Tarea 1: Añade un puerto inout de 8 bits llamado io_bus aquí
  
  
  input [7:0] send_value,
  input send_enable,
  output [7:0] receive_value
);

  // Tarea 2: Añade una sentencia assign que impulse io_bus con send_value cuando send_enable es 1, de lo contrario Z
  
  
  // Tarea 3: Añade una sentencia assign que lea io_bus en receive_value
  

endmodule
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Fundamentos