Menu
Coddy logo textTech

Porty dwukierunkowe

Część sekcji Podstawy ścieżki Verilog w Coddy. Lekcja 32 z 90.

Port inout to port dwukierunkowy, który może zarówno wysyłać, jak i odbierać sygnały. W różnych momentach może działać jako wejście lub wyjście. Większość portów to albo input (dane wpływają), albo output (dane wypływają). Port inout może robić jedno i drugie. W zależności od sytuacji może wysyłać dane na zewnątrz lub odbierać je.

Pomyśl o tym jak o ulicy dwukierunkowej, a nie jednokierunkowej.

Porty wejścia-wyjścia są używane do:

  • Współdzielonych magistral: wiele urządzeń podłączonych do tych samych przewodów
  • Magistral danych pamięci: dane można odczytywać lub zapisywać
  • Komunikacji dwukierunkowej: I2C, SPI itd.

W danym momencie tylko jedno urządzenie steruje magistralą. Pozostałe urządzenia muszą znajdować się w stanie wysokiej impedancji (Z).

Deklarowanie portu wejścia-wyjścia

inout [7:0] data_bus;   // 8-bitowa magistrala dwukierunkowa
inout ready;             // Jednobitowy sygnał dwukierunkowy

Jak działa Inout

Port wejścia/wyjścia wymaga sygnału sterującego, który decyduje, czy działa jako wejście, czy wyjście:

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
  • Gdy enable = 1, moduł wysterowuje magistralę (tryb wyjścia)
  • Gdy enable = 0, moduł zwalnia magistralę (tryb wejścia, stan wysokiej impedancji)

Ważne zasady dotyczące Inout

ZasadaDlaczego
Musi być zadeklarowane jako wireNie może być reg
Nie można jednocześnie odczytywać i zapisywaćSpowodowałoby to konflikt (X)
Użyj Z, aby zwolnić magistralęUmożliwia sterowanie nią innym urządzeniom
W danej chwili może być tylko jeden sterownikZapobiega konfliktom na magistrali

Inout a input i output

Typ portuKierunekMoże sterowaćMoże odczytywać
inputJednokierunkowy (tylko wejście)NieTak
outputJednokierunkowy (tylko wyjście)TakNie
inoutDwukierunkowy (w obie strony)Tak (gdy włączony)Tak (zawsze)

Częsty błąd

// BŁĄD: Nie można przypisywać wartości do inout wewnątrz bloku always
always @(posedge clk) begin
  data_bus <= something;   // Błąd! Użyj assign z warunkiem
end

// POPRAWNIE: Użyj assign z warunkiem enable
assign data_bus = (enable) ? something : 8'bZ;
challenge icon

Wyzwanie

Dodaj brakujący port inout oraz instrukcje assign, aby ten bufor dwukierunkowy działał.

Co należy zrobić:

  1. Dodaj 8-bitowy port inout o nazwie io_bus
  2. Dodaj instrukcję assign, która steruje io_bus za pomocą send_value, gdy send_enable ma wartość 1, a w przeciwnym razie Z
  3. Dodaj instrukcję assign, która odczytuje io_bus do receive_value

Spróbuj swoich sił

module bidir_buffer (
  // Zadanie 1: Dodaj tutaj 8-bitowy port inout o nazwie io_bus
  
  
  input [7:0] send_value,
  input send_enable,
  output [7:0] receive_value
);

  // Zadanie 2: Dodaj instrukcję assign, która ustawia io_bus na send_value, gdy send_enable wynosi 1, a w przeciwnym razie na Z
  
  
  // Zadanie 3: Dodaj instrukcję assign, która przypisuje wartość odczytaną z io_bus do receive_value
  

endmodule
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Podstawy

Poćwicz samodzielnie: Kompilator Verilog online