Menu
Coddy logo textTech

Параметры

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

Вы можете создавать множество копий одного и того же модуля и использовать их в разных местах — это называется **множественными экземплярами** (multiple instances). Вместо того чтобы писать один и тот же код снова и снова, вы пишете его один раз и используете повторно столько раз, сколько потребуется. Каждый экземпляр представляет собой отдельную копию этого оборудования на чипе.

Но что, если вам нужно, чтобы каждая копия была разной? Например, один 8-битный счетчик, один 16-битный счетчик и один 32-битный счетчик. Без параметров вам пришлось бы написать три отдельных модуля.

Параметры решают эту проблему.

Параметр — это постоянное значение, которое вы можете задать при создании экземпляра. Это позволяет настраивать каждую копию модуля по-разному.

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

module counter #(
  parameter WIDTH = 8
)(
  input clk,
  output reg [WIDTH-1:0] count
);
  always @(posedge clk) count <= count + 1;
endmodule

Конструкция #(parameter WIDTH = 8) определяет параметр с именем WIDTH со значением по умолчанию 8.

При объявлении параметров мы используем символ # сразу после имени модуля и перед списком портов. Символ # сообщает Verilog, что далее следует список параметров, настраивающих модуль. Если у вашего модуля нет параметров, вы просто полностью опускаете #.

Использование параметров

Параметры можно использовать везде, где требуется константа:

reg [WIDTH-1:0] data;        // Размер вектора
count <= count + 1;           // Работает с любой шириной
assign out = data[WIDTH-1];   // Позиция старшего значащего бита (MSB)

Переопределение параметров

При использовании модуля вы можете изменить значение параметра:

// Ширина по умолчанию (8 бит)
counter u1 (.clk(clk), .reset(reset), .count(count1));

// Переопределение до 16 бит
counter #(.WIDTH(16)) u2 (.clk(clk), .reset(reset), .count(count2));

Несколько параметров

Вы можете использовать несколько параметров:

module fifo #(
  parameter DEPTH = 16,
  parameter WIDTH = 8
)(
  input clk, wr_en, rd_en,
  input [WIDTH-1:0] data_in,
  output [WIDTH-1:0] data_out
);
  reg [WIDTH-1:0] memory [0:DEPTH-1];
endmodule

Localparam

localparam работает аналогично, но его значение нельзя переопределить извне:

module example;
  localparam STATE_IDLE = 2'b00;
  localparam STATE_RUN = 2'b01;
  localparam STATE_STOP = 2'b10;
  // Эти значения фиксированы внутри этого модуля
endmodule

Используйте localparam для констант, которые не должны изменяться.

challenge icon

Задание

Добавьте параметр с именем WIDTH со значением по умолчанию 4.

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

  1. Добавьте параметр с именем WIDTH
  2. Установите его значение по умолчанию равным 4
  3. Параметр указывается внутри #( ) после имени модуля

Шпаргалка

Параметры позволяют настраивать экземпляры модулей по-разному без переписывания кода.

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

module counter #(
  parameter WIDTH = 8  // default value
)(
  input clk,
  output reg [WIDTH-1:0] count
);
  always @(posedge clk) count <= count + 1;
endmodule

Переопределение параметров при создании экземпляра

counter u1 (.clk(clk), .count(count1));          // uses default (8)
counter #(.WIDTH(16)) u2 (.clk(clk), .count(count2)); // overridden to 16

Несколько параметров

module fifo #(
  parameter DEPTH = 16,
  parameter WIDTH = 8
)( ... );

Localparam (непереопределяемая константа)

localparam STATE_IDLE = 2'b00;
localparam STATE_RUN  = 2'b01;

Используйте localparam для внутренних констант, которые не должны изменяться извне модуля.

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

module counter #(
  // Добавьте сюда параметр WIDTH со значением по умолчанию 4
  
)(
  input clk,
  input reset,
  output reg [WIDTH-1:0] count
);

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

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

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