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

Piensa en ello como una calle de doble sentido en lugar de una carretera de un solo sentido.

Los puertos de entrada y salida se utilizan para:

  • Buses compartidos: varios 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 demás dispositivos deben estar en estado de alta impedancia (Z).

Declarar un puerto de entrada/salida

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 actúa 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 módulo controla el bus (modo de salida)
  • Cuando enable = 0, el módulo libera el bus (modo de entrada, alta impedancia)

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)
Usa Z para liberar el busPermite que otros dispositivos controlen el bus
Solo un controlador a la vezEvita la contención del bus

Inout frente a Input frente a Output

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

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

Añade el puerto inout que falta y las instrucciones 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 instrucción assign que dirija io_bus con send_value cuando send_enable sea 1; de lo contrario, Z
  3. Añade una instrucció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

Practica por tu cuenta: Compilador de Verilog online