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 (los datos fluyen hacia adentro) o output (los datos fluyen hacia afuera). Un puerto inout puede hacer ambas cosas: puede enviar datos hacia afuera o recibir datos hacia adentro, dependiendo de la situación.

Piénsalo como una calle de doble sentido en lugar de una carretera 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 una entrada o como una 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;  // Manejar el bus cuando esté habilitado, de lo contrario Z
  assign data_in = bus;                     // Leer siempre el bus
  
endmodule
  • Cuando enable = 1, el módulo controla el bus (modo de salida)
  • Cuando enable = 0, el módulo libera el bus (modo de entrada, high-Z)

Reglas importantes para Inout

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

Inout vs Input vs Output

Tipo de puertoDirecciónPuede controlarPuede leer
inputUnidireccional (solo entrada)No
outputUnidireccional (solo salida)No
inoutBidireccional (ambos)Sí (cuando está habilitado)Sí (siempre)

Error común

// INCORRECTO: No se puede asignar a inout dentro de un bloque always
always @(posedge clk) begin
  data_bus <= something;   // ¡Error! Use assign con una condición
end
// CORRECTO: Usar assign con condición de habilitación
assign data_bus = (enable) ? something : 8'bZ;
challenge icon

Desafío

Añade el puerto inout faltante y las sentencias assign para que este búfer bidireccional funcione.

Qué hacer:

  1. Añade un puerto inout de 8 bits llamado io_bus
  2. Añade una sentencia assign que maneje io_bus con send_value cuando send_enable sea 1, de lo contrario Z
  3. Añade una sentencia assign que lea io_bus en receive_value

Hoja de referencia

inout es un puerto bidireccional que puede tanto enviar como recibir señales. Solo un dispositivo controla el bus a la vez; los demás deben emitir alta impedancia (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

Reglas clave:

  • Debe ser wire (no reg)
  • Use assign con una condición ternaria — nunca asigne dentro de un bloque always
  • Libere con Z cuando no esté enviando señal para evitar la contención del bus

Pruébalo tú mismo

module bidir_buffer (
  // Tarea 1: Agregue 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: Agregue una sentencia assign que maneje io_bus con send_value cuando send_enable sea 1, de lo contrario Z
  
  
  // Tarea 3: Agregue 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