Краткие сведения о языке описания цифровых схем на языке Verilog

Территория рекламы
1

Лекция: Краткие сведения о языке описания цифровых схем на языке Verilog

Примечание: Обратите внимание – не язык программирования Verilog,

а описание цифровых схем на языке Verilog.

Введение

Язык VERILOG был разработан в 1985 г. одной из корпораций США и позднее утвержден институтом электроинженеров США (IEEE) — стандарт IEEE 1364 в 1994 г. В отличие от VHDL, который строго типизирован и синтаксически напоминает языки ADA и PASCAL, VERILOG базируется на Си, имеет меньше встроенных возможностей саморасширения, но зато более прост в реализации (более простой и быстрый компилятор). VERILOG имеет более развитый интерфейс с языком Си и лаконичен, что позволяет уменьшить объем описаний схем примерно в полтора раза по сравнению с VHDL. В настоящее время принят вариант нового стандарта IEEE 1364—2001 (VERILOG-2001), который, в частности, включил в себя ряд стилистических средств, сближающих его с VHDL.

Лекция

Идентификаторы, ключевые слова, числа

Идентификаторы, ключевые слова записываются по одним и тем же правилам, поэтому они и объединены в данный параграф. Общие правила записи следующие:

идентификаторы не должны совпадать с ключевыми словами;

идентификаторы не могут начинаться с символов ($) или ( ‘- ап остроф);

идентификатор не может начинаться с цифры;

длина идентификатора по стандарту не ограничена, но может ограничиваться в конкретном компиляторе;

ключевые слова всегда пишутся строчными буквами !!!;

директивы компилятора начинаются с символа (‘ - апостроф);

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

X, z, Z и. щ

Идентификаторы

Идентификаторы используются в языке Verilog в качестве символических имен для обозначения переменных, констант, модулей, функций, задач и т.д. и могутиспользоваться для обозначения этих объектов в любом месте описания.в любом месте описания.

Идентификатор представляет собой последовательность из букв, цифр, символов доллара ($) и символов подчеркивания (_) с учётом изложенных выше правил.

из букв, цифр, символов

Числа

Числа или иначе константы могут определяться в следующих форматах:

- десятичном (d):

- шестнадцатеричном (h) :

- восьмеричном (o):

- двоичном (b).

Допускается вводить эти буквы (d, h, o, b) как прописными, так и строчными.

В языке Verilog предусмотрены две формы для записи чисел.

Первая форма представляет собой простое десятичное число, как последовательность цифр от 0 до 9 и может включать символы плюс или минус. Вторая форма представления чисел имеет следующий формат:

<size> _<base format> _<number> ,

где “_” пробел или символ табуляции.

Первое поле size содержит десятичные цифр и указывает разрядность константы в битах, это поле может опускаться, если разрядность константы заранее определена. Например, производится присвоение константного значения переменной, разрядность которой задана при ее объявлении. Если разрядность не определена, то разрядность принимается по умолчанию 32 (32 в большинстве систем синтеза, в некоторых разрядность по умолчанию может отличаться).

Второе поле base format содержит букву, определяющую формат представления числа (десятичный, двоичный, шестнадцатеричный ...). Эта буква предваряется символом одиночной кавычки (').

Последнее поле number содержит цифры допустимые для выбранного формата: от 0 до 9 для десятичного формата; от 0 до 7 для восьмеричного; 0 и 1 для двоичного; от 0 до 9 и буквы а, Ь, с, d, е, f для шестнадцатеричного. Буквенные обозначения могут вводиться как строчными, так и прописными буквами.

Числа со знаком записываются символами плюса (+) и минуса (-) перед полем size, Эти символы перед полем number недопустимы !!!. Например, запись -8’hC6 эквивалентна записи –(8’hC6), а запись 8’h-C6 вызовет синтаксическую ошибку.

Помимо указанных цифр в поле number могут присутствовать буквы x, X, z, Z исимвол (?) (в поле size они недопустимы !!!). Буквы х и X обозначают неизвестное(неопределенное) состояние, т.е. состояние соответствующих битов неизвестно. Буквыz и Z обозначают состояние высокого импеданса – z-состояние или отсутствиеисточника (драйвера). Символ ? эквивалентен символу z и предназначен для лучшейчитаемости кода в случае, когда это состояние безразлично (don't-care). Существует

возможность сокращать запись числа, например: 8’b1 будет эквивалентно записи 8’b11111111, но запись 8’b01 будет эквивалентна записи 8’b00000001. Поэтому такие сокращенные записи могут мешать читаемости кода и употреблять их без надобности

не следует.

Для улучшения читаемости допускается ещё два приёма: допускается вставлять пробелы и символы табуляции между полями записи, например, 8’hB6 можно записать как 8 ’h B6. Вставлять пробелы внутри поля number не допускается, но можно вставлять символ подчеркивания (_), для разбиения числа на некоторые группы. Примеры 83465 можно записать как 83_465; 8’b01100111 можно записать как 8’b0110_0111. Символ подчёркивания в поле size или перед полем number недопустим !!!.

Краткие сведения о языке описания цифровых схем Verilog

Из вышесказанного следует, что Verilog - язык описания цифровых схем. Познакомимся с базовыми типами источников сигнала, используемыми в языке Verilog.

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

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

wire a; //назначить проводу сигнал a

Можно назначить однобитному проводу a другой сигнал, например, сигнал b:

wire b; //назначить проводу сигнал bassign a = b; //подключение провода b к проводу a

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

wire a = b; //назначить сигналу a сигнал b

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

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

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

wire [3:0] d; //назначить 4-х битной шине сигнал d assign c = d; //всегда подключение одной шины к другой –шины d к шине с

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

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

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

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

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

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

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

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

Можно определить на языке Verilog массивы сигнальных шин:

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

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

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

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

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

Помни: Ранее надо описать (задать) p и m как регистры

Можно определить массив регистров, которые обычно называют “память”  (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; // c=a&b - логический элемент 2ANDendmodule

Представление постоянных сигналов или просто чисел на языке Verilog:

wire [12:0] s = 12; //32-х битное десятичное число 12, которое будет “обрезано” до 13 битwire [12:0] z = 13’d12; //13-ти битное десятичное число 12wire [3:0] t  = 4'b0101; //4-х битное двоичное число 0101wire [3:0] q  = 8'hA5;   //8-ми битное шестнадцатеричное число A5wire [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);

input X1, X2, X3, X4, X5, X6, X7;

output Y1, Y2, Y3;

assign Y1=X1 | X3 | X5 | X7;

assign Y2=X2 | X3 | X6 | X7;

assign Y3=X4 | X5 | X6 | X7;

endmodule

Аналогичная опишем четырехканальный мультиплексор, структурная формула которого в СДНФ имеет вид:

В соответствии со структурной формулой схема мультиплексора в блочном описании на языке Verilog имеет вид (исправить ошибку в схеме):

Опишем схему мультиплексора на языке Verilog

1-й способ:

module MULTIPLEXOR (A0, A1, D0, D1, D2, D3, Y);

input A0, A1, D0, D1, D2, D3;

output Y;

assign Y=(D0 & !A1& !A0) | (D1 & !A1& A0) | (D2 & A1& !A0) | (D3 & A1 & A0);

endmodule

2-й способ (описание мультиплексора через wire):

module MULTIPLEXOR (input A0, input A1, input D0, input D1, input D2, input D3,

output Y);

wire S1, S2, S3, S4, S5, S6;

NOT my_1_not ( .OUT(S1), .IN1(A0));

NOT my_2_not ( .OUT(S2), .IN1(A1));

AND3 my_1_and ( .OUT(S3), .IN1(S1), .IN2(S2), .IN3(D0));

AND2 my_2_and ( .OUT(S4), .IN1(A0), .IN2(D1));

AND3 my_3_and ( .OUT(S5), .IN1(S1), .IN2(A1), .IN3(D2));

AND3 my_4_and ( .OUT(S6), .IN1(A0), .IN2(A1), .IN3(D3));

OR4 my_or ( .OUT(Y), .IN1(S3), .IN2(S4), .IN3(S5), .IN4(S6));

endmodule

Разработка модулей высокого уровня на ПЛИС на примере сумматора

Мы знаем про основные базовые логические элементы – и это тоже модули. Используем их в модуле более высокого уровня. Сделаем однобитный сумматор, а на его основе много битный сумматор (более высокого уровня).

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

Однобитный сумматор складывает два однобитных числа a и b. При выполнении сложения однобитных чисел может случиться «переполнение», то есть результат уже будет двух битным (1+1=2 или в двоичном виде 1’b1+1’b1=2’b10). Поэтому включим в сумматор выходной сигнал переноса c_out.

Дополнительный входной сигнал c_in служит для приема сигнала переноса от сумматоров младших разрядов (при построении много битных сумматоров).

Таблица истинности работы однобитного сумматора.

п/п

a

b

c_in

sum

c_out

Примечание

0

0

0

0

0

0

1

0

1

1

1

1

Перенос

2

1

0

0

1

0

3

1

1

1

0

1

Перенос

Примечание: С целью упрощения таблицы не все события в таблице перечислены для c_in, sum, c_out.

Структурные формулы работы однобитного сумматора с учетом минимизации учитывает все возможные события.

sum=(a^b) ^ c_in

c_out=((a^b) & c_in) ^ (a &b),

где символ «^» - сложение по модулю 2, символ «&» - логическая операция конъюнкция (and).

Схема согласно структурной формулы в графическом виде имеет вид:

Опишем эту схему на языке Verilog, устанавливая в теле модуля экземпляры других модулей.

Итак, модуль одно битного сумматора содержит 3 экземпляра модуля XOR и два экземпляра модуля AND2.

Порядок описания экземпляра модуля такой:

• название модуля, тип которого нам нужен (adder1) с указанием входов и выходов;

• описываем подключение сигналов: точка и затем имя сигнала модуля, затем в скобках имя проводника, который сюда подключен.

module adder1(input a, input b, input

c_in, output sum, output c_out);

wire s1,s2,s3;

XOR my_1_xor( .OUT (s1), .IN1 (a), .IN2 (b) );

AND2 my_1_and2( .OUT (s3), .IN1 (a), .IN2 (b) );

XOR my_2_xor( .OUT (sum), .IN1 (s1), .IN2 (c_in) );

AND2 my_2_and2( .OUT (s2), .IN1 (s1), .IN2 (c_in) );

XOR my_3_xor( .OUT (c_out), .IN1 (s2), .IN2 (s3) );

Endmodule

Опишем на языке Verilog однобитный сумматор на поведенческом уровне, то есть на основе структурных формул:

module adder1(input a, input b, input

c_in, output sum, output c_out);

assign sum = (a^b) ^ c_in;

assign c_out = ((a^b) & c_in) ^ (a&b);

endmodule

Следует помнить, что существуют разные методы описания и нужно уметь ими всеми пользоваться.

Итак, мы создали однобитный сумматор. На его основе можно создать n-битный сумматор. Рассмотрим, например, четырех битный сумматор (с

последовательным переносом).

Блочнe. схемe 4-х битного сумматора представим в виде:

Опишем эту схему на языке Verilog:

module adder4(output [3:0]sum, output c_out, input [3:0]a, input

[3:0]b );

wire c0, c1, c2;

adder1 my0_adder1( .sum (sum[0]) , .c_out (c0), .a (a[0]), .b

(b[0]), .c_in (1’b0) );

adder1 my1_adder1( .sum (sum[1]) , .c_out (c1), .a (a[1]), .b

(b[1]), .c_in (c0));

adder1 my2_adder1( .sum (sum[2]) , .c_out (c2), .a (a[2]), .b

(b[2]), .c_in (c1));

adder1 my3_adder1( .sum (sum[3]) , .c_out (c_out), .a (a[3]), .b

(b[3]), .c_in (c2) );

endmodule

Таким образом, мы реализовали четырехбитный сумматор. Мы получили его как модуль верхнего уровня adder4, состоящий из модулей adder1, которые, в свою очередь состоят из модулей примитивов AND2 и XOR.

Арифметические и логические функции

Мы уже знаем про модули, их входные и выходные сигналы и как они могут быть соединены друг с другом. Знаем, как можно сделать много битный сумматор. Нужно ли каждый раз, когда складываем два числа, делать такие сложные модули? Конечно нет! Поэтому познакомимся с основными арифметическими и логическими операторами языка Verilog.

С помощью комбинаторной логики посчитаем некоторые арифметические и логические функции.

Сложение и вычитание.

Пример модуля, который одновременно и складывает и вычитает два числа. Здесь входные операнды у нас 8-ми битные, а результат 9-ти битный. Verilog корректно сгенерирует бит переноса (carry bit) и поместит его в девятый бит выходного результата. С точки зрения Verilog входные операнды беззнаковые.

module simple_add_sub

(

operandA, operandB,

out_sum, out_dif

);

//два входных 8-ми битных операнда

input [7:0] operand A, operand B;

/*Выходы для арифметических операций имеют дополнительный 9-й бит

переполнения*/

output [8:0] out_sum, out_dif;

assign out_sum = operandA + operandB; //сложение

assign out_dif = operandA – operandB; //вычитание

endmodule

12

• Логический и арифметический сдвиг.

Рассмотрим пример модуля, который выполняет сдвиги. В нашем примере результат для сдвига влево16-ти битный. Если сдвигать влево или вправо слишком далеко, то результат получится просто ноль. Часто для сдвига используются только часть бит от второго операнда, для того, чтобы сэкономить логику.

module simple_shift

(

operandA, operandB,

out_shl, out_shr, out_sar

);

// два входных 8-ми битных операнда

input [7:0] operandA, operandB;

// Выходы для операций сдвига

output [15:0] out_shl;

output [7:0] out_shr;

output [7:0] out_sar;

//логический сдвиг влево

assign out_shl = operandA << operandB;

/* пример: на сколько сдвигать определяется 3-мя битами второго

операнда */

assign out_shr = operandA >> operandB[2:0];

//арифметический сдвиг вправо (сохранение знака числа)

assign out_sar = operandA >>> operandB[2:0];

endmodule

• Битовые логические операции

Битовые операции в Verilog выглядят так же, как и в языке C. Каждый бит результата вычисляется отдельно соответственно битам операндов. Пример:

module simple_bit_logic (

operandA, operandB,

out_bit_and, out_bit_or, out_bit_xor, out_bit_not);

//два входных 8-ми битных операнда

input [7:0] operandA, operandB;

//Выходы для битовых (bit-wise) логических операций

output [7:0] out_bit_and, out_bit_or, out_bit_xor, out_bit_not;

assign out_bit_and = operandA & operandB; //И

assign out_bit_or = operandA | operandB; //ИЛИ

assign out_bit_xor = operandA ^ operandB; //исключающее ИЛИ

assign out_bit_not = ~operandA; //НЕ

endmodule

Операции отношения

Следующие примеры иллюстрируют операторы отношения:

a < b a меньше чем b;

a > b a больше чем b;

a <= b a меньше или равно b;

a >= b a больше или равно b;

Все эти выражения возвращают лог.0 если приведенное отношение ложно (false) или лог.1 если отношение истинно (true). Если один из операндов имеет неопределенное значение, то и результат будет неопределен. Все операторы отношения имеют одинаковый приоритет и более низкий, чем приоритет арифметических операторов. Следующий пример иллюстрирует смысл этого правила:

a < size -1 // Эта конструкция идентична

a < (size -1) // этой, но

size – (1 < a) // эта конструкция отличается

size – 1 < a // от этой

Заметим, что в конструкции size – (1 < a) операция отношения вычисляется первой, а затем результат (0 или 1) вычитается из переменной size. В следующем же выражении сначала size уменьшается на 1, а затем результат сравнивается с а.

Операторы сравнения

Операторы сравнения имеют более низкий приоритет, чем операторы сравнения. В следующем примере иллюстрируются операторы сравнения.

a === b // a равно b, включая x

a !== b // a не равно b, включая x

a == b // a равно b, результат может быть неизвестен

a != b // a не равно b, результат может быть неизвестен

Все четыре оператора имеют одинаковый приоритет. Они сравнивают операнды бит в бит, и заполняют нулями в случае если операнды имеют различную разрядность. Так же как и операторы отношения они возвращают 0 если false и 1 если true. Если хотя бы один операнд содержит x, то операции == и != возвращают неопределенное значение. Операции === и !== сравнивают операнды с учетом x, поэтому всегда возвращают либо 0, либо 1.

Логические операции

Операторы логического И (&&) и логического ИЛИ (||) тесно связаны между собой. Результат логического сравнения может принимать значение «истинно» (true, 1) или «ложно» (false, 0), или если один из операндов имеет неопределенное значение, то и результат будет неопределен. Допустим, один из операндов имеет значение равное 10, а второй равен нулю. Результат логического И будет равен 0, так как второй операнд равен нулю. Результат логического ИЛИ, однако будет равен 1, так как первый операнд отличен от нуля. Verilog HDL воспринимает операнд равный 0 как «ложный», в то же время если операнд не равен нулю (не обязательно равен 1, например 10), то он воспринимается как «истинный». Именно это и произошло в приведенном примере: операция (true && false) привела к результату false, а операция (true || false) привела к результату true.

Операторы сдвига

К операторам сдвига относятся операторы <<, >>, <<< и >>>. Первые два оператора

выполняют простой сдвиг влево или вправо на количество позиций указанных

операндом в правой части выражения, два других выполняют циклический или иначе арифметический сдвиг. В следующем примере иллюстрируется механизм действия этих операторов.

Выражение Результат

8’b01001111 << 3 8’b01111000

8’b01001111 <<< 3 8’b01111010

8’b01001111 >> 3 8’b00001001

8’b01001111 >>> 3 8’b11101001

Условный оператор

Условный оператор имеет три операнда, разделенные двумя операторами в

следующем формате:

cond_expr ? true_expr : false_expr;

Если условие (cond_expr) вычисляется как «ложное» (false), то в качестве результата

будет использовано выражение false_expr. Если условие «истинно» (true), то будет

использовано выражение true_expr.

Операция объединения (конкатенация)

Операция конкатенации является одной из наиболее удобных и мощных операций в языке Verilog. Суть ее заключается в слиянии нескольких переменных в единое целое, единую переменную, с которой можно производить любые другие операции.

Необходимо отметить два момента: операция конкатенации обладает наивысшим приоритетом по сравнению с любой другой операцией вне символов конкатенации ({}), но операции заключенные внутри фигурных скобок имеют еще больший приоритет (Операции внутри фигурных скобок это недокументированное свойство языка, главное в этом случае, чтобы в результате внутренней операции результат получил определенную разрядность). Вторым моментом является тот факт, что операция конкатенации недопустима с вещественными числами. Синтаксис операции приведен ниже: {<expr_1>, <expr_2>, … <expr_n>};

Операция может содержать несколько повторяющихся элементов, для сокращения записи используется множитель, который указывает сколько раз повторяется данный элемент: {4{w}} эквивалентно {w, w, w, w}

Множитель может быть целой, неотрицатеьной константой или константным

выражением. Также в операции могут использоваться внутренние объединения: {{a, b, c}, {3{d, e}}} эквивалентно {a, b, c, d, e, d, e, d, e}

Результат операции слияния может использоваться в любом случае в качестве операндов или в качестве вектора (переменной) которой присваивается значение. Это широко используется для случаев, когда функция должна вернуть несколько значений.

С целью закрепления знаний языка описания аппаратуры, рассмотрим примеры описания ЦУ на языке Verilog.

Пример создания на САПР Quartus II цифрового устройства с использованием языка описания аппаратуры Verilog

Создадим на САПР Quartus II логический элемент 2И-НЕ с помощью языка описания аппаратуры Verilog. Для этого:

Выбрать в главном меню "File\New Project Wizard…" ("Файл\Мастер создания проекта…") (рис. 2.33).

Рис. 2.33

В появившемся окне "New Project Wizard: Directory, Name, Top-Level Entity [page 1 of 5] " (" Мастер создания проекта: Папка, Имя и Модуль верхнего уровня [страница 1 из 5]") щелкнуть по кнопке с тремя точками у верхнего поля ввода. В новом окне "Select Directory" ("Выбрать папку"), переместившись в желаемое место на диске, создать новую папку для вновь создаваемого проекта под именем, например, "ANDNOT2" и " зайти" в неё (папка необходима, поскольку проект содержит около пятидесяти файлов). После этого щелкнуть по кнопке "Отрыть" окна "Select Directory".

Возвратиться в окно "New Project Wizard: Directory, Name, Top-Level Entity [page 1 of 5] " и убедиться в том, что в верхнем поле ввода занесен полный маршрут к созданной папке, а именно, во втором поле – имя проекта, которое совпадает с именем папки, и в третьем (нижнем) поле – имя модуля верхнего уровня, совпадающего с именем папки. Щелкнуть по кнопке " Finish" ("Завершение") (рис. 2.34).

Рис. 2.34

Выбрать в главном меню "File\New…" ("Файл\Новый") (рис. 2.35).

Рис. 2.35

В появившемся окне " New" на закладке "Device Design File" ("Конструкторские файлы устройств") выбрать строку " Verilog HDL File " ("файл на универсальном языке описания аппаратуры Verilog ") (рис. 2.36). Щелкнуть по кнопке "ОК" в нижней части окна.

Рис. 2.36

На рабочем поле приложения появится окно созданного файла с именем в квадратных скобках ["Verilog.v"]. Его расширение ".v" означает, что это " Verilog HDL File ", т.е. файл с языком описания в Verilog (рис. 2.37).

Рис. 2.37

Описать схему 2И-НЕ в verilog HDL (рис. 2.38):

module ANDNOT2(output OUT, input IN1, input IN2);

assign OUT=~(IN1&IN2);

endmodule

Рис. 2.38

Выбрать в главном меню "File\Save As" ("Файл\Сохранить с Новым Именем ").

В появившемся окне "Сохранить как" будет предложено сохранить файл с именем проекта с расширением .v. Следует принять предложение и щелкнуть по кнопке "Сохранить".

Сделаем текущий файл главным файлом проекта, для этого выбираем в главном меню Project/Set As Top Level Entity (рис. 2.39).

Рис. 2.39

Выбрать в главном меню "Assignments\Devise…" ("Назначения\Микросхема…" ) (рис. 2.40).

Рис. 2.40

В открывшемся окне "Devise " в списке "Familiy" ("Семейство") выбрать для нашего примера семейство микросхем MAX3000A. В расположенном ниже списке "Available devices:" ("Доступные микросхемы:") выбрать микросхему, например, EPM3032ALC44-10. Далее нажать на кнопку “Device and Pin Options “ (“устройство и варианты контактов”) (рис. 2.41).

Рис. 2.41

В появившемся окне выбираем закладку “Unused Pins” (“неиспользованные контакты”) и в графе “Reserve all unused pins” (“Для всех неиспользованных контактов ”) выбрать “As input tri-started” (“В качестве входов с высоким входным сопротивлением”) (рис. 2.42). Это обозначает, что неиспользуемые входы будут входами с высоким входным сопротивлением. Это обезопасит микросхему и плату.

Рис. 2.42

Произвести компиляцию проекта, нажав на кнопку “Start Compilation”, находящейся на панели инструментов (рис. 2.43).

Рис. 2.43

После компиляции должно выскочить сообщение о её успешном завершении.

Распределение контактов входов и выходов ЦУ

При создании проекта входы и выходы на ПЛИСе задаются автоматически (программа автоматически определяет контакты и их назначение) и практически всегда находятся не там где нам нужно. Для принудительного назначения контактов входов и выходов необходимо в главном меню выбрать опцию “Assigments/Pins” (“Назначение/Контакты”) (рис. 2.44).

Рис. 2.44

В появившемся окне выбрать на схематичном изображении один из контактов, например, номер 27 (рис. 2.45), и присвоить ему вход IN1. Для этого необходимо 2 раза нажать левой кнопкой мыши на контакт 27, после чего появится окно “Pin Properties” (“Свойства контакта”).

Рис. 2.45

В окне “Pin Properties” (“Свойства контакта”) в списке “Node Name” выбираем интересующий нас вход IN1 и нажимаем “OK” (рис. 2.46).

Рис. 2.46

Аналогично присваиваем контакту №28 (Рис….) IN2 и контакту №6 OUT (рис. 2.47).

Рис. 2.47

Снова производим компиляцию проекта и убеждаемся в её правильном завершении.

Always-блоки, операторы if и case в Verilog

Процесс-блоки (always-блоки)

Блоки подобного типа здесь названы в силу того, что они реализуют некий процесс, который может повторятся многократно. В литературе их часто называют always-блоками по ключевому слову, определяющему такой блок.

Для описания поведенческого блока используется следующий синтаксис:

always @(<sensitivity_list>) <statements>

<sensitivity_list> – это список всех входных сигналов, к которым чувствителен блок. Это список входных сигналов, изменение которых влияет выходные сигналы этого блока. "Always" переводится как "всегда". Такую запись можно прочитать вот так: "Всегда выполнять выражения <statements> при изменении сигналов, описаных в списке чувствительности <sensitivity list>". Если указать список чувствительности неверно, то это не должно повлиять на синтез проекта, но может повлиять на его симуляцию. В списке чувствительности имена входных сигналов разделяются ключевым словом "or": always @(a or b or d) <statements>

Иногда гораздо проще и надежней включать в список чувствительности все сигналы. Это делается так: always @* <statements>

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

reg [3:0] c;always @(a or b or d)beginc = <выражение использующее входные сигналы a,b,d>;end

Синтаксис оператора if

Оператор ветвления if широко применяется для реализации элементов регистровой логики, таких как регистры данных, сдвига, счетчиков, цифровых автоматов и т.д. Синтаксис этого оператора очень похож на синтаксис в языке С. Общий вид оператора выглядит так:

if (<cond_expr1>)

[begin]

<statements>;

[end]

else if (<cond_expr2>)

[begin]

<statements>;

[end]

else

[begin]

<statements>;

[end]

Обязательной ветвью в этом операторе является ветвь после ключевого слова if. Ветви else if и else добавляются если они необходимы. Условные выражения cond_expr принимают значения true (результат cond_expr отличен от нуля) или false (результат равен нулю). Логика выполнения оператора следующая: если выполняется условие cond_expr1 (cond_expr1 != 0), то выполняется ветвь под оператором if, а остальные ветви пропускаются. Когда условие не выполняется (cond_expr1 == 0), осуществляется проверка условия cond_expr2. Ветвей else if в операторе может быть несколько. Если не выполняется предыдущее условие, то выполняется следующее. Когда не выполнилось ни одно из условий, управление передается ветви else (если она есть). Когда эта ветвь отсутствует, осуществляется выход из оператора. Ключевые слова begin end обозначают границы последовательных блоков. Если в ветви только одно выражение, эти ключевые слова можно опустить. Ветви if, else if и else иногда называют параллельными в том смысле, что всегда выполняется только одна из них. Операторы if могут быть вложенными – внутри одной ветви оператора вполне может быть размещен другой оператор if.

Синтаксис операторов case

Синтаксис оператора case выглядит так:

case (<cond_expr>)

<const_cond_1> : <statement>;

<const_cond_2> : <statement>;

* * *

<const_cond_n> : <statement>;

[default : <statement>;]

endcase

В этом операторе результат cond_expr по порядку сравнивается с константными условиями const_cond. В случае совпадения результата с одним из выражений, выполняется выражение statement соответствующее этому константному условию. Если не выполнилось ни одно из условий, то выполняется ветвь под ключевым словом default (если она есть – в противном случае не выполняется ни одно из выражений). Завершается оператор ключевым словом endcase.

← Предыдущая
Страница 1
Следующая →

Скачать

Lek_Kratkie_svedenia_yazyka_Verilog.docx

Lek_Kratkie_svedenia_yazyka_Verilog.docx
Размер: 1.2 Мб

Бесплатно Скачать

Пожаловаться на материал

Обратите внимание – не язык программирования Verilog, а описание цифровых схем на языке Verilog.

У нас самая большая информационная база в рунете, поэтому Вы всегда можете найти походите запросы

Искать ещё по теме...

Похожие материалы:

Теории макроэкономического равновесия

Основные макроэкономические школы. Понятие макроэкономического равновесия, его виды. Основные макроэкономические теории экономического равновесия

Образцы сочинения по Русском языку

Что важнее: красота душевная или физическая. Связь таланта и трудолюбия. Трагедия одинокой души. Взаимоотношения личности и коллектива. Какие нравственные черты вырабатывает спорт у человека. О нравственных калеках. О силе доброго слова Что лежит в основе воспитанности человека. Что влияет на человека в ситуации нравственного выбора. Как противостоять низости и подлости. Нужно учиться культуре радости. Душевная чуткость человека и доброта

Анафилактический шок. Реферат

Анафилактический шок как иммунная реакция организма Клиническая картина Лечение

Патопсихология

Патопсихология – отрасль психологической науки, относящаяся к прикладным областям знания.

Вопросы к зачету по дисциплине «История науки и техники»

Сохранить?

Пропустить...

Введите код

Ok