Menu
Coddy logo textTech

Входные и выходные порты

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

Порты ввода и вывода — это соединения, которые позволяют модулю взаимодействовать с внешним миром. Они подобны выводам на микросхеме. Порты являются интерфейсом между модулем и остальной частью проекта.

У каждого модуля есть:

  • Входные порты — сигналы, которые поступают в модуль
  • Выходные порты — сигналы, которые выходят из модуля

Входные порты

Входные порты получают данные извне. Их нельзя изменять внутри модуля — только читать.

input clk;        // Однобитовый вход
input [7:0] data; // 8-битный входной вектор
input a, b;       // Несколько входов в одной строке

Правила для входных портов (inputs):

  • Не могут получать значение внутри модуля
  • Не могут быть объявлены как reg
  • Всегда wire (по умолчанию)

Выходные порты

Выходные порты отправляют данные наружу. Они могут управляться блоками assign или always.

output out;           // Однобитный выход
output [3:0] result;  // 4-битный выход
output reg busy;      // Выход может быть типа reg
output wire ready;    // Выход может быть типа wire

Правила для выходных сигналов:

  • Могут быть wireassign) или regalways)
  • Должны управляться чем-то внутри модуля

Синтаксис объявления портов

Синтаксис объявления портов — это определенный способ записи входных и выходных портов в модуле. Он сообщает Verilog три вещи о каждом порте:

  1. Направление — является ли оно входным (input), выходным (output) или двунаправленным (inout)?
  2. Размер — какова его разрядность в битах?
  3. Имя — как оно называется?
module example (
  input [7:0] data_in,    // Входной вектор
  input clk,              // Одиночный вход
  input enable,           // Одиночный вход
  output reg [7:0] out,   // Выходной регистр
  output busy             // Выходной провод
);

Почему важно направление портов

Направление сообщает Verilog:

  • Какие сигналы модуль может читать (входы)
  • Какие сигналы модуль может записывать (выходы)
  • Какие типы соединений разрешены

Использование неправильного направления приводит к ошибкам компиляции.

Пример кода

module port_demo (
  input [3:0] a,        // Только для чтения
  input [3:0] b,        // Только для чтения
  output reg [3:0] sum, // Можно записывать (reg)
  output [3:0] diff     // Можно записывать (wire)
);
  always @(*) begin
    sum = a + b;        // Запись в выходной reg
  end
  
  assign diff = a - b;   // Запись в выходной wire
endmodule
challenge icon

Задание

Завершите объявление портов

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

  1. Добавьте 8-битный вход с именем data_in
  2. Добавьте однобитный вход с именем clk
  3. Добавьте 4-битный выход с именем result (используйте reg — будет присваиваться в блоке always)
  4. Добавьте однобитный выход с именем valid (используйте wire — будет присваиваться с помощью assign)

Шпаргалка

Порты — это интерфейс между модулем и внешним миром.

Входные порты

Входы всегда имеют тип wire и доступны только для чтения внутри модуля:

input clk;        // Однобитный
input [7:0] data; // 8-битный вектор
input a, b;       // Несколько входов

Выходные порты

Выходы могут иметь тип wire (управляются через assign) или reg (управляются через always):

output wire ready;    // Используется с assign
output reg busy;      // Используется с always

Объявление портов в заголовке модуля

Каждое объявление порта определяет направление, размер и имя:

module example (
  input [7:0] data_in,   // 8-битный вход
  input clk,             // однобитный вход
  output reg [3:0] sum,  // 4-битный выходной reg
  output diff            // однобитный выходной wire
);
  always @(*) sum = data_in[3:0] + 1;
  assign diff = data_in[0];
endmodule

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

module port_challenge (
  // Задача 1: Добавьте 8-битный вход с именем data_in
  
  
  // Задача 2: Добавьте однобитный вход с именем clk
  
  
  // Задача 3: Добавьте 4-битный выход с именем result (используйте reg)
  
  
  // Задача 4: Добавьте однобитный выход с именем valid (используйте wire)
  
  
);

  reg [3:0] counter;
  
  always @(posedge clk) begin
    counter <= counter + 1;
    result <= counter;
  end
  
  assign valid = (counter > 8);
  
endmodule
quiz iconПроверьте себя

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

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