Menu
Coddy logo textTech

Порты Inout

Часть раздела Основы путешествия по Verilog на Coddy — урок 32 из 90.

Порт inout — это двухнаправленный порт (bidirectional), который может как передавать, так и принимать сигналы. Он может выступать в роли input или output в разное время. Большинство портов являются либо input (данные поступают внутрь), либо output (данные выводятся наружу). Порт inout может делать и то, и другое — он может выводить (drive) данные или принимать их в зависимости от ситуации.

Представьте это как улицу с двусторонним движением вместо дороги с односторонним движением.

Порты inout используются для:

  • Общих шин — несколько устройств подключены к одним и тем же проводам
  • Шин данных памяти — данные могут считываться или записываться
  • Двунаправленной связи — I2C, SPI и т. д.

Только одно устройство управляет шиной одновременно. Другие устройства должны находиться в высокоимпедансном состоянии (Z).

Объявление порта Inout

inout [7:0] data_bus;   // 8-битная двунаправленная шина
inout ready;             // Однобитный двунаправленный сигнал

Как работает Inout

Порту inout требуется сигнал управления, чтобы решить, работает ли он как input или output:

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
  • Когда enable = 1, модуль управляет шиной bus (режим вывода)
  • Когда enable = 0, модуль отпускает шину bus (режим ввода, высокоимпедансное состояние Z)

Важные правила для Inout

ПравилоПочему
Должен быть объявлен как wireCannot быть reg
Нельзя одновременно читать и записыватьЭто создаст конфликт (X)
Используйте Z, чтобы освободить шинуПозволяет другим устройствам управлять шиной
Только один драйвер одновременноПредотвращает конфликт на шине

Inout vs Input vs Output

Тип портаНаправлениеМожет управлять (Drive)Может читать (Read)
inputОднонаправленный (только вход)НетДа
outputОднонаправленный (только выход)ДаНет
inoutДвунаправленный (оба)Да (когда включен)Да (всегда)

Частая ошибка

// WRONG: Нельзя присваивать inout внутри блока always
always @(posedge clk) begin
  data_bus <= something;   // Ошибка! Используйте assign с условием
end

// CORRECT: Используйте assign с условием enable
assign data_bus = (enable) ? something : 8'bZ;
challenge icon

Задание

Добавьте недостающий порт inout и операторы assign, чтобы этот двунаправленный буфер заработал.

Что нужно сделать:

  1. Добавьте 8-битный порт inout с именем io_bus
  2. Добавьте оператор assign, который передает send_value на io_bus, когда send_enable равен 1, иначе Z
  3. Добавьте оператор assign, который считывает io_bus в receive_value

Попробуйте сами

module bidir_buffer (
  // Задание 1: Добавьте 8-битный порт inout с именем io_bus здесь
  
  
  input [7:0] send_value,
  input send_enable,
  output [7:0] receive_value
);

  // Задание 2: Добавьте оператор assign, который подаёт send_value на io_bus, когда send_enable равен 1, иначе Z
  
  
  // Задание 3: Добавьте оператор assign, который считывает io_bus в receive_value
  

endmodule
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Основы