Menu
Coddy logo textTech

Portas Inout

Parte da seção Fundamentos do Journey de Verilog da Coddy — lição 32 de 90.

Uma porta inout é uma porta bidirecional que pode tanto enviar quanto receber sinais. Ela pode atuar como uma entrada ou uma saída em diferentes momentos.

A maioria das portas é input (os dados fluem para dentro) ou output (os dados fluem para fora). Uma porta inout pode fazer ambos — ela pode enviar dados para fora ou receber dados para dentro, dependendo da situação.

Pense nisso como uma rua de mão dupla em vez de uma estrada de mão única.

Portas inout são usadas para:

  • Barramentos compartilhados — múltiplos dispositivos conectados aos mesmos fios
  • Barramentos de dados de memória — os dados podem ser lidos ou gravados
  • Comunicação bidirecional — I2C, SPI, etc.

Apenas um dispositivo aciona o barramento por vez. Outros dispositivos devem estar em estado de alta impedância (Z).

Declarando uma Porta Inout

inout [7:0] data_bus;   // barramento bidirecional de 8 bits
inout ready;             // sinal bidirecional de bit único

Como o Inout Funciona

Uma porta inout requer um sinal de controle para decidir se ela está atuando como uma entrada ou saída:

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;  // Aciona o barramento quando habilitado, caso contrário Z
  assign data_in = bus;                     // Sempre lê o barramento
  
endmodule
  • Quando enable = 1, o módulo aciona o barramento (modo de saída)
  • Quando enable = 0, o módulo libera o barramento (modo de entrada, high-Z)

Regras Importantes para Inout

RegraPor que
Deve ser declarado como wireNão pode ser reg
Não pode ser lido e escrito ao mesmo tempoCriaria um conflito (X)
Use Z para liberar o barramentoPermite que outros dispositivos conduzam
Apenas um condutor por vezPrevine a contenção do barramento

Inout vs Input vs Output

Tipo de PortaDireçãoPode AcionarPode Ler
inputUnidirecional (apenas entrada)NãoSim
outputUnidirecional (apenas saída)SimNão
inoutBidirecional (ambos)Sim (quando habilitado)Sim (sempre)

Erro Comum

// ERRADO: Não é possível atribuir a inout dentro de um bloco always
always @(posedge clk) begin
  data_bus <= something;   // Erro! Use assign com condição
end
// CORRETO: Use assign com condição enable
assign data_bus = (enable) ? something : 8'bZ;
challenge icon

Desafio

Adicione a porta inout que está faltando e as instruções assign para fazer este buffer bidirecional funcionar.

O que fazer:

  1. Adicione uma porta inout de 8 bits chamada io_bus
  2. Adicione uma instrução assign que direcione io_bus com send_value quando send_enable for 1, caso contrário Z
  3. Adicione uma instrução assign que leia io_bus para receive_value

Folha de consulta

inout é uma porta bidirecional que pode tanto enviar quanto receber sinais. Apenas um dispositivo aciona o barramento por vez; os outros devem produzir alta impedância (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; // Aciona quando habilitado, caso contrário libera
  assign data_in = bus;                    // Sempre lê o barramento
endmodule

Regras principais:

  • Deve ser wire (não reg)
  • Use assign com uma condição ternária — nunca atribua dentro de um bloco always
  • Libere com Z quando não estiver acionando para evitar contenção de barramento

Experimente você mesmo

module bidir_buffer (
  // Tarefa 1: Adicione uma porta inout de 8 bits chamada io_bus aqui
  
  
  input [7:0] send_value,
  input send_enable,
  output [7:0] receive_value
);

  // Tarefa 2: Adicione uma instrução assign que direcione io_bus com send_value quando send_enable for 1, caso contrário Z
  
  
  // Tarefa 3: Adicione uma instrução assign que leia io_bus para receive_value
  

endmodule
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Fundamentos