Verilog

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;
    endendmodule
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;
      endendmodule
„<=“ 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.

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äsklustwire 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;

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.