Параметры Verilog с параметрической шириной

#verilog #system-verilog

#verilog #система-verilog

Вопрос:

Нетрудно согласиться с тем, что параметризованный дизайн модуля является хорошей практикой, а ширина данных — хорошей отправной точкой.

Я годами определял константы 0 и 1 требуемой ширины шины или операнда. Это позволяет избежать предупреждений компилятора и явно сообщать о намерении. Обычно используется что-то вроде:

 parameter   WIDTH = 16;
//  ...
parameter   ZERO  = {WIDTH{1'b0}};            // all zeroes
parameter   UNO   = {{WIDTH-1{1'b0}}, 1'b1};  // all zeroes except LSB
 

Все в порядке, пока я не захочу определить произвольную константу с заданной параметризованной ШИРИНОЙ.
Я, конечно, могу написать константу с фиксированной шириной, но это не то, что я хочу:

 parameter   FULL   = 16'd57;
 

Однако аналогичная конструкция с использованием параметрической ШИРИНЫ завершается ошибкой синтаксиса:

 parameter   LEVEL   = WIDTH'd57;   // <== *ERROR*
 

Каков правильный синтаксис — если он есть?

Ответ №1:

Это было проблемой в Verilog, потому что RHS присвоения параметра использовался как самостоятельно определенная ширина параметра. SystemVerilog решил эту проблему, позволив вам указать тип данных как часть parameter объявления

 parameter   WIDTH = 16;
//  ...
parameter bit [WIDTH-1:0] ZERO  = '0;           // all zeroes
parameter bit [WIDTH-1:0] UNO   = 1;  // all zeroes except LSB
parameter bit [WIDTH-1:0] LEVEL = 57;
 

Тип данных не изменяется при переопределении.

Другой способ — использовать приведение размеров

уровень параметра = ШИРИНА'(56);

Но если вы сделаете это таким образом и переопределите параметр, тип данных станет шириной типа переопределяющего значения.

Комментарии:

1. Это просто фантастика! Спасибо. Спецификация типа данных — это драгоценный камень. Тем не менее, я нахожу, что приведение размеров также имеет значение, если — в качестве примера — я хочу создать зависимый параметр и использовать разделение — в качестве примера:

2. parameter bit [WIDTH-1:0] LEVEL1 = WIDTH'(LEVEL/2-1); Примечание: Для простого деления на 2 я все равно могу использовать LEVEL>>1 без необходимости приведения.