Язык описания аппаратуры Verilog
Особенности языка Verilog 1.Вычисления управляются потоком данных 2.Есть поддержка параллельных процессов, событий 3.Существует понятие модельного времени 4.Присутствуют типы данных, отражающие схемотехнические понятия (сила сигнала, уровень сигнала, регистр, проводник и т.д.)
Иерархия уровней моделирования Системный уровень Уровень регистровых передач (RTL) Вентильный уровень (логический) Уровень переключателей (схемотехнический) Компонентный уровень
Области применения языка Verilog 1. Проектирование СБИС заказных микросхем (ASIC) конфигураций перепрограммируемых логических ИС 2. Верификация на различных уровнях (вентильном, RTL)
История создания языка Verilog (Automated Integrated Design Systems/Gateway Design Automation) Verilog (Cadence Design Systems) Verilog-95 (IEEE , Open Verilog International) Verilog-2001 (IEEE , Open Verilog International) Verilog-2005 (IEEE , Accellera) Время IEEE 1364 IEEE P Фил Мурби (Phil Moorby)
Коммерческие симуляторы СимуляторКомпанияПоддерживаемые HDL Active-HDL/RivieraAldecVHDL-2002, V2001, SV2005 ISE SimulatorXilinxVHDL-93, V2001 ModelSimMentor GraphicsVHDL-2002, V2001, SV2005 NC-Verilog/Incisive Cadence Design Systems VHDL-2002, V2001, SV2005 Quartus II SimulatorAlteraVHDL-1993, V2001, SV2005 VCSSynopsysVHDL-2002, V2001, SV2005 Verilogger Extreme, Verilogger Pro SynaptiCADV2001, V1995 Verilog-XLCadenceV1995 VeritakSugawara SystemsV2001 Vxxxx – Verilog-xxxx, SVxxxx – SystemVerilog-xxxx, VHDL = VHDL
Лексические элементы // Идентификаторы reg store; reg _store_; reg 1store; reg store_1; reg Store_1; reg store$; reg $store; /* Расширенные идентификаторы */ reg \1st(*)re ; reg \store1 ; // равно reg store1;
Лексические элементы // Символьные и строковые литералы A // символ 0010 // строка из 4 символов N123FE // строка из 6 символов N 1 // переносы не допустимы 2 3 G // Константы parameter tick=10; // допускается изменение из внешнего модуля `define ONE 1b1; // изменения не допускаются
Представление чисел /* - длина числа в битах - основание системы исчисления: b, o, h, d префикс s для чисел со знаком */ b10_10 16hFF34 1b hX 145e4
Алфавит моделирования {0, 1, Z, X} 0 – логический ноль или результат сравнения false 1 – логическая единица или результат сравнения true Z – состояние высокого импеданса Х – неопределенное состояние Strength1: supply1, strong1, pull1, large1, weak1, medium1, small1, highz1 Strength0: supply0, strong0, pull0, large0, weak0, medium0, small0, highz0 Силы сигналов
Типы данных (соединения) wire или tri – простой провод (соединение, связь, цепь); wor или trior – монтажное ИЛИ; wand или triand – монтажное И; tri0 – привязка к 0 в третьем состоянии; tri1 – привязка к 1 в третьем состоянии; supply0 – постоянный 0 (сила источника питания); supply1 – постоянный 1 (сила источника питания); trireg – сохранение последнего значения сигнала на шине при установлении драйверов в третье состояние. wire a, e, d; wire [3:0] b; wire (strong1, weak0) [32:0] c;
Типы данных (переменные) reg – вектор любого размера; integer – 32-разрядная переменная со знаком; time – 64-разрядная переменная со знаком, применяется встроенными функциями для моделирования времени; real или realtime – переменная с плавающей запятой. reg A; reg [100:0] B; reg [31:0] mem[0:255]; // память, 32 слова по 256 бит integer C; real D;
Арифметические операции `+ – сложение = 4 `- – вычитание 10 – 9 = 1 `/ – деление 10 / 3 = 3 `* – умножение 5 * 3 = 15 `% – модуль 2 % 3 = 2 `** – возведение в степень 2 ** 4 = 16 `+, `- – унарные операции -4b1011 = 4b0101
Логические операции `&& – логическое И 4b1011 && 4b0010 = 1b1 4b1011 && 4b001X = 1bX `|| – логическое ИЛИ 4b1011 || 4b0010 = 1b1 4b101X || 4b0010 = 1bX `! – логическое отрицание 4b1011 = 1b0
Поразрядные логические операции `& – поразрядное И 4b1011 & 4b0010 = 4b0010 `| – поразрядное ИЛИ 4b1011 | 4b0010 = 4b1011 `~ – поразрядная инверсия ~4b1011 = 4b0100 `^ – исключающее ИЛИ 4b1011 ^ 4b0010 = 4b1001 `~^ или `^~ – исключающее ИЛИ-НЕ 4b1011 ^ 4b0010 = 4b0110
Операции отношения `< – меньше 4b1011 1b0 `> – больше 4b1011 > 4b0010 => 1b1 `== – равно 10 == 10 => true `!= – не равно 10 != 10 => false `>= – больше либо равно `
Операции свертки `& – И всех разрядов &4b1101 => 1b0 `| – ИЛИ всех разрядов |4b1101 => 1b1 `~| – ИЛИ-НЕ всех разрядов ~|4b1101 => 1b0 `~& – И-НЕ всех разрядов ~&4b1101 1b1 `^ – исключающее ИЛИ всех разрядов ^4b1101 => 1b1 `~^ – исключающее ИЛИ-НЕ всех разрядов ~^4b1101 => 1b0
Операции сдвига `> – логический сдвиг вправо 4b11_01 >> 2 => 4b00_11 `> – арифметический сдвиг вправо 4sb1_101 >> 1 => 4sb1_110
Операторы конкатенации и повторения {переменная1, переменная2, … переменнаяN} {a[3:0], b[10:7]} => вектор длиной 8 бит {3b100, 2b11} => 5b10011 {N{переменная}} {4{2b01}} => 8b {3{a}} => {a, a, a} {4{a,b}} => {a, b, a, b, a, b, a, b}
Операторы выбора ? : Amax = C > D ? C : D; if ( ) else if (index > 0) if (rega > regb) result = rega; else // относится к ближайшему if result = regb;
reg [31:0] instruction; reg [2:0] aluOp; casez (instruction[31:26]) 6'b00????: aluOp = 3'b000; 6'b100???: aluOp = 3'b001; 6'b101???: aluOp = 3'b010; 6'b1100??: aluOp = 3'b001; 6'b11010?: aluOp = 3'b100; 6'b110110: aluOp = 3'b101; endcase Операторы case, casex, casez reg [1:0] sel; reg [15:0] in0, in1, in2, in3, out; case (sel) 2'b00: out = in0; 2'b01: out = in1; 2'b10: out = in2; 2'b11: out = in3; default out = 16'bx; endcase reg [1:0] sel, ag; reg [15:0] in0, in1, in2, in3, out; casex (sel) 2'b00: out = in0; 2'b01: out = in1; 2'b0x, 2'b0z: out = ag ?16'bx : 16'b0; 2'b10: out = in2; 2'b11: out = in3; 2'bx0, 2'bz0: out = ag ? 16'bx: 16'b0; default out = 16'bx; endcase
Оператор цикла repeat parameter size = 8, longsize = 16; reg [size:1] opa, opb; reg [longsize:1] result; begin: mult reg [longsize:1] shift_opa, shift_opb; shift_opa = opa; shift_opb = opb; result = 0; repeat (size) begin if (shift_opb[1]) result = result + shift_opa; shift_opa = shift_opa > 1; end
Оператор цикла while begin: count1s reg [7:0] tempreg; count = 0; tempreg = rega; while (tempreg) begin if (tempreg[0]) count = count + 1; tempreg = tempreg >> 1; end
Оператор цикла for begin :init_mem reg [7:0] tempi; for (tempi = 0; tempi < memsize; tempi = tempi + 1) memory[tempi] = 0; end begin : search_first reg [7:0] tempi; for (tempi = 0; tempi < memsize; tempi = tempi + 1) begin: search if (memory[tempi] == 0) disable search; end
Присваивание значений Виды присваиваний Непрерывные (соединения) Процедурные (соединения, переменные) Блокирующие `= Не блокирующие `
Непрерывное присваивание wire [15:0] sum, a, b; wire cin, cout; assign {cout, sum} = a + b + cin;
Процедурное присваивание, LHS delay * module block; reg a, b, c, d, e, f; initial begin #10 a = 1; // модельное время = 10 #2 b = 0; // модельное время = 12 #4 c = 1; // модельное время = 16 end initial begin #10 d
Процедурное присваивание, LHS delay
Процедурное присваивание, RHS delay * module block; reg a, b, c, d, e, f; initial begin a = #10 1; // модельное время = 10 b = #2 0; // модельное время = 12 c = #4 1; // модельное время = 16 end initial begin d
Процедурное присваивание, RHS delay
(часть 1) :vpi_time_precision - 11; :vpi_module "system"; :vpi_module "v2005_math"; :vpi_module "va_math"; S_ scope module, "block1" "block1" 2 3;.timescale ; v _0.var *"_s0", 0 0; Local signal v006864F0_0.var *"_s1", 0 0; Local signal v _0.var *"_s2", 0 0; Local signal v006865A0_0.var "a", 0 0; v006865F8_0.var "b", 0 0; v _0.var "c", 0 0; v006866A8_0.var "d", 0 0; v _0.var "e", 0 0; v _0.var "f", 0 0; Процедурное присваивание, RHS delay (часть 2).scope S_ ; T_0 ; %set/v v _0, 1, 1; %movi 8, 1000, 11; %ix/get 0, 8, 11; %delayx 0; %load/v 8, v _0, 1; %set/v v006865A0_0, 8, 1; %set/v v006864F0_0, 0, 1; %movi 8, 200, 9; %ix/get 0, 8, 9; %delayx 0; %load/v 8, v006864F0_0, 1; %set/v v006865F8_0, 8, 1; %set/v v _0, 1, 1; %movi 8, 400, 10; %ix/get 0, 8, 10; %delayx 0; %load/v 8, v _0, 1; %set/v v _0, 8, 1; %delay 100, 0; %end;.thread T_0;.scope S_ ; (часть 3) T_1 ; %ix/load 0, 1; %assign/v0 v006866A8_0, 1000, 1; %ix/load 0, 1; %assign/v0 v _0, 200, 0; %ix/load 0, 1; %assign/v0 v _0, 400, 1; %end;.thread T_1;.scope S_ ; T_2 ; %vpi_call 2 18 "$dumpfile", "block.vcd"; %vpi_call 2 19 "$dumpvars"; %end;.thread T_2;
Управление задержками #10 rega = regb; #d rega = regb; // d определен как параметр #((d+e)/2) rega = regb; #regr regr = regr + 1; // задержка равна содержимому regr reg enable, a, b; initial begin wait (!enable) #10 a = 1; // модельное время = 110 #10 b = 1; // модельное время = 120 end initial #100 enable = 0;
Управление задержками a = #5 b; // эквивалентно: begin temp = b; #5 a = temp; end a clk) b; // эквивалентно: begin temp = clk) a = temp; end
Параллельные и последовательные блоки begin #10 a = 1; // #10 #20 a = 0; // #30 end r = 1; #250 r = 0; end clock) q = 0; // posege clock) q = 1; // следующий end // posege fork #30 a = 0; // #30 #10 a = 1; // #10 join clock) q = clock) w = 1; join join areg = breg; end
Системные функции $monitor (строка форматирования, список переменных); $monitor(%h, output); $display и $write (строка форматирования, список переменных); $display(Output in %h hex and %d decimal, output, output); $finish #1000 $finish; $dumpfile(filename.vcd); // Value Change Dump $dumpvars; $time // текущее модельное время
Модульная структура // Файл lazy.v: module lazy (out, in, clk); parameter size = 1, delay = 1; input [0:size-1] in; input clk; output [0:size-1] out; reg [0:size-1] out; clk) #delay out = in; endmodule // Файл main.v: `include lazy.v module main; reg clk; wire [1:10] out_a, in_a; wire [1:5] out_b, in_b; lazy #(10, 15) mod_a (out_a, in_a, clk); lazy mod_b (out_b, in_b, clk); #800 $finish; always #100 clk = ~clk; initial begin clk = 0; in_a = 10b11111_01011; in_b = 5b10101; end endmodule
Уровень переключателей
Структурная модель инвертора module inv_sw (out, in); output out; input in; supply1 power; supply0 ground; pmos (out, power, in); nmos (out, ground, in); endmodule module stimulus; regin; wireout; inv_sw I0 (out, in); initial begin #2 $display (in - out"); forever #5 $display ("%b - %b", in, out); end initial begin #5 in=1'b1; #5 in=1'b0; #5 in=1'b1; #5 in=1'b0; #5 in=1'b1; #5 in=1'b0; #5 in=1'b1; #5 in=1'b0; #5 $finish; end endmodule /* in - out */
module mux(in0, in1, in2, in3, sel, out); output [15:0] out; reg [15:0] out; input [1:0] sel; input [15:0] in0, in1, in2, in3; begin case (sel) 2'b00: out = in0; 2'b01: out = in1; 2'b10: out = in2; 2'b11: out = in3; default out = 16'bx; endcase end endmodule Поведенческая модель мультиплексора module main(); reg [1:0] ctl; wire [15:0] A, B, C, D; wire [15:0] Y; assignA = 'h11; assignB = 'h22; assignC = 'h33; assignD = 'h44; mux mux1(A, B, C, D, ctl, Y); initial begin #10 ctl = 2'b00; #10 ctl = 2'b01; #10 ctl = 2'b10; #10 ctl = 2'b11; #10; $finish; end endmodule
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use std.textio.all; entity main is end entity; architecture arch1 of main is signal A : unsigned(15 downto 0); signal B : unsigned(15 downto 0); signal C : unsigned(15 downto 0); signal D : unsigned(15 downto 0); signal Y : unsigned(15 downto 0); signal ctl : unsigned(1 downto 0) := "00"; component mux is port ( in0 : in unsigned(15 downto 0); in1 : in unsigned(15 downto 0); in2 : in unsigned(15 downto 0); in3 : in unsigned(15 downto 0); VL_out : out unsigned(15 downto 0); sel : in unsigned(1 downto 0) ); end component; Модель мультиплексора на VHDL, часть 1 begin mux1: mux port map ( in0 => A, in1 => B, in2 => C, in3 => D, VL_out => Y, sel => ctl ); process is begin wait for 10 ns; ctl
entity mux is port ( in0 : in unsigned(15 downto 0); in1 : in unsigned(15 downto 0); in2 : in unsigned(15 downto 0); in3 : in unsigned(15 downto 0); VL_out : out unsigned(15 downto 0); sel : in unsigned(1 downto 0) ); end entity; architecture arch1 of mux is signal VL_out_Reg : unsigned(15 downto 0); begin VL_out
Преимущества и недостатки + Прост для изучения + Активно поддерживается сообществом + Существует богатая инструментальная и библиотечная база + Подходит для синтеза FPGA и ASIC, т.е. создавался специально для вентильного уровня + Функционал языка расширяем при помощи VPI (ранее PLI) - Слабые возможности для проектирования на системном уровне - Сложности в использовании библиотек и вообще больших проектов - Более медленный в сравнении с VHDL, так как является интерпретируем языком
Just a test