joi, 10 februarie 2011

Capitolul IV

 Sistemul


4.1    Noţiuni generale

Ştim de acum cum să specificăm interfaţa unui modul. Dar cum se specifică corpul lui?
Cea mai simplă cale pentru a descrie un sistem este de a ne referi la el ca la o strucutură cu un set de componente interconectate. Aici vom învăţa cum să specificăm modele mai complexe.
Vom începe cu descrierea unui modul utilizând cele mai simple componente – primitivele de porţi. Ele sunt predefinite în limbajul Verilog. Putem lua câteva porţi, le iniţializăm în modul, le conectăm cu alte porţi cu fire şi ele devin o parte a modulului. (Secţiunea 2).
Mai departe (secţiunea 3) vom face o introducere în concepţiile de definire a primitivelor în cazul când primitivele standard sunt insuficiente pentru realizarea problemei.
Deseori putem avea nevoie să utilizăm componente mai complexe ca primitivele. Deci vom analiza (în secţiunea 4) cum să utilizăm aceste componente mai complexe, modulele. Utilizarea nu este mai complexă decât utilizarea primitivelor, atât timp cât respectăm câteva reguli simple.



4.2    Primitive Verilog.
4.2.1    Introducere în specificarea structurală.
Orice sistem poate fi descris în formă de set de module interconectate. Modulele la rândul lor pot conţine la fel un set de submodule interconectate. Verilog permite asemenea specificaţii ale sistemului.
Reprezentarea structurală a sistemului este orientată mai mult spre implementarea fizică decât spre comportamentul lui, dar este mai puţin corectă din cauza detalierii prea mari.   
O structură Verilog poate include componente de diferit nivel de complexitate, începând de la tranzistoare şi terminând cu circuite mai complexe.
Verilog are un set predefinit de porţi logice, cunoscute ca primitive. Orice circuit digital poate fi constituit din aceste porţi primitive. Deoarece porţile primitive sunt atât de esenţiale într-un sistem digital, în continuare vom discuta despre specificarea şi utilizarea lor.

4.2.2    Primitive de porţi predefinite.
Verilog oferă un set de 14 primitive de porţi logice care pot fi utilizate pentru a specifica structural un circuit. Primitivele de porţi logice sunt împărţite în patru grupe:
-    porţi cu intrări multiple;
-    porţi cu ieşiri multiple;
-    porţi tristate;
Grupul de porţi cu intrări multiple conţine şase porţi logice and, nand, or, nor, xor, xnor. Fiecare din ele execută o operaţie logică pentru mai multe intrări. Tabelele de adevăr pentru porţi cu două intrări au fost precăutate mai devreme. Tabelele pentru porţi cu mai multe intrări este o extensie a celor cu două intrări.
Grupul de porţi cu ieşiri multiple conţin numai două porţi: buf şi not. Fiecare din ele au o intrare şi mai multe ieşiri.
Porţile tristate reprezintă bufere tristate activate cu ,,1’’ sau ,,0’’ ele sunt bufif0, bufif1, notif0 şi notif1, poarta tristate inactivă are valoarea ,,z’’ la ieşire. Aceste porţi au o intrare, o ieşire şi o intrare de control.
4.2.3    Construirea unei specificaţii cu primitive.
Pentru a construi o specificaţie, în afară de primitive, avem nevoie de specificat declaraţiile instanţelor de poartă şi declaraţia semnalelor de interconectare. Aşa cum despre declaraţiile de semnale s-a vorbit mai devreme, ne vom concentra numai asupra instanţelor de primitive.
Utilizarea unei instanţe de primitivă înseamnă a selecta un element-poartă din bibliotecă şi a conecta semnalele la intrările şi ieşirile respective ale lui. Ca rezultat se vor conţine cel puţin două elemente de cod in descriere: numele primitivei şi lista semnalelor numite terminale.
În plus, o instanţă de primitivă poate conţine opţional informaţii despre puterea porţii, timpul de propagare, un nume unic pentru o poartă particulară, şi în cazul unui tabel de porţi, numărul de ordine a lui.
4.2.4    Ordinea instanţelor
Dacă ne vom întreba care e ordinea corectă a specificaţiilor de porţi, sau în ce ordine se activează porţile, vom găsi răspunsul în cele ce urmează.
Într-un circuit real, porţile funcţionează concomitent şi toate intrările sunt ,,înştiinţate’’ continue despre schimbări. Când un semnal se schimbă, poarta respectivă se activează şi execută operaţia logică respectivă.
Într-o declaraţie textuală în Verilog este imposibil de specificat instanţe de porţi într-o formă concurentă. În schimb, compilatorul, simulatorul şi sintetizatorul atribuie acestor tipuri de specificaţii funcţionalitate concurentă. Se întâmplă, deci, acelaşi lucru ca şi la circuitele reale, adică, la schimbarea unei intrări se activează poarta indiferent de locul unde se află.
În consecinţă nu are importanţă în ce ordine sunt specificate instanţele de primitive, circuitul va reacţiona la fel.
Toate construcţiile în Verilog sunt predefinit concurente în particular declaraţiile într-un bloc comportamental pot fi secvenţiale.

4.3    Primitive definite de utilizator(UDP).
4.3.1    Primitive definite de utilizator.
Deseori un circuit digital poate fi construit din porţi logice, dar nu totdeauna acest lucru este practic.
În particular, fiecare bistabil reprezintă două porţi conectate cros-over.
Pentru a elimina această incomoditate, Verilog permite specificarea şi utilizarea primitivelor definite de utilizator – UDP-uri (User-Defined primitive). Astfel de primitive pot fi combinaţionale sau secvenţiale şi reprezintă componente mai complexe decât porţile logice. Ele diferă de modulele obişnuite prin structură şi mod de iniţiere şi nici o intrare, iar ieşirea poate reprezenta un vector. Ele se pot considera ca construcţii a limbajului aflându-se undeva între primitive.
Un UDP are o structură specială şi este specificată numai în formă de tabel de adevăr. Tabela de adevăr are o formă diferită de primitivele combinaţionale şi cele secvenţiale. Le vom examina, în cele ce urmează.

 4.3.2    UDP-urile combinaţionale.
Definiţia unui UDP combinaţional conţine:
-    declaraţia porturilor care constă dintr-o singură ieşire şi mai multe intrări;
-    tabela de adevăr care descrie funcţionalitatea primitivei.
Ordinea intrărilor în lista de porturi are o mare importanţă primul semnal în listă trebuie să fie ieşirea primitivei urmată de intrările ei.
Funcţionalitatea primitivei este descrisă de o tabelă de adevăr. Ea, tabela, constă din coloane ale intrărilor urmată de coloana ieşirii. În fiecare  linie intrările sunt separate de ieşire prin două puncte (:), în fiecare linie ordinea intrărilor trebuie să corespundă cu ordinea lor în lista de porturi din antetul primitivei. Nu sunt metode de a schimba ordinea într-o tabelă. Fiecare combinaţie a intrărilor trebuie să fie specificată pentru a avea o valoare la ieşire, pentru toate combinaţiile ne specificate ieşirea va lua valoarea ,,x’’.
În afară de valorile obişnuite (,,0’’, ,,1’’, ,,x’’ sau ,,z’’), intrările pot fi specificate utilizând caracterul  ,,?’’ care substituie orice valoare a (,,0’’, ,,1’’, ,,x’’) şi ,,b’’ în loc de ,,0’’ sau ,,1’’.
4.3.3    UDP-urile segvenţiale pe nivel.
Dacă o primitivă este un circuit secvenţial, atunci ieşirea care reprezintă următoarea stare depinde nu numai de combinaţia intrărilor ci şi de valoarea stării curente din această cauză tabelul de adevăr secvenţial mai are încă o coloană care reprezintă starea curentă.
Tabelul în acest caz este reprezentat prin coloanele pentru toate intrările, după care urmează o coloană ce reprezintă starea aşteptată pentru fiecare combinaţie. Deoarece careva combinaţie poate avea ca rezultat pentru următoarea stare valoarea stării curente, se utilizează simbolul ,,-‘’ pentru a indica acest lucru. Acest simbol arată că nu au avut loc schimbări în starea circuitului.
În plus, o primitivă secvenţială poate fi iniţializată. Pentru a atribui o valoare iniţială pentru ieşirea primitivei se utilizează cuvântul cheie iniţial, urmat de atribuirea unei valori numelui de port de ieşire.


4.3.4    UDP-urile secvenţiale pe front
Multe circuite secvenţiale reacţionează nu la nivelul semnalului de intrare ci la tranziţia semnalului, (adică frontul) de la o valoare la alta. Probabil cel mai bun exemplu pentru un asemenea comportament este un bistabil care se schimbă pe font.
Frontul poate fi specificat în două moduri: ca o pereche de valori incluse în paranteze, adică (01) pentru tranziţia de la ,,0’’ la ,,1’’ sau simbolic, utilizând simboluri de o literă:
,,r’’ – front crescător – echivalent cu (01)
,,f’’ – front descrescător – echivalent cu (10)
,,p’’ – front pozitiv – echivalent cu (01), (0x) sau (x1)
,,*’’ – pentru orice schimbare – echivalent cu (??)
Verilog permite specificarea nu numai a unui semnal de tranziţie într-o înscriere a tabelului.
Un UDP pe front poate fi iniţializat la fel ca şi cel pe nivel.



4.3.5    Utilizarea UDP-urilor.
UDP-urile pot fi utilizate în mod asemănător cu primitivele porţilor predefinite. Diferenţa este că UDP-urile trebuie declarate.
Declaraţiile nu sunt tratate la acelaşi nivel a ierarhiei specificarea primitivelor în interiorul unui modul (între cuvintele cheie modul şi endmodule), ci se pot specifica înainte sau după modul, independent dacă sunt utilizate în acest modul. Ele se pot specifica într-un fişier separat utilizând directiva compilatorului include. Aceste obţinui dau posibilitatea de a crea o bibliotecă de UDP-uri.
UDP-urile extind semnificativ setul mic de primitive predefinite, în special primitivele secvenţiale, Însă ele sunt limitate de o singură ieşire posibilă. Se interzice definirea unor circuite de bază aşa ca sumatorul sau registrul, care se definesc ca module normale


4.4    Instanţe de Modul
4.4.1    Ierarhia şi primitivele.

Deoarece un circuit digital poate fi compus din porţi, orice specificaţie Verilog poate fi construită din primitive – predefinite sau UDP-uri. Însă ambele metode nu prea convin din cauya că pot ascunde erori. Deseori putem avea specificaţii ale unor blocuri care vor fi definite ca module Verilog şi ne va feri de eforturi mari dacă vom fi utilizate direct în specificaţia nouă.
Aşa cum Verilog permite instanţa a unor asemenea blocuri ca modulele, la fel ca şi primitivele nu e nevoie de studiat noi construcţii de limbaj pentru a face asta. Instanţele de modul însă, oferă mai multă flexibilitate decât utilizarea primitivelor pentru că modulele pot fi mai complexe cu un număr arbitrar de porturi. Primitivele nu pot avea instanţe de alte primitive însă modulele pot instanţa alte module, şi din aceste considerente putem construi o ierarhie cu mai multe nivele.
O restricţie importantă este că un modul nu se poate conţine în altul.

4.4.2    Regulile de conetare a porturilor.
Pentru o flexibilitate mai înalta a instanţelor de modul e nevoie de respectat câteva reguli de conectare a porturilor cu mediu extern.
Fiecare port constă din două capete de conexiune. Unul în interiorul modulului şi altul în exteriorul lui. Fiecare tip are anumite restricţii.
-    porturile de tip input trebuie să fie de tip net în interior şi pot fi conectate exterior la un net sau reg;
-    porturile inout trebuie să fie şi interior şi exterior de tip net;
-    output – interior net sau reg, exterior pot fi conectate exclusiv numai la un net.



4.4.3    Ordinea porturilor in listă.
Aplicarea semnalelor unui port într-o instanţă de modul poate fi făcută după ordinea în listă sau nume. Aceste două moduri nu pot fi mixate.
Ordinea în asocierea dintre semnele şi porturi este acea care este specificată în interiorul instanţei de modul. Adică primul semnal este atribuit (aplicat) primului port, al doilea la al doilea, etc.

4.4.4    Conectarea porturilor după nume.
Deşi conectarea porturilor după ordine este destul de naturală, uneori e nevoie de o  atribuire mai flexibilă. Uneori, când instanţele de modul au o listă mare de porturi, este dificil de a menţine ordinea lor. Conectarea porturilor după numele lor este mai simplă şi mai sigură. Pentru mai mulţi dintre noi nu e o problemă să reţinem în minte careva porturi, putini vor fi în stare să spună de exemplu care este portul al 17-lea într-un modul ce reprezintă microprocesorul 8051.
Pentru a facilita asocierea porturilor cu semnale după nume, Verilog permite conectarea la porturi după numele acestora. În acest caz semnalul trebuie să aibă un nume identic ca şi portul corespunzător. Fiecare semnal este specificat în paranteze după numele portului. Numele portului este precedat de punct.
Deoarece fiecare port este numit explicit, dispare nevoia de a menţine ordinea porturilor ca şi în specificaţia de modul. De fapt conexiunea după nume poate fi specificată în orice ordine.

4.4.5    Porturile neconectate.
Pe lângă posibilitatea utilizării atribuirii după numele de port, modulele au o importantă proprietate pe care primitivele nu le au – orice port poate rămâne neconectat.
Modul de specificare a porturilor care nu sunt conectate depinde de tipul conexiunii la port.
-    când semnele sunt conectate conform ordinii în listă, numărul de porturi este semnificativ şi de aceea fiecare port e reprezentat printr-un spaţiu liber. Aşa cum numărul de virgule în listă determină numărul de porturi, spaţiul se poate omite;
-    în cazul conexiunii după nume, portul fără conexiune pur şi simplu nu se include.
4.5    Test - Sistemul
        Să se selecteze afirmaşiile corecte:
1.    Orice circuit digital poate fi construit cu ajutorul primitivelor.
2.    Primul argument într-o primitivă de poartă este ieşirea ei.
3.    Verilog permite specificarea a unui număr arbitrar de intrări într-o instanţă de primitivă.
4.    O instanţă de primitivă cere un nume unic.
5.    Ordinea instanţelor este nesemnificativă.
6.    Ordinea coloanelor într-o tabela de adevăr a UDP-ului nu are vre-o semnificaţie dacă coloanele sunt descrise de numele semnalului.
7.    UDP-urile pot fi specificate în versiune scalară şi vectorială.
8.    Unicul mod de specificare a UDP-ului este tabela de adevăr.
9.    Orice UDP poate avea numai o ieşire.
10.    UDP-urile secvenţiale se pot iniţializa.
11.    UDP-urile sunt specificate într-un modul pe care îl utilizăm.
12.    Modulele care vor fi iniţializate trebuie să respecte un stil special a codului.
13.    Toate porturile într-o instanţă de modul trebuie neapărat conectate.
14.    Predefinit porturile într-o instanţă de modul sunt conectate după ordinea în listă.
15.    Porturile conectate după nume într-o instanţă de modul, nu pot fi în aceiaşi ordine ca şi în declaraţia de modul.