Введение в Verilog, Первый урок.

Verilog

Verilog HDL - язык описания цифровых схем. Он используется для проектирования цифровых микросхем ASIC и микросхем загружаемой логики FPGA (Field Programmable Gate Array) - по этой ссылке можно прочитать про их внутреннее устройство. Программировать FPGA не очень сложно. Мы научим вас этими уроками:

  • Часть 1. Базовые типы источников сигнала в языке Verilog HDL - это wire, reg, шины. Группирование логики в модули (module / endmodule). Входные и выходные сигналы модулей (input, output, inout).
  • Часть 2. Простейшие модули AND, NAND, OR, NOR, XOR, XNOR, NOT. Установка экземпляров модулей и соединение их проводами. Иерархия модулей в языке описания аппаратуры Verilog HDL.
  • Часть 3. Арифметические и логические действия в языке Verilog. Операторы сложения и вычитания (+ , -) , логический и арифметический сдвиг ( << , >> , >>> ), битовые операции ( & , | , ^, ~ ), булевые операции ( && , || , ! ), операторы редукции, условного выбора ( ? ) и сравнения.
  • Часть 4. Поведенческие блоки. Конструкции always, if-else, case-endcase, циклы for(...).
  • Часть 5. Синхронная логика и триггера в Verilog HDL. Блокирующее и не блокирующее присваивание.

На первом уроке познакомимся с базовыми типами источников сигнала используемыми в языке.

Пожалуй было бы не плохо начать наше обсуждение с понятия сигнал (signal). Сигналы – это электрические импульсы, которые передаются по проводам (wire) между логическими элементами схемы. Провода переносят информацию не производя над ней никаких вычислений. В цифровой схеме сигналы важны для передачи двоичных данных.

Базовый тип источника сигнала в языке Verilog – это провод, wire. Таким образом, если у вас есть арифметическое или логическое выражение, вы можете ассоциировать результат выражения с именованным проводом и позже использовать его в других выражениях. Это немного похоже на переменные, только их (как провода в схеме) нельзя пересоединить на лету, нельзя поменять назначение. Значение провода (wire) – это функция того, что присоединено к нему.

Вот пример декларации однобитного провода в “программе” Verilog:


wire a;


Вы можете ему назначить другой сигнал, скажем сигнал “b”, вот так:


wire b;
assign a = b;


Или вы можете определить сигнал и сделать назначение ему одновременно в одном выражении:


wire a = b;


У вас могут быть провода передающие несколько бит:


wire [3:0] c; //это четыре провода


Провода передающие несколько бит информации называются “шина”, иногда “вектор”.  Назначания к ним делаются так же:


wire [3:0] d;
assign c = d; //“подключение” одной шины к другой


Количество проводов в шине определяется любыми двумя целыми числами разделенными двоеточием внутри квадратных скобок.


wire [11:4] e; //восьмибитная шина
wire [0:255] f; //256-ти битная шина


Из шины можно выбрать некоторые нужные биты и назначить другому проводу:


wire g;
assign g = f[2];  //назначить сигналу “g” второй бит шины “f”


Кроме того, выбираемый из шины бит может определяться переменной:


wire [7:0] h;
wire i = f[h];  //назначить сигналу “i” бит номер “h” из шины “f”


Вы можете выбрать из сигнальной шины некоторый диапазон бит и назначить другой шине с тем же количеством бит:


wire [3:0] j = e[7:4];


Так же, в большинстве диалектов Verilog,  вы можете определить массивы сигнальных шин:


wire [7:0] k [0:19];  //массив из двадцати 8-ми битных шин


Еще существует другой тип источника сигнала называемый регистр: reg. Его используют при поведенческом (behavioral) описании схемы. Если регистру постоянно присваивается значение комбинаторной (логической) функции, то он ведет себя точно как провод (wire).  Если же регистру присваивается значение в синхронной логике, например по фронту сигнала тактовой частоты, то ему, в конечном счете, будет соответствовать физический D-триггер или группа D-триггеров. D-триггер – это логический элемент способный запоминать один бит информации. В англоязычных статьях D-триггер называют flipflop.

Регистры описываются так же как и провода:


reg [3:0] m;
reg [0:100] n;


Они могут использоваться так же, как и провода в правой части выражений, как операнды:


wire [1:0] p = m[2:1];


Вы можете определить массив регистров, которые обычно называют “память”  (RAM):


reg [7:0] q [0:15];  //память из 16 слов, каждое по 8 бит


Еще один тип источника сигнала – это integer. Он похож на регистр reg, но всегда является 32х битным знаковым типом данных. Например, объявим:


integer loop_count;


Verilog позволяет группировать логику в блоки. Каждый блок логики называется “модулем” (module). Модули имеют входы и выходы, которые ведут себя как сигналы wire.

При описании модуля сперва перечисляют его порты (входы и выходы):


module my_module_name (port_a, port_b, w, y, z);


А затем описывают направление сигналов:


input port_a;
output [6:0] port_b;
input [0:4] w;
inout y; //двунаправленный сигнал, обычно используется

         //только для внешних контактов микросхем


Позже мы увидим, что выход модуля может быть сразу декларирован как регистр reg, а не как провод wire:


output [3:0] z;
reg [3:0] z;


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


module my_module
(
    input wire port_a,
    output wire [6:0]port_b,
    input wire [0:4]w,
    inout wire y,
    output reg [3:0]z
);


Теперь можно использовать входные сигналы, как провода wire:


wire r = w[1];


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


assign port_b = h[6:0];


В конце описания логики каждого модуля пишем слово endmodule.


module my_module_name (input wire a, input wire b, output wire c);
assign c = a & b;
endmodule


Последний тип источника сигнала, о котором мы поговорим на этом уроке – это постоянные сигналы или просто числа:


wire [12:0] s = 12; //32-х битное десятичное число, которое будет “обрезано” до 13 бит
wire [12:0] z = 13’d12; //13-ти битное десятичное число
wire [3:0] t  = 4'b0101; //4-х битное двоичное число
wire [3:0] q  = 8'hA5;   //8-ми битное шестнадцатеричное число A5
wire [63:0] u = 64'hdeadbeefcafebabe;  //64-х битное шестнадцатеричное число


Если точно не определить размер числа, то оно принимается по умолчанию 32-х разрядным. Это может быть проблемой при присвоении сигналам с большей разрядностью.

Числа – это числа. Они могут использоваться во всяких арифметических и логических выражениях.  Например, можно прибавить 1 к вектору “aa”:


wire [3:0] aa;
wire [3:0] bb;
assign bb = aa + 1;


На следующем уроке будет рассказано про некоторые арифметические и логические функции.

Примеры простейших конструкций языка Verilog HDL можно посмотреть в специальном разделе Verilog в картинках. Здесь показано, как текст Verilog может быть трансформирован в схему.

Если вы захотите проверить свои знания Verilog на практике, то выбирайте FPGA плату в интернет магазине:

buy button

 


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