**Verilog**, standardiseeritult **IEEE 1364**, on riistvarakirjelduskeel (HDL), mida kasutatakse elektriliste süsteemide modelleerimiseks. Verilogi kasutatakse kõige enam üldisel registrilisel tasemel digitaalsete skeemide kavandamisel ja ülevaatusel. Lisaks kasutatakse seda ka analoog- ja digitaalsignaalide skeemide koostamisel.

Ülevaade
--------

Riistvaralised kirjelduskeeled, nagu näiteks Verilog, erinevad tarkvaralistest programmeerimiskeeltest, sest need sisaldavad meetodeid aja ja signaalide levimise kiiruse omavahelise sõltuvuse kirjeldamiseks. Leidub kaks määravat operaatorit: tõkestav (=) ja lubav (<=) määrang. Lubav määrang võimaldab disaineritel kirjeldada olekumasina uuendusi vajaduseta määrata ja kasutada ajutist mälu. Kuna need ideed on osa Verilogi keelesemantikast, saavad disainerid kirjeldada skeeme suhteliselt kompaktsel ja sisutihedal viisil. Verilogi kasutuselevõtmine 1984. aastal võimaldas skeemide disaineritel, kes juba kasutasid graafilist skemaatikapõhist tarkvara ning erilisi koostatud tarkvaraprogramme elektriliste skeemide dokumenteerimiseks ja simuleerimiseks, suurendada tohutult oma produktiivsust.

Verilogi loojad tahtsid keelt, mis oleks sarnane C-programmeerimiskeele süntaksiga, mida juba omakorda kasutati laialdaselt tarkvara arenduses. Verilog on tõstutundlik ja omab tavalist eelprotsessorit nagu C(kuigi vähem keerukamat kui ANSI C/C++). Selle tingimuslaused (*if/else, for, while, case* jne.) on samaväärsed ja eelnevad operaatorid ühilduvad. Süntaktiliste erinevuste hulgas on muutujate deklareerimine (Verilogil on vaja teada bittide laiust võrgu/registrite tüüpidel), eraldatud protsesside plokid (*begin/end* loogeliste sulgude {} asemel) ja paljud muud väiksemad erinevused.

Verilogi disain koosneb moodulite hierarhiast. Moodulid kapseldavad disainihierarhia ja suhtlevad teiste moodulitega läbi määratud sisendite, väljundite ja mõlemasuunaliste portide kogumite. Seespidiselt võib moodul sisaldada igasuguseid kombinatsioone järgnevatest: võrgu/muutujate deklaratsioonid (ühendused, registrid, täisarvud), samaaegsed ja järjestikused käsuplokid ning juhtumid teistest moodulitest (allhierarhiad). Järjestikused käsud paiknevad *begin/end* ploki sees ja teostatakse ploki piires antud järjekorras. Plokid ise teostatakse aga samaaegselt, mis teeb Verilogist andmevookeele.

Verilogi idee "ühendusest" koosneb signaaliväärtustest (4-olekuline: „1, 0, Ujukomaarv, määratlemata") ja tugevustest (tugev, nõrk jne). See süsteem lubab jagatud signaaliliinide abstraktset modelleerimist, kus mitmed allikad juhivad ühist võrku. Kui ühendusel on mitu juhti, siis ühenduse (loetav) väärtus leitakse läbi allika juhtide ja nende tugevuste omavahelise funktsiooni.

Verilogi käskude alamhulgad on sünteesitavad. Tema mooduleid, mis kohanduvad sünteesitavale koodi stiilile RTL (lühend nimest *register-transfer level*), saab füüsiliselt teostada sünteesiva tarkvaraga. Sünteesiv tarkvara kujundab (abstraktse) Verilogi allika algoritmiliselt võrguloendiks. See on teisisõnu loogiliselt samaväärne kirjeldus, mis koosneb ainult algelistest loogikaelementidest (NING, VÕI, EI, triger jne), mis on omakorda olemas erilistel FPGA või VLSI (lühend nimest *Very-large-scale integration*) tehnoloogiatel. Edasised muudatused võrguloendile viivad lõpuks koostatavate skeemide joonisteni (näiteks fotomaskikogum ASIC-le või bittvoofail FPGA-le).

Näiteid
-------

"Hello world! programm näeb välja selline:

```
module main;
  initial
    begin
      $display("Hello world!");
      $finish;
    end
endmodule

```

Lihtne näide kahest trigerist:

```
module toplevel(clock,reset);
  input clock;
  input reset;
 
  reg triger1;
  reg triger2;
 
  always @ (posedge reset or posedge clock)
    if (reset)
      begin
        triger1 <= 0;
        triger2 <= 1;
      end
    else
      begin
        triger1 <= triger2;
        triger2 <= triger1;
      end
endmodule

```

„<=" operaator Verilogis on veel üks näide sellest, et see on riistvarakirjelduskeel, mitte tavaline protsessikeel. Seda teatakse lubava määranguna. „<=" operaatori tegevus ei avalda mõju järgmise kellatsüklini. See tähendab, et käskude järjekord pole oluline ning toob sama tulemuse: **triger1** ja **triger2** vahetavad väärtuseid iga kellatsükli tagant. 
Teist määravat operaatorit „=" teatakse tõkestava määranguna. „=" määrangu kasutusel uuendatakse sihtmuutuja kohe loogikaeesmärkide järgi. Kui ülemises näites oleksid käsud kasutanud „=" operaatorit „<=" asemel, poleks **triger1** ja **triger2** vahetunud. Selle asemel oleks kompilaator sättinud lihtsalt **triger1** võrdseks **triger2**-ga (ja samaaegselt eiranud ülemäärast loogikat seada **tiger2** võrdseks **triger1**-ga).

Näide viivitustest (*delay*):

```
...
reg a, b, c, d;
wire e;
...
always @(b or e)
  begin
    a = b & e;
    b = a | b;
    #5 c = b;
    d = #6 c ^ e;
  end

```

*Always* (alati) klausel kirjeldab teist kasutusmeetodit. See tähendab, et see teostub ükskõik millal ükski loendis olevatest olemitest (**b** või **e**) muutub. Kui üks nendest muutub, määratakse **a**-le otsekohe uus väärtus, ning vastavalt tõkestavale määrangule määratakse **b**-le hiljem omakorda uus väärtus (võttes arvesse **a** uue väärtuse). Pärast viieühikulist viivitust määratakse **c**-le **b** väärtus ning **c^e** väärtus talletatakse nähtamatus mäluosas. Seejärel peale omakorda kuueühikulist viivitust määratakse **d**-le talletatud **c^e** väärtus. 

Protsessisiseselt juhitavad signaalid [*initial* (algus) või *always* plokk] peavad olema registri (*reg*) tüüpi. Protsessiväliselt juhitavad signaalid peavad olema ühenduse (*wire*) tüüpi. Võtmesõna *reg* ei tähenda ilmtingimata riistvaralist registrit.

Konstantide definitsioonid
--------------------------

Verilog lubab lisada konstantide definitsioonidele parameetreid laiuse kirjeldamiseks. Tavaline süntaks näeb välja selline:

<*Bittide laius*>'<*kahendastme täht*><*number*>

Näited:

* 12'h123 – Kuueteistkümnendkoodis 123 (kasutades 12 bitti)
* 20'd44 – Kümnendkoodis 44 (kasutades 20 bitti – laiend 0 on automaatne)
* 4'b1010 – Kahendkoodis 1010 (kasutades 4 bitti)
* 6'o77 – Kaheksandkoodis 77 (kasutades 6 bitti)

Sünteesitavad konstruktsioonid
------------------------------

Verilogis on käske, millel pole analoogiat reaalse riistvaraga, nagu näiteks $display. Järelikult ei saa kasutada suurt osa keelest riistvara kirjeldamiseks. Järgnevalt on toodud klassikalised näited keele alamhulkadest, millele leidub otsene vaste reaalsete väratitega.

Näited multipleksoritest – kolm võimalust sama asja tegemiseks.

```
 
// Esimene näide kasutab pidevat käsklust
wire out;
assign out = sel ? a : b;
 
// Teine näide kasutab protseduuri
// sama asja saavutamiseks.
 
reg out;
always @(a or b or sel)
  begin
    case(sel)
      1'b0: out = b;
      1'b1: out = a;
    endcase
  end
 
// Viimasena võib kasutada protsessistruktuuris ''if/else'' tingimusi.
reg out;
always @(a or b or sel)
  if (sel)
    out = a;
  else
    out = b;

```

Operaatorid
-----------

Märkus: Need operaatorid pole tähtsuse järjekorras.

| Operaatori tüüp | Operaatori sümbolid | Sooritatavad operatsioonid |
| --- | --- | --- |
| Bitiline | ~ | Bitiline EI (ühe täiend) |
| & | Bitiline NING |
| | | Bitiline VÕI |
| ^ | Bitiline XOR (välistav VÕI) |
| ~^ või ^~ | Bitiline XNOR (Välistav VÕI-EI) |
| Loogiline |  ! | EI |
| && | NING |
| || | VÕI |
| Vähendav & Vähendav NING |
| ~& | Vähendav NING-EI |
| ~| | Vähendav VÕI |
| ~| | Vähendav VÕI-EI |
| ^ | Vähendav XOR |
| ~^ või ^~ | Vähendav XNOR |
| Aritmeetiline | + | Liitmine |
| – | Lahutamine |
| – | Kahe täiend |
| \* | Korrutamine |
| / | Jagamine |
| \*\* | Astendamine (\*Verilog-2001) |
| Relatsioon | > | Suurem kui |
| < | Väiksem kui |
| >= | Suurem või võrdne |
| <= | Väiksem või võrdne |
| == | Loogiline võrdelisus (biti väärtus 1'bX on võrdusest eemaldatud) |
|  != | Loogiline erinevus (biti väärtus 1'bX on võrdusest eemaldatud) |
| === | 4-olekuline loogiline võrdelisus (biti väärtus 1'bX on võetud tähelisena) |
|  !== | 4-olekuline loogiline erinevus (biti väärtus 1'bX on võetud tähelisena) |
| Nihe | >> | Loogiline nihe paremale |
| << | Loogiline nihe vasakule |
| >>> | Aritmeetiline nihe paremale (\*Verilog-2001) |
| <<< | Aritmeetiline nihe vasakule (\*Verilog-2001) |
| Aheldamine | {, } | Aheldamine |
| Replikatsioon | {n{m}} | Kopeeri väärtust m n korda |
| Tingimus |  ? : | Tingimus |

Neljaväärtuseline loogika
-------------------------

IEEE 1364 liides määrab ära neljaväärtuselise loogika, millel on neli erinevat olekut: 0, 1, Z (kõrge impedants) ja X (tundmatu loogikaväärtus). VHDL-i jaoks leidub veel omakorda üheksatasemeline liides IEEE 1164 mitmeväärtuseliseks loogikaks.

Süsteemikäsud
-------------

Süsteemikäsud on olemas lihtsamate sisend-väljundfunktsioonide ja erinevate koostemõõtmete käsitlemiseks. Kõik süsteemikäsud algavad märgiga $, et eristada neid kasutajakäskudest ja -funktsioonidest. Siinkohal on toodud väike nimekiri enimkasutatud käskudest, mis pole kindlasti kõikehõlmav.

* $display – Väljastab ekraanile rea, millele järgneb kohe uus rida.
* $write – Kirjutab ekraanile rea, millele ei järgne uut rida.
* $swrite – Väljastab muutujale rea, millele ei järgne uut rida.
* $sscanf – Loeb muutujast vormindatud sõne. (\*Verilog-2001)
* $fopen – Avab käsitletava faili (kirjutamine või lugemine).
* $fdisplay – Kirjutab faili rea, millele järgneb kohe uus rida.
* $fwrite – Kirjutab faili rea, millele ei järgne uut rida.
* $fscanf – Loeb failist vormindatud sõne. (\*Verilog-2001)
* $fclose – Sulgeb ja võimaldab kasutuseks lahtise käsitletava faili.
* $readmemh – Loeb kuueteistkümnendfaili sisu mälumassiivi.
* $readmemb – Loeb binaarfaili sisu mälumassiivi.
* $monitor – Väljastab kõik väärtuseid muutnud loetletud muutujad.
* $time – Hetkel simuleeritava aja väärtus.
* $dumpfile – Sätib VCD (inglise keeles *Value change dump*) vormingu väljundfaili nime.
* $dumpvars – Võimaldab ja eemaldab muutujad.
* $dumpports – Võimaldab ja eemaldab muutujad laiendatud VCD vormingus.
* $random – Tagastab juhusliku väärtuse.

Viited
------

1. ↑  History Of Verilog Asic World Directory (vaadatud 4. detsembril 2012)
2. ↑  Lara Simsic: The C Programmers Guide to Verilog 9. juuli 2003 (vaadatud 4. detsembril 2012)
3. ↑  Verilog – Modules (vaadatud 4. detsembril 2012)
4. ↑  Deepak Kumar Tala: Wire And Reg In Verilog 15. veebruar 2012 (vaadatud 4. detsembril 2012)
5. ↑  Finbarr O’Regan: Verilog Synthesis Methodology oktoober 2001 (vaadatud 4. detsembril 2012)
6. ↑  Introduction to Verilog (vaadatud 4. detsembril 2012)
7. ↑  Verilog Wires and Registers (vaadatud 4. detsembril 2012)
8. ↑  Puneet Aggarwal: System Tasks and Functions (vaadatud 4.detsembril 2012)

* Navabi, Zainalabedin *"Verilog Digital System Design"*, ilmumisaasta 2005, kirjastus: McGraw-Hill, ISBN 9780071588928
* Janick Bergerdon, *"Designing Digital Computer Systems With Verilog*, ilmumisaasta 2007, kirjastus: Cambridge University Press, ISBN 9780511261664