Menu
Coddy logo textTech

Inout Ports

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

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

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

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

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

Только одно устройство одновременно drives шину. Другие устройства должны находиться в состоянии высокого импеданса (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
  • when enable = 1, module drives bus (режим output)
  • when enable = 0, module releases bus (режим input, высокоимпедансное состояние)

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

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

Inout по сравнению с Input и Output

Тип portНаправлениеМожет DriveМожет читать
inputОдностороннее (только внутрь)НетДа
outputОдностороннее (только наружу)ДаНет
inoutДвустороннее (в обоих направлениях)Да (when enabled)Да (always)

Распространённая ошибка

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

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

Задание

Add пропущенный порт inout и операторы assign, чтобы этот двунаправленный буфер работал.

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

  1. Add 8-битный порт inout called io_bus
  2. Add оператор assign, который drives io_bus значением send_value, when send_enable равен 1, otherwise Z
  3. Add оператор assign, который reads io_bus into 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, который подаёт на io_bus значение send_value, когда send_enable равен 1, иначе Z
  
  
  // Задача 3: Добавьте оператор assign, который считывает io_bus в receive_value
  

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

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

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

Потренируйтесь самостоятельно: Онлайн-компилятор Verilog