Menu
CoddyTech

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