Визуальная электроника

В данной статье показаны некоторые нововведения языка SystemVerilog в области организации данных по сравнению с Verilog-2001 для синтезируемого подмножества языка. 

История SystemVerilog довольна длина и туманна. Начавшись после принятия стандарта Verilog-95, она вылилась в Verilog-2001. Однако язык не слишком подходил для верификации, инженеры использовании языки семейства «E» — VERA, Testbuilder. В современном виде SystemVerilog появился после 2005 года. Сейчас средства синтеза и моделирование такие как Quartus II, ISE, ModelSim/QuestaSim уверенно поддерживают SystemVerilog. Стандарт называется IEEE 1800-2012.

Прим. Эта статья давно написана, но не опубликована. Надеюсь будет полезна начинающим.

SystemVerilog привнес в мир Verilog много новых интересны конструкций:

  • C-lile синтаксис
  • ООП Структуры,
  • очереди,
  • динамические массивы,
  • перечисления
  • Приведения типов
  • Контроль поведения программы с помощью foreach, return, break, continue и т.д
  • Semaphores, mailboxes.
  • Интерфейсы
  • Assertions

Универсальный тип logic.

Теперь нет нужны выбирать между reg и wire, всюду используется logic. Синтезатор сам решить что надо сделать (привет signal из VHDL).

Инициализация типов.

В SystemVerilog стали доступны улучшенные возможности инициализации типов. Теперь не надо писать

SystemVerilog Code:
  1. reg [63:0] data = 64'hFFFFFFFFFFFFFFFF;

Можно сделать просто так:

SystemVerilog Code:
  1. reg [63:0] data = '1;

Запись data = '0 инициализируем вектор нулями, а data = 'bz — третьим состоянием

Перечисляемые типы.

Наконец-то state машину можно описать вот так

SystemVerilog Code:
  1. enum {WAITE, LOAD, STORE} State, NextState;
  2. always_ff @(posedge clock, negedge resetN)
  3. if (!resetN) State <= WAITE;
  4. else State <= NextState;
  5.  
  6. always_comb begin
  7. case (State)
  8. WAITE: NextState = LOAD;
  9. LOAD: NextState = STORE;
  10. STORE: NextState = WAITE;
  11. endcase
  12. end

Кроме того, перечисляемому типу можно присваивать значения:

SystemVerilog Code:
  1. enum {ONE = 1,FIVE = 5,TEN = 10 } state;

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

SystemVerilog Code:
  1. enum bit {TRUE, FALSE} Boolean;
  2. // перечисляемы тип с шириной 2 бита.
  3. // может принимать четыре состояния
  4. enum logic [1:0] {WAITE, LOAD, READY} state;

Для печати значения имени перечисляемого типа используется следующая конструкция:

SystemVerilog Code:
  1. $display("nCurrent state is %s (%b)", State.name);

Струкруты

Объявить структуры можно следующим способом:

SystemVerilog Code:
  1. struct {
  2. int a, b; // 32-bit variables
  3. opcode_t opcode; // user-defined type
  4. logic [23:0] address; // 24-bit variable
  5. bit error; // 1-bit 2-state var.
  6. } Instruction_Word;

Для структур поддерживается объявление typedef

SystemVerilog Code:
  1. typedef struct { // structure definition
  2. logic [31:0] a, b;
  3. logic [ 7:0] opcode;
  4. logic [23:0] address;
  5. } instruction_word_t;
  6. instruction_word_t IW; // structure allocation

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

SystemVerilog Code:
  1. struct packed {
  2. logic valid;
  3. logic [ 7:0] tag;
  4. logic [31:0] data;
  5. } data_word;

В данном виде она представляется как вектор. Поэтому возможны такие конструкции

pic1

SystemVerilog Code:
  1. data_word.tag = 8’hf0;
  2. data_word[39:32] = 8’hf0; // делаем тоже самое

Объединения union

Объединения это значение памяти которое может хранить разные типы данных, но одновременно только одно.
Синтаксис полностью C-like.

SystemVerilog Code:
  1. union {
  2. int i;
  3. int unsigned u;
  4. } data;
  5. ...
  6. data.i = -5;
  7. $display("data is %d", data.i);
  8. data.u = -5;
  9. $display("now data is %d", data.u);

Наибольший практический интерес представляют packed unions. В них для представления разных типов используемся фиксированное число бит.

Информация, записанная через один тип, может быть считана в другом виде (другом типе).

Например:

SystemVerilog Code:
  1. typedef struct packed {
  2. logic [15:0] source_address;
  3. logic [15:0] destination_address;
  4. logic [23:0] data;
  5. logic [ 7:0] opcode;
  6. } data_packet_t;
  7.  
  8. union packed {
  9. data_packet_t packet; // packed structure
  10. logic [7:0][7:0] bytes; // packed array
  11. } dreg;

pic2

Так как объединение упаковано, то информация выровнена, поэтому данные записанные через logic[7:0] можно считать через data_packet_t

SystemVerilog Code:
  1. initial begin
  2. logic [15:0] src, dst;
  3. for (i = 0; i <= N; i = i + 1) begin
  4. dreg.bytes[i] <= byte_in; //store as bytes
  5. end
  6. src = dreg.source_address;
  7. dst = dreg.destination_address;
  8. end

Packed Array

SystemVerilog позволяет создавать мультиразмерные упакованные массивы

SystemVerilog Code:
  1. logic [3:0][7:0] data; // 2-D packed array
  2. logic [1:0][3:0][7:0] data; // 3-D packed array

Стандарт IEEE определяем как эти элемент должны хранится в памяти. Например для описания

SystemVerilog Code:
  1. logic [3:0][7:0] data; // 2-D packed array

pic3

Поскольку массив хранится в памяти как вектор, то допустимо использовать все теже операции что и над векторами

SystemVerilog Code:
  1. logic [3:0][15:0] a, b, result; // packed arrays
  2. result = (a << 1) + b;

Доступ к вектору может быть как поэлементным, так и включая целую размерность(и). Так называемы срез массива.

SystemVerilog Code:
  1. logic [1:0][1:0][7:0] a; // 3-D packed array
  2. a[1][1][0] = 1’b0; // присваиваем один бит массиву
  3. a = 32’hF1A3C5E7; // записываем сразу массив целиком
  4. a[1][0][3:0] = 4’hF; // доступ к части массивы
  5. a[0] = 16’hFACE; // доступ к срезу

Для копирования содержимого одного массива в другой можно использовать прямой доступ или по срезам

SystemVerilog Code:
  1. bit [1:0][15:0] a; //32х битный вектор, элемент bit только 0 или 1
  2. logic [3:0][7:0] b; //32х битный вектор, элемент logic O,1,Z,X
  3. logic [15:0] c; // 16ти битный вектор
  4. logic [39:0] d; // 40 битный вектор
  5. b = a; // присвоение 32х битного массива 32х битному массиву
  6. c = a; // старшие 16 бит будут обрезаны
  7. d = a; // старшие 8 бит будут нулями

Список литературы

1. www.asic-world.com/systemverilog
2. «SystemVerilog For Design Second Edition» by Stuart Sutherland

 

Автор: covsh

Источник

 

Добавить комментарий