Menu
Coddy logo textTech

Ports Inout

Fait partie de la section Fondamentaux du Journey Verilog de Coddy — leçon 32 sur 90.

Un port inout est un port bidirectionnel qui peut à la fois envoyer et recevoir des signaux. Il peut agir comme une entrée ou une sortie à différents moments.

La plupart des ports sont soit input (les données entrent), soit output (les données sortent). Un port inout peut faire les deux — il peut envoyer des données ou en recevoir, selon la situation.

Considérez cela comme une rue à double sens plutôt qu'une route à sens unique.

Les ports inout sont utilisés pour :

  • Bus partagés — plusieurs périphériques connectés aux mêmes fils
  • Bus de données mémoire — les données peuvent être lues ou écrites
  • Communication bidirectionnelle — I2C, SPI, etc.

Un seul dispositif pilote le bus à la fois. Les autres dispositifs doivent être dans un état de haute impédance (Z).

Déclaration d'un port Inout

inout [7:0] data_bus;   // bus bidirectionnel 8 bits
inout ready;             // signal bidirectionnel à un seul bit

Comment fonctionne Inout

Un port inout nécessite un signal de commande pour décider s'il agit comme une entrée ou une sortie :

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;  // Piloter le bus lorsqu'il est activé, sinon Z
  assign data_in = bus;                     // Toujours lire le bus
  
endmodule
  • Lorsque enable = 1, le module pilote le bus (mode sortie)
  • Lorsque enable = 0, le module libère le bus (mode entrée, high-Z)

Règles importantes pour Inout

RèglePourquoi
Doit être déclaré comme wireNe peut pas être reg
Ne peut pas être lu et écrit en même tempsCréerait un conflit (X)
Utilisez Z pour libérer le busPermet à d'autres périphériques de piloter
Un seul pilote à la foisEmpêche la contention de bus

Inout vs Input vs Output

Type de portDirectionPeut piloterPeut lire
inputUnidirectionnel (entrée uniquement)NonOui
outputUnidirectionnel (sortie uniquement)OuiNon
inoutBidirectionnel (les deux)Oui (lorsqu'activé)Oui (toujours)

Erreur courante

// ERREUR : Impossible d'assigner à un inout à l'intérieur d'un bloc always
always @(posedge clk) begin
  data_bus <= something;   // Erreur ! Utilisez assign avec une condition
end
// CORRECT : Utiliser assign avec une condition d'activation
assign data_bus = (enable) ? something : 8'bZ;
challenge icon

Défi

Ajoutez le port inout manquant et les instructions assign pour faire fonctionner ce tampon bidirectionnel.

Ce qu'il faut faire :

  1. Ajoutez un port inout de 8 bits appelé io_bus
  2. Ajoutez une instruction assign qui pilote io_bus avec send_value quand send_enable est à 1, sinon à Z
  3. Ajoutez une instruction assign qui lit io_bus dans receive_value

Aide-mémoire

inout est un port bidirectionnel qui peut à la fois émettre et recevoir des signaux. Un seul périphérique pilote le bus à la fois ; les autres doivent sortir une haute impédance (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; // Piloter lorsqu'activé, sinon libérer
  assign data_in = bus;                    // Toujours lire le bus
endmodule

Règles clés :

  • Doit être un wire (pas un reg)
  • Utilisez assign avec une condition ternaire — n'assignez jamais à l'intérieur d'un bloc always
  • Libérez avec Z lorsqu'il n'y a pas de pilotage pour éviter les conflits de bus

Essayez vous-même

module bidir_buffer (
  // Tâche 1 : Ajoutez un port inout de 8 bits nommé io_bus ici
  
  
  input [7:0] send_value,
  input send_enable,
  output [7:0] receive_value
);

  // Tâche 2 : Ajoutez une instruction assign qui pilote io_bus avec send_value quand send_enable est à 1, sinon Z
  
  
  // Tâche 3 : Ajoutez une instruction assign qui lit io_bus dans receive_value
  

endmodule
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Fondamentaux