
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; // c=a&b - логический элемент 2AND endmodule
Представление постоянных сигналов или просто чисел на языке Verilog:
wire [12:0] s = 12; //32-х битное десятичное число 12, которое будет “обрезано” до 13 бит wire [12:0] z = 13’d12; //13-ти битное десятичное число 12 wire [3:0] t = 4'b0101; //4-х битное двоичное число 0101 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
Синтаксис операций Verilog похож на синтаксис операций языка С. Символы операций, их названия, а также применимость к вещественным переменным приведены в таблице 1.
Таблица 1
Символ |
Описание операции |
Применимость к real |
+ - * / |
Арифметические |
Допустимо |
% |
Модуль |
Не допустимо |
> >= < <= |
Отношения |
Допустимо |
! |
Логическое отрицание |
Допустимо |
&& |
Логическое И |
Допустимо |
|| |
Логическое ИЛИ |
Допустимо |
== |
Логическое равенство |
Допустимо |
!= |
Логическое неравенство |
Допустимо |
=== |
Идентичность |
Не допустимо |
!=== |
Неидентичность |
Не допустимо |
~ |
Побитовая инверсия |
Не допустимо |
& |
Побитовое И |
Не допустимо |
| |
Побитовое ИЛИ |
Не допустимо |
^ |
Побитовое исключающее ИЛИ |
Не допустимо |
|
|
|
<< |
Сдвиг влево |
Не допустимо |
>> |
Сдвиг вправо |
Не допустимо |
<<< |
Циклический сдвиг влево |
Не допустимо |
>>> |
Циклический сдвиг вправо |
Не допустимо |
?: |
Условный оператор |
Допустимо |
Рассмотрим операции Verilog в порядке убывания приоритета:
+ - ! ~ (унарные) наивысший приоритет
* / %
+ - (бинарные)
<< >> <<< >>>
< <= > >=
?: Низший приоритет
Операции с равным приоритетом выполняются слева направо, за исключением символа ?, который выполняется справа налево.
Для закрепления синтаксиса операций Verilog опишем на языке Verilog цифровое устройство шифратор с 8 входами и 3-мя выходами.
СДНФ:
Y1=X1 v X3v X5v X7
Y2=X2 v X3 v X6 v X7
Y3=X4 v X5 v X6 v X7
Зная структурные формулы шифратора, например, в СДНФ, опишем его схему на языке Verilog.
1-й способ:
module SHIFRATOR (input X1, input X2, input X3, input X4, input X5, input X6, input X7, output Y1, output Y2, output Y3);
assign Y1=X1 | X3 | X5 | X7; //где “|” – логическая операция ИЛИ (дизъюнкция)
assign Y2=X2 | X3 | X6 | X7;
assign Y3=X4 | X5 | X6 | X7;
endmodule
2-й способ:
module SHIFRATOR (X1, X2, X3, X4, X5, X6, X7, Y1, Y2, Y3);