image

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

История SystemVerilog довольна длина и туманна. Начавшись после принятия стандарта Verilog-95, она вылелась в Verilog-2001. Однако язык не слишком подходил для верификации, инженеры использовании языки семейства «E» — VERA, Testbuider. В современном виде 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 стали доступны улучшенные возможности инициализации типов. Теперь не надо писать
reg [63:0] data = 64'hFFFFFFFFFFFFFFFF;


Можно сделать просто так:
reg [63:0] data  = '1;


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

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


Наконец-то state машину можно описать вот так
enum {WAITE, LOAD, STORE} State, NextState;
always_ff @(posedge clock, negedge resetN)
	if (!resetN) State <= WAITE;
	else State <= NextState;
	
always_comb begin
	case (State)
		WAITE: NextState = LOAD;
		LOAD: NextState = STORE;
		STORE: NextState = WAITE;
	endcase
end


Кроме того, перечисляемому типу можно присваивать значения:
enum {ONE = 1,FIVE = 5,TEN = 10 } state;


По умолчанию перечисляемому типу ставится в соответствие значение int. Однако, можно написать и вот так
// перечисляемы тип с шириной 1 бит.
// может принимать только два состояний
enum bit {TRUE, FALSE} Boolean;
// перечисляемы тип с шириной 2 бита.
// может принимать четыре состояния
enum logic [1:0] {WAITE, LOAD, READY} state;


Для печати значения имени перечисляемого типа используется следующая конструкция:
$display("\nCurrent state is %s (%b)", State.name);


Струкруты


Объявить структуры можно следующим способом:
struct {
	int a, b; // 32-bit variables
	opcode_t opcode; // user-defined type
	logic [23:0] address; // 24-bit variable
	bit error; // 1-bit 2-state var.
	} Instruction_Word;


Для структур поддерживается объявление typedef
typedef struct { // structure definition
	logic [31:0] a, b;
	logic [ 7:0] opcode;
	logic [23:0] address;
	} instruction_word_t;
	instruction_word_t IW; // structure allocation


По умолчанию структура представляется как unpacked. Ключевое слово packed позволяет быть структуре запакованной.
struct packed {
	logic valid;
	logic [ 7:0] tag;
	logic [31:0] data;
	} data_word;


В данном виде она представляется как вектор. Поэтому возможны такие конструкции
image
data_word.tag = 8’hf0; 
data_word[39:32] = 8’hf0; // делаем тоже самое


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


Объединения это значение памяти которое может хранить разные типы данных, но одновременно только одно.
Синтаксис полностью C-like.
union {
	int i;
	int unsigned u;
} data;
...
data.i = -5;
$display("data is %d", data.i);
data.u = -5;
$display("now data is %d", data.u);


Наибольший практический интерес представляют packed unions. В них для представления разных типов используемся фиксированное число бит.
Информация, записанная через один тип, может быть считана в другом виде (другом типе). Например:
typedef struct packed {
	logic [15:0] source_address;
	logic [15:0] destination_address;
	logic [23:0] data;
	logic [ 7:0] opcode;
} data_packet_t;

union packed {
	data_packet_t packet; // packed structure
	logic [7:0][7:0] bytes; // packed array
} dreg;


image
Так как объединение упаковано, то информация выровнена, поэтому данные записанные через logic[7:0] можно считать через data_packet_t
initial begin
	logic [15:0] src, dst; 
	for (i = 0; i <= N; i = i + 1) begin
		dreg.bytes[i] <= byte_in; //store as bytes
	end
	src = dreg.source_address;
	dst = dreg.destination_address;
end


Packed Array


SystemVerilog позволяет создавать мультиразмерные упакованные массивы
logic [3:0][7:0] data; // 2-D packed array
logic [1:0][3:0][7:0] data; // 3-D packed array


Стандарт IEEE определяем как эти элемент должны хранится в памяти. Например для описания
logic [3:0][7:0] data; // 2-D packed array


image
Поскольку массив хранится в памяти как вектор, то допустимо использовать все теже операции что и над векторами
logic [3:0][15:0] a, b, result; // packed arrays
result = (a << 1) + b;


Доступ к вектору может быть как поэлементным, так и включая целую размерность(и). Так называемы срез массива.
logic [1:0][1:0][7:0] a; // 3-D packed array
a[1][1][0] = 1’b0; // присваиваем один бит массиву
a = 32’hF1A3C5E7; // записываем сразу массив целиком
a[1][0][3:0] = 4’hF; // доступ к части массивы
a[0] = 16’hFACE; // доступ к срезу


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


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


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

Комментарии (9)


  1. aronsky
    12.08.2015 21:18
    +2

    Как мне 5 лет назад не хватало подобной статьи — приходилось всё по крупицам собирать. Ни одной книги, всего 2 мануала и то платных. Помню тиммейта вызвали в немецкий офис известной японско-германской конторы, на которую мы тогда работали и он нашёл у них отличный подробный мануал. Естественно, выносить за территорию его никто не дал и он каждый день выделял по пол часа на фотографирование страниц на HTC HD2.
    Наверное такой радости от рабочей литературы я не получал больше никогда.


  1. evocatus
    13.08.2015 11:21

    И что, вся эта красота синтезируется?


    1. covsh
      13.08.2015 13:16
      +2

      естественно не все синтезируется. насчет Altera есть таблица что Quartus поддерживает. Меня же больше интересовала верификация


      1. covsh
        13.08.2015 13:24

        так же у Altera есть online курс про поддрержку SV


        1. capitanov
          13.08.2015 13:55

          а для Xilinx как дела обстоят?


          1. covsh
            13.08.2015 14:06
            +1

            сам с xilinx не работал, но гугл находит отличную статью на русском


            1. capitanov
              13.08.2015 14:10

              Интересная статья. Жаль, что Vivado у Xilinx заточен под 7 серию камней и выше.


  1. capitanov
    13.08.2015 12:04
    +2

    Эх! По сравнению с монстрообразным VHDL, на которым мы сейчас пишем — SV кажется ну просто минималистичным и красивым.
    Интересно, какие синтезаторы в настоящий момент поддерживают SV?


    1. covsh
      13.08.2015 13:17

      насчет VHDL не соглашусь с вами, все таки он красивый и строгий! =)