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

Podobne dokumenty
Projektowanie Scalonych Systemów Wbudowanych VERILOG

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

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

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

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

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

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

Laboratorium Podstaw Techniki Cyfrowej

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

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.

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

Projektowanie scalonych systemów wbudowanych VERILOG. VERLIOG - historia

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

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

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

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

Proste układy sekwencyjne

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.

Sumatory H D L. dr inŝ. Paweł Tomaszewicz Instytut Telekomunikacji Politechnika Warszawska

Programowalne układy logiczne

Automat skończony FSM Finite State Machine

Języki projektowania HDL

Projektowanie Scalonych Systemów Wbudowanych VERILOG

Projektowanie Scalonych Systemów Wbudowanych VERILOG

Sposoby projektowania systemów w cyfrowych

Część 3. Układy sekwencyjne. Układy sekwencyjne i układy iteracyjne - grafy stanów TCiM Wydział EAIiIB Katedra EiASPE 1

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

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

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

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

Języki projektowania HDL

Cyfrowe układy sekwencyjne. 5 grudnia 2013 Wojciech Kucewicz 2

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

(przykład uogólniony)

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

Krótkie wprowadzenie do ModelSim i Quartus2

Programowanie Układów Logicznych kod kursu: ETD6203 W dr inż. Daniel Kopiec. Pamięć w układach programowalnych

Układy reprogramowalne i SoC Implementacja w układach FPGA

LABORATORIUM 3 ALGORYTMY OBLICZENIOWE W ELEKTRONICE I TELEKOMUNIKACJI. Wprowadzenie do środowiska Matlab

Przerzutnik ma pewną liczbę wejść i z reguły dwa wyjścia.

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

Architektura komputerów Wykład 2

Synteza logiczna APSC

Układy mnoŝące H D L. dr inŝ. Paweł Tomaszewicz Instytut Telekomunikacji Politechnika Warszawska

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

PRZERZUTNIKI: 1. Należą do grupy bloków sekwencyjnych, 2. podstawowe układy pamiętające

Instrukcje sekwencyjne

Sterowniki Programowalne (SP)

Altera Quartus II. Opis niektórych komponentów dostarczanych razem ze środowiskiem. Opracował: mgr inż. Leszek Ciopiński

Lista tematów na kolokwium z wykładu z Techniki Cyfrowej w roku ak. 2013/2014

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

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

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

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

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

ZASADY PROGRAMOWANIA KOMPUTERÓW

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

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

Programowalne układy logiczne

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady

Adresowanie obiektów. Adresowanie bitów. Adresowanie bajtów i słów. Adresowanie bajtów i słów. Adresowanie timerów i liczników. Adresowanie timerów

Język AHDL. Synteza strukturalna. dr inŝ. Paweł Tomaszewicz Instytut Telekomunikacji Politechnika Warszawska H D L

Podstawy Programowania C++

Programowanie w Turbo Pascal

Pętla for. Wynik działania programu:

Projektowanie Urządzeń Cyfrowych

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

Asynchroniczne statyczne układy sekwencyjne

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

L E X. Generator analizatorów leksykalnych

Wykład 8: klasy cz. 4

Język VERILOG w praktyce

Język C++ zajęcia nr 2

Projektowanie układów na schemacie

Podstawowe elementy układów cyfrowych układy sekwencyjne Rafał Walkowiak Wersja

Numeryczne rozwiązywanie równań i układów równań

Laboratorium 10 Temat: Zaawansowane jednostki testowe. Operacje na plikach. Funkcje.

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

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

LABORATORIUM TECHNIKA CYFROWA. Pamięci. Rev.1.35

Podstawy programowania w języku C i C++

Układy kombinacyjne 1

Kurs Verilog cz.1 wstęp

Statyczne badanie przerzutników - ćwiczenie 3

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

Układy kryptograficzne z uŝyciem rejestrów LFSR

7. Pętle for. Przykłady

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

Pliki. Operacje na plikach w Pascalu

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

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

Podstawy Elektroniki dla Elektrotechniki. Liczniki synchroniczne na przerzutnikach typu D

Laboratorium przedmiotu Technika Cyfrowa

Pętla for. Matematyka dla ciekawych świata -19- Scilab. for i=1:10... end. for k=4:-1:1... end. k=3 k=4. k=1. k=2

Projekt prostego procesora

Języki opisu sprzętu VHDL Mariusz Rawski

Pętle. Dodał Administrator niedziela, 14 marzec :27

Układy VLSI Bramki 1.0

Zmienne, stałe i operatory

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44

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 Tablice i wektory Reguły łączenia portów Wykład 3 2018 10 październik 2018 Przykład opóźnień Sterowanie przebiegiem czasu Modelowanie na poziomie przepływu danych Modelowanie na poziomie behawioralnym http://www.fis.agh.edu.pl/~skoczen/hdl AGH WFiIS Informatyka Stosowana Języki Opisu Sprzętu 1

Wektor a Tablica Porównanie struktur danych: reg [3:0] val; reg val [3:0]; ERROR: ISim, Xilinx Line 28: Cannot assign to memory val directly Line 28: Cannot assign a packed type to an unpacked type Line 30: Cannot assign to memory val directly Line 30: Cannot access memory val directly Line 30: Illegal operand for operator + Line 30: Unpacked value/target cannot be used in assignment AGH, WFiIS, HDL 2

Wektor a Tablica Porównanie struktur danych: reg [3:0] val; reg val [3:0]; ISim, Xilinx ERROR: Line 22: Port val must not be declared to be an array Tablica może być portem w VHDL-u i SystemVerilog-u AGH, WFiIS, HDL 3

Tablica przypisania, odwołania ERROR: ISim, Xilinx Line 36: Cannot assign to memory array1 directly Line 36: Range is not allowed in a prefix Line 36: Unpacked value/target cannot be used in assignment ERROR: XST, Xilinx line 25: XST does not support arrays over 2 dimensions. AGH, WFiIS, HDL 4

Reguły łączenia portów Port należy sobie wyobrazić jako złożony z dwóch części: wewnętrznej i zewnętrznej. Części te są ze sobą połączone. Istnieją reguły łączenia portów, które muszą być spełnione kiedy moduł jest urealniany. Rozmiary portów wewnątrz i na zewnątrz mogą być różne, ale zgłaszane jest ostrzeżenie. Port może pozostać w stanie nie podłączonym. Jest to przydatne do celów testowania. Należy wtedy przy urealnianiu pozostawić wolne miejsce na liście portów. Reguły łączenia portów typ portu wewnętrznie zewnętrznie input węzeł rejestr, węzeł output rejestr, węzłowy węzeł inout węzeł węzeł Porty węzeł węzeł inout instancja moduł rejestr węzeł input węzeł rejestr węzeł węzeł output AGH WFiIS, IS, st.ii, sem.2 5

module Top; wire C_OUT; reg SUM; reg [3:0] A, B; reg C_IN; Porty Przykład nie poprawnego podłączenia wyjścia sumatora fulladd4 do zmiennej rejestrowej. fulladd4 fa0(sum, C_OUT, A, B, C_IN);... endmodule AGH WFiIS, IS, st.ii, sem.2 deklaracja zmiennych łączonych do urealnienia fa0 modułu fulladd4 Encounter RTL Compiler, Cadence fulladd4 fa0(sum, C_OUT, A, B, C_IN); ncelab: *W,CUVMPW (./error.v,6 15): port sizes differ in port connection. fulladd4 fa0(sum, C_OUT, A, B, C_IN); ncelab: *E,CUVMOT (./error.v,6 15): illegal output port specification. ncverilog: *E,ELBERR: Error during elaboration (status 1), exiting. module fulladd4(output [3:0] sum, output c_out, input [3:0] a, b, input c_in);... <wnętrze modułu>... endmodule Błąd związany ze złamaniem reguł łączenia końcówek. Kompilacja przebiegnie poprawnie ale w czasie elaboracji tzn. podczas łączenia modułów z urealnieniami występuje błąd wywołany tym, że zmienna SUM musi być typu wire. Dodatkowo pojawił o się ostrzeżenie związane z deklaracją SUM jako skalara. 6

Podłączanie portów przez kolejność Przy urealnianiu sygnały muszą wystąpić w tej samej kolejności jak na liście portów. module Top; //deklaracja zmiennych połączeń wire C_OUT; reg [3:0] A, B; wire SUM; reg C_IN; //urealnienie fulladd4 pod nazwą fa_ordered przez kolejność fulladd4 fa_ordered(sum, C_OUT, A, B, C_IN);... endmodule module fulladd4(output [3:0] sum, output c_out, input [3:0] a, b, input c_in);... <wnętrze modułu>... endmodule przypomnienie AGH WFiIS, IS, st.ii, sem.2 7

Podłączanie portów przez nazwę Pamiętanie kolejności jest nie praktyczne. Można dowolnie zmieniać kolejność na liście portów ale trzeba podać obie nazwy wg. następującej składni:.name_module(name_instance) Nazwa portu w definicji modułu Nazwa sygnału, do którego port ma być połączony w module urealniającym //urealnienie fulladd4 pod nazwą fa_byname przez nazwę fulladd4 fa_byname(.c_out(c_out),.sum(sum),.b(b),.c_in(c_in),.a(a)); Porty nie podłączane w ogóle nie muszą występować w urealnieniu. //urealnienie fulladd4 pod nazwą fa_byname przez nazwę fulladd4 fa_byname(.sum(sum),.b(b),.c_in(c_in),.a(a)); AGH WFiIS, IS, st.ii, sem.2 8

Nazwy hierarchiczne Nazwa hierarchiczna Jest to lista identyfikatorów oddzielonych kropkami, która umożliwia jednoznaczne zlokalizowanie urealnienia, sygnału lub zmiennej w pełnej hierarchii projektu. stimulus top-level n1 nand m1 SR_latch n2 nand Q, Qbar, S, R sygnały stimulus q, qbar, set, reset zmienne stimulus.q stimulus.qbar stimulus.set A, b sygnały stimulus.reset stimulus.m1.q stimulus.m1 stimulus.m1.qbar stimulus.m1.s stimulus.m1.r stimulus.m1.n1 stimulus.m1.n2 stimulus.m1.n1.a stimulus.m1.n1.b AGH WFiIS, IS, st.ii, sem.2 9

Opóźnienia bramek i węzłów module buf3del(); reg i, ctrl; bufif1 #(2) b1 (o1, i, ctrl); bufif1 #(2,3) b2 (o2, i, ctrl); bufif1 #(2,3,1) b3 (o3, i, ctrl); Incisive, Cadence initial begin i = 1'b0; ctrl = 1'b0; #2 ctrl = 1'b1; #6 i = 1'b1; #4 i = 1'b0; #6 i = 1'b1; #7 ctrl = 1'b0; end endmodule ctrl i o1 o2 o3 AGH, WFiIS, IS, st.i, HDL 10

Sterowanie przebiegiem czasu Jest to metoda określania chwil czasu symulacji, w których ma nastąpić wykonanie instrukcji proceduralnych. Verilog posiada trzy rodzaje sterowania przebiegiem czasu: timing control opóźnieniowy (delay-based) - określa czas upływający od napotkania instrukcji do jej wykonania (symbol: #) zdarzeniowy (event-based) - zdarzenie polegające na zmianie wartości rejestru lub węzła wyzwala wykonanie instrukcji (symbole: @, or). Rozróżnia się sterowanie: zwykłe, z nazwą i wielokrotne czułe na poziom (level-sensitive) - wykonanie instrukcji czeka na wystąpienie określonego na sygnałach warunku (słowo kluczowe wait) Konstrukcje sterowania czasem są niesyntezowalne Timing controls i timing checks to są dwie zupełnie odmienne rodziny konstrukcji Veriloga AGH, WFiIS, HDL 11

Sterowanie przebiegiem czasu Opóźnieniowe Zdarzeniowe Czułe na poziom # @ wait zwykłe wewnątrz przypisań zerowe zwykłe z nazwą wielokrotne AGH, WFiIS, HDL 12

Sterowanie opóźnieniowe delay-based Określa odstęp czasu między napotkaniem instrukcji, a je wykonaniem. Trzy sposoby specyfikowania: #<liczba> #<identyfikator> #<min:typ:max> użyta przez elaborator gdzie liczba określa liczbę jednostek czasu symulacji gdzie identyfikator określa parametr lub zmienną gdzie opcja linii komend decyduje, która z trzech liczb jest irun -maxdelays nazwa.v (-mindelays lub -typdelays) Trzy rodzaje: zwykłe (regular) wewnątrz przypisań (intra-assignment) zerowe (zero delay) Konstrukcja ta jest niesyntezowalna AGH, WFiIS, HDL 13

Opóźnienie zwykłe Określane dla lewej strony przypisania proceduralnego. //deklaracje parametrów localparam latency = 20, delta = 2; //deklaracje zmiennych rejestrowych reg a, y, z, p, q; initial begin a = 1 b0; //bez opóźnienia #10 y = 1 b1; //opóźnienie z liczbą; przypisanie po 10 //jednostkach czasu #latency z = 1 b0; //opóźnienie z identyfikatorem o 20 jedn. #(latency+delta) p = 1 b1;//opóźnienie z wyrażeniem o 22 jedn. #y a = a + 1 b1; //opóźnienie z identyfikatorem o wartość y #(4:5:6) q = 1 b0; //min:typ:max w zależności od opcji linii komend end initial $monitor($time," a=%d y=%d z=%d p=%d q=%d",a,y,z,p,q); initial #60 $finish; regular Incisive, Cadence Wynik symulacji: irun -mindelay regular.v 0 a=0 y=x z=x p=x q=x 10 a=0 y=1 z=x p=x q=x 30 a=0 y=1 z=0 p=x q=x 52 a=0 y=1 z=0 p=1 q=x 53 a=1 y=1 z=0 p=1 q=x 57 a=1 y=1 z=0 p=1 q=0 AGH, WFiIS, HDL 14

Opóźnienie zwykłe Przykład popsuty tak aby y było nie zainicjowane y=x w momencie gdy służy ono do wyznaczenia opóźnienia: //deklaracje parametrów localparam latency = 20, delta = 2; //deklaracje zmiennych rejestrowych reg a, y, z, p, q; initial begin a = 1 b0; //bez opóźnienia #latency z = 1 b0; //opóźnienie z identyfikatorem o 20 jedn. #(latency+delta) p = 1 b1;//opóźnienie z wyrażeniem o 22 jedn. #y a = a + 1 b1; //opóźnienie z identyfikatorem o wartość y #(4:5:6) q = 1 b0; //min:typ:max w zależności od opcji linii komend #10 y = 1 b1; //opóźnienie z liczbą; przypisanie po 10 //jednostkach czasu end initial $monitor($time," a=%d y=%d z=%d p=%d q=%d",a,y,z,p,q); initial #60 $finish; regular Incisive, Cadence Wynik symulacji: irun -typdelay regular.v 0 a=0 y=x z=x p=x q=x 20 a=0 y=x z=0 p=x q=x 42 a=1 y=x z=0 p=1 q=x 47 a=1 y=x z=0 p=1 q=0 57 a=1 y=1 z=0 p=1 q=0 AGH, WFiIS, HDL 15

Opóźnienie zwykłe Przykład z zamienionym blokiem sekwencyjnym na blok równoległy: //deklaracje parametrów localparam latency = 20, delta = 2; //deklaracje zmiennych rejestrowych reg a, y, z, p, q; initial fork a = 1 b0; //bez opóźnienia #latency z = 1 b0; //opóźnienie z identyfikatorem o 20 jedn. #(latency+delta) p = 1 b1;//opóźnienie z wyrażeniem o 22 jedn. #y a = a + 1 b1; //opóźnienie z identyfikatorem o wartość y #(4:5:6) q = 1 b0; //min:typ:max w zależności od opcji linii komend #10 y = 1 b1; //opóźnienie z liczbą; przypisanie po 10 //jednostkach czasu join initial $monitor($time," a=%d y=%d z=%d p=%d q=%d",a,y,z,p,q); initial #25 $finish; regular Incisive, Cadence Wynik symulacji: irun -maxdelay regular.v 0 a=1 y=x z=x p=x q=x 6 a=1 y=x z=x p=x q=0 10 a=1 y=1 z=x p=x q=0 20 a=1 y=1 z=0 p=x q=0 22 a=1 y=1 z=0 p=1 q=0 AGH, WFiIS, HDL 16

Opóźnienie wewnątrz przypisań Określane dla prawej strony przypisania proceduralnego. intra-assignmet //opóźnienie wewnątrz przypisań initial begin x = 0; z = 0;... y = #5 x + z; end //metoda równoważna za pomocą opóźnienia zwykłego initial begin x = 0; z = 0; temp_xz = x + z;... #5 y = temp_xz; end Konstrukcja ta jest niesyntezowalna od razu weź x i z i dodaj je; następnie czekaj 5 jednostek czasu i dopiero wykonaj przypisanie wartość x+z w chwili bieżącej wstaw do zmiennej tymczasowej nawet jeśli x i z uległy zmianie pomiędzy chwila 0 i 5, to nie ma to wpływu na wartość y AGH, WFiIS, HDL 17

Opóźnienie zerowe Jest metodą na określenie, które instrukcje spośród tych, które wykonują się w tej samej chwili czasu symulacji, mają być wykonane jako ostatnie. initial begin x = 0; y = 0; end initial begin #0 x = 1; //zerowe opóźnienie #0 y = 1; end //czyli x i y będą mieć wartości 1 Konstrukcja ta jest niesyntezowalna AGH, WFiIS, HDL 18

Sterowanie zdarzeniowe event-based Zdarzenie jest zmianą wartości rejestru lub węzła. Zdarzenia mogą wyzwalać wykonanie instrukcji lub bloku instrukcji. Są trzy rodzaje sterowania zdarzeniowego: zwykłe (regular) z nazwą (named) wielokrotne (or) AGH, WFiIS, HDL 19

Zwykłe sterowanie zdarzeniowe Jest określane za pomocą symbolu @, który umożliwia sterowanie wrażliwe na zbocze sygnału. regular //przypisanie q = d wykonuje się przy: @(clock) q = d; //każdej zmianie sygnału clock @(posedge clock) q = d; //narastającym zboczu sygnału clock @(negedge clock) q = d; //opadającym zboczu sygnału clock q = @(posedge clock) d; //narastającym zboczu sygnału clock //jednak obliczenie jego wartości jest wykonane natychmiast Uwagi: posedge narastające zbocze sygnału to zmiana jego wartości z do 0 1, x, z x 1 z 1 Konstrukcja ta jest niesyntezowalna negedge opadające zbocze sygnału to zmiana jego wartości z do 1 0, x, z x 0 z 0 AGH, WFiIS, HDL 20

Sterowanie zdarzeniowe z nazwą W Verilogu można zadeklarować zdarzenie i potem wyzwalać i rozpoznawać jego zajście. Zdarzenie nie przechowuje danych. Deklarowane jest za pomocą słowa kluczowego event. Wyzwalane jest za pomocą symbolu ->, a rozpoznawane symbolem @. named event received; bufor danych przechowuje dane po przybyciu ostatniego pakietu danych //deklaracja zdarzenia received always @(posedge clock) //wykonaj na zboczach narastających begin if (last_data_packet) ->received; jeśli to ostatni pakiet wyzwól zdarzenie received end always @(received) //oczekuj na zdarzenie received data_buf={data_pkt[0],data_pkt[1],data_pkt[2],data_pkt[3]}; jeśli zdarzenie received zostało wyzwolone to zapisz wszystkie cztery pakiety w buforze danych za pomocą operatora konkatenacji Konstrukcja ta jest niesyntezowalna AGH, WFiIS, HDL 21

Sterowanie zdarzeniowe wielokrotne or Umożliwia wyzwalanie zmianą jednego z wielu sygnałów lub zdarzeń rozdzielonych słowem kluczowym or lub przecinkiem,. Lista tych sygnałów lub zdarzeń jest też nazywana listą wrażliwości. Verilog-1995 //zatrzask czuły poziomem z asynchronicznym kasowaniem always @(reset or clock or d) //czekaj na zmianę tych sygnałów begin if (reset) //jeśli reset=1, q ustaw na 0 q = 1 b0; else if(clock) // jeśli clock=1, zatrzaśnij wejście q = d; end always @(reset, clock, d) begin if (reset) q = 1 b0; else if(clock) q = d; end Verilog-2001 AGH, WFiIS, HDL 22

Sterowanie poziomem wait Polega na oczekiwaniu aż spełniony zostanie pewien warunek zanim instrukcja lub ich grupa zostanie wykonana. Do tego celu używa się słowa kluczowego wait. //jeśli count_enable=0 to count nie zmienia się //jeśli count_enable=1 to count jest inkrementowane co 20 jed. always wait (count_enable) #20 count = count + 1; Konstrukcja ta jest niesyntezowalna AGH, WFiIS, HDL 23

Modelowanie przepływu danych Verilog pozwala na projektowanie w terminach przepływu danych między rejestrami i jakim procesom dane podlegają. Przypisanie ciągłe Jest podstawowym poleceniem modelowania na poziomie przepływu danych używanym do sterowania (ustawiania) wartości w węzłach. Przypisanie ciągłe zastępuje więc bramki. assign <opóźnienia> <zmienna_węzłowa> = <wyrażenie> Charakterystyka przypisania ciągłego: Po lewej stronie występuje skalar lub wektor węzłów. lub ich połączenie (concatenation). Jest obliczane tuż po wystąpieniu zmiany jednego z argumentów po stronie prawej i uzyskana wartość jest przypisywana do strony lewej. Argumenty po prawej stronie mogą być rejestrami lub węzłami lub wywołaniami funkcji. Mogą być skalarne lub wektorowe. Opóźnienia określają moment przypisania obliczonej wartości. data flow level AGH, WFiIS, HDL 24

Przypisanie ciągłe - przykłady //przypisanie ciągłe; out, i1, i2 - to węzły skalarne assign out = i1 & i2; data flow level //przypisanie ciągłe dla wektorów węzłów; //addr to 16-bitowy wektor węzłów, //addr1 i addr2 to 16-bitowe wektory rejestrowe assign addr[15:0] = addr1[15:0] ^ addr2[15:0]; //lub assign addr = addr1 ^ addr2; // przypisanie ciągłe z wykorzystaniem operatora //dołączania po stronie prawej assign {out,addr} = 17 h1ffff; //niejawne przypisanie ciągłe wire a = b && c; AGH, WFiIS, HDL 25

module mux2to1 (output out, input i0, i1, s); endmodule assign out = ~s & i0 s & i1; module mux2to1 (output out, input i0, i1, s); endmodule Multiplekser assign out = s?i1:i0; module mux4to1 (output out, input i0, i1, i2, i3, s1, s0); endmodule assign out = s1?(s0?i3:i2):(s0?i1:i0); module mux4to1 #(parameter nb=4) (output [nb-1:0] out, input [nb-1:0] i0, i1, i2, i3, input [1:0] adr); assign out = adr[1]?(adr[0]?i3:i2):(adr[0]?i1:i0); endmodule AGH, WFiIS, HDL 26

Projektowanie układów kombinacyjnych Sumator pełny a b c_in sum c_out 0 0 0 0 0 0 1 0 1 0 1 0 0 1 0 1 1 0 0 1 0 0 1 1 0 0 1 1 0 1 1 0 1 0 1 1 1 1 1 1 c_out = a b c_in + a b c_in + a b = a^b c_in + a b c_in a b 00 01 11 10 0 0 0 1 0 1 0 1 1 1 sum = a^b^c_in c_in a b 00 01 11 10 0 0 1 0 1 1 1 0 1 0 AGH, WFiIS, HDL 27

Sumator pełny 1 bitowy gate level module fulladd1(output sum, c_out, input a, b, c_in); wire s1, c1, c2; endmodule xor (s1, a, b); and (c1, a, b); xor (sum, s1, c_in); and (c2, s1, c_in); or (c_out, c2, c1); AGH, WFiIS, HDL 28

Sumator pełny 1 bitowy data flow level //1-bitowy sumator pełny przy użyciu dataflow module fulladd4 (output sum, output c_out, input a, b, input c_in); endmodule //funkcja sumatora pełnego assign {c_out, sum} = a + b +c_in; AGH, WFiIS, HDL 29

Sumator pełny 4 bitowy module fulladd4(output [3:0] sum, output c_out, input [3:0] a, b, input c_in); wire c1, c2, c3; fulladd1 fa0( sum[0], c1, a[0], b[0], c_in); fulladd1 fa1(sum[1], c2, a[1], b[1], c1); fulladd1 fa2(sum[2], c3, a[2], b[2], c2); fulladd1 fa3(sum[3], c_out, a[3], b[3], c3); endmodule gate level a[0] b[0] a[1] b[1] a[2] b[2] a[3] b[3] c_in fulladd1 fa0 c1 fulladd1 fa1 c2 fulladd1 fa2 c3 fulladd1 fa3 c_out sum[0] sum[1] sum[2] sum[3] AGH, WFiIS, HDL 30

Sumator pełny 4 bitowy //4-bitowy sumator pełny przy użyciu dataflow module fulladd4 (output [3:0] sum, output c_out, input [3:0] a, b, input c_in); endmodule //funkcja sumatora pełnego assign {c_out, sum} = a + b +c_in; data flow level a[0] b[0] a[1] b[1] a[2] b[2] a[3] b[3] c_in fulladd1 fa0 c1 fulladd1 fa1 c2 fulladd1 fa2 c3 fulladd1 fa3 c_out sum[0] sum[1] sum[2] sum[3] AGH, WFiIS, HDL 31

Zatrzask d 1 0 q Aktywny stanem niskim sygnału bramki g module latchn (input d, g, output q); assign q = g?q:d; endmodule g Incisive, Cadence d g q XST, Xilinx WARNING: Found 1-bit latch for signal <qm>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems. AGH, WFiIS, HDL 32

Przerzutnik Master negative 1 qm Slave positive 0 1 q Aktywny zboczem narastającym sygnału zegara clk module ffms (input d, clk, output q); //master assign qm = clk?qm:d; d 0 //slave assign q = clk?qm:q; clk endmodule Incisive, Cadence d clk q AGH, WFiIS, HDL 33

Instrukcja initial Określa blok initial zawierający pojedynczą lub wiele zgrupowanych instrukcji behawioralnych ujętych w blok sekwencyjny lub równoległy. Nie posiada żadnych parametrów. Wykonanie bloku initial rozpoczyna się w chwili zerowej i odbywa się tylko jeden raz (nigdy potem nie jest powtarzane). Jeśli występuje wiele bloków initial to wszystkie rozpoczynają się wykonywać równocześnie w chwili zerowej. Wykonanie każdego z nich odbywa się niezależnie. Blok initial jest używany w symulacji do inicjalizacji, monitorowania, generowania przebiegów i innych procesów wykonywanych tylko raz. Przykład bloku initial : initial begin a = 1'b1; forever #10 a = ~a; end Konstrukcja ta jest niesyntezowalna AGH, WFiIS, HDL 34

Instrukcja always Określa blok always zawierający pojedynczą lub wiele zgrupowanyvch instrukcji behawioralnych ujętych w blok sekwencyjny lub równoległy. Parametrem jest lista zdarzeń, które wyzwalają aktywność opisaną w bloku należącym do tej instrukcji. Listę tą nazywamy listą czułości lub wrażliwości procesu. Wykonanie bloku always zaczyna się w chwili zerowej i jest wykonywany cały czas jak pętla, której kolejny cykl rozpoczynany jest w chwili zajścia zdarzenia opisanego na liście wrażliwości. Blok always używany jest do modelowania stale powtarzanej aktywności układu cyfrowego. W zależności od sposobu użycia może służyć do modelowania układów kombinacyjnych lub sekwencyjnych. Każda konstrukcja initial i always reprezentuje oddzielny strumień aktywności rozpoczynający się w zerowej chwili czasu symulacji. Konstrukcje te nie mogą być zagnieżdżane. AGH, WFiIS, HDL 35

Instrukcja always Przykład bloku always: always @(posedge clk, posedge rst) if(rst) q <= 1 b0; else q <= d; Jest to podstawowy model przerzutnika D z kasowaniem asynchronicznym. AGH, WFiIS, HDL 36

Bloki Aby initial i always mogły działać na większych fragmentach kodu niż jedna linia potrzebne są bloki służące do zgrupowaniu pojedynczych instrukcji aby mogły działać jak jedna. Są dwa rodzaje bloków: Sekwencyjny begin - end Równoległy fork - join AGH, WFiIS, HDL 37

Blok sekwencyjny Poszczególne instrukcje są wykonywane w kolejności ich napotkania. Następna może być wykonana tylko po ukończeniu poprzedniej. Jeśli stosowane są opóźnienia lub zdarzenia, czas jest obliczany względem chwili ukończenia wykonania poprzedniej instrukcji. //bez opóźnień reg x, y; reg [1:0] z, w; initial begin x = 1 b0; y = 1 b1; z = {x, y}; w = {y, x}; end //z opóźnieniami reg x, y; reg [1:0] z, w; initial begin x = 1 b0; //zakończono dla time=0 #5 y = 1 b1; //zakończono dla time=5 #10 z = {x, y}; //zakończono dla time=15 #20 w = {y, x}; //zakończono dla time=35 end W obu przypadkach wyniki są takie same: x=1 b0, y=1 b1, z=2 b01, w=2 b10. W pierwszym przypadku dla czasu symulacji time=0, a w drugim time=35. AGH, WFiIS, HDL 38

Blok sekwencyjny - przykład module stimulus; reg x, y, a, b, m; initial m = 1 b0; //jedna instrukcja; nie wymaga grupowania initial begin #5 a = 1 b1; //wiele instrukcji; wymaga grupowania #25 b = 1 b0; end Kolejność wykonania initial begin #10 x = 1 b0; #25 y = 1 b1; end initial #50 $finish endmodule Jednostka czasu Wykonana instrukcja 0 m = 1 b0; 5 a = 1 b1; 10 x = 1 b0; 30 b = 1 b0; 35 y = 1 b1; 50 $finish AGH, WFiIS, HDL 39

Blok równoległy Poszczególne instrukcje są wykonywane równocześnie. Kolejność instrukcji jest określona przez sterowanie opóźnieniami i zdarzeniami przypisanymi do każdej instrukcji. Jeśli stosowane są opóźnienia lub zdarzenia, czas jest obliczany względem chwili wejścia do bloku. Porządek napisania poszczególnych instrukcji jest bez znaczenia. reg x, y, [1:0] z, w; initial begin x = 1 b0; //zakończono dla time=0 #5 y = 1 b1; //zakończono dla time=5 #10 z = {x, y}; //zakończono dla time=15 #20 w = {y, x}; //zakończono dla time=35 end reg x, y, [1:0] z, w; initial fork x = 1 b0; //zakończono dla time=0 #5 y = 1 b1; //zakończono dla time=5 #10 z = {x, y}; //zakończono dla time=10 #20 w = {y, x}; //zakończono dla time=20 join W obu przypadkach wyniki są takie same: x=1 b0, y=1 b1, z=2 b01, w=2 b10. W pierwszym przypadku dla czasu symulacji time=35, a w drugim time=20. Konstrukcja ta jest niesyntezowalna 40 AGH, WFiIS, HDL

Blok równoległy Blok równoległy zawsze powoduje powstanie hazardu, ponieważ wszystkie instrukcje wykonywane są równocześnie więc od symulatora zależy kiedy naprawdę procesor wykona poszczególne instrukcje. //bez opóźnień reg x, y; reg [1:0] z, w; initial fork join x = 1 b0; y = 1 b1; z = {x, y}; w = {y, x}; Jeśli najpierw wykona x=1 b0 i y=1 b1 to wynik będzie taki sam jak dla bloku sekwencyjnego. Jednak wynik będzie z=2 bxx i w=2 bxx jeśli przypisania x=1 b0 i y=1 b1 wykonają się na końcu. Tego nie można przewidzieć. AGH, WFiIS, HDL 41

initial begin Zagnieżdżanie bloków Bloki mogą być dowolnie zagnieżdżane. Praktyczne znaczenie może mieć umieszczenie bloku równoległego wewnątrz bloku sekwencyjnego. end x = 1 b0; fork #5 y = 1 b1; #10 z = {x, y}; join #20 w = {y, x} Blok fork zostanie zakończony po 10 jednostce czasu więc przypisanie do w zajdzie w 30 jednostce czasu. AGH, WFiIS, HDL 42

Blokom można nadawać nazwy. Stają się wtedy częścią hierarchii projektu. Odwołania do zmiennych mogą być wykonywane za pomocą nazw hierarchicznych. Bloki z nazwą umożliwiają: definiowanie zmiennych lokalnych, przerywanie wykonania kodu instrukcją disable, tworzenie pętli generate. module top; initial begin: block1 //blok sekwencyjny o nazwie block1 integer i; to jest zmienna statyczna i lokalna w block1... end initial fork: block2 //blok równoległy o nazwie block2 reg i; to jest zmienna statyczna i lokalna w block2... join endmodule Blok z nazwą AGH, WFiIS, HDL 43

Wykonanie bloków z nazwą można zatrzymywać. Służy do tego słowo kluczowe disable. Za pomocą tej instrukcji można: przerwać wykonywanie pętli, obsłużyć błąd lub sterować wykonaniem fragmentu kodu. reg [15:0] flag; integer i; //indeks Blok z nazwą znajdź pierwszy bit o wartości 1 w zmiennej flag initial begin flag = 16 b 0010_0000_0000_0000; i = 0; begin: block1 //blok główny o nazwie block1 while (i < 16) begin if (flag[i]) begin $display( natrafiono bit 1 na pozycji %d,i); disable block1; end i=i+1; end end end AGH, WFiIS, HDL 44

Przypisanie proceduralne Służy do zmiany wartości zmiennych typu reg, integer, real i time. Takie zmienne mogą zmienić swoją wartość tylko przez kolejne przypisanie proceduralne. <lwartość> = <wyrażenie> <lwartość> - jest to: zmienna typu reg, integer, real lub time lub element pamięci; pojedynczy bit (np. Addr[0]); grupa bitów zmiennej wektorowej (np. Addr[31:16]); połączenie kilku powyższych. Są dwa rodzaje przypisań proceduralnych: blokujące, nieblokujące. AGH, WFiIS, HDL 45

Blokujące przypisania proceduralne Zwane też sekwencyjnymi Są wykonywane w kolejności w jakiej pojawiają się w bloku sekwencyjnym. reg x, y, z; reg [15:0] reg_a, reg_b; integer count; initial begin x = 1 b0; y = 1 b1; z = 1 b1; //przypisania skalarne count = 0; //przypisanie do zmiennej integer reg_a = 16 b0; reg_b = reg_a; //inicjacja wektorów #15 reg_a[2] = 1 b1; //przypisanie do jednego bitu z opóźnieniem #10 reg_b[15:13] = {x,y,z}; //przypisanie wyniku konkatenacji //do części wektora count = count + 1; //ponowne przypisanie do zmiennej integer end W tym przykładzie przypisania: od x = 1 b0 do reg_b = reg_a są wykonywane w chwili 0, reg_a[2] = 1 b1 w chwili 15, reg_b[15:13] = {x,y,z} i inkrementacja count w chwili 25. AGH, WFiIS, HDL 46

Przypisania blokujące Przypisania blokujące nazywają się tak, gdyż blokują wykonanie następnej instrukcji proceduralnej w bloku sekwencyjnym do chwili, aż przypisanie rzeczywiście zostanie wykonane. Jest to tak jak spodziewamy się w typowym języku proceduralnym jak C. Jeśli użyjemy opóźnienia to wykonanie będzie blokowane aż określony czas opóźnienia upłynie. Jest to bezużyteczne przy syntezie ale bardzo potrzebne przy tworzeniu modułów testujących. Z punktu widzenia syntezy lepszą nazwą jest przypisanie natychmiastowe. AGH, WFiIS, HDL 47

Nieblokujące przypisania proceduralne Zwane też równoczesnymi lub kolejkowanymi Pozwalają na kolejkowanie przypisań bez powstrzymywania wykonywania instrukcji występujących w bloku sekwencyjnym. Do zapisu nieblokujących dla mniejszy lub równy ). przypisań stosuje się operator <= (taki sam jak Koniecznie należy je stosować przy modelowaniu elementów sekwencyjnych (przerzutników). AGH, WFiIS, HDL 48

Przypisania nieblokujące Przypisania nieblokujące nazywają się tak, gdyż nie blokują wykonania następnej instrukcji proceduralnej w bloku sekwencyjnym. Niezależnie od tego czy użyto opóźnienia czy nie wykonanie jest kontynuowane dalej. Jest to inaczej niż w typowym języku proceduralnym jak C. Prawa strona przypisania jest obliczana natychmiast, ale uzyskana wartość nie jest przypisywana do strony lewej aż dopiero po zakończeniu wykonania całego bloku. Z punktu widzenia syntezy lepszą nazwa byłoby przypisanie trochę odłożone lub przypisanie późne. AGH, WFiIS, HDL 49

Nieblokujące przypisania proceduralne reg x, y, z; reg [15:0] reg_a, reg_b; integer count; initial begin x = 1 b0; y = 1 b1; z = 1 b1; //przypisania skalarne count = 0; //przypisanie do zmiennej integer reg_a = 16 b0; reg_b = reg_a; //inicjacja wektorów reg_a[2] <= #15 1 b1; //przypisanie do jednego bitu z opóźnieniem reg_b[15:13] <= #10 {x,y,z}; //przypisanie wyniku dołączania //do części wektora count <= count + 1; //ponowne przypisanie do zmiennej integer end W tym przykładzie przypisania: od x = 0 do reg_b = reg_a są wykonywane sekwencyjnie w chwili 0. Następnie wykonywane są trzy przypisania nieblokujące. Symulator wstawia je do kolejki i nie czekając na ich wykonanie przechodzi do następnej instrukcji. Przypisanie: reg_a[2] = 1 b1 zostanie wykonane w chwili 15, reg_b[15:13] = {x,y,z} w chwili 10, inkrementacja count w chwili 0 ale dopiero po wykonaniu przypisań blokujących przewidzianych na chwile 0. AGH, WFiIS, HDL 50

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. AGH, WFiIS, HDL 51

reg x, y,z; initial begin x = #5 1'b0; //x otrzymuje wartość 0 w chwili 5 y = #3 1'b1; //y otrzymuje wartość 1 w chwili 8 z = #6 1'b0; //z otrzymuje wartość 0 w chwili 14 end x y z Incisive, Cadence AGH, WFiIS, HDL 52

reg x, y,z; initial begin x <= #5 1'b0; //x otrzymuje wartość 0 w chwili 5 y <= #3 1'b1; //y otrzymuje wartość 1 w chwili 3 z <= #6 1'b0; //z otrzymuje wartość 0 w chwili 6 end x y z Incisive, Cadence AGH, WFiIS, HDL 53

reg a, b,c, d; initial begin a <= #5 1'b0; //a otrzymuje wartość 0 w chwili 5 b = #3 1'b1; //b otrzymuje wartość 1 w chwili 3 c <= #6 1'b0; //c otrzymuje wartość 0 w chwili 9 d = #7 1'b0; //d otrzymuje wartość 0 w chwili 10 end a b c d Incisive, Cadence AGH, WFiIS, HDL 54

reg a, b,c, d; initial begin a = #5 1'b0; //a otrzymuje wartość 0 w chwili 5 b <= #3 1'b1; //b otrzymuje wartość 1 w chwili 8 c = #6 1'b0; //c otrzymuje wartość 0 w chwili 11 d <= #7 1'b0; //d otrzymuje wartość 0 w chwili 18 end a b c d Incisive, Cadence AGH, WFiIS, HDL 55

Nieblokujące przypisanie proceduralne (c.d.) Stosowane są jako metoda modelowania równoczesnego transferu danych kilkoma różnymi drogami zachodzącego w momencie wystąpienia pewnego zdarzenia. always @ (posedge clock) begin reg1 <= #1 in1; reg2 <= @(negedge clock) in2 ^ in3; reg3 <= #1 reg1; //stara wartość reg1 end Przy każdym narastającym zboczu zegara zachodzi następująca sekwencja zdarzeń: Odczytane zostają wartości zmiennych in1, in2, in3, reg1 występujących po stronie prawej przypisań. Wyrażenia występujące z prawej strony są obliczane, a ich wyniki zapamiętywane w tymczasowych zmiennych symulatora. Operacje wpisania uzyskanych wyników do strony lewej są umieszczane w kolejce wykonania pod czasami określonymi w instrukcjach. Tzn. zapis zmiennych reg1 i reg3 jest zaplanowany na chwilę czasu 1 po narastającym zboczu zegara, a zapis zmiennej reg2 odbędzie się w chwili wystąpienia opadającego zbocza zegara. Operacje przypisania są wykonywane w przewidzianym czasie. Faktyczna kolejność przestaje być istotna gdyż przypisywane wartości są już obliczone i czekają. W ten sposób wiadomo, że w reg3 znajdzie się stara wartość reg1 nawet jeśli przypisanie do reg1 nastąpi wcześniej. AGH, WFiIS, HDL 56

Nieblokujące przypisanie proceduralne (c.d.) Dwa równoczesne bloki always z przypisaniami sekwencyjnymi always @(posedge clock) a = b; always @(posedge clock) b = a; Występuje hazard. Nie wiemy, która z operacji zostanie wykonana wcześniej. Zawartości rejestrów nie zostaną wymienione, ale w obydwu znajdzie się ta sama wartość tzn. początkowa wartość a lub b, zależnie od konkretnej implementacji Veriloga. AGH, WFiIS, HDL 57

Nieblokujące przypisanie proceduralne (c.d.) Dwa równoczesne bloki always z przypisaniami równoczesnymi always @(posedge clock) a <= b; always @(posedge clock) b <= a; Zawartości zmiennych a i b zostaną zamienione na każdym narastającym zboczu zegara, gdyż operacje są wykonywane z pośredniczeniem przez zmienne tymczasowe. To samo można osiągnąć inaczej, ale dłużej przy użyciu zmiennych tymczasowych. AGH, WFiIS, HDL 58

Nieblokujące przypisanie proceduralne (c.d.) Stosowanie przypisań nie blokujących wyklucza potrzebę używania zmiennych tymczasowych. always @(posedge clock) begin temp_a = a; temp_b = b; a = temp_b; b = temp_a; end Stosowanie przypisań równoczesnych jest rekomendowane gdyż zabezpiecza przed powstaniem hazardu tzn. rezultat nie zależy od kolejności wykonania operacji. Z drugiej strony przypisania równoczesne mogą spowodować spowolnienie symulacji i większe zużycie pamięci. AGH, WFiIS, HDL 59

Przypisania z opóźnieniami Pięć przypadków: always @* #d a = b; LHS Blocking Left Hand Side always @* a = #d b; RHS Blocking Right Hand Side always @* #d a <= b; LHS Nonblocking Left Hand Side always @* a <= #d b; RHS Nonblocking Right Hand Side assign #d a = b; Continuous AGH, WFiIS, HDL 60