Ссылаясь на погрешность: Непостоянное выражение. Размер всех упакованных переменных должен быть определен в времени компиляции. Но здесь вы предоставляете размер , который не является допустимым. Отныне ошибка.
Там может быть несколько полезных и не очень полезных обходные следующим образом:
Объявить size
, data_range_hi
и data_range_lo
в качестве параметров. С параметры: оценено во время время компиляции/разработки, это сработает. Но вы не можете изменить эти параметры непосредственно во время выполнения.
task rand_wr_data (output bit [31:0] data);
parameter int size=8, data_range_hi=8,data_range_lo=0;
bit unsigned [(size - 1):0] rand_data_bits;
В качестве альтернативы и эффективный способ, ссылаясь на SystemVerilog LRM 1800-2012 раздел 13.8:
A parameterized subroutine allows the user to generically specify or define an implementation. When using that subroutine one may provide the parameters that fully define its behavior. This allows for only one definition to be written and maintained instead of multiple subroutines with different array sizes, data types, and variable widths.
И следующий пункт:
The way to implement parameterized subroutines is through the use of static methods in parameterized classes (see 8.10 and 8.25).
The class may be declared virtual in order to prevent object construction and enforce the strict static usage of the method.
Вы можете создать параметризированный virtual
класс и static
задача внутри него.Вызов этой задачи должен выполняться с помощью оператора области видимости (::
) и переопределения параметров. Что-то может быть сделано следующим образом:
virtual class wrapper #(parameter int size=8, int data_range_hi=8, int data_range_lo=0);
static task rand_wr_data(output bit [31:0] data);
bit unsigned [(size - 1):0] rand_data_bits;
// ...
// ...
endtask
endclass
// ...
// in some module/class, call task
wrapper #(16,8,0)::rand_wr_data (a);
// ...
Объявив класс, как virtual
гарантирует, что никакие объекты не могут быть созданы для этого класса. Пример, приведенный в разделе 13.8 LRM, также может оказаться полезным.
Рабочим примером является EDAPlayground here.
Coming на вопросы:
Is there a way to create a packed array using variables like in my code?
Да, как описано выше.
Is there another way to do what I would like to do above?
Там могут быть и другие способы, как define
директив, которые могут быть установлены во время выполнения с помощью пользователя, но они остаются постоянными во всей симуляции.
Can I receive variable size array as a task parameter instead of an array that has to have its size declared?
Да, как обсуждалось выше.
In line 6 of my code, I would like to assign an unsigned int to a 32-bit array but I receive different result after that. How can I accomplish that?
Бит является по умолчанию unsigned
, поэтому нет необходимости объявлять bit unsigned
, только bit
будет работать; но это не проблема. Проблема здесь выглядит wr_data_bits
определяется как bit unsigned [(data_range_hi - data_range_lo):0] wr_data_bits;
, а rand_data
определяется как int unsigned rand_data
. размер обоих может различный.
В случае, если вы пройдете 31
как (data_range_hi - data_range_lo)
, значения будут соответствовать. Данная примерная ссылка на код показывает равные значения.
wr_data_bits = 5e23536 rand_data = 5e23536
Я пробовал искать его, но не нашел много информации. Для получения дополнительной информации см. Ссылку this.
спасибо. Вы извлекли важные моменты из Cookbook SystemVerilog, чтобы упростить понимание. Я реализовал, как было предложено, и код работает. – user3531168