Скачиваний:
9
Добавлен:
31.05.2023
Размер:
124.2 Кб
Скачать
  1. Понятие сигнал (signal) на языке описания цифровых устройств Verilog.

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

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

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

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

wire b; //назначить проводу сигнал b assign 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; //восьмибитная шина e wire [0:255] f; //256-ти битная шина f

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

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

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

wire [7:0] f; //восьми битная шина f(испр в лекц) wire 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.

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

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

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

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

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

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

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

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

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

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

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

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

Числа

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

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

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

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

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

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

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

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

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

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

Первое поле size содержит десятичные цифр и указывает разрядность константы в битах. Если разрядность не определена, то разрядность принимается по умолчанию 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-состояние или отсутствие источника (драйвера). Имеется возможность сокращать запись числа, например: 8’b1 будет эквивалентно записи 8’b11111111, но запись 8’b01 будет эквивалентна записи 8’b00000001. Поэтому такие сокращенные записи могут мешать читаемости кода и употреблять их без надобности

не следует.

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

Ключевые слова

module

input

output

reg

wire

assign

always

initial

if

else

case

switch

while

for

и тд

  1. Структура построения модуля на языке описания цифровых устройствVerilog.

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

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;

  1. Синтез шифратора с 8 входами и на языке Verilog.

На поведенческом уровне

module ex_6 (

input [7:0]a,

output [2:0]b

)

always @*

begin

case( a )

8’b00000001: b = 3’b000;

8’b00000010: b = 3’b001;

8’b00000100: b = 3’b010;

8’b10000000: b = 3’b111;

endcase

end

endmodule

Второй вариант

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

  1. Синтез мультиплексора с 4-я входами и на языке Verilog.

На поведенческом уровне

module ex_7 (

input [3:0]in, [1:0]s,

output out

)

always @*

begin

case( s )

2’b00: out = in[0];

2’b01: out = in[1];

2’b10: out = in[2];

2’b11: out = in[3];

endcase

end

endmodule

На поведенческом (второй вариант)

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

На логическом

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

  1. Синтез однобитного сумматора на языке Verilog.

На поведенческом уровне

module ex_8(

input a, b;

output [1:0]c

)

assign c = a + b; // или assign {c_out, c} = a+b; (c_out и по одному биту)

endmodule

На логическом

module sum(

input a, b,

input c_in,

output sum,

output c_out

);

wire s1, s2, s3;

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

AND2 my_and_1(.IN1(a), .IN2(b), .OUT(s2));

AND2 my_and_2(.IN1(s1), .IN2(c_in), .OUT(s3));

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

OR2 my_xor_3(.IN1(s3), .IN2(s2), .OUT(c_out));

endmodule

  1. Синтез n-битного сумматора с последовательным переносом на языке 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

module adder4(

input [3:0]a, [3:0]b,

input c_in,

output [3:0]sum,

output c_out

);

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

  1. Синтез модуля на языке Verilog, который одновременно складывает и вычитает два числа.