Лекция 2 - Основы языка Verilog (Слайды лекций)
Описание файла
Файл "Лекция 2 - Основы языка Verilog" внутри архива находится в папке "Слайды лекций". PDF-файл из архива "Слайды лекций", который расположен в категории "". Всё это находится в предмете "программируемые логические интегральные схемы" из 8 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст из PDF
Лекция 2Программируемые логическиеинтегральные схемыОсень 2016План лекции••••Модули и шиныСтруктурное описание модулейФункциональное описание модулейБлокирующее и неблокирующееприсваивание• Параметризованные модулиЛогические значения• 0 — логический ноль• 1 — логическая единица• x — неопределённое значение– например, в неинициализированном регистре• z — состояние высокого импеданса– оно нужно в основном для управления шиной, ккоторой подключено много независимых устройств– в ближайшее время это значение нам непонадобитсяЛогические значения• Что мы строим: схему, между узлами которой вреальном времени передаются логические значения• 0 и 1 — это конкретные уровни напряжения• x — это абстракция: уровень напряжениясоответствующий неизвестному логическомузначениюVerilog: модули и шины• «Строительный блок» языка Verilog – модуль• Входы и выходы могут быть проводами ирегистрами (wire и reg), а также могут бытьобъявлены как массивы ([7:0] bus, {a,b,c})• Массив проводов – это шина:Verilog: определение модуля• Лучше всего описывать модуль в отдельном файле срасширением .v и названием, совпадающим сназванием модуляФайл mod.v:module mod(a, b, c);input wire a;input wire [1:0] b;output reg [2:0] c;// descriptionendmodule// EMPTY LINE!(первый вариант)Verilog: определение модуля• Лучше всего описывать модуль в отдельном файле срасширением .v и названием, совпадающим сназванием модуляФайл mod.v:module mod(input wire a,input wire [1:0] b,output reg [2:0] c);// descriptionendmodule// EMPTY LINE!(второй вариант)Verilog: правила соединения портов• Входы блока: внутри блока входы могут быть толькопроводами (wire), а вне блока могут быть какпроводами, так и регистрами(reg)• Выходы блока: внутри блока выходы могут быть какпроводами, так и регистрами, а вне блока толькопроводами• Смешанные порты: внутри и вне блока могут бытьтолько проводамиVerilog: способы описания модуля• Обычно различают два подхода к описанию модуля:– структурный: явно описать экземпляры (instances)модулей и связи между ними– функциональный: без явного описания структуры задатьповедение (реализуемые функции) модулей и связимежду нимиСтруктурное описаниеФункциональное описаниеVerilog: структурное описание –экземпляры модулейmodule m(input i1, i2, i3, output o1, o2, o3);wire w;m1 upleft(.i1(i1), .i2(i2), .o(w));m1 downleft(.i1(i2), .i2(i3), .o(o3));m2 right(.i1(w), .i2(o3), .o1(o1), .o2(o2));endmoduleВсе встречающиеся в описании имена (в том числе провода: wire) должны бытьопределены перед первым использованиемVerilog: структурное описание –примитивыmodule m(…);…not(o1,i1);or(o2,i1,…,in);and(o3,i1,…,in);…endmoduleVerilog: структурное описание –примерmodule dff_from_nandm();wire Q, Q_bar;reg D, CLK;nandnandnandnandU1(X,D,CLK);U2(Y,X,CLK);U3(Q,Q_bar,X);U4(Q_bar,Q,Y);endmoduleVerilog: структурное описание –непрерывное присваиваниеmodule trivial(input i, output o);assign o = i;endmoduleassign «провод» = «выражение»;В любой момент времени (с некоторой задержкой при изменении значения) напроводе должно быть значение выраженияVerilog: выраженияЧто можно использовать при написании выражений:• логические операции– например, a && b — логическое И• арифметические операции– например, a + b — это сложение двух чисел одинаковойбитности с переполнением• побитовые операции– например, a & b — это побитовое И двух битовых массивоводинаковой длины• отношения– например, a < b возвращает логическую 1, если число,двоичная запись которого есть a, меньше такового для b, илогический 0 иначеVerilog: выраженияЧто можно использовать при написании выражений:• Конкатенации– например, {a, b} — битовый массив, составленный из a и b• редукции– например, &a — логическая 1, если все биты a — единицы, илогический 0 иначе• условия– например, cond ? a : b работает как в C++; cond должноиметь логическое значение, а a и b должны иметьодинаковое число бит• константы– например, 0 — это логический ноль, а 5’b00110 —пятибитная двоичная запись числа 6(полный список операций можно найти в интернете)Verilog: функциональное описание –always-блок• Он выглядит так:always @(a or posedge b or negedge c)// statement• В аргументе перечисляются места (например, провода), приизменении сигнала в которых должно производиться какое-тодействие• В данном случае:– при изменении логического значения в a,– а также когда в b возникает передний фронт,– а также когда в c возникает задний фронт••Действие перезаписывает значения сигналов модуляПосле выполнения действия получившиеся значениясохраняются в проводах до следующего выполнения блокаVerilog: функциональное описание –always-блок• Он выглядит так:always @(a or posedge b or negedge c)begin//sequence of statementsend• Действий можно задавать много, и тогда их обычнымобразом нужно соединить в составное действиеVerilog: функциональное описание –always-блок• Он выглядит так:always @(a, posedge b, negedge c)begin//sequence of statementsend• В какой-то момент разработчики стандарта Verilog поняли, что“or” писать неудобно, так что разрешили вместо него ставитьзапятую• Какие же действия можно писать в always-блоке?Verilog: функциональное описание –блокирующие присваиванияalways @(a, b)beginb = c;a = b;c = a;end• Последовательно делается следующее:– в b выставляется начальное значение из c– в a выставляется изменённое значение из b– в c выставляется изменённое значение из a• Блокирующее присваивание моделирует последовательноевыполнение команд: пока присваивание не выполнено,следующие команды не выполняются (но в конечном итогестроится схема, просто она имеет хитрую структуру с блокамипамяти)Verilog: функциональное описание –неблокирующие присваиванияalways @(a, b)beginb <= c;a <= b;c <= a;end• Одновременно делается следующее:– в b выставляется начальное значение из c– в a выставляется начальное значение из b– в c выставляется начальное значение из a• Вообще говоря, одновременности не бывает, но вреальной схеме эти действия будут выполнены близкопо времени, и блоки памяти будут организованы так,чтобы выставлялись именно начальные значенияVerilog: регистры(переменные)• При выставлении сигналов в схеме могут понадобитьсядополнительные (неявные) ячейки памяти• Чтобы компилятор имел возможность распознать такие места ипо необходимости синтезировать дополнительную память, вVerilog вводится понятие регистра или переменной(терминология менялась в стандарте)• Всё, что появляется в присваиваниях (=, <=) слева, должно бытьобъявлено как переменная:reg a, b, c;always @(a, b)beginb = c; a = b; c = a;end• Всё остальное может быть объявлено переменнойVerilog: регистры(переменные)• Имя не может одновременно быть переменной ипроводом• В некоторых случаях (например, при встрече в левойчасти непрерывного присваивания) имя не может бытьпеременной• Все входы и выходы являются проводами по умолчанию• Все входы обязаны быть проводами• Выходы можно определять как переменные: достаточно– дописать в начале модуля reg «имя выхода»; или– при определении выхода написатьoutput reg «имя выхода»вместоoutput «имя выхода»Verilog: функциональное описание –условные переходыif(cond) stmt;else stmt;case(a)3'b000: stmt;3'b010: stmt;3'b011: stmt;default: stmt;endcase• Условные инструкции тоже можно писать• Как и инструкцию switch-case• Они интерпретируются обычным образом(примерно как в C++)Verilog: функциональное описание –примерыmodule register3(input load, reset, clock,input [2:0] in,output reg [2:0] out);always @(posedge clock, negedge reset)if(~reset) out <= 0;else if(~load) out <= in;endmoduleVerilog: функциональное описание –примерыmodule adder(input [7:0] a, b,output [7:0] sum);assign sum = a + b;endmoduleVerilog: параметрыmodule register3(input load, reset, clock,input [2:0] in,output reg [2:0] out);Иногда бывает нужно написатьнесколько невероятно похожих, но всёже разных модулейalways @(posedge clock, negedge reset)if(~reset) out <= 0;else if(~load) out <= in;endmodulemodule register5(input load, reset, clock,input [4:0] in,output reg [4:0] out);always @(posedge clock, negedge reset)if(~reset) out <= 0;else if(~load) out <= in;endmoduleVerilog: параметры• Чтобы описать сразу всё разнообразие модулей,отличающихся только какими-то константнымизначениями (например, регистры — размеромшины), достаточно описать один модуль ссоответствующими параметрами:module register#(parameter Width = 5)( input load, reset, clock,input [Width-1:0] in,output reg [Width-1:0] out);always @(posedge clock, negedge reset)if(~reset) out <= 0;else if(~load) out <= in;endmoduleVerilog: параметры• Чтобы описать сразу всё разнообразие модулей,отличающихся только какими-то константнымизначениями (например, регистры — размеромшины), достаточно описать один модуль ссоответствующими параметрами:Или так:module register(load, reset, clock, in , out);parameter Width = 5;input load, reset, clock;input [Width-1:0] in;output reg [Width-1:0] out;always @(posedge clock, negedge reset)if(~reset) out <= 0;else if(~load) out <= in;endmoduleVerilog: параметрыparameter Width = 5;• Параметр можно писать вместо числа почти везде вмодуле (нельзя — в константах на месте размера)• Значение параметра по умолчанию указывается приего определении (здесь — 5)• Экземпляр параметризованного модуля может бытьвызван двумя способами:– с явным указанием параметров (указание параметров— такое же, как и входов-выходов)register r #(.Width(3)) («arguments»)– без указания параметров — тогда подставляетсязначение по умолчаниюregister r («arguments»)Verilog: реальные примерыVerilog: реальные примеры –оперативная памятьVerilog: реальные примеры –оперативная память// ram.v// RAM for the single-cycle processormodule ram #(parameter N = 6, M = 32)( input wireclk,input wirewe,input wire [N-1:0] adr,input wire [M-1:0] din,output reg [M-1:0] dout);reg [M-1:0] mem[2**N-1:0];always @(posedge clk)if (we) mem[adr] <= din;assign dout = mem[adr];endmoduleVerilog: реальные примеры –регистровый файлVerilog: реальные примеры –регистровый файл// regfile.v// Register file for the single-cycle processormodule regfile(input wireclk,input wirewe3,input wire [4:0] ra1, ra2, wa3,input wire [31:0] wd3,output reg [31:0] rd1, rd2);reg [31:0] rf[31:0];always @(posedge clk)if (we3) rf[wa3] <= wd3;assign rd1 = (ra1 != 0) ? rf[ra1] : 0;assign rd2 = (ra2 != 0) ? rf[ra2] : 0;endmoduleVerilog: реальные примеры –арифметико-логическое устройствоVerilog: реальные примеры –арифметико-логическое устройство// alu.v// ALU for the single-cycle processormodule alu(input wire [31:0] a, b,input wire [2:0] alucontrol,output reg [31:0] result,output regzero);reg [31:0] condinvb, sum;assign condinvb = alucontrol[2] ? ~b : b;assign sum = a + condinvb + alucontrol[2];always @(*)case (alucontrol[1:0])2'b00: result = a & b;2'b01: result = a | b;2'b10: result = sum;2'b11: result = sum[31];endcaseassign zero = (result == 32'b0);endmodule.