Wykład 5. Języki Opisu Sprzętu. Prowadzący: dr inż. Andrzej Skoczeń Współrzędne: D , tel. w ,

Podobne dokumenty
Wykład 4. Języki Opisu Sprzętu. Prowadzący: dr inż. Andrzej Skoczeń Współrzędne: D , tel. w ,

Wykład 4. Języki Opisu Sprzętu

Projektowanie Scalonych Systemów Wbudowanych VERILOG

Język HDL - VERILOG. (Syntetyzowalna warstwa języka) Hardware Description Language Krzysztof Jasiński PRUS PRUS

Laboratorium Podstaw Techniki Cyfrowej

Programowalne układy logiczne kod kursu: ETD Układy kombinacyjne, przypisania, blokujące i nieblokujące cz.2 W

Przykładowe pytania z części PSPICE. 1. Podaj zasady tworzenia pliku symulacyjnego. 2. Czy składnia PSPICE jest czuła na wielkość liter? 3.

Język HDL - VERILOG. (Syntetyzowalna warstwa języka) Hardware Description Language Krzysztof Jasiński PRUS PRUS

Mikrokontroler ATmega32. Język symboliczny

Systemy wbudowane. Projektowanie systemów wbudowanych na bazie układów CPLD/FPGA Język opisu sprzętu Verilog cz.1

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 12 - sem.iii. M. Czyżak

Programowalne układy logiczne kod kursu: ETD Podstawy języka Verilog W

Wykład 3. Języki Opisu Sprzętu. Prowadzący: dr inż. Andrzej Skoczeń Współrzędne: D , tel. w ,

Pętle i tablice. Spotkanie 3. Pętle: for, while, do while. Tablice. Przykłady

Opis: Instrukcja warunkowa Składnia: IF [NOT] warunek [AND [NOT] warunek] [OR [NOT] warunek].

Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory

Aby w pełni przetestować układ o trzech wejściach IN_0, IN_1 i IN_2 chcemy wygenerować wszystkie możliwe kombinacje sygnałów wejściowych.

Podstawy Programowania C++

Pojedyncze wartości zadeklarowanego typu Ustawiane przed rozpoczęciem symulacji bez moŝliwości

1 Podstawy c++ w pigułce.

Wykład 7. Języki Opisu Sprzętu. Prowadzący: dr inż. Andrzej Skoczeń. Obsługa plików. Składnia Veriloga: Komórki prymitywne użytkownika

Literatura. adów w cyfrowych. Projektowanie układ. Technika cyfrowa. Technika cyfrowa. Bramki logiczne i przerzutniki.

Projektowanie układów VLSI-ASIC techniką od ogółu do szczegółu (top-down) przy użyciu pakietu CADENCE

Układy cyfrowe w Verilog HDL. Elementy języka z przykładami. wersja: cz.3

AHDL - Język opisu projektu. Podstawowe struktury języka. Komentarz rozpoczyna znak i kończy znak %. SUBDESIGN

Podstawy programowania w języku C

Podstawy programowania. Wykład: 4. Instrukcje sterujące, operatory. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Logika Temporalna i Automaty Czasowe

Operacje wykonywane są na operandach (argumentach operatorów). Przy operacji dodawania: argumentami operatora dodawania + są dwa operandy 2 i 5.

Języki programowania C i C++ Wykład: Typy zmiennych c.d. Operatory Funkcje. dr Artur Bartoszewski - Języki C i C++, sem.

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Podstawy programowania w języku C i C++

Tranzystor JFET i MOSFET zas. działania

Projektowanie scalonych systemów wbudowanych VERILOG. VERLIOG - historia

Automat skończony FSM Finite State Machine

Instrukcje sterujące. Programowanie Proceduralne 1

Informatyka I. Wykład 3. Sterowanie wykonaniem programu. Instrukcje warunkowe Instrukcje pętli. Dr inż. Andrzej Czerepicki

Synteza logiczna APSC

1. ISE WebPack i VHDL Xilinx ISE Design Suite 10.1 VHDL Tworzenie projektu Project Navigator Xilinx ISE Design Suite 10.1 File

Podstawy programowania skrót z wykładów:

Modelowanie liczników w języku Verilog i ich implementacja w strukturze FPGA

Modelowanie złożonych układów cyfrowych (1)

Część 4 życie programu

Wykład 2. Języki Opisu Sprzętu. Prowadzący: dr inż. Andrzej Skoczeń Współrzędne: D , tel. w ,

Język C - podstawowe informacje

Podstawowe operacje arytmetyczne i logiczne dla liczb binarnych

/* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include <aduc834.h>

Laboratorium przedmiotu Technika Cyfrowa

Instrukcje warunkowe i skoku. Spotkanie 2. Wyrażenia i operatory logiczne. Instrukcje warunkowe: if else, switch.

bocznej Tabela stanów sterownika Światła na drodze:

Pętla for. Wynik działania programu:

JAVA. Platforma JSE: Środowiska programistyczne dla języka Java. Wstęp do programowania w języku obiektowym. Opracował: Andrzej Nowak

Operatory. Operatory bitowe i uzupełnienie informacji o pozostałych operatorach. Programowanie Proceduralne 1

Języki projektowania HDL

Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1

LABORATORIUM TECHNIKA CYFROWA LICZNIKI I REJESTRY. Rev.1.1

Podstawy Programowania Podstawowa składnia języka C++

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Podstawy programowania. 1. Operacje arytmetyczne Operacja arytmetyczna jest opisywana za pomocą znaku operacji i jednego lub dwóch wyrażeń.

Wykład 2 Składnia języka C# (cz. 1)

1 Wstęp. 2 Proste przykłady. 3 Podstawowe elementy leksykalne i typy danych. 6 Opis strukturalny. 7 Moduł testowy (testbench)

1 Podstawy c++ w pigułce.

Poradnik programowania procesorów AVR na przykładzie ATMEGA8

System operacyjny Linux

Laboratorium Projektowania Systemów VLSI-ASIC Katedra Elektroniki Akademia Górniczo-Hutnicza

(przykład uogólniony)

Architektura systemów komputerowych Laboratorium 13 Symulator SMS32 Operacje na bitach

Język Verilog w projektowaniu układów FPGA

Skrypty i funkcje Zapisywane są w m-plikach Wywoływane są przez nazwę m-pliku, w którym są zapisane (bez rozszerzenia) M-pliki mogą zawierać

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

Logika Temporalna i Automaty Czasowe

Mikrooperacje. Mikrooperacje arytmetyczne

Układy reprogramowalne i SoC Język VHDL (część 4)

Wydział Zarządzania AGH. Katedra Informatyki Stosowanej. Podstawy VBA cz. 1. Programowanie komputerowe

Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227 WYKŁAD 7 WSTĘP DO INFORMATYKI

Wykład 2. Informatyka Stosowana. 8 października 2018, M. A-B. Informatyka Stosowana Wykład 2 8 października 2018, M. A-B 1 / 41

Krótkie wprowadzenie do ModelSim i Quartus2

Układy arytmetyczne. Joanna Ledzińska III rok EiT AGH 2011

Stałe definiuje się używając funkcji define. Przykład: define( PODATEK, 22); define( INSTALACJAOS, 70); define( MS, Microsoft );

Instrukcje sterujące. wer. 11 z drobnymi modyfikacjami! Wojciech Myszka :53:

LEKCJA. TEMAT: Funktory logiczne.

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk

Technika cyfrowa Synteza układów kombinacyjnych

Szkoła programisty PLC : sterowniki przemysłowe / Gilewski Tomasz. Gliwice, cop Spis treści

Bloki anonimowe w PL/SQL

Arytmetyka liczb binarnych

Verilog HDL. Język Opisu Sprzętu Hardware Description Language Część I. Elementy języka. dr inż. Paweł Tomaszewicz H D L

Wstęp do informatyki- wykład 5 Instrukcja selekcji if-else Operatory arytmetyczne i logiczne

Wstęp do Techniki Cyfrowej... Synchroniczne układy sekwencyjne

Algorytmika i Programowanie VBA 1 - podstawy

Języki i paradygmaty programowania

Wprowadzenie do architektury komputerów systemy liczbowe, operacje arytmetyczne i logiczne

Operatory AND, OR, NOT, XOR Opracował: Andrzej Nowak Bibliografia:

Ćwiczenie 01 - Strona nr 1 ĆWICZENIE 01

Zmienne, stałe i operatory

Politechnika Białostocka Wydział Elektryczny Katedra Automatyki i Elektroniki. ĆWICZENIE Nr 4 (3h) Przerzutniki, zatrzaski i rejestry w VHDL

Układy kombinacyjne 1

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

Krótkie przypomnienie

Wydział Zarządzania AGH. Katedra Informatyki Stosowanej. Podstawy VBA cz. 2. Programowanie komputerowe

Transkrypt:

Języki Opisu Sprzętu Prowadzący: dr inż. Andrzej Skoczeń Współrzędne: D-10 222, tel. w. 28-72, e-mail: skoczen@fis.agh.edu.pl Proceduralne przypisanie ciągłe Wykład 5 2019 16 październik 2019 Operatory w Verilogu Dyrektywy kompilatora Instrukcje sterujące (warunki, rozgałęzienia i pętle) Wnioskowanie zatrzasku i enkoder priorytetowy http://www.fis.agh.edu.pl/~skoczen/hdl AGH WFiIS Informatyka Stosowana Języki Opisu Sprzętu 1

Proceduralne przypisanie ciągłe module xx (...); reg [4:0] komb_out; wire [4:0] c; reg [4:0] a, b; always @* assign komb_out = a (b & c); endmodule Taka składnia jest także poprawna ale znaczenie jest odmienne. 2

Proceduralne przypisanie ciągłe Jest to przypisanie ciągłe do: Zmiennej rejestrowej, Pozostaje ważne tylko przez czas określony jego odwołaniem, Jest nadrzędne w stosunku do zwykłego przypisania proceduralnego. W sposób ciągły przypisuje wartość do zmiennej rejestrowej z priorytetem wyższym niż zwykłe przypisanie proceduralne. Po jego odwołaniu przez deassign zmienna rejestrowa nadal utrzymuje uzyskaną wartość, aż do chwili wystąpienia zwykłego przypisania proceduralnego. assign zmienna_reg = wyrazenie;... deassign zmienna_reg; Lewa strona przypisania może być zmienną lub połączeniem zmiennych. Nie może być słowem pamięci lub tablicy i nie może być bitem lub grupą bitów wektora. 3

module assigntry(input clk, rst, set, d, output reg q); always @* Przy przejściu rst w stan niski wyjście q otrzyma stan niski. if(~rst) assign q = 1'b0; else Przy przejściu set w stan niski wyjście q otrzyma stan wysoki. if(~set) assign q = 1'b1; else deassign q; always @(posedge clk) q <= d; endmodule Jeżeli żadne z wejść set, rst nie jest w stanie niskim wyjście zostanie uwolnione i kontrolę nad nim przejmie zwykłe przypisanie proceduralne w drugim always. Komunikaty o błędach w czasie syntezy za pomocą RTL Compiler (Cadence): if(~rst) assign q = 1'b0; Error : Unsupported procedural assignment. [VLOGPT-39] [read_hdl] : Procedural assign in file 'assign.v' on line 7, column 16. : 'assign' and 'deassign' statements within a sequential statement are not supported for synthesis. Synteza jest poprawna w XST w nawigatorze ISE: Process "Synthesize - XST" completed successfully XST, Xilinx Encounter RTL Compiler, Cadence 4

module assigntry(input clk, rst, set, d, output reg q); always @(posedge clk) q <= d; always @* if(~rst) assign q = 1'b0; else if(~set) assign q = 1'b1; else deassign q; endmodule Symulacja RTL (behavioral) ISim, Xilinx 5

XST, Xilinx module assigntry (input clk, rst, d, set, output q); wire rst_inv; wire set_inv; wire VCC; X_FF #(.INIT ( 1'b0 )) q_1 (.CLK(clk),.RST(rst_inv),.I(d),.SET(set_inv),.O(q),.CE(VCC)); X_INV X_INV X_ONE endmodule ISim, Xilinx set_inv1_inv_0 (.I(set),.O(set_inv)); rst_inv1_inv_0 (.I(rst),.O(rst_inv)); NlwBlock_assigntry_VCC (.O(VCC)); Symulacja Post-Translate module tb; reg clk, rst, set, d; wire q; assigntry uut (.clk(clk),.rst(rst),.set(set),.d(d),.q(q)); wire GSR = glbl.gsr; initial begin clk = 0; forever #40 clk = ~clk; end initial begin @(negedge GSR); rst = 1'b1; set = 1'b1; d = 1'b1; #100 rst = 1'b0; #120 rst = 1'b1; #110 set = 1'b0; #110 set = 1'b1; #150 set = 1'b0; #10 rst = 1'b0; #100 rst = 1'b1; #10 set = 1'b1; #100 d = 1'b0; end initial #1000 $finish; endmodule 6

Proceduralne przypisanie ciągłe Są to konstrukcje przeznaczone do tworzenie modeli symulacyjnych i pisania modułów testowych (test-bench). Dwa rodzaje: Do zmiennej rejestrowej uważana za zły styl kodowania, assign... deassign ; Do zmiennej węzłowej lub rejestrowej force... release ; zastosowanie ograniczone do generacji wymuszeń i dubugowania. 7

Proceduralne przypisanie ciągłe force zmienna_reg_net = wyrazenie;... release zmienna_reg_net; Na zmiennych rejestrowych działa tak jak assign ale ma jeszcze wyższy priorytet. Na zmiennych węzłowych nadpisuje przypisania ciągłe i wyjścia instancji na czas określony przez wystąpienie instrukcji release. 8

`timescale 1 ns / 100 ps module force_release_tb; reg w, x, y; wire f; and and_1 (f, w, x, y); initial begin $monitor("%d ns, f=%b", $time,f); end endmodule w = 1 b1; x = 1 b0; y = 1 b1; #10 force f = w x y; #10 release f; #10 $finish; Bramka and na 10 jednostek czasu zostaje zastąpiona przez funktor LUB modelowany przypisaniem force Wynik symulacji : 0 ns, f=0 10 ns, f=1 20 ns, f=0 Incisive, Cadence 9

Zestawienie różnych przypisań Typ danych Wyjście instancji Ciągłe Proceduralne priorytet Proceduralne ciągłe assign force Węzłowe X X Rejestrowe X X 10

Reguły stosowania przypisań blokujących i nieblokujących Podstawowe zasady syntezowalności kodu Zawsze używaj przypisań blokujących (=) w blokach always przeznaczonych do tworzenia układów kombinacyjnych, Zawsze używaj przypisań nieblokujących (<=) w blokach always przeznaczonych do tworzenia układów sekwencyjnych, Nie mieszaj obu typów przypisań w jednym bloku always, Nie wykonuj przypisań do tej samej zmiennej w dwóch różnych blokach always. 11

Modelowanie za pomocą bloku always Modelowanie układów sekwencyjnych Na liście wrażliwości znajduje się aktywne zbocze sygnału zegarowego i ewentualnie aktywne zbocze asynchronicznego sygnału kasowania: always @(posedge clk, posedge rst) Zatrzaski Są sekwencyjne gdyż trudno nie przyznać, że są to elementy pamięciowe Są kombinacyjne, gdyż powstają przy błędnym modelowaniu układów kombinacyjnych Modelowanie układów kombinacyjnych Na liście wrażliwości znajdują się zmiany wartości wszystkich sygnałów występujących po stronie prawej przypisań w tym bloku: always @* 12

Operatory arytmetyczne Operatory dwuargumentowe: (**) potęgowanie, (*) mnożenie, (/) dzielenie, (+) dodawanie, (-) odejmowanie, (%) modulo. Jeśli jakikolwiek bit argumentów ma wartość nieokreśloną x to cały wynik jest nieokreślony. Operatory jednoargumentowe (+) i (-) określają znak argumentu. reg [3:0] A, B; integer D, E; //A = 4 b0011; B = 4 b0100; D = 6; E = 4; A + B //wynik 4 b0111 D/E //wynik 1; obcina czesc ułamkową A * B //wynik 4 b1100 B A //wynik 4b 0001 Wynikiem operacji będzie real jeśli jeden z argumentów jest real. Jeśli obydwa argumenty są bez znaku to wynik także jest bez znaku. data flow level 13

Operatory logiczne data flow level Operatory dwuargumentowe: ( ) logiczne-lub, (&&) logiczne-i. Operatory jednoargumentowe: (!) logiczne-nie. Wynikiem zawsze jest wartość jednobitowa: 0 fałsz, 1 prawda lub x nieokreślony. Wynik różny od zera jest traktowany jak prawda. //A = 3; B = 0; A && B //daje falsz A B //daje prawda!a //daje falsz!b //daje prawda //A = 2 b0x; B = 2 b10; A && B //daje x 14

Operatory relacyjne data flow level (>) większy, (<) mniejszy, (>=) większy-lub-równy, (>=) mniejszy-lub-równy. Jeśli argument jest x lub z to wynik jest x. //A = 4; B = 3; X = 4 b1010; Y = 4 b1101; Z = 4 b1xxx; A <= B A > B Y >= X Y < Z //wynik 0-falsz //wynik 1-prawda //wynik 1-prawda //wynik x 15

Operatory równości Operatory dwuargumentowe: (==) równość, (!=) nierówność oraz wersje z uwzględnieniem x i z (===) i (!==). Wynikiem zawsze jest wartość jednobitowa: 0 fałsz, 1 prawda, a wartość x nieokreślony może się pojawić tylko w przypadkach (==) i (!=). //A = 4; B = 3; //X = 4 b1010; Y = 4 b1101; //Z = 4 b1xxz; M = 4 b1xxz; N = 4 b1xxx; A == B A!= B X == Z Z === M Z === N M!== N //daje falsz //daje prawda //daje x //daje prawda //daje falsz //daje prawda data flow level Używać oszczędnie w zastosowaniu do syntezy: reg a; if (a == 1 b1)... ; //jest równoważne if(a)... ; 16

Operatory bitowe Operatory dwuargumentowe: ( ) bitowe-lub, (&) bitowe-i, (^) bitowe-xor, (~^ lub ^~) bitowe-xnor. data flow level Operatory jednoargumentowe: (~) bitowe-nie. Jeśli argumenty są różnych rozmiarów to krótszy uzupełniany jest zerami z przodu. & 0 1 x 0 0 0 0 1 0 1 x x 0 x x 0 1 x 0 0 1 x 1 1 1 1 x x 1 x ^ 0 1 x 0 0 1 x 1 1 0 x x x x x ^~ 0 1 x 0 1 0 x 1 0 1 x x x x x //X = 4 b1010; Y = 4 b1101; z jest traktowane jak x. //Z = 4 b10x1; ~X //daje 4 b0101 X & Y //daje 4 b1000 X Y //daje 4 b1111 a X Y daje 1 b1 X ^ Y //bitowy xor daje 4 b0111 X ~^ Y //bitowy xnor daje 4 b1000 X & Z //daje 4 b10x0 ~ 0 1 1 0 x x 17

Operatory redukcyjne Operatory jednoargumentowe : ( ) or, (&) and, (^) xor, (~ ) nor, (~&) nand, (~^ lub ^~) xnor. data flow level //X = 4 b1010; &X //1 & 0 & 1 & 0 daje 1 b0 X //1 0 1 0 daje 1 b1 ^X //1 ^ 0 ^ 1 ^ 0 daje 1 b0 18

Operatory przesunięć Operatory dwuargumentowe: (>>) w prawo, (<<) w lewo. data flow level działają na wektorach, przesuwają określoną w drugim argumencie ilość bitów, powstające miejsce zapełniają zawsze zerami (nie ma zawijania). //X = 4 b1100; Y = X >> 1; //daje 4 b0110 Y = X << 1; //daje 4 b1000 Y = X << 2; //daje 4 b0000 19

Operator dołączania Operatory wieloargumentowy: ({}) łączenie. Działa na argumentach o znanym rozmiarze. data flow level //A=1 b1, B=2 b00, C=2 b10, D=3 b110 reg [3:0] Y0; reg [10:0] Y1; reg [2:0] Y2; Y0 = {B,C}; //daje 4 b0010 Y1 = {A,B,C,D,3 b001}; //daje 11 b10010110001 Y2 = {A,B[0],C[1]}; //daje 3 b101 20

Operator powtarzania data flow level Polega na wielokrotnym łączeniu tyle razy ile określono w stałej replikacji {stala_repli{arg}} reg A; reg [1:0] B, C; reg [2:0] D; //A=1 b1; B=2 b00; C=2 b10; reg [3:0] Y0; reg [7:0] Y1; reg [9:0] Y2; Y0 = { 4{A} }; //daje 4 b1111 Y1 = { {4{A}}, {2{B}} }; //daje 8 b11110000 Y2 = { {4{A}}, {2{B}}, C}; //daje 10 b1111000010 21

Operator warunkowy Zastępuje instrukcję if, Dostarcza konstrukcji multipleksera 2 do 1: data flow level warunek? wyraz_prawda : wyraz_falsz //bufor trójstanowy trzy-bitowego wire [2:0] addr_bus, adrr_out; assign addr_bus = driver_enable? adrr_out : 3 bz; //2-do-1 mux assign out = control? in1 : in2; //zagniezdzanie assign out = (A==3)? (control?x:y) : (control?m:n); 22

Dyrektywy kompilatora Definiuje się w postaci : `<słowo_kluczowe> Słowa kluczowe: omówimy `define `undef `include `ifdef `else `elsif `endif `ifndef `timescale niektóre inne: `celldefine `endcelldefine `line `default_nettype `unconnected_drive `unconnected_drive `resetall 23

Dyrektywa `define Definiowanie makra tekstowego `define <nazwa_makra> <wartość> Rola i działanie podobne jak #define w C. Odwołanie: `<nazwa_makra> `define WORD_SIZE 32 definicja makra określającego domyślną długość słowa; wywołanie: `WORD_SIZE `define S $stop alias gdziekolwiek pojawi się `S wstawione zostanie $stop `define WORD_REG reg [WORD_SIZE-1:0] często używany ciąg znaków deklaracja 32-bitowego rejestru: `WORD_REG reg32; 24

Dyrektywa `include Wstawianie pliku źródłowego `include <nazwa_pliku> Rola i działanie podobne jak #include w C. //wstaw plik header.v zawierający deklaracje `include header.v... <kod Verilog a>... Należy unikać umieszczania modułów w plikach włączanych za pomocą dyrektywy `include. Najlepszym użyciem tej dyrektywy jest stosowanie jej do współdzielenia informacji sterującej zawartej w dyrektywach `define, `timescale, i im podobnych. 25

Dyrektywa `timescale `timescale <jednostka> / <dokładność> `timescale 10 ns / 1 ns module test #(parameter d = 1.55); reg set; initial begin end endmodule #d set = 1 b0; #d set = 1 b1; #d $finish; W tym przykładzie dyrektywa `timescale 10 ns / 1 ns określa jednostkę czasu dla modułu test na 10ns. W rezultacie wartości czasu w module są mnożone przez 10ns z zaokrągleniem do najbliższej 1ns. Parametr d jest typu real, gdyż taka stała jest do niego wpisana. Dlatego wartość parametru d jest skalowana do 16ns. Wartość 0 jest przypisywana do rejestru set w chwili czasu symulacji 16ns i wartość 1 w chwili 32ns. W argumentach dozwolone są tylko potęgi liczby 10: Dozwolone liczby całkowite: 1, 10, and 100. Dozwolone ciągi znaków określających jednostki pomiaru czasu: s, ms, us, ns, ps, fs. 26

Dyrektywy `ifdef, `else, `endif Kompilacja warunkowa umożliwia zastosowanie tego samego kodu w dwóch różnych sytuacjach indywidualizując go w czasie kompilacji projektu. initial begin `ifdef GL $shm_open("seqdetgl.shm"); `else $shm_open("seqdet.shm"); `endif $shm_probe("as"); #220 $shm_close(); $finish; end Makro GL może być zdefiniowane dyrektywą `define w pliku lub opcją define w linii poleceń. Przy wywołaniu symulatora: $ irun define GL test.v... będą wykonane te linie matomiast jeśli zrobimy to tak: $ irun test.v... wykonana będzie tylko ta linie initial begin `ifdef GL $sdf_annotate("seqdet.sdf",test,,"seqdet_sdf.log","maximum",,); `endif end Incisive, Cadence Sposób na to żeby dokładnie ten sam moduł testowy używać do symulacji przed i po syntezie. 27

Instrukcje sterujące Instrukcja warunkowa: if Instrukcja wyboru: case, casex, casez Pętle: while, for, repeat, forever 28

Instrukcja warunkowa Używana do podejmowania decyzji. Są trzy rodzaje: if... else Prosta - bez else, Z jednym else, Z wielokrotnym zagnieżdżeniem if-else-if, Prosta (bez else). Kod instrukcje wykonuje się gdy <wyrażenie> ma wartość logiczna 1. if (<wyrażenie>) instrukcje ; if(!lock) buffer = data; if(enable) out = in; 29

Instrukcja warunkowa Z jednym else. Kod instrukcje1 wykonuje się gdy <wyrażenie> ma wartość logiczną 1. Jeśli ta wartość jest 0 lub jest nieokreślona (x lub z) wykonuje się kod instrukcje0. if (<wyrażenie>) instrukcje1 ; else istrukcje0 ; if (number_queued < MAX_Q_DEPTH) begin data_queue = data; number_queued = number_queued +1 end else $display( Kolejka pełna. Próbuj ponownie. ); if... else 30

Instrukcja warunkowa Z wielokrotnym zagnieżdżeniem if-else-if. if (<wyrażenie1>) instrukcje1 ; else if (<wyrażenie2>) instrukcje2 ; else if (<wyrażenie3>) instrukcje3 ; else instrukcje_domyślne //wykonanie instrukcji w oparciu //o wartość sygnału sterującego ALU if (alu_control == 0) y = x + z; else if (alu_control == 1) y = x - z; else if (alu_control == 2) y = x * z; else $display( Błędna wartość sygnału sterującego ALU ); if... else 31

Instrukcja wyboru Instrukcja ta zastępuje trzeci typ instrukcji warunkowej if. case (wyrażenie) alternatywa1: instrukcje1 alternatywa2: instrukcje2 alternatywa3: instrukcje3 default: instrukcje_domyślne endcase Lista pozycji identyfikowanych wzorcami bitowymi dopasowywanymi do wyniku wyrażenia. //wykonanie instrukcji w oparciu //o wartość sygnału sterującego ALU reg [1:0] alu_control;... case (alu_control) 2 d0 : y = x + z; 2 d1 : y = x - z; 2 d2 : y = x * z; default : $display( Błędny sygnał sterujący ALU ); endcase case 32

Instrukcja wyboru Przykład użycia case do modelowania multipleksera 4-do-1: module mux4_to_1 (output reg out, input [3:0] in, input s1, s0); always @(s1, s0, in) case ({s1, s0}) //konkatencja adresów 2 d0 : out = in[0]; 2 d1 : out = in[1]; 2 d2 : out = in[2]; 2 d3 : out = in[3]; default : $display( Zły sygnał sterujący ); endcase endmodule case 33

Instrukcja wyboru Przykład użycia case do modelowania demultipleksera 1-do-4: module demux1to4 (output reg out0, out1, out2, out3, input in, s1, s0); always @(s1, s0, in) case ({s1, s0}) 2 b00: begin out0=in; out1=1 bz; out2=1 bz; out3=1 bz; end 2 b01: begin out0=1 bz; out1=in; out2=1 bz; out3=1 bz; end 2 b10: begin out0= 1 bz; out1=1 bz; out2=in; out3=1 bz; end 2 b11: begin out0= 1 bz; out1=1 bz; out2=1 bz; out3=in; end case 2 bx0, 2 bx1, 2 bxz, 2 bxx, 2 b0x, 2 b1x, 2 bzx: begin out0=1 bx; out1=1 bx; out2=1 bx; out3=1 bx; end Jeden bit adresu jest nieokreślony 2 bz0, 2 bz1, 2 bzz, 2 b0z, 2 b1z: to wszystkie wyjścia są nieokreślone begin out0=1 bz; out1=1 bz; out2=1 bz; out3=1 bz; end Jeden bit adresu jest niepodłączony default : $display( Zły sygnał sterujący ); to wszystkie wyjścia są niepodłączone endcase endmodule 34

Instrukcje wyboru casex, casez Instrukcja case, porównuje wartości 0, 1, x i z w wyrażeniach i alternatywach. Są dwie inne wersje instrukcji case, które omijają porównywanie: casez - z-owych, casex - x-owych i z-owych pozycji bitowych w wyrażeniu i alternatywach. Przykład użycia casex do modelowania logiki stanu następnego automatu skończonego przy kodowaniu z gorącą jedynką: reg [3:0] state, next_state; casex (state) 4 b1xxx : next_state = 4 b0100; 4 bx1xx : next_state = 4 b0010; 4 bxx1x : next_state = 4 b0001; 4 bxxx1 : next_state = 4 b1000; default : next_state = 4 b0000; endcase Tylko jeden bit jest brany pod uwagę przy określaniu następnego stanu automatu. Jeśli np. state=4 b10xz to wykonana zostanie instrukcja next_state=4 b0100. 35

casex Verilog posiada instrukcję casex, która jest wersją instrukcji case pozwalającą traktować wartości "z", "?" i "x" w czasie porównań jak pozycje nie podlegające porównywaniu ("don't care ). "z", "?" i "x" są traktowane jak nie wpływające na wynik gdy występują w wyrażeniu i/lub w pozycjach instrukcji. W kodzie syntezowalnym nie używaj instrukcji casex. Użycie instrukcji casex może powodować problemy projektowe. Instrukcja casex traktuje wartość x jak bit nie mający znaczenia ( don t care ) jeśli znajdują się w wyrażeniu lub alternatywach. Kłopot pojawia się kiedy sygnał testowany przez wyrażenie casex jest inicjowany do wartości nieokreślonej x. Symulacja kodu RTL, w którym użyto casex nie testuje nieokreślonych sygnałów. Skutkiem tego odpowiadająca symulacja modelu strukturalnego pochodzącego z syntezy będzie propagować wartości x gdy dojdzie do testowania tego sygnału. 36

casez Verilog posiada instrukcję casez, która jest wersją instrukcji case pozwalającą traktować wartości "z" i "?" w czasie porównań jak pozycje nie podlegające porównywaniu ("don't care ). "z" i "?" traktowane są jak nie wpływające na wynik gdy występują w wyrażeniu i/lub w pozycjach instrukcji. Użycie casez w kodzie syntezowalnym wymaga ostrożności. Kiedy używasz instrukcji case z wartościami "don't care stosuj instrukcję casez, i używaj znaków "?" zamiast "z" w pozycjach listy do wskazania bitów nieokreślonych. Użycie instrukcji casez może powodować takie same problemy projektowe jak w przypadku casex, ale przeoczenie niepoprawnego działania w czasie weryfikacji jest mniej prawdopodobne. Kłopot pojawia się kiedy sygnał testowany przez wyrażenie casez jest inicjowany do wartości wysokiej impedancji z. Jednak instrukcja casez jest krótką, zwięzłą, tabelaryczną metodą do modelowania użytecznych struktur: enkodery priorytetowe, dekodery adresu. Dlatego nie powinna być całkowicie eliminowana z inżynierskiego użycia. 37

Pętle W Verilogu są cztery rodzaje pętli: while for repeat forever Pętle mogą występować tylko wewnątrz bloków initial i always. Mogą zawierać opóźnienia. Pętle aby były syntezowalne muszą posiadać stałe ograniczenia i warunek zakończenia pętli musi być znany przed elaboracją. 38

Pętla while Jest wykonywana dopóki wyrażenie nie stanie się fałszem. //inkrementowanie zmiennej count od 0 do 127 //zakończenie na 128 //wyświetlanie zliczania integer count; initial begin count = 0; while (count < 128) begin $display( count = %d,count); count = count + 1; end end //wykonaj pętlę do chwili gdy //count osiągnie wartość 127 //zakończ gdy count będzie 128 39

Pętla while c.d. `define TRUE 1 b1; `define FALSE 1 b0; reg [15:0] flag; integer i; //indeks reg continue; znajdź pierwszy bit o wartości 1 w zmiennej flag initial begin flag = 16 b 0010_0000_0000_0000; i = 0; continue = `TRUE; while ((i < 16) && continue) begin if (flag[i]) begin $display( natrafiono bit 1 na pozycji %d,i); continue = `FALSE; end i=i+1; end end 40

Pętla for Składa się z trzech elementów: Warunku początkowego, Sprawdzenia kiedy warunek końcowy stanie się prawdą, Przypisania proceduralnego zmieniającego wartość zmiennej sterującej. Pętla for w wielu wypadkach zastępuje pętlę while w bardziej zwięzły sposób. Pętla while jest jednak bardziej ogólnym narzędziem. //inkrementowanie zmiennej count od 0 do 127 //zakończenie na 128 //wyświetlanie zliczania integer count; initial for ( count=0; count<128; count=count+1) $display( count = %d,count); 41

Pętla for c.d. //inicjalizacja elementów tablicy `define MAX_STATES 32 integer state [0:`MAX_STATES-1]; //32-elementowa tablica integer i; initial begin for ( i=0; i<32; i=i+2) //inicjuj parzyste komórki zerami state[i] = 0; for ( i=1; i<32; i=i+2) //inicjuj nieparzyste jedynkami state[i] = 1; end 42

Pętla repeat Wykonuje się taką ilość razy jaką określa stała, zmienna lub sygnał użyty w instrukcji repeat. Ta zmienna lub sygnał obliczana jest przed rozpoczęciem pętli nie może ulec zmianie w czasie jej wykonywania. Inkrementowanie zmiennej count od 0 do 127, zakończenie na 128, wyświetlanie zliczania. initial begin count = 0; repeat(128) begin $display( count = %d,count); count = count + 1; end end 43

Przykład: po otrzymaniu sygnału data_start czyta dane przez kolejne osiem cykli module data_buffer #(parameter cycle=8) (input data_start, clock, input [15:0] data,); reg [15:0] buffer [0:7]; integer i; always @(posedge clock) begin if (data_start) begin rozpocznij jeśli data_start jest 1 i = 0; repeat(cycle) begin zapisz dane na zboczu narastającym następnych 8 cykli @(posedge clock) czekaj na zbocze sygnału zegarowego clock buffer[i] = data; i = i + 1; end end end endmodule Pętla repeat Nowe wyzwolenie bloku always zajdzie dopiero po zakończeniu cyklu ośmiu zboczy narastających zagara clock Ten moduł jest niesyntezowalny ze względu na zastosowanie zdarzeniowego sterowania upływem czasu. Zastosowanie pętli repeat ze stałą liczbą powtórzeń jest syntezowalne. 44

buffer buffer Pętla repeat Dwa przykłady symulacji modułu z poprzedniego slajdu. Incisive, Cadence clock data data_start Krótki impuls data_start rozpoczynający transmisję clock data data_start Długi impuls data_start rozpoczynający transmisję 45

Pętla forever Pętla nieskończona, równoważna while(1). Zakończenie powoduje zadanie systemowe $finish. Można z niej wyjść za pomocą instrukcji disable. Musi być używana w połączeniu ze sterowaniem przebiegiem czasu gdyż w przeciwnym wypadku wykonywałaby się w nieskończoność bez upływu czasu, a reszta projektu nie byłaby wykonywana wcale. //generacja zegara reg clock; initial begin clock = 0; forever #10 clock = ~clock;... end Kod nieosiągalny //okres 20 jedn. //synchronizuj zawartość dwóch rejestrów //na każdym zboczu narastającym reg clock, x, y; initial forever @(posedge clock) x = y; 46

Pełna instrukcja case Mówimy, że instrukcja case jest pełna (full) gdy wszystkie możliwe wzory bitowe mogą być dopasowane do pozycji na liście case lub do pozycji domyślnej default. Jeśli instrukcja case nie zawiera pozycji domyślnej i jeśli jest możliwe znalezienie wzorca binarnego, który nie pasuje do żadnej ze zdefiniowanych pozycji case, to instrukcja case nie jest pełna (full). module mux3a (output reg y, input [1:0] sel, input a, b, c); Raport z elaboracji : Linia 4 Encounter RTL Compiler, Cadence Line No Type Full Parallel ---------------------------------------- 4 case NO AUTO ---------------------------------------- Done elaborating 'mux3a'. przy atrybucie hdl_report_case_info ustawionym na true always @(a, b, c, sel) case (sel) 2'b00: y = a; 2'b01: y = b; 2'b10: y = c; endcase endmodule Brak pozycji z wzorcem 2 b11 47

Wnioskowanie zatrzasku Blok always jest wykonywany wielokrotnie. Jeśli w pewnym przejściu, do zmiennej out nie zostanie przypisana żadna wartość, to narzędzie do syntezy wywnioskuje (infer), że nie chcemy zmienić jej wartości, którą uzyskała w poprzednim przejściu przez ten blok. Syntezator stworzy więc element do przechowywania tej poprzedniej wartości czyli zatrzask utrzymujący poprzednią wartość zmiennej out, aż do momentu gdy zostanie ona ponownie zmodyfikowana. Zjawisko to rzadko jest pożądane przez projektanta i świadomie przez niego spowodowane. Zjawisko to nazywane jest wnioskowaniem zatrzasku (latch inferring). Unikanie tego zjawiska polega na przypisywaniu wartości każdej zmiennej w każdej możliwej ścieżce przejścia przez kombinacyjny blok always. 48

Jednym z najbardziej powszechnych sposobów prowadzących do stworzenia zatrzasku jest zrobienie przypisań do wielu wyjść z pojedynczej instrukcji case, ale zaniedbanie przypisania do wszystkich wyjść ze wszystkich pozycji case. Najłatwiejszym sposobem eliminacji zatrzasków jest wykonanie początkowych przypisań domyślnej wartości do wszystkich wyjść natychmiast poniżej listy wrażliwości procesu, tuż przed instrukcją case. module addrdecode1a ( output reg mce0_n, mce1_n, rce_n, input [31:30] addr); always @(addr) casez (addr) 2'b10: {mce1_n,mce0_n}=2'b10; 2'b11: {mce1_n,mce0_n}=2'b01; 2'b0?: rce_n=1'b0; endcase endmodule Wnioskowanie zatrzasku Syntezator użyje trzech zatrzasków, po jednym dla każdego z sygnałów: mce1_n, mce0_n, rce_n oraz utworzy logikę do sterowania wejściami bramkującymi tych zatrzasków. module addrdecode1a ( output reg mce0_n, mce1_n, rce_n, input [31:30] addr); always @(addr) begin {mce1_n,mce0_n,rce_n}=3'b111; casez (addr) 2'b10: {mce1_n,mce0_n}=2'b10; 2'b11: {mce1_n,mce0_n}=2'b01; 2'b0?: rce_n=1'b0; endcase end endmodule Moduł poprawiony 49

Encounter RTL Compiler, Cadence Wynik syntezy modułu mux3a. Wynik syntezy poprawionego modułu mux3a. module mux3a_fixed (output reg y, input [1:0] sel, input a, b, c); always @(a, b, c, sel) begin y = 1 bx; case (sel) 2'b00: y = a; 2'b01: y = b; 2'b10: y = c; endcase end endmodule Wystarczyło przypisać wartość x przed case-em aby z układu zniknął zatrzask, dwa inwertery i bramka NOR. 50

Równoległa instrukcja case Mówimy, że instrukcja case jest równoległa (parallel) gdy możliwe jest dopasowanie wyrażenia case do jednej i tylko jednej pozycji listy case. Jeśli możliwe jest znalezienie wartości wyrażenia, które pasuje do więcej niż jednej pozycji na liście wzorców case, to pasujące pozycje nazywa się pozycjami nakładającymi się (overlapping) i taka instrukcja case nie jest równoległa. module intctl1a ( output reg int2, int1, int0, input [2:0] irq); Raport z elaboracji : Linia 5 Encounter RTL Compiler, Cadence Line No Type Full Parallel -------------------------------------------- 5 casez NO NO -------------------------------------------- Done elaborating 'intctl1a'. always @(irq) begin {int2, int1, int0} = 3'b0; casez (irq) 3'b1??: int2 = 1'b1; 3'b?1?: int1 = 1'b1; 3'b??1: int0 = 1'b1; endcase end endmodule Kiedy projekt ma nakładające się pozycje w instrukcji case funkcjonalność przed i po syntezie będzie odmienna. Spowoduje to powstanie enkodera priorytetowego. 51

Enkoder priorytetowy Enkoder to układ kombinacyjny służący do konwersji kodu 1 z n (1 z n ) na określony kod wyjściowy. Ma więc n wejść z czego tylko jedno jest w stanie aktywnym. Enkodery muszą jednak wytwarzać jednoznaczną odpowiedź gdy na wejściach jest więcej niż jedna jedynka tzn. mamy kod k z n (k z n ). Dlatego trzeba ustalić priorytety wejść tak, aby na wyjściu pojawiał się kod tego z aktywnych wejść, które ma najwyższy priorytet. Jest to enkoder priorytetowy. Priorytet wyższy dla bardziej znaczącego bitu D7 D6 D5 D4 D3 D2 D1 D0 Q2 Q1 Q0 any 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 x 0 0 1 1 0 0 0 0 0 1 x x 0 1 0 1 0 0 0 0 1 x x x 0 1 1 1 0 0 0 1 x x x x 1 0 0 1 0 0 1 x x x x x 1 0 1 1 0 1 x x x x x x 1 1 0 1 1 x x x x x x x 1 1 1 1 52

Enkoder priorytetowy Bardziej znaczący bit ma wyższy priorytet Gdy chcemy zbudować enkoder priorytetowy to rekomendowane są następujące dwa rozwiązania: module priority_encoder (output reg [2:0] code, output reg any, input [7:0] encin); always @(encin) begin any=1'b1; if (encin[7]) code = 3'd7; else if (encin[6]) code = 3'd6; else if (encin[5]) code = 3'd5; else if (encin[4]) code = 3'd4; else if (encin[3]) code = 3'd3; else if (encin[2]) code = 3'd2; else if (encin[1]) code = 3'd1; else if (encin[0]) code = 3'd0; else begin code = 3'd0; any = 1'b0; end end endmodule module priority_encoder (output [2:0] code, output any, input [7:0] encin); assign code = (encin[7])? 3'd7 : (encin[6])? 3'd6 : (encin[5])? 3'd5 : (encin[4])? 3'd4 : (encin[3])? 3'd3 : (encin[2])? 3'd2 : (encin[1])? 3'd1 : 3'd0; assign any = ( encin)? 1'b1 : 1'b0; endmodule 53