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 entrada o salida en distintos momentos. La mayoría de los puertos son input (los datos entran) o output (los datos salen). Un puerto inout puede hacer ambas cosas. Puede enviar datos o recibirlos, según la situación.

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

Los puertos de entrada/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).

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 funciona como entrada o como 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 conduce el bus (modo de salida)
  • Cuando enable = 0, el módulo libera el bus (modo de entrada, alta impedancia)

Reglas importantes para Inout

ReglaMotivo
Debe declararse como wireNo puede ser reg
Varios dispositivos no deben controlar el bus al mismo tiempoLos controladores en conflicto producen X
Usa Z para liberar el busPermite que otros dispositivos lo controlen
Solo un controlador a la vezEvita la contención del bus

Inout frente a Input frente a Output

Tipo de puertoDirecciónPuede impulsarPuede leer
inputUnidireccional (solo entrada)NoSí
outputUnidireccional (solo salida)SíSí (el valor que impulsa)
inoutBidireccional (ambas)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! Usa assign con una condición
end

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

Desafío

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

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, usa Z
  3. Añade una instrucción assign que lea io_bus en receive_value

Pruébalo tú mismo

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

  // Tarea 2: Agrega una sentencia assign que asigne send_value a io_bus cuando send_enable sea 1; en caso contrario, Z
  
  
  // Tarea 3: Agrega una sentencia assign que lea io_bus y asigne su valor a 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