2015-12-23 5 views
1

Я хотел бы создать задачу, которая делает следующее в SystemVerilog:SystemVerilog: Создание упакованных массивов с использованием переменных

  1. получить 3 входных параметров и параметров 1 выход.
  2. Производит рандомизацию данных и назначение данных битовой переменной (выходной параметр).

    1. task rand_wr_data(input int size, int data_range_hi, int data_range_lo, output bit [31:0] data); 
    2.  bit unsigned [(size - 1):0] rand_data_bits; 
    3.  bit unsigned [(data_range_hi - data_range_lo):0] wr_data_bits; 
    4.  
    5.  int unsigned rand_data = $urandom(); 
    6.  wr_data_bits = rand_data; 
    7.  data = wr_data_bits << (data_range_lo + 1); 
    8. endtask: rand_data 
    

Приведенные выше код дает мне ошибку, как из непостоянных ошибок выражения в строке 2 и 3 чего Я использовать константу в объявлении диапазона для массива. Я пробовал следующее, но безрезультатно.

[parameter | localparam | const] int data_size = size; 

Поэтому, у меня есть несколько запросов следующим образом:

  1. Есть ли способ, чтобы создать упакованный массив, используя переменные, как в моем коде?
  2. Есть ли другой способ сделать то, что я хотел бы сделать выше?
  3. Могу ли я получить массив переменных размера в качестве параметра задачи вместо массива, который должен объявить свой размер?
  4. В строке 6 моего кода я хотел бы присвоить unsigned int 32-битовому массиву, но после этого получим другой результат. Как я могу это сделать?

спасибо.

ответ

3

Ссылаясь на погрешность: Непостоянное выражение. Размер всех упакованных переменных должен быть определен в времени компиляции. Но здесь вы предоставляете размер , который не является допустимым. Отныне ошибка.

Там может быть несколько полезных и не очень полезных обходные следующим образом:

Объявить 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.

+0

спасибо. Вы извлекли важные моменты из Cookbook SystemVerilog, чтобы упростить понимание. Я реализовал, как было предложено, и код работает. – user3531168

Смежные вопросы