ELECTRONICĂ DIGITALĂ VOL. II VERILOG HDL

Size: px
Start display at page:

Download "ELECTRONICĂ DIGITALĂ VOL. II VERILOG HDL"

Transcription

1 Dan Nicula Gheorghe Toacşe ELECTRONICĂ DIGITALĂ VOL. II VERILOG HDL EDITURA TEHNICĂ

2 II Această pagina va fi înlocuită. II

3 Şi această pagina va fi înlocuită. III III

4 Încă o pagina ce va fi înlocuită. IV

5 Prefaţă VERILOG, VERY-LOGIC HDL ( limbaj de descriere hardware foarte logic ): un nume extraordinar de bine ales pentru un limbaj care a devenit astăzi fundamental pentru proiectarea circuitelor integrate digitale. Acum 10 ani, în 1995, scriam în prefaţa unei cărti: Limbajul VHDL permite o exprimare sintetică în electronica digitală atât la nivel inferior, de poartă logică, cât şi la nivel superior, de sistem. Tehnicile de proiectare automată în electronică nu pot fi aplicate fără existenţa unui astfel de limbaj. Acum 7 ani, în 1998, predam beneficiarului un proiect scris în VHDL. În faza de depanare, beneficiarul îmi cere: Adaugă un registru pe această ieşire. Nici o problemă, zic şi încep să scriu următoarea porţiune de cod VHDL: -- acesta este modelul VHDL al unui registru de 8 biti signal extraff : std_logic_vector(7 downto 0); process(clk, reset) begin if (reset = 1 ) then extraff <= (others => 0 ); elsif (clk event and (clk = 1 )) then extraff <= semnal; if; process; iesire <= extraff; Am fost lăsat să termin şi apoi am fost întrebat: Vrei să vezi cum se scrie acelaşi lucru în Verilog?. Iată cum a fost răsplătită curiozitatea mea: // acesta este modelul VerilogHDL al unui registru de 8 biti clk or posedge reset) if (reset) iesire <= 0; else iesire <= semnal; Acum 6 ani, în 1999, mi s-a cerut proiectarea unui sistem digital cu cerinţa expresă: a se descrie în Verilog. Reacţia mea a fost imediată: - Nu ştiu Verilog. Replica a venit şi mai rapid: - Dar ştii VHDL. Verilog este foarte logic. Vei învăţa limbajul repede. În mai puţin de două zile, eram fluent în Verilog ca şi în VHDL. Pentru mine ca inginer, descoperirea Verilog a însemnat începutul unei noi ere. O eră aflată sub semnul simplificării proiectării. Acum, în 2005, am inclus în acest volum o parte din experienţa mea de utilizator al limbajului Verilog HDL în proiectarea de circuite integrate digitale. Cât timp proiectanţii şi companiile lor vor avea ca obiectiv producerea unor bunuri de calitate mare într-un timp scurt, Verilog va continua să fie o soluţie dominantă. Întreaga comunitate a firmelor de producţie de procesoare, calculatoare, circuite specifice ASIC utilizează Verilog ca principal limbaj de modelare.

6 VI Electronică digitală În prezent, Verilog este un limbaj folosit în toate etapele de proiectare a circuitelor integrate digitale: specificaţii; modelarea RTL; generare de vectori de test; mediu de simulare; module de monitorizare/verificare; netlist post-sinteză; biblioteci de componente specifice tehnologiei; model temporal cu parametrii actualizaţi conform implementării; documentare. Pentru un utilizator care învaţă pentru prima oară un limbaj de descriere hardware, alegerea Verilog este foarte justificată. Simplitatea şi apropierea acestuia de hardware permit utilizatorului începător atât concentrarea asupra proiectării arhitecturale, cât şi satisfacţia unei eficienţe a proiectării. Utilizatorii avansaţi găsesc în Verilog satisfacţia unui limbaj matur, folosit în mod curent pentru proiectarea unor circuite integrate reale. Pentru utilizatorii începători, acest volum prezintă o pagina cu limbajul Verilog condensat, pagină ce se doreşte a fi o referinţă rapidă pentru proiectantul Verilog HDL. Utilizatorii avansaţi pot găsi în această carte soluţii eficiente, optimizate pentru implementare hardware, la probleme ce par simple la nivel algoritmic. Modelarea pentru sintetizabilitate şi modelarea pentru obţinerea unui circuit care să funcţioneze la frecvenţă maximă sunt două idei pe care s-a concentrat acest volum. Toate porţiunile de cod şi mediile de testare asociate pot fi accesate pe situl cărţii. La aceeaşi adresă se găsesc indicaţii pentru obţinerea unei licenţe de evaluare a unui simulator Verilog. Situl web al acestei cărţii este: Anexa din finalul acestui volum prezintă simularea unei porţi inversoare în SPICE. Anexa este realizată cu contribuţia dl. Corneliu ZAHARIA. Acest volum este rodul anilor de predare a cursurilor de Limbaje de descriere hardware şi Proiectarea circuitelor integrate, la specializarea Ingineria Calculatoarelor de la Universitatea TRANSILVANIA din Braşov. Experienţa contactului cu lumea reală a proiectanţilor de circuite integrate digitale a fost asigurată prin participarea la activitatea de cercetare şi dezvoltare a firmei easic ( Probleme practice avansate, prezentate în ultimul capitol al acestui volum, au fost întâlnite în activitatea curentă la această firmă. Braşov, Septembrie Autorii

7 Cuprins 1 INTRODUCERE 1.1 Ce este Verilog? De ce HDL? Terminologia Verilog Aspectul temporal Concurenţa evenimentelor Modulul Mediul de simulare a modelelor HDL Comparaţie Verilog-VHDL 21 2 FUNDAMENTELE LIMBAJULUI VERILOG HDL 2.1 Convenţii lexicale Structura codului Verilog Setul de valori Numere întregi Numere reale Şiruri Tipuri de date şi obiecte Operatori Operatori aritmetici Operatori relaţionali Operatori de egalitate Operatori logici Operatori logici pe vectori Operatori de reducere Operatori de deplasare Operator condiţional Operatori de concatenare şi replicare Specificaţii concurente Specificaţii secvenţiale Specificaţii de atribuire secvenţiale Specificaţii condiţionale Specificaţii de selecţie Specificaţii de iteraţii Specificaţii de control temporal 59

8 VIII Electronică digitală 2.8 Directive de compilare define şi undefine ifdef, ifndef, else, if include timescale Stil şi calitate 67 3 MODELAREA CIRCUITELOR ELEMENTARE 3.1 Circuite combinaţionale Modelarea circuitelor logice cu assign Modelarea circuitelor logice cu always Circuite de multiplexare Codificator/decodificator Latch D Bistabil D/RS Bistabil T/JK Numărătoare sincrone Automate secvenţiale sincrone Semi-automat descris cu o singură specificaţie Modelarea ieşirilor automatelor Modelarea automatelor ca registru de stare şi circuit combinaţional Automat cu stări codificate one-hot NOŢIUNI AVANSATE DE VERILOG 4.1 Task-uri şi funcţii Modelarea memoriilor Generarea structurilor hardware Modelarea la nivel de poartă logică Porţi cu intrări multiple Porţi cu ieşiri multiple Porţi cu ieşiri în trei stări Porţi cu ieşiri fixe Modelarea la nivel de tranzistor Task-uri şi funcţii de sistem Task-uri de afişare Task-uri de accesare a fişierelor Task-uri pentru controlul simulării Task-uri pentru verificări temporale Funcţii referitoare la timpul simulării Funcţii pentru generarea numerelor aleatorii Primitive definite de utilizator Accesarea semnalelor în ierarhie Funcţii PLI Crearea unei aplicaţii PLI Apelarea aplicaţiei PLI Noutăţi introduse de standardul IEEE Verilog

9 Cuprins IX 5 PROBLEME REZOLVATE 5.1 Circuite de prelucrare a impulsurilor Circuite formatoare de impulsuri Generarea unui semnal în avans sau cu întârziere Circuit secvenţial pentru recunoaştere de pattern Verificator de protocol de comunicaţie Generarea semnalului de transport al unui numărător sincron Modelarea registrelor Registrul paralel Registrul cu reacţie, LFSR Sincronizarea semnalelor la trecerea între două domenii de ceas Sincronizarea unui semnal cu evoluţie lentă la trecerea dintr-un domeniu de ceas de frecvenţă scăzută într-un domeniu de ceas de frecvenţă ridicată Sincronizarea unui puls la trecerea dintr-un domeniu de ceas de frecvenţă ridicată într-un domeniu de ceas de frecvenţă scăzută Sincronizarea unui puls la trecerea dintr-un domeniu de ceas de frecvenţă scăzută într-un domeniu de ceas de frecvenţă ridicată Aplicaţie la sincronizarea unui bus cu variaţie lentă Aplicaţie la sincronizarea unui bus cu variaţie rapidă (FIFO) Interfaţarea cu CPU Multiplicator secvenţial Modelarea şi testarea memoriilor Modelarea multiplexoarelor Multiplexor modelat cu valori neprecizate Multiplexor în buclă cu bistabil Multiplexor pe bus Controller pentru memorie SDRAM Modelul Verilog al controllerului SDRAM Mediul de testare al controllerului SDRAM 229 Anexa A MODELAREA SPICE A UNUI INVERSOR CMOS A.1 Modelul SPICE al tranzistoarelor MOS 239 A.2 Ridicarea caracteristicii de sarcină I DS (V DS ) pentru tranzistorul NMOS 240 A.3 Modelul SPICE al inversorului CMOS 244 A.4 Determinarea caracteristicii de transfer şi a parametrilor inversorului CMOS 245 A.4.1 Nivelurile de tensiune 246 A.4.2 Marginea de zgomot 247 A.4.3 Timpul de propagare 247 A.4.4 Consumul de putere 250 A.4.5 Factorul de merit 251

10 X Electronică digitală Anexa B CUVINTE CHEIE REZERVATE ALE VERILOG HDL Anexa C MEMENTO LIMBAJ VERILOG Anexa D CONŢINUT SIT CARTE

11 Capitolul 1 INTRODUCERE Această parte a cărţii nu se doreşte a fi un manual complet al limbajului VerilogHDL, ci o sursă de învăţare rapidă şi eficientă a descrierii circuitelor digitale. Cu bună ştiinţă, vor fi expuse doar acele caracteristici ale limbajului care sunt mai des folosite la modelarea sistemelor digitale pentru sintetizabilitate. Pe parcursul acestei părţi apar următoarele semne care marchează pasaje cu diferite particularităţi: V cod sursă Verilog; S descrierea sintaxei unei specificaţii Verilog; T paragraf care face referire la un modul de test existent pe situl de web al cărţii. Paragrafele de cod Verilog şi referirea la numele variabilelor HDL sau la cuvinte cheie vor fi marcate evidenţiat prin scrierea acestora cu caractere tip typesetting. De remarcat că, în aceste paragrafe de cod sursă, cuvintele ce conţin caractere specifice limbii române (ă, â, î, ş, ţ) au fost înlocuite cu caracterele de origine ale acestora (a, a, i, s, t). Motivul este acela că Verilog nu suportă caracterele specific româneşti, nici măcar sub formă de comentarii. 1.1 Ce este Verilog? Un sistem digital se poate descrie fie schematic, fie textual. Datorită complexităţii sistemelor actuale, descrierea schematică nu mai permite gestionarea proiectelor mari. În schimb, descrierea textuală are nenumărate avantaje, cel mai important fiind uşurinţa prelucrării acestei descrieri de către programele de calculator. În prezent există două limbaje de descriere hardware (HDL = Hardware Description Language) care acoperă cea mai mare parte din proiectarea sistemelor digitale: 1

12 2 CAPITOLUL 1. INTRODUCERE Verilog şi VHDL. Verilog este un limbaj de descriere hardware a cărui denumire provine din concatenarea cuvintelor din limba engleză Very-logic (foarte logic). VHDL este un limbaj de descriere hardware a cărui denumire provine din concatenarea literei V (iniţiala abrevierii VHSIC = Very High Speed Integrated Circuits) şi HDL. VHDL nu este o abreviere pentru Verilog HDL. Verilog şi VHDL sunt două limbaje de descriere hardware diferite. Între acestea există multe asemănări dar există şi deosebiri. În continuare, prin HDL se va face referire la limbajele de descriere hardware în general, incluzând atât Verilog, cât şi VHDL. Un limbaj de descriere hardware este un limbaj utilizat pentru descrierea unui sistem digital, ca de exemplu un calculator sau o componentă a acestuia. HDL nu este un limbaj de programare pentru că nu descrie programe rulate de un procesor. Codul sursă scris în HDL nu trebuie numit program (cu înţelesul implicit de program pentru calculator ). Este recomandată denumirea codului sursă HDL ca model, cu înţelesul de model al unui sistem hardware. Limbajele de descriere hardware oferă suportul pentru proiectarea circuitelor integrate digitale. În HDL se poate descrie un sistem digital modelat la cel mai înalt nivel, precizându-se doar comportamentul abstract al acestuia. Mai detaliat, se poate descrie în HDL structura de registre a unui sistem digital şi ecuaţiile transferului de informaţii dintre registre. Acest nivel de descriere este denumit RTL (Register Transfer Level) şi este destul de detaliat pentru a fi acceptat ca intrare de către programe de calculator care fac trecerea de la model la realizare fizică (sinteza). După sinteză, descrierea sistemului digital implementat într-o anumită tehnologie se poate genera automat sub forma unui netlist HDL. Netlist (cuvânt provenit din limba engleză din concatenarea cuvintelor net =legătură/reţea şi list =listă) este denumirea unui model HDL particular: conţine o descriere structurală a unor instanţieri de componente descrise într-o bibliotecă de componente specifice tehnologiei de realizare a circuitului integrat. Netlist-ul este generat automat de către software. HDL oferă posibilitatea descrierii unui sistem digital la nivel de porţi logice şi bistabile. Proiectanţii de tehnologie folosesc tot HDL pentru a modela componentele primitive ale tehnologiei la nivel de sârme, tranzistoare, rezistoare. Descrierea textuală a circuitelor electronice digitale în HDL este folosită atât la proiectarea, cât şi la sinteza, la verificarea funcţională sau la analiza temporală a acestora. Verilog este unul dintre cele două cele mai folosite limbaje de descriere hardware. Părerile referitoare la avantajele şi dezavantajele fiecăruia sunt foarte diverse. Se spune că Verilog este mai uşor de învăţat pentru că este aşa cum îi spune numele very logic. VHDL a fost standardizat în 1987 sub numărul IEEE Ulterior, lipsa unor tipuri de date general acceptate a fost rezolvată prin apariţia standardului IEEE VHDL este un limbaj a cărui sintaxă seamănă cu sintaxa limbajului ADA. Promovarea limbajului ca standard a fost făcută de către Departamenul de Apărare al Statelor Unite. Verilog HDL a avut o traiectorie diferită, el provenind din mediul industrial. Sintaxa Verilog seamănă cu sintaxa limbajului C. Verilog a fost dezvoltat ca un limbaj de descriere proprietar de către firma ameri-

13 1.2. De ce HDL? 3 cană Gateway Design System Corporation între Succesul de care s-a bucurat simulatorul Verilog (Verilog-XL) produs de Gateway Design Automation a determinat o creştere rapidă a acestei firme. Ca efect, în 1989, Cadence Design Systems (cea mai mare firmă din domeniul producţiei de software pentru suportul proiectării de circuite integrate) a achiziţionat atât firma Gateway Design Automation, cât şi limbajul Verilog HDL produs de către aceasta. În 1990, Cadence Design Systems a decis deschiderea limbajului Verilog HDL către public. În 1991, se formează organizaţia OVI (Open Verilog International) cu scopul de a promova şi standardiza limbajul Verilog. Verilog HDL este standardizat cu numărul IEEE În plus, acest standard defineşte o colecţie de rutine software care permit interfaţarea dintre Verilog şi alte programe (de obicei C). Colecţia de rutine este cunoscută sub numele de PLI (Programming Language Interface). Standardizarea Verilog a determinat apariţia unor mici companii care ofereau simulatoare Verilog. Există simulatoare care acceptă descrieri mixte Verilog şi VHDL. 1.2 De ce HDL? Se pot remarca două scopuri ale modelării unui sistem digital: Realizarea sistemului cu cost minim într-un timp scurt şi Evitarea erorilor de proiectare. Primul motiv nu mai are nevoie de nici un fel de comentariu. Viteza de creştere extrem de mare pentru domeniul circuitelor integrate este unanim recunoscută. Orice întârziere a apariţiei unui produs nou pe piaţă poate aduce companiei producătoare pierderi însemnate. Al doilea motiv nu este foarte uşor de acceptat de către cei mai familiarizaţi cu dezvoltarea de produse software. Mai în glumă, mai în serios, se poate spune că: Hard-ul nu-i ca soft-ul. O greşeală găsită tardiv în software, chiar după ce produsul a fost livrat utilizatorului final poate fi uşor remediată cu o nouă versiune sau o peticire ( patch, în limba engleză). Noua versiune se poate distribui dintr-un sit de web, fără costuri prea mari pentru producătorul de software. În general, în hardware, greşeala costă mult mai mult decât în software. Pentru un circuit dedicat pentru o aplicaţie (ASIC = Application Specific Integrated Circuit), repararea unei greşeli poate însemna refacerea integrală a circuitului şi suportarea integrală a costurilor extrem de mari de producţie. Versiunile alpha sau beta din producţia de software sunt înlocuite cu mii de ore de verificare automată în producţia de hardware. Toate procedurile de verificare ale circuitelor integrate contemporane se bazează pe existenţa HDL şi a modelelor textuale. Derularea unui proiect pornind de la descrierea sa schematică presupune utilizarea unei metodologii de proiectare de jos în sus ( bottom-up, în limba engleză). Metodologia bottom-up presupune desenarea schemei modulelor elementare (cu simboluri de primitive existente într-o bibliotecă de tehnologie) şi ulterior conectarea acestora pentru a forma sistemul. Este de neconceput această abordare pentru proiectarea unui sistem mare, cum ar fi un procesor.

14 4 CAPITOLUL 1. INTRODUCERE Metodologia de proiectare a sistemelor digitale actuale, de mari dimensiuni este o metodologie de sus în jos ( top-down, în limba engleză). Metodologia top-down presupune modelarea sistemului la nivel înalt (comportamental) înainte de a defini detaliile de implementare. Câteva din avantajele acestei metodologii sunt precizate în continuare: Sistemele digitale actuale nu mai pot fi stăpânite prin descriere schematică. Limbajele HDL oferă suport pentru metodologia de proiectare topdown. Posibilitatea corectării greşelilor de concepţie în faze foarte timpurii. Având un model al întregului sistem, se poate evalua funcţionarea acestuia în conexiune cu alte circuite. De exemplu, se poate simula funcţionarea unui întreg produs realizat sub formă de circuite integrate montate pe un cablaj imprimat, chiar dacă unele componente nu sunt realizate. Multe sisteme actuale nu sunt exclusiv hardware, ci hardware - software. Existenţa unui model de simulare al sistemului hardware înainte ca acesta să fie realizat fizic, permite munca în paralel a echipelor de dezvoltare de software şi de hardware. Prin aceasta, dezvoltarea de software este suprapusă în timp peste dezvoltarea de hardware. Mai mult, se pot testa programele software împreună cu modelul de simulare hardware. Posibilitatea partajării proiectării şi a lucrului în echipă. Fiecare echipă se poate concentra pe implementarea modulului ce i-a fost atribuit, având totodată la dispoziţie un model de simulare, de referinţă, a întregului sistem. Indepenţă faţă de tehnologia de implementare. De multe ori se doreşte conversia unui proiect dintr-o tehnologie în alta. Motivele sunt diverse: realizarea unui prototip cu dispozitive programabile înainte de lansarea în producţie ca un circuit specific sau realizarea aceluiaşi produs într-o tehnologie mai modernă sau mai ieftină. Conversia tehnologiei este posibilă prin reutilizarea modelului HDL. Reutilizarea codului. Module cu o funcţie specifică pot fi utilizate de către un proiectant în mai multe produse sau chiar pot fi vândute ca module separate. De exemplu, proiectantul unui circuit cu acces USB va putea decide preluarea unui controller USB produs de altă firmă, concentrându-se pe aspectele specifice ale circuitul său. În figura 1.1 este reprezentată grafic metodologia de proiectare top-down a circuitelor integrate digitale. Se remarcă faptul că descrierea textuală în HDL este prezentă în toate etapele de proiectare. Specificaţii. Uneori se includ porţiuni de cod HDL în specificaţii pentru a se exemplifica funcţia unui modul. Modelarea RTL. Codul scris de proiectant se verifică prin simulare, iar ulterior serveşte ca intrare pentru programele de sinteză de hardware. Aceasta este etapa principală de proiectare a sistemului digital.

15 1.2. De ce HDL? 5 Specificatii de proiectare Lega: Document Bibilioteca de componente Model HDL RTL Sintetizator hardware Simulator HDL Fisier cod HDL Software EDA Netlist HDL la nivel de poarta logica Simulator HDL Generator de vectori de test + Monitorizare Biblioteca de tehnologie Implementare Model HDL temporal Simulator HDL Figura 1.1 Reprezentarea grafică a metodologiei de proiectare top-down a circuitelor integrate digitale. Poziţia HDL în cadrul acestei metodologii. Generare de vectori de test. Modulul de proiectat trebuie testat în conjuncţie cu modele ale mediului exterior. Modelele care generează stimuli se descriu tot în HDL chiar dacă nu întotdeauna vor fi sintetizate. Capabilităţile HDL ajută proiectantul la realizarea unor generatoare de stimuli guvernate de anumite reguli sau chiar stimuli aleatorii. În plus, producătorii de circuite oferă modelele HDL ale acestora pentru a putea fi integrate în simularea unor sisteme mari. Este cazul modelelor de memorie folosite la proiectarea controllerelor de memorie. Mediu de simulare. Testarea circuitului proiectat alături de modelele circuitelor exterioare acestuia presupune crearea unui model HDL ce le include pe toate acestea, cu precizarea conexiunilor. Forţa unui mediu de simulare constă şi în posibilitatea configurării acestuia, conform cerinţelor beneficiarului (nu ale proiectantului). Module de monitorizare/verificare. Verificarea automată presupune e- xistenţa unor module HDL care monitorizează apariţia unor condiţii logice şi lansează mesaje de atenţionare sau de eroare către proiectant.

16 6 CAPITOLUL 1. INTRODUCERE Netlist post-sinteză. Sintetizatorul converteşte descrierea RTL într-o descriere structurală cu instanţieri de componente din biblioteca de tehnologie. Proiectantul are obligaţia de a verifica faptul că netlistul are acelaşi comportament ca modelul RTL, prin simularea netlistului în mediul de simulare în care a validat modelul RTL. Biblioteci de componente specifice tehnologiei. Simularea netlistului presupune existenţa descrierii HDL a fiecărei componente instanţiate. Modelele componentelor sunt realizate de către proiectanţii de tehnologii în diverse limbaje de descriere hardware, suportate de metodologia aleasă de proiectant şi de către programele EDA (EDA = Electronic Design Automation, totalitatea programelor ce oferă suport în proiectarea circuitelor electronice). Model temporal cu parametrii actualizaţi conform implementării. Post-implementare, după ce sunt cunoscute toate detaliile implementării (plasare, rutare), este necesară o nouă verificare, înainte de a se transmite proiectul către fabricant. La acest nivel, este necesară cunoaşterea întârzierilor atât a porţilor logice şi bistabilelor, cât şi a sârmelor de interconectare a acestora. Documentare. Realizarea unui proiect presupune scrierea unei documentaţii care să însoţească produsul. La această documentaţie va face apel şi proiectantul în cazul apariţiei unor defecte sau a lansării în execuţie a unei versiuni superioare. Codul HDL, ca documentare a proiectului, este o resursă valoroasă pentru că permite simularea unei situaţii reale care nu a fost testată anterior. 1.3 Terminologia Verilog Verilog, ca un limbaj de descriere hardware, are caracteristici conceptual diferite de cele ale limbajelor de programare (software). Principalele caracteristici ale HDL sunt aspectul temporal şi concurenţa evenimentelor Aspectul temporal Orice componentă hardware are un timp de propagare. Transferul datelor între diferite componente hardware se face prin sârme de conexiune care au şi ele o a- numită întârziere. Valoarea şi combinarea acestor întârzieri determină funcţionarea sau nu a circuitului modelat, la frecvenţa necesară. Variabilele (semnalele) Verilog modelează sârmele de interconexiune ale modulelor. Din acest motiv, specificaţiile de atribuire de semnal pot modela şi întârzierile. În Verilog, unităţile de timp sunt relative, raportate la unitatea fizică de timp specificată prin directiva timescale. Circuitele logice combinaţionale pot fi modelate ţinând cont de întârzierile existente. Ca exemplu, se prezintă modelul structurii interne a unui multiplexor, modelat cu porţi logice cu întârzieri asociate. // #<N> = <N> unitati de timp assign #1 s_n = ~s; // ~ simbolul operatorului logic NOT assign #2 w0 = i0 & s_n; // & simbolul operatorului logic AND

17 1.3. Terminologia Verilog 7 assign #2 w1 = i1 & s; assign #2 y = w0 w1; // simbolul operatorului logic OR Concurenţa evenimentelor Programele software sunt prin excelenţă secvenţiale. Acest lucru este determinat de faptul că procesoarele execută programe secvenţiale. Sistemele hardware sunt concurente. Fiecare poartă logică îşi execută propria funcţie logică în mod indepent de existenţa altor porţi logice. Un proiectant de software descrie în codul sursă un algoritm secvenţial, ceea ce va genera, în final, un program secvenţial executat de un procesor. Un proiectant de hardware descrie un comportament al unui sistem digital ce va genera, în final, o structură de porţi şi bistabile interconectate. Limbajele de descriere hardware au facilităţi de gestiune a evenimentelor concurente. Specificaţiile existente în corpul modulelor (cod sursă) Verilog sunt concurente (se execută toate la acelaşi moment al timpului de simulare, iar ordinea acestora în codul sursă nu este relevantă). De exemplu, porţiunea de cod ce urmează este echivalentă (şi ca rezultat al simulării şi ca hardware generat prin sinteză) cu structura modelată anterior. assign #2 y = w0 w1; assign #2 w0 = i0 & s_n; assign #1 s_n = ~s; assign #2 w1 = i1 & s; Pentru a uşura munca proiectantului de hardware (care este tentat să aibă o gândire algoritmică secvenţială), limbajul Verilog prevede existenţa unei specificaţii concurente care înglobează specificaţii secvenţiale. Specificaţia always este o specificaţie concurentă. Specificaţiile ce apar în corpul acesteia sunt specificaţii secvenţiale (ordinea în care apar acestea în codul sursă este relevantă). Execuţia specificaţiei always constă în executarea secvenţială a tuturor specificaţiilor conţinute de aceasta până la sfârşit sau până la apariţia unei specificaţii de întârziere Modulul Următorul paragraf prezintă traducerea capitolului 1, Prezentare generală a documentului iniţial editat de OVI (Open Verilog International) sub titlul de manual de referinţă al limbajului Verilog (LRM = Language Reference Manual), versiunea 1.0, noiembrie Verilog HDL descrie un proiect hardware sau o parte de proiect. Descrierile proiectelor în Verilog HDL sunt modele Verilog. Verilog HDL este atât un limbaj comportamental, cât şi structural. Modelele Verilog HDL pot descrie atât funcţia unui proiect, cât şi componentele şi conexiunile dintre componentele unui proiect. Modelele Verilog pot fi dezvoltate pe diferite nivele de abstractizare. Aceste nivele de abstractizare şi tipurile de modele ce le corespund sunt următoarele:

18 8 CAPITOLUL 1. INTRODUCERE algoritmic: un model care implementează un algoritm al proiectului prin construcţii de nivel înalt ale limbajului; RTL: un model care descrie curgerea datelor între registre şi modul de procesare a acestora; nivel de poartă: un model care descrie porţile logice şi conexiunile dintre porţi logice într-un proiect; nivel de comutare: un model care descrie tranzistoarele şi nodurile de stocare (a informaţiei) dintr-un dispozitiv şi conexiunile dintre ele. Blocul elementar de construcţie în Verilog HDL este modulul. Formatul modulului facilitează proiectarea top-down şi bottom-up. Un modul conţine modelul unui proiect sau a unei părţi de proiect. Modulele pot încorpora alte module pentru a forma un model ierarhic care descrie cum se includ componentele unui proiect în ansamblul proiectului. Construcţiile Verilog HDL, aşa cum sunt declaraţiile şi specificaţiile, sunt incluse în module. Limbajul Verilog HDL comportamental este un limbaj structurat şi procedural, la fel ca limbajul de programare C. Construcţiile comportamentale ale limbajului sunt utilizate în cadrul modelelor algoritmice şi RTL. Limbajul comportamental are următoarele capabilităţi: proceduri structurate pentru execuţie secvenţială sau concurentă; controlul explicit al timpului la care se activează o procedură, specificat atât de expresii ce desemnează întârzieri, cât şi de schimbările valorii care determină evenimente; evenimente desemnate explicit să determine activarea şi dezactivarea acţiunilor în cadrul altor proceduri; construcţii procedurale pentru operaţii condiţionale, de decizie, de selecţie sau de iteraţii; proceduri denumite task-uri care pot avea parametrii şi durate non-zero; proceduri denumite funcţii care permit definirea unor noi operatori; operanzi aritmetici, logici, pe biţi şi de reducere pentru construcţia de expresii. Construcţiile structurale ale Verilog HDL sunt utilizate pentru modelele la nivel de poartă şi la nivel de comutare. Limbajul structural are următoarele capabilităţi: un set complet de primitive combinaţionale; primitive pentru poartă de transmisiune şi dispozitive rezistive; abilitatea de a modela structuri MOS. În Verilog HDL, acurateţea modelării structurale este îmbunătăţită de specificaţii de întârzieri prin primitive şi precizări ale tăriei porturilor de ieşire. Valorile semnalelor pot avea diferite tării şi o gamă completă de valori ambigue pentru a reduce pesimismul condiţiilor necunoscute.

19 1.3. Terminologia Verilog 9 Definirea unui modul este inclusă între cuvintele cheie module şi module. Identificatorul ce urmează cuvântului cheie module reprezintă numele modulului. Se recomandă utilizarea unor nume sugestive pentru comportamentul sau structura modulului. Opţional, modulul poate conţine o listă de porturi de intrare/ieşire. Ordinea porturilor poate fi semnificativă la instanţierea modulului. Din acest motiv, se recomandă o asociere explicită între porturi şi sârme în momentul instanţierii unui modul. Identificatorii din lista de porturi trebuie declaraţi ca intrări, ieşiri sau bidirecţionali în partea de definiţii a modulului. Sintaxa completă a declaraţiei unui modul este prezentată în continuare: S <modul> ::= module <nume_modul><lista_porturi>? ; <articol_modul>* module <nume_modul> ::=<IDENTIFICATOR> <lista_porturi> ::=(<port><,<port>>*) <articol_modul> ::=<declaratie_parametru> =<declaratie_port_intrare> =<declaratie_port_iesire> =<declaratie_port_bidirectional> =<declaratie_conexiune> =<declaratie_conexiune_reg> =<declaratie_timp> =<declaratie_intreg> =<declaratie_real> =<declaratie_eveniment> =<instantiere_poarta> =<instantiere_primitiva> =<instantiere_modul> =<redefinire_parametru> =<atribuire_continua> =<bloc_specify> =<specificatie_initial> =<specificatie_always> =<task> =<functie> <lista_porturi> este o listă de declaraţii de nume de porturi despărţite prin virgulă. Direcţia şi dimensiunea porturilor este declarată ulterior în corpul modulului. În corpul modulului pot apărea următoarele articole:

20 10 CAPITOLUL 1. INTRODUCERE <declaratie_parametru>: Parametrul este o constantă de modul care poate avea o valoare implicită ce poate fi modificată în momentul instanţierii modulului. Două instanţe ale aceluiaşi modul pot avea valori diferite ale unui parametru. Modificarea parametrului se poate face cu <asociere_parametru_valoare> sau cu <redefinire_parametru>. Exemple: //Modificarea parametrului prin <asociere_parametru_valoare> sumator #(8) U1Sumator (...); // instanta de sumator pe 8 biti sumator #(4) U2Sumator (...); // instanta de sumator pe 4 biti //Modificarea parametrului prin <redefinire_parametru> defparam U2Sumator.width = 16; sumator U2Sumator (...); // instanta de sumator pe 16 biti <declaratie_port_intrare>, <declaratie_port_iesire>, <declaratie_port_bidirectional>: Declaraţiile direcţiei şi ale dimensiunilor porturilor. Exemple: input cpuclk_i; // intrare pe 1 bit input reset_ni; // intrare pe 1 bit input[15:0] cpuaddr_i; // bus de intrare pe 16 biti inout[31:0] data_io; // bus de date bidirectional de 32 biti output rdy_o; // iesire pe 1 bit De remarcat că denumirea porturilor a fost aleasă astfel încât să conţină informaţia referitoare la direcţia portului, informaţie foarte utilă la gestionarea unui cod de dimensiuni mari. Mai multe recomandări referitoare la scrierea codului Verilog se găsesc în secţiunea 2.9. <declaratie_conexiune>, <declaratie_conexiune_reg>, <declaratie_timp>, <declaratie_intreg>, <declaratie_real>: Declaraţiile de variabile Verilog modelează atât sârme fizice sau abstracte, cât şi obiecte folosite la modelarea comportamentală de nivel înalt (generatoare de vectori de test ce nu vor fi sintetizate). Descrierea tipurilor de date şi a obiectelor Verilog este prezentată în secţiunea 2.4. <declaratie_eveniment>: Declarare de condiţii (evenimente) care pot determina o acţiune. Evenimentele se declară prin cuvântul rezervat event. <instantiere_poarta>, <instantiere_primitiva>, <instantiere_modul>: Instanţierea unei porţi logice definite în limbaj, a unei primitive definite de utilizator sau a unui modul reprezintă mecanismul de descriere a structurii unui modul. Sintaxa specificaţiei de instanţiere de modul este prezentată în continuarea acestei secţiuni.

21 1.3. Terminologia Verilog 11 <redefinire_parametru>: Redefinirea explicită a unui parametru al unui modul în momentul instanţierii acestuia se face folosind cuvântul cheie defparam urmat de numele instanţei modulului, numele parametrului şi valoarea acestuia. <atribuire_continua>: Atribuirea continuă este introdusă prin cuvântul cheie assign şi este prezentată în secţiunea 2.6. <bloc_specify>: Timpii de propagare din interiorul unui modul pot fi declaraţi într-un bloc dedicat, folosind grupul de cuvinte cheie specify şi specify. <specificatie_initial>: Specificaţia concurentă initial nu este sintetizabilă. Ea este folosită pentru descrierea comportamentului modulelor care generează vectori de test. Specificaţia initial este descrisă în secţiunile 2.6 şi 2.7. <specificatie_always>: Specificaţia concurentă always implementează un mecanism de includere a uneia sau a mai multor specificaţii secvenţiale într-un bloc ce se execută concurent cu celalalte specificaţii concurente. Specificaţia always este descrisă în secţiunile 2.6 şi 2.7. <task>, <functie>: Un task este similar cu o procedură C: permite includerea unei secţiuni de cod în diferite locuri ale descrierii modulului. O funcţie este similară cu un task, dar spre deosebire de acesta, funcţia returnează o singură valoare, nu poate conţine întârzieri (se execută într-un timp nul) şi nu poate apela task-uri. Task-urile şi funcţiile Verilog sunt descrise în secţiunea 4.1. Instanţierea modulului într-un alt modul permite crearea unei ierarhii în structura proiectului. Nu se pot defini module care să se includă pe ele însele (imbricate). O definire de modul nu poate conţine o altă definire de modul între cuvintele sale cheie module şi module. Un modul include alt modul prin instanţierea unei copii a acestuia. Procesul este similar cu plantarea unor capsule de circuite integrate pe o placă. Acelaşi tip de circuit poate fi plasat de mai multe ori pe un cablaj imprimat, eventual având conectări diferite. Similar, un modul poate fi instanţiat de mai multe ori în unul sau mai multe module diferite, instanţele putând avea parametrii diferiţi. Specificaţia <instantiere_modul> creează una sau mai multe instanţieri (apariţii) ale modulului. De exemplu, un model de bistabil D se poate instanţia de 16 ori pentru a genera un registru de 16 biţi. Sintaxa specificaţiei de instanţiere de modul este prezentată în continuare: S <instantiere_modul> ::= <nume_modul> <asociere_parametru_valoare>? <instanta_modul> <,<instanta_modul>>* ; <nume_modul> ::= <IDENTIFIER> <asociere_parametru_valoare> ::= # ( <expresie> <,<expresie>>* )

22 12 CAPITOLUL 1. INTRODUCERE <instanta_modul> ::= <nume_instanta> ( <lista_conexiuni_modul>? ) <nume_instanta> ::= <IDENTIFICATOR> <lista_conexiuni_modul> ::= <conexiune_port_prin_pozitie> <,<conexiune_port_prin_pozitie>>* = <conexiune_port_prin_nume> <,<conexiune_port_prin_nume>>* <conexiune_port_prin_pozitie> ::= <expresie> = <NULL> <conexiune_port_prin_nume> ::=.<IDENTIFICATOR> ( <expresie> ) În continuare sunt prezentate câteva exemple de module Verilog care descriu circuite digitale elementare. Modul vot majoritar cu trei intrări: descriere algoritmică a propagării datelor. V module votmajoritar3df ( i1, // intrare de vot 1 i2, // intrare de vot 2 i3, // intrare de vot 3 decizie // decizie in urma votului ); input i1, i2, i3; output decizie; wire wire wire vot12; vot13; vot23; assign vot12 = (i1 & i2); assign vot13 = (i1 & i3); assign vot23 = (i2 & i3); assign decizie = vot12 vot13 vot23; // operator AND // operator OR module Modul vot majoritar cu trei intrări: descriere cu porţi logice definite în limbaj.

23 1.3. Terminologia Verilog 13 V module votmajoritar3gl ( i1, // intrare de vot 1 i2, // intrare de vot 2 i3, // intrare de vot 3 decizie // decizie in urma votului ); input i1, i2, i3; output decizie; wire wire wire vot12; vot13; vot23; and (vot12, i1, i2); // vot12 = i1 and i2 and (vot13, i1, i3); and (vot23, i2, i3); or (decizie, vot12, vot13, vot23); module T La testarea celor două module votmajoritar3df şi votmajoritar3gl, în mediul de testare testvotmajoritar, se observă apariţia glitch-urilor de hazard combinaţional pe ieşirile ambelor module testate. De remarcat şi variaţia variabilelor declarate pentru a monitoriza numărul de cazuri testate. Ca referinţă, figura 1.2 prezintă formele de undă obţinute prin simulare. Figura 1.2 Vot majoritar: forme de undă rezultate în urma testării. Numărător sincron reversibil cu presetare: descrierea comportamentală. V module updncounterpreset ( clk, // intrare de ceas reset_n, // semnal de reset asincron

24 14 CAPITOLUL 1. INTRODUCERE updn_n, ld, di, en, count ); input input input input input[3:0] input output[3:0] reg[3:0] // sens de numarare: 1=crescator, 0=descrescator // semnal de presetare // valoare presetata // validarea numararii // iesirea numaratorului clk; reset_n; updn_n; ld; di; en; count; count; // ld en updn_n clk count* // // 1 x x ^ di // ^ count + 1 // ^ count - 1 // 0 0 x ^ count clk or negedge reset_n) begin if (!reset_n) begin // reset asincron count <= 4 b0; if (ld) begin // preset sincron count <= di; if (en) begin // numarare validata if (updn_n) begin // numarare in sens crescator count <= count + 1; // numarare in sens descrescator count <= count - 1; module

25 1.3. Terminologia Verilog 15 T Ca referinţă, figura 1.3 prezintă formele de undă obţinute prin simulare. Figura 1.3 Numărator: forme de undă rezultate în urma testării. Sumator complet de 1 bit: descriere comportamentală cu operator aritmetic. V module add1c ( a, // primul operand b, // al doilea operand ci, // transport de intrare s, // rezultatul co // transport de iesire ); input a; input b; input ci; output s; output co; assign {co, s} = a + b + ci; // suma celor 3 intrari, // reprezentata pe 2 biti, // este atribuita // concatenarii bitilor co si s module Sumator complet de 1 bit: descriere la nivel de porţi logice. V module add1gl ( a, // primul operand b, // al doilea operand ci, // transport de intrare s, // rezultatul co // transport de iesire

26 16 CAPITOLUL 1. INTRODUCERE ); input a; input b; input ci; output s; output co; wire c1; wire c2; wire c3; xor sum (s, a, b, cin); // s = a xor b xor cin and (c1, a, b); // c1 = a and b; and (c2, a, cin); // c2 = a and cin; and (c3, b, cin); // c3 = b and cin; or (co, c1, c2, c3); // co = c1 or c2 or c3; module Sumator de 4 biţi: descriere structurală cu instanţieri de sumatoare de 1 bit. V module add4st ( a, // primul operand b, // al doilea operand ci, // transport de intrare s, // rezultatul co // transport de iesire ); input[3:0] a; input[3:0] b; input ci; output[3:0] s; output co; wire[2:0] cr; // transport intermediar intre biti // instanta bit 0 add1gl add1gl_0 (.a (a[0] ),.b (b[0] ),.ci (ci ),.s (s[0] ),

27 1.3. Terminologia Verilog 17 );.co (cr[0] ) // instanta bit 1 add1gl i_add1gl_1 (.a (a[1] ),.b (b[1] ),.ci (cr[0] ),.s (s[1] ),.co (cr[1] ) ); // instanta bit 2 add1gl i_add1gl_2 (.a (a[2] ),.b (b[2] ),.ci (cr[1] ),.s (s[2] ),.co (cr[2] ) ); // instanta bit 3 add1gl i_add1gl_3 (.a (a[3] ),.b (b[3] ),.ci (cr[2] ),.s (s[3] ),.co (co ) ); module Sumator de dimensiuni generice: descriere comportamentală parametrizabilă. V module addxc ( a, // primul operand b, // al doilea operand ci, // transport de intrare s, // rezultatul co // transport de iesire ); parameter width = 8; // valoare implicita a parametrului // valoarea actuala poate fi schimbata la instantiere

28 18 CAPITOLUL 1. INTRODUCERE input[width-1:0] a; input[width-1:0] b; input ci; output[width-1:0] s; output co; assign {co, s} = a + b + ci; module Multiplexor 2x1: descriere comportamentală. V module mux2x1c ( i0, // intrare de date 0 i1, // intrare de date 1 s, // intrare de selectie y // iesire ); input i0; input i1; input s; output y; assign y = s? i1 : i0; module Multiplexor 2x1: descriere cu porţi logice definite în limbaj. V module mux2x1gl ( i0, // intrare de date 0 i1, // intrare de date 1 s, // intrare de selectie y // iesire ); input i0; input i1; input s; output y; wire s_n;

29 1.3. Terminologia Verilog 19 wire s0, s1; not (s_n, s); nand (s0, i0, s_n); nand (s1, i1, s); nand (y, s0, s1); // s0 = not(i0 and s_n) module Multiplexor2x1: descriere cu primitive definite de utilizator. V module mux2x1tudp ( i0, // intrare de date 0 i1, // intrare de date 1 s, // intrare de selectie y // iesire ); input i0; input i1; input s; output y; mux2x1 (y, i0, i1, s); module primitive mux2x1 (y, i0, i1, s); output y; // primul port este iesirea input i0; input i1; input s; table // i0 i1 s : y aceasta linie este doar un comentariu 0? 0 : 0; 1? 0 : 1;? 0 1 : 0;? 1 1 : 1; 0 0 x : 0; 1 1 x : 1; table primitive Multiplexor 4x1: descriere structurală cu primitive mux2x1 definite de utilizator.

30 20 CAPITOLUL 1. INTRODUCERE V module mux4x1tudp ( i0, // intrare de date 0 i1, // intrare de date 1 i2, // intrare de date 2 i3, // intrare de date 3 s, // intrare de selectie y // iesire ); input i0; input i1; input i2; input i3; input[1:0] s; output y; wire wire mux1; mux0; mux2x1 (mux1, i2, i3, s[1]); mux2x1 (mux0, i0, i1, s[1]); mux2x1 (y, mux0, mux1, s[0]); module Multiplexor: descriere cu poartă de transmisiune. V module mux2x1ttg ( i0, // intrare de date 0 i1, // intrare de date 1 s, // intrare de selectie y // iesire ); input i0; input i1; input s; output y; wire s_n; // not (iesire, intrare) not (s_n, s);

31 1.4. Mediul de simulare a modelelor HDL 21 // cmos (iesire, intrare, controln, comtrolp) cmos(y, i0, s_n, s); cmos(y, i1, s, s_n); module 1.4 Mediul de simulare a modelelor HDL Testarea unui model de sistem digital se face într-un mediu de simulare similar cu o masă de laborator. Ca exemplu, se consideră studierea în laborator a comportamentului unei porţi logice. Pe lângă circuitul de studiat, pe masa de laborator există şi aparate electronice: sursă de alimentare, sursă de semnal, osciloscop. Conectarea aparatelor la porturile circutului de studiat se face cu sârme. Ansamblul circuit de studiat-aparate este un sistem închis (nu există conectoare cu ceva din exteriorul mesei). Similar, într-un mediu de simulare sunt instanţiate trei tipuri de module: modelul sistemului de studiat; modele de generatoare de stimuli (similare generatoarelor de semnal); modele de monitorizare şi verificare (similare aparatelor de măsură şi control). Toate aceste module sunt instanţiate (incluse) într-un modul fără porturi (similar mesei de lucru din laborator). Conexiunile se fac între porturile sistemului de studiat şi porturile corespunzătoare ale generatoarelor de stimuli sau între porturile sistemului de studiat şi porturile monitoarelor/verificatoarelor de condiţii. Figura 1.4 prezintă grafic structura unui mediu de simulare Verilog. Modelul dispozitivului de testat este stimulat prin semnale provenite de la generatorul de vectori de test. Opţional, acesta poate verifica ieşirile sistemului şi genera stimuli în consecinţă. Pentru verificări automate, se recomandă includerea unuia sau a mai multor module responsabile pentru verificarea datelor, a protocolului de comunicaţie sau a altor condiţii logice complexe. Monitoarele au numai porturi de intrare şi generează mesaje de eroare sau de atenţionare, fără a modifica starea ansamblului. Modulele generatoare de vectori de test pot prelua din fişiere diverse date folosite pentru determinarea valorilor semnalelor generate. Modulele de monitorizare a semnalelor şi de verificare pot scrie în fişiere externe date sub diferite formate. În plus, aceste module pot afişa sau scrie în fişiere mesaje informative, de atenţionare sau de eroare. 1.5 Comparaţie Verilog-VHDL Există nenumărate comparaţii între Verilog şi VHDL. În acest paragraf nu se face o comparaţie completă a celor două limbaje de descriere hardware. În schimb, se prezintă două sisteme digitale mici (o poartă şi un bistabil) modelate în cele două limbaje. Avantaje evidente ale Verilog HDL:

32 22 CAPITOLUL 1. INTRODUCERE Mediu de testare Generator de vectori de test Modul sintetizabil testat Monitorizare si verificare Figura 1.4 Mediu de simulare: dispozitiv de testat, generator de vectori, monitor. tipuri de date simple şi eficiente; porţi logice definite în limbaj; cod mai concentrat. Avantaje evidente ale VHDL: suport puternic pentru descriere de vectori de test şi lucru cu fişiere; posibilitatea modelării sistemelor analogice sau de comandă şi control (motoare electrice, senzori). Exemplu: Bistabil D VHDL Verilog entity dff is module dff (d, clk, q); port (d, clk: in bit; q: out bit); input d, clk; dff; output q; architecture basic of dff is begin process (clk) begin if (rising_edge(clk)) then q <= d; q <= d; if; process; basic; clk) module

33 1.5. Comparaţie Verilog-VHDL 23 Exemplu: Poartă AND cu două intrări VHDL Verilog entity and2 is module and2 (a, b, y); port (a, b: in bit; y: out bit); input a, b; and2; output y; architecture basic2 of and2 is begin y <= a and b; assign y = a & b; basic2; module

34

35 Capitolul 2 FUNDAMENTELE LIMBAJULUI VERILOG HDL 2.1 Convenţii lexicale Ca orice limbaj, Verilog are un număr de atomi lingvistici. Aceşti atomi pot fi operatori, delimitatori, comentarii, numere, şiruri, identificatori sau cuvinte cheie rezervate. Toate cuvintele cheie rezervate sunt scrise cu minuscule. Lista tuturor cuvintelor cheie este prezentată în anexa B. Limbajul Verilog (spre deosebire de VHDL) este un limbaj case-sensitive : literele minuscule au semnificaţie diferită de literele majuscule corespunzătoare. Delimitatorii de atomi lingvistici sunt caracterul spaţiu, caracterul tabulator şi caracterul linie nouă. Cu excepţia prezenţei acestora în şiruri de caractere, aceste caractere sunt ignorate. Verilog suportă două feluri de comentarii: Comentarii pe o singură linie. Comentariul se întinde de la apariţia a două caractere slash (//) şi până la sfârşitul liniei (marcat de caracterul linie nouă ). Comentarii pe mai multe linii. Comentariul se întinde între marcherul de început /* şi marcherul de sfârşit */. Comentariile pe linii multiple nu pot fi incluse unele în altele. 2.2 Structura codului Verilog În Verilog există o singură entitate lingvistică: modulul. În afara modulului nu pot exista decât directive de compilare. În interiorul modulului pot apărea atât specificaţii, cât şi directive de compilare. Includerea într-un cod sursă Verilog a codului Verilog existent într-un alt fişier se face prin directiva de compilare include. 25

36 26 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL Includerea unui fişier în altul se face static, la compilare şi este echivalentă cu copierea fişierului inclus în poziţia în care apare directiva de includere de fişiere. Modulul conţine atât descrierea interfeţei cu mediul exterior (alte module), cât şi comportamentul sau structura sa. Toate declaraţiile făcute într-un modul sunt locale acelui modul. Ca o consecinţă, nu există obiecte (semnale) globale ca într-un program software. Semnalele declarate cu acelaşi nume, dar în module diferite, sunt semnale diferite. Într-un modul pot fi instanţiate alte module pentru a crea o structură ierarhică. Spre deosebire de VHDL, în Verilog modulul nu are o declaraţie explicită şi nici nu conţine regiuni explicite pentru declaraţii. Semnalele trebuie declarate înainte de prima referire la acestea, dar declaraţia poate fi făcută oriunde în corpul modulului. Există două tipuri de subprograme utilizate în mod similar cu procedurile şi funcţiile C. Definirea subprogramelor are rolul de a condensa codul Verilog în cazul necesităţii repetării unor porţiuni identice de cod. Există două tipuri de subprograme marcate de cuvintele rezervate: task şi function. 2.3 Setul de valori Verilog are un set de valori simplu, definit în limbaj. 0: valoare logică 0 sau condiţie falsă; 1: valoare logică 1 sau condiţie adevărată; x: valoare logică necunoscută; z: stare de înaltă impedanţă. Valoarea z la intrarea unei porţi logice este interpretată ca fiind x. Caracterele x şi z pot fi minuscule sau majuscule. Există trei tipuri de constante în Verilog: Numere întregi; Numere reale; Şiruri. Pentru a uşura interpretarea acestora, se pot utiliza caractere de subliniere (_) pentru a despărţi caracterele ce desemnează constante. Caracterul de subliniere nu poate fi primul caracter Numere întregi Numerele întregi pot fi scrise în forma implicită ca numere reprezentate în baza 10 sau ca valori exprimate într-o bază de numeraţie precizată explicit. Numerele întregi sunt echivalente cu scrierea acestora în binar. Numerele negative sunt reprezentate sub forma de complement faţă de 2. Sintaxa reprezentării numerelor întregi este: S

37 2.3. Setul de valori 27 [dimensiune] <baza_de_numeratie> <valoare> Un număr în format cu bază explicită este totdeauna considerat pozitiv. Dacă dimensiunea nu este precizată se consideră o valoare implicită depentă de implementarea simulatorului (de obicei 32 de biţi). Bazele de numeraţie acceptate sunt: baza 2: desemnată de litera b sau litera B; baza 8: desemnată de litera o sau litera O; baza 10: desemnată de litera d sau litera D; baza 16: desemnată de litera h sau litera H. Exemple: 13 numărul 13 exprimat în baza 10 (în binar 1101) -13 numărul -13 exprimat în baza 10 (în binar, pe 4 biţi 1011, iar pe 5 biţi 10011) 4 b1010 numărul 10 exprimat în binar pe 4 biţi 12 o327 număr exprimat pe 12 biţi în baza 8 16 hbeef număr exprimat pe 16 biţi în baza 16 8 d-3-8 d3 număr exprimat ilegal (valoarea nu poate fi negativă) număr exprimat legal ca fiind complementul faţă de 2 al numărului pozitiv 3, reprezentat pe 8 biţi (echivalent cu 8 b1111_1101) 16 h DEAD formă legală cu spaţii între dimensiune şi caracterul şi între bază de numeraţie şi valoare 4 b0010 formă ilegală cu spaţii între caracterul şi baza de numeraţie width b1010 formă ilegală, dimensiunea nu poate fi un parametru sau o expresie b1010 formă legală, dimensiunea poate lipsi (numărul este reprezentat pe numărul maxim de biţi, în acest caz 4) hff număr exprimat în baza 16, reprezentat pe 8 biţi 8 b101 număr exprimat în baza 2, reprezentat pe 8 biţi ca 8 b b0000_0101 număr echivalent cu forma anterioară (caracterele _ sunt ignorate) 3 b0110_0101 număr echivalent cu 3 b101 (caracterele din stânga sunt trunchiate dacă valoarea are mai mulţi biţi decât dimensiunea precizată explicit) 8 b0_11_0_0101 folosire legală a caracterului de subliniere pentru delimitare 8 b_0110_0101 folosire ilegală a caracterului de subliniere la începutul valorii 8 d260 număr echivalent cu 4 în baza 10 (provenit din trunchierea caracterului cel mai semnificativ al reprezentării în binar 9 b1_0000_0100.) 8 bx 4 bz valoare nedefinită extinsă pe 8 biţi xxxxxxxx valoare z extinsă pe 4 biţi zzzz Numere reale Numerele reale pot fi reprezentate sub două forme:

38 28 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL Numere zecimale (cu virgulă). Exemple: 3.14, , Numere în format ştiinţific (cu exponent). Exemple: E2 (314,15), 1.0E3 (1000,0), 5E-3 (0,005), 1_ _89 (1234,56789), 5.3E-3. Forma: 5. este ilegală deoarece după punctul zecimal trebuie să apară cel puţin o cifră. Numerele reale nu sunt sintetizabile. Numerele reale sunt automat convertite la numere întregi prin rotunjire Şiruri Un şir este format dintr-o secvenţă de caractere incluse între ghilimele ( ). Fiecare caracter este reprezentat pe 8 biţi şi este tratat ca un întreg pozitiv. De exemplu, pentru a stoca mesajul "WAIT" este necesară definirea unei variabile de 32 de biţi. parameter nrchar = 4; reg[nrchar*8-1:0] mesaj;... mesaj <= "WAIT"; Câteva caractere de control pot fi introduse în şiruri dacă sunt precedate de caracterul backslash (\). \n trece la linie nouă (CR) \t tabulator (TAB) \\ caracterul \ \" caracterul apostrof dublu (") 2.4 Tipuri de date şi obiecte Verilog are două grupe de tipuri de date: Tipul net: Acest tip de date modelează o conexiune fizică între elementele structurale. Valoarea unei date de acest tip este determinată de sursa sa, care poate fi o specificaţie de atribuire continuă (assign) sau o instanţiere de componentă. Dacă nu există nici o sursă (driver de semnal), atunci data de tip net păstrează valoarea implicită z. Cel mai folosit tip din această categorie este tipul wire. Tipul register: Acest tip de date modelează un element abstract de stocare a datelor. Valorile obiectelor de acest tip pot fi atribuite din interiorul specificaţiilor always şi initial. Valoarea implicită a acestui tip de date este x. Sârmele de conexiune modelate în Verilog pot fi de tip net sau de tip register. Diferenţa dintre cele două tipuri constă în modul în care se actualizează valoarea obiectelor de acest tip. O sârmă de tip net are valoarea continuu atribuită de către driverul ei. O sârmă de tip register îşi păstrează valoarea până la următoarea atribuire a unei noi valori. Este absolut incorectă afirmaţia conform căreia obiectele de tip register modelează registre formate din bistabile. Ca exemplu, se prezintă în continuare două modele de porţi logice, modelate cu cele două tipuri de date.

39 2.4. Tipuri de date şi obiecte 29 wire outgate1; // declara un obiect de tip net (wire) reg outgate2; // declara un obiect de tip register (reg) assign outgate1 = a & b; // iesirea outgate1 este continuu evaluata // conform expresiei (a AND b) or b) outgate2 <= a & b; // iesirea outgate2 este evaluata conform // expresiei (a AND b) doar cand exista o // modificare a semnalului a sau // a semnalului b Cu alte cuvinte, semnalul de tip wire modelează o sârmă obişnuită căreia trebuie să i se atribuie tot timpul o valoare. Semnalul de tip reg modelează o sârmă mai specială (nu un registru) capabilă să îşi păstreze valoarea între două actualizări succesive. Această proprietate a sârmelor de tip reg le face folositoare la modelarea elementelor de memorare din sistemele digitale (bistabile). Datele de tip net pot fi declarate cu mai multe cuvinte cheie, în funcţie de comportamentul acestora: wire tri wor trior wand triand trireg tri0 tri1 Tip folosit cel mai frecvent pentru declararea de sârme. Corespunde modelului unei sârme fizice. Tip identic în sintaxă şi semantică cu wire, este folosit pentru semnalarea posibilelor surse multiple pentru un semnal. Tip de sârmă ce modelează conexiunea OR cablat. Tip identic în sintaxă şi semantică cu wor. Tip de sârmă ce modelează conexiunea AND cablat. Tip identic în sintaxă şi semantică cu wand. Tip de sârmă ce modelează o sârmă cu încărcare capacitivă, capabilă să reţină ultima valoare după ce sursa semnalului a intrat în stare de înaltă impedanţă. Tip ce modelează sârme cu surse multiple care iau valoarea 0 în cazul în care toate sursele semnalului au intrat în stare de înaltă impedanţă. Tip ce modelează sârme cu surse multiple care iau valoarea 1 în cazul în care toate sursele semnalului au intrat în stare de înaltă impedanţă. supply0 Tip utilizat pentru modelarea conexiunii la masă, valoare logică permanent 0. supply1 Tip utilizat pentru modelarea conexiunii la sursa de alimentare, valoare logică permanent 1.

40 30 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL În Verilog este posibilă nedeclararea unei sârme de tip net. În acest caz, declaraţia implicită este de tip wire de 1 bit. Se recomandă neutilizarea acestei reguli Verilog şi declararea explicită a tuturor sârmelor. Datele de tip register pot fi declarate cu mai multe cuvinte cheie, în funcţie de comportamentul acestora: reg integer time real realtime Tip folosit cel mai frecvent pentru declararea de sârme cu memorie. Este folosit pentru modelarea ieşirilor de bistabile. Tip folosit exclusiv la modelarea la nivel înalt (nu pentru sinteză) fiind echivalent cu tipul reg pe 32 de biţi. Tip folosit exclusiv la modelarea la nivel înalt pentru stocarea şi manipularea valorilor ce semnifică timp. Tip folosit exclusiv la modelarea la nivel înalt pentru stocarea şi manipularea valorilor ce semnifică numere reale. Tip identic în sintaxă şi semantică cu tipul real. Atât sârmele de tip net, cât şi cele de tip reg pot fi extinse pe una sau două dimensiuni. Extinderea pe o dimensiune modelează un bus. Extinderea pe două dimensiuni modelează o matrice de date. Verilog nu oferă suport pentru structuri de date de mai mult de două dimensiuni. Dimensiunea vectorilor se precizează la declararea sârmei între cuvântul cheie ce desemnează tipul de sârmă şi numele acesteia. parameter width_p = 16; wire [7:0] databus; // bus de 8 biti reg[width_p-1:0] shreg; // bus de dimensiune parametrizabila assign databus = 8 hab; // atribuire catre tot bus-ul assign databus[0] = 1 b0; // atribuire catre un membru al bus-ului assign databus[2:0] = 3 b101; // atribuire catre o portiune din bus // registru de deplasare in inel de dimensiuni generice // valoarea viitoare se obtine din valoarea curenta // deplasata cu un bit la stanga si // transferul MSb pe pozitia LSb ck) shreg <= {shreg[width_p-2:0], shreg[width_p-1]}; Deşi nu este impusă nici o restricţie, se recomandă utilizarea indexării vectorilor în sens descrescător, de la un număr maxim până la 0 (nu până la 1). Dimensiunea matricilor se precizează la declararea sârmei: lăţimea se declară între cuvântul cheie ce desemnează tipul de sârmă şi numele acesteia, iar adâncimea se declară după numele semnalului. parameter width_p = 16; parameter deep_p = 8;

41 2.4. Tipuri de date şi obiecte 31 reg[15:0] wire[15:0] wire regfile[255:0]; // declaratie de matrice bidimensionala // ce poate corespunde unui set de // 256 registre de cate 16 biti reg178; zeroflag; reg[width_p-1:0] mem[deep_p-1:0]; // matrice de memorie bidimensionala // de dimensiuni parametrizabile wire[width_p-1:0] mem_0; // vector corespunzator locatiei // de la adresa 0 assign mem_0 = mem[0]; // atribuirea unui membru al matricii // bidimensionale catre un vector assign reg178 = regfile[178]; // accesarea registrului de la // adresa 178 assign zeroflag = reg178[2]; // accesarea bitului 2 din registrul de // la adresa 178 Exemplul următor prezintă folosirea declaraţiilor de tip wire şi reg în cazul modelării structurale a unui bistabil T implementat cu un bistabil D şi o poartă XOR. Prima versiune de modelare descrie bistabilul D cu o specificaţie always. Din acest motiv, sârma qt_o (asociată portului de ieşire cu acelaşi nume) a fost declarată de tip reg. Comportamentul sârmei d (internă modulului) a fost descris cu o specificaţie continuă assign. Din acest motiv, sârma d a fost declarată de tip wire. V module tver1 ( reset_ni, // reset asincron activ in 0 ck_i, // semnal de ceas t_i, // intrarea bistabilului T qt_o // iesirea bistabilului T ); input input input output reset_ni; ck_i; t_i; qt_o; // iesire declarata ca reg reg qt_o; // sarma interioara declarata ca wire wire d;

42 32 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL assign d = t_i ^ qt_o; // operator XOR ck_i or negedge reset_ni) begin if (!reset_ni) begin qt_o <= 1 b0; qt_o <= d; module A doua versiune de modelare încapsulează descrierea bistabilul D într-un modul denumit dff. În interiorul acestui modul, portul de ieşire qd_o a fost declarat reg deoarece a fost atribuit din specificaţie always. În schimb, la instanţierea modului dff în modulul tffver2, portul său de ieşire qd_o este conectat la portul de ieşire qt_o al modulului tffver2 cu o sârma obişnuită de tip wire. V module dff ( reset_ni, // reset asincron activ in 0 ck_i, // semnal de ceas d_i, // intrarea bistabilului D qd_o // iesirea bistabilului D ); input input input output reset_ni; ck_i; d_i; qd_o; reg qd_o; // port de iesire de tip reg, atribuit in always ck_i or negedge reset_ni) begin if (!reset_ni) begin qd_o <= 1 b0; qd_o <= d_i; module module tver2 (

43 2.4. Tipuri de date şi obiecte 33 reset_ni, // reset asincron activ in 0 ck_i, // semnal de ceas t_i, // intrarea bistabilului T qt_o // iesirea bistabilului T ); input input input output reset_ni; ck_i; t_i; qt_o; // declararea sarmei d (interna modulului) wire d; assign d = t_i ^ qt_o; // instantierea bistabilului D dff i_dff(.reset_ni (reset_ni ),.ck_i (ck_i ),.d_i (d ), // asociere dintre portul de intrare d_i // si sarma d.qd_o (qt_o ) // asociere dintre portul de iesire qd_o // si sarma qt_o (conectata la iesirea // modulului tver2) ); module A treia versiune de modelare încapsulează toată descrierea într-o singură specificaţie always. Sârma conectată pe intrarea bistabilului nu mai este declarată explicit. Această versiune este cea mai folosită la proiectarea RTL pentru modelarea unui bistabil T şi are avantajul că ascunde structura internă pentru a descrie doar comportamentul. V module tver3 ( reset_ni, // reset asincron activ in 0 ck_i, // semnal de ceas t_i, // intrarea bistabilului T qt_o // iesirea bistabilului T ); input input input output reset_ni; ck_i; t_i; qt_o;

44 34 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL // declaratia iesiri de tip reg reg qt_o; ck_i or negedge reset_ni) begin if (!reset_ni) begin qt_o <= 1 b0; qt_o <= t_i ^ qt_o; module T În scop de testare, cele trei versiuni de modelare au fost incluse într-un mediu unic de simulare. 2.5 Operatori Verilog are trei tipuri de operatori: cu unul, doi sau trei operanzi. Operatorii unari apar în faţa operandului, operatorii binari apar între cei doi operanzi, iar operatorii ternari separă cei trei operanzi. a = ~b; // ~ este operator unar (complementare logica) c = d & e; // & este operator binar (functie logica AND) f = g? h : i; //?: este operator ternar // (conditie, functie multiplexor) // daca g=1, f=h, altfel f=i Tabelul 2.1 prezintă operatorii Verilog în ordinea precedenţei acestora Operatori aritmetici Operatorii aritmetici sunt: + plus (unar şi binar); - minus (unar şi binar); * multiplicare; / împărţire; % modulo. Operatorii + şi - sunt sintetizabili. Operatorul * este sintetizat ca un circuit combinaţional de către unele sintetizatoare. Operatorii / şi % se recomandă a nu se folosi în cod ce urmează a fi sintetizat.

45 2.5. Operatori 35 Operator Descriere + Operator unar pentru număr pozitiv - Operator unar pentru număr negativ! Operator unar pentru negare logică ~ Operator unar pentru negare pe biţi & Operator de reducere AND (aplicat unui vector produce un bit) ~& Operator de reducere NAND ^ Operator de reducere XOR ~^ Operator de reducere XNOR Operator de reducere OR ~ Operator de reducere NOR * Operator binar de multiplicare / Operator binar de împărţire % Operator binar modulo + Operator binar de adunare - Operator binar de scădere << Operator binar de deplasare stânga >> Operator binar de deplasare dreapta < Operator binar de comparare mai mic <= Operator binar de comparare mai mic sau egal > Operator binar de comparare mai mare >= Operator binar de comparare mai mare sau egal == Operator binar de egalitate logică!= Operator binar de inegalitate logică === Operator binar de egalitate cu selecţie!== Operator binar de inegalitate cu selecţie & Operator binar logică AND pe biţi (aplicat unor operanzi vectori produce un vector) ^ Operator binar logică XOR pe biţi ~^ Operator binar logică XNOR pe biţi Operator binar logică OR pe biţi && Operator binar AND logic (aplicat unor expresii, produce o valoare de adevăr a unei condiţii) Operator binar OR logic?: Operator ternar condiţional Tabelul 2.1 Operatorii Verilog în ordinea precedenţei acestora.

46 36 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL Dimensiunea rezultatului operaţiilor aritmetice depinde de dimensiunea celui mai mare operand şi de dimensiunea şi tipul obiectului destinaţie. Dacă se atribuie unui obiect un rezultat pe mai puţini biţi, atunci rezultatul se extinde cu zerouri. În cazul obiectului destinaţie de tip întreg, rezultatul îezultatul se extinde si extinde bitul de semn (0 pentru numere pozitive şi 1 pentru numere negative). Dacă se atribuie unui obiect un rezultat pe mai mulţi biţi atunci, rezultatul se trunchiază la numărul de biţi ai obiectului destinaţie. Exemple: module testoparitm(); reg[3:0] reg[4:0] reg[5:0] reg[7:0] integer reg[7:0] opa, opb, opc; opd; ope; opf; opg; oph; initial begin opa = 4 b1110; // 14 opb = 4 b1000; // 8 oph = -9; // -9 opc = opa + opb; // suma evaluata pe 4 biti $display("binar: %b + %b = %b, Zecimal: %0d + %0d = %0d", opa, opb, opc, opa, opb, opc); opd = opa + opb; // suma evaluata pe 5 biti $display("binar: %b + %b = %b, Zecimal: %0d + %0d = %0d", opa, opb, opd, opa, opb, opd); ope = opa + opb; // suma evaluata pe 6 biti $display("binar: %b + %b = %b, Zecimal: %0d + %0d = %0d", opa, opb, ope, opa, opb, ope); opf = opa * opb; // multiplicare evaluata la 8 biti $display("binar: %b * %b = %b, Zecimal: %0d * %0d = %0d", opa, opb, opf, opa, opb, opf); opc = opb - opa; // diferenta evaluata pe 4 biti $display("binar: %b - %b = %b, Zecimal: %0d - %0d = %0d", opb, opa, opc, opb, opa, opc); opd = opb - opa; // diferenta evaluata pe 5 biti $display("binar: %b - %b = %b, Zecimal: %0d - %0d = %0d", opb, opa, opd, opb, opa, opd); ope = opb - opa; // diferenta evaluata pe 6 biti

47 2.5. Operatori 37 $display("binar: %b - %b = %b, Zecimal: %0d - %0d = %0d", opb, opa, ope, opb, opa, ope); opg = opb - opa; // diferenta evaluata ca numere intregi $display("binar: %b - %b = %b, Zecimal: %0d - %0d = %0d", opb, opa, opg, opb, opa, opg); opc = opa / opb; // impartire $display("binar: %b / %b = %b, Zecimal: %0d / %0d = %0d", opa, opb, opc, opa, opb, opc); opc = opa % opb; // modulo $display("binar: %b mod %b = %b, Zecimal: %0d mod %0d = %0d", opa, opb, opc, opa, opb, opc); $display("-9 reprezentat pe 8 biti. Binar: %b, Zecimal: %0d", oph, oph); opf = opb + oph; // scadere cu numere "negative". // Rezultat asteptat -1 $display("binar: %b - %b = %b, Zecimal: %0d - %0d = %0d", opb, oph, opf, opb, oph, opf); oph = opf + 3; // adunare cu numere "negative". // Rezultat asteptat +2 $display("binar: %b + %b = %b", opf, 3, oph); $display("zecimal: %0d + %0d = %0d", opf, 3, oph); module În urma simulării, se obţine următorul text: # Binar: = 0110, Zecimal: = 6 # Binar: = 10110, Zecimal: = 22 # Binar: = , Zecimal: = 22 # Binar: 1110 * 1000 = , Zecimal: 14 * 8 = 112 # Binar: = 1010, Zecimal: 8-14 = 10 # Binar: = 11010, Zecimal: 8-14 = 26 # Binar: = , Zecimal: 8-14 = 58 # Binar: = , Zecimal: 8-14 = -6 # Binar: 1110 / 1000 = 0001, Zecimal: 14 / 8 = 1 # Binar: 1110 mod 1000 = 0110, Zecimal: 14 mod 8 = 6 # -9 reprezentat pe 8 biti. Binar: , Zecimal: 247 # Binar: = , Zecimal: = 255 # Binar: =

48 38 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL # Zecimal: = 2 În cadrul operaţiilor aritmetice obiectele de tip net, obiectele de tip reg şi numerele întregi în format cu bază de numeraţie sunt considerate numere pozitive fără semn. Sunt considerate numere întregi cu semn obiectele de tip integer şi numere întregi în format zecimal. Numerele negative sunt reprezentate în binar în complement faţă de 2. Dacă un bit al unui operand este x atunci rezultatul operaţiei aritmetice este x Operatori relaţionali Operatorii relaţionali sunt: > mai mare; < mai mic; >= mai mare sau egal; <= mai mic sau egal. Rezultatul unui operator relaţional este adevărat (1) sau fals (0). Exemple: 15 > 12 fals (0) 15 > 8 hx nedefinit (x) b1000 >= b fals (0) 3 >= 3 adevărat (1) Operatori de egalitate Operatorii de egalitate sunt: == egalitate logică;!= inegalitate logică; === egalitate cu selecţie;!== inegalitate cu selecţie. Rezultatul unui operator de egalitate este adevărat (1) sau fals (0). Exemple:

49 2.5. Operatori 39 opa = b10x0 opb = b10x0 opc = 16 BExF opd = 16 BEEF opa == opb fals (0) opa === opb adevărat (1) 2 b11 === 8 b3 adevărat (1) opc!= opd nedefinit (x) opc!== opd adevărat (1) Operatori logici Operatorii logici sunt: && AND logic; OR logic;! negarea unară. Rezultatul unui operator logic este reprezentat pe un bit: 0, 1 sau x (indecis). Operanzii vectori sunt evaluaţi ca 0 dacă au toate valorile 0, altfel sunt evaluaţi ca 1. Exemple: siga = 1 b0 sigb = 1 b1 busc = 4 b1010 evaluat ca 1 busd = 4 b1001 evaluat ca 1 buse = 4 b0000 evaluat ca 0 sigf = 1 bx evaluat ca x siga && sigb fals (0) siga sigb adevărat (1)!sigA adevărat (1) busc && busd adevărat (1) busc busd adevărat (1)!busC fals (0)

50 40 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL!busE adevărat (1)!sigF indecis (x) Operatori logici pe vectori Operatorii logici pe vectori sunt: ~ negare bit cu bit; & AND pe biţi; OR pe biţi; ^ XOR pe biţi; ~^ XNOR pe biţi. Operatorii logici pe vectori operează bit cu bit. Rezultatul unui operator pe vector este tot un vector, având dimensiunea operanzilor. Tabelele funcţiilor implementate de operatorii logici sunt prezentate în tabelul 2.2. & (and) 0 1 x z (or) 0 1 x z x x x x x 0 x x x x x 1 x x z 0 x x x z x 1 x x ^ (xor) 0 1 x z ~^ (xnor) 0 1 x z x x x x x x x x x x x x x x x x x x z x x x x z x x x x ~ (not) 0 1 x z 1 0 x x Tabelul 2.2 Tabelul funcţiilor implementate de operatorii logici. Exemple: siga = 1 b0 sigb = 1 b1 busc = 4 b1010 busd = 4 b1001

51 2.5. Operatori 41 buse = 4 b0000 sigf = 1 bx siga & sigb 1 b0 siga sigb 1 b1 ~siga 1 b1 busc & busd 4 b1000 busc busd 4 b1011 ~busc 4 b0101 ~buse 4 b1111 ~sigf 1 bx siga & sigf 1 b0 sigb & sigf 1 bx Operatori de reducere Operatorii de reducere sunt: & AND între toţi biţii vectorului; ~& inversul operatorului &; OR între toţi biţii vectorului; ~ inversul operatorului ; ^ XOR între toţi biţii vectorului; ~^ inversul operatorului ^. Operatorii de reducere se aplică unui operand vector şi produc rezultat pe un bit. Aceşti operatori sunt foarte utili în exprimarea unor funcţii pe vectori de dimensiune parametrizabilă. Exemple: busa = 4 b1010 busb = 4 b1011 &busa evaluat ca 0 busa evaluat ca 1

52 42 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL ^busa evaluat ca 0 ^busb evaluat ca 1 Operatorul de reducere ^ poate fi folosit pentru a verifica dacă un bit dintr-un bus are valoare x: busc = 4 b10x0 ^busc evaluat ca x Această observaţie poate fi folosită în specificaţii de verificare a coerenţei datelor de pe un bus: if (^busc === 1 bx) $display("valoare necunoscuta pe busc = %b", busc); O altă aplicaţie a operatorilor de reducere constă în compararea valorii unui vector cu valoarea întreagă 0 (toţi biţii egali cu 0) sau verificarea ajungerii la capătul domeniului de reprezentare a numerelor pozitive (toţi biţii egali cu 1). &busc 1 dacă toţi biţii sunt egali cu 1 ~ busc 1 dacă toţi biţii sunt egali cu 0 (echivalent cu busc === b0) Operatori de deplasare Operatorii de deplasare sunt: << deplasare stânga; >> deplasare dreapta. Operatorii de deplasare produc deplasarea biţilor operandului din stânga cu numărul de poziţii precizat în dreapta, în direcţia precizată de operator. Exemple: reg[7:0] busa;... busa = 8 b1001_ busa >> 2 busa << 2 evaluat ca 8 b0010_0111 evaluat ca 8 b0111_0000

53 2.5. Operatori 43 Operatorii de deplasare sunt foarte folosiţi pentru a descrie operaţii de înmulţire şi împărţire cu numere puteri ale lui 2 sau descrierea exponenţierii în binar. 1 << 3 1 deplasat stânga cu 3 biţi, echivalent cu 2 la puterea 3, echivalent cu 4 b1000 parameter power_p = 7; 1 << power_p echivalent cu 2 la puterea 7, 8 b opa << opb opa >> opb echivalent cu opa înmulţit cu 2 la puterea opb echivalent cu opa împărţit la 2 la puterea opb Acest operator este utilizat şi la modelarea unui decodificator: input[3:0] dcd_i; output[7:0] dcd_o; // rezultatul este un vector de 8 biti avand un singur bit 1, // pe pozitia cu index egal cu dcd_i assign dcd_o = (1 b1 << dcd_i); Operator condiţional Există un singur operator condiţional: <conditie>? <expresie1> : <expresie0> În cazul condiţiei adevărate, operatorul întoarce valoarea <expresie1>. Altfel, o- peratorul întoarce valoarea <expresie0>. Comportamentul este similar cu cel al circuitului multiplexor. Exemple: assign y = sel? i1 : i0; Operatori de concatenare şi replicare Concatenarea este operaţia de alăturare a biţilor într-un bus. Două sau mai multe expresii care semnifică biţi se pot alătura pentru a forma o valoare reprezentată pe mai mulţi biţi. Operatorii de concatenare sunt caracterele acolade: { şi }. O anumită expresie poate fi replicată de un număr de ori în cadrul concatenării. Exemple: // initializarea cu un pattern reg[127:0] reg128; reg128 <= {4{32 hdead_beef}}; // de 4 ori cate 32 de biti // echivalent cu 128 hdead_beef_dead_beef_dead_beef_dead_beef // registrul cu deplasare stanga reg[31:0] leftshreg; leftshreg <= {leftshreg[30:0], 1 b0};

54 44 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL // registrul cu deplasare in inel reg[31:0] inelreg; inelreg <= {inelreg[30:0], inelreg[31]}; // extindere de semn a vectorilor cu // semnificatie de numere intregi (cu semn) wire[7:0] sign8; wire[15:0] sign16; assign sign16 = {{8{sign8[7]}}, sign8}; // sign8 = 8 b0001_1111 (pozitiv) => sign16 = 16 b0000_0000_0001_1111 // sign8 = 8 b1001_1111 (negativ) => sign16 = 16 b1111_1111_1001_1111 Operatorii de concatenare au câteva limitări: În şirul de concatenare nu sunt admise constante cu dimensiuni neprecizate (ilegal {busa, 5}, dar legal {busa, 4 d5}) Numărul de repetări nu poate fi decât o constantă (ilegal {num{2 b10}}, dar legal {3{2 b10}}). 2.6 Specificaţii concurente Specificaţiile concurente se execută în paralel, indiferent de poziţia în care apar în codul sursă. Fiecare specificaţie concurentă are semnificaţia proprie, indepent de celelalte specificaţii concurente. Fiecare specificaţie concurentă este executată asincron faţă de celelalte specificaţii concurente. Un task nu se poate apela într-o specificaţie concurentă. Există trei tipuri de specificaţii concurente: specificaţia assign (numită şi specificaţia de atribuire continuă); specificaţia initial (construcţie lexicală procedurală executată o singură dată); specificaţia always (construcţie lexicală procedurală executată la infinit). Specificaţia assign se poate considera că este forma cea mai simplă de a modela circuite logice combinaţionale. Sintaxa specificaţiei assign este următoarea: S <atribuire_continua> ::= assign <tarie_driver>? <intarziere>? <lista_de_atribuiri> <tarie_driver> ::= ( <STRENGTH0>, <STRENGTH1> ) = ( <STRENGTH1>, <STRENGTH0> ) <intarziere>

55 2.6. Specificaţii concurente 45 ::= # <numar> = # <identificator> = # (<expresie_mintypmax><,<expresie_mintypmax>>?<, <expresie_mintypmax>>?) <lista_de_atribuiri> ::= <atribuire> <,<atribuire>>* <atribuire> ::= <nume_semnal> = <expresie> <STRENGTH0> ::= supply0 strong0 pull0 weak0 highz0 <STRENGTH1> ::= supply1 strong1 pull1 weak1 highz1 <expresie_mintypmax> ::= <expresie> = <expresie1> : <expresie2> : <expresie3> Specificaţia este introdusă de cuvântul rezervat assign. Precizarea tăriei sursei este opţională şi se face sub forma unui cuplu de cuvinte cheie ce precizează tăria stării de 0 şi a stării de 1. Precizarea întâzierii cu care se face atribuirea este opţională. Întârzierea este precedată de simbolul # şi are valoarea absolută determinată de directiva timescale. Întârzierea poate fi un număr, un identificator care are asociată o valoare numerică sau un triplet de valori ale întârzierii minime, tipice şi maxime despărţite prin caracterul două puncte (:). Lista de atribuiri conţine una sau mai multe atribuiri de semnale. O atribuire de semnal este formată din numele semnalului căruia i se atribuie o valoare, simbolul de atribuire = şi o expresie din care, în urma evaluării, rezultă o valoare similară cu cea a semnalului atribuit. Exemple de atribuiri continue: assign (pull0, strong1) #2 dst = src; // atribuie semnalului dst valoarea src // cu intarziere de 2 unitati de timp, // taria semnalului dst fiind "pull0" in // stare 0 si "strong1" in stare 1 assign #delay dst = src; // atribuie semnalului dst valoarea src // cu o intarziere precizata de variabila // delay assign #(1:2:3) dst = src; // atribuie semnalului dst valoarea src // cu intarzierea: // 1 unitate de timp (minim) // 2 unitate de timp (tipic) // 3 unitate de timp (maxim)

56 46 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL Specificaţia initial este o specificaţie concurentă care include una sau mai multe specificaţii procedurale (secvenţiale). Specificaţia initial se execută o singură dată. Execuţia acesteia începe la timpul 0. În cadrul specificaţiilor procedurale se pot include şi specificaţii de temporizare. Odată executată ultima specificaţie secvenţială, specificaţia concurentă initial îşi încetează efectul. De menţionat că, specificaţia initial nu este sintetizabilă (nu poate descrie un comportament de hardware real), ea fiind ignorată de către toate programele de sinteză. Specificaţia initial este folosită exclusiv pentru modelarea vectorilor de test. Sintaxa specificaţiei initial este următoarea: S <specificatie_initial> ::=initial <specificatie_secventiala> Specificaţia always este o specificaţie concurentă, care include una sau mai multe specificaţii procedurale (secvenţiale), similar cu specificaţia initial. Diferenţa dintre acestea constă în faptul că specificaţia always se execută la infinit. Execuţia acesteia începe la timpul 0. După execuţia ultimei specificaţii secvenţiale se reia execuţia acestora de la început, cu prima specificaţie aflată după cuvântul cheie always. În cadrul specificaţilor procedurale se pot include şi specificaţii de temporizare. În plus, specificaţia always conţine o condiţie care determină reluarea execuţiei specificaţiilor. Sintaxa specificaţiei always este următoarea: S <specificatie_always> ::=always <specificatie_secventiala> Prin natura sa, specificaţia always este repetitivă. Din acest motiv, este obligatorie controlarea temporizării repetării acesteia. Dacă o specificaţie always nu are prevăzut un mecanism de temporizare, deşi nu este eroare de sintaxă, simularea va fi blocată la timpul 0 datorită unei bucle infinite cu întârziere nulă. Codul următor modelează un inversor ideal al cărui ieşire este conectată la intrare. Evident, acest circuit oscilează pe frecvenţa infinit. always clk = ~clk; Precizarea unui timp după care se repetă specificaţia conduce la un mod foarte uzual de modelare a unui generator de semnal periodic, de ceas: always #5 clk = ~clk; Semnalul clk va avea un comportament periodic similar cu cel al unui semnal de ceas cu perioada 10ns (semnalul îşi complementează starea la fiecare 5ns). Detalierea specificaţiilor secvenţiale ce pot apărea în câmpul <specificatie_secventiala> este făcută în secţiunea 2.7.

57 2.7. Specificaţii secvenţiale Specificaţii secvenţiale Specificaţiile secvenţiale (procedurale) sunt specificaţii ce pot apărea doar în corpul specificaţiilor concurente initial sau always. Aceste specificaţii se execută strict în ordinea în care apar în codul sursă. Mai multe specificaţii secvenţiale pot fi grupate într-un bloc ce se comportă ca o singură specificaţie prin delimitarea sa prin cuvintele cheie begin şi. Construcţiile HDL concurente permit descrierea hardware la un nivel relativ detaliat. Modelarea unui circuit digital la nivel de porţi logice şi atribuiri continue este foarte apropiată de structura fizică a circuitului. În schimb, acest tip de construcţii nu permit un nivel suficient de abstractizare necesar descrierii sistemelor complexe de mari dimensiuni. Sintaxa specificaţiilor secvenţiale este prezentată în continuare: S <specificatie_secventiala> ::=<atribuire_blocanta>; = <atribuire_neblocanta>; = if (<conditie>) <specificatie_secventiala> = if (<conditie>) <specificatie_secventiala> else <specificatie_secventiala> = case (<expresie>) <articol_case>+ case = casez (<expresie>) <articol_case>+ case = casex (<expresie>) <articol_case>+ case = forever <specificatie_secventiala> = repeat (<expresie>) <specificatie_secventiala> = while (<expresie>) <specificatie_secventiala> = for (<atribuire>; <expresie>; <atribuire>) <specificatie_secventiala> = <control_intarziere> <specificatie_secventiala> = <control_eveniment> <specificatie_secventiala> = wait (<expresie>) <specificatie_secventiala> = -> <nume_eveniment>; = <bloc_secvential> = <bloc_paralel> = <activare_task> = <activare_task_sistem> = disable <nume_task>; = disable <nume_bloc>; = force <atribuire>; = release <net>; Specificaţii de atribuire secvenţiale Atribuirile secvenţiale se deosebesc de atribuirile continue prin modul lor de acţiune. Atribuirile continue (realizate prin specificaţia assign) atribuie valori variabilelor de tip net similar modului în care ieşirea unei porţi logice determină valoarea logică

58 48 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL a sârmei asociate. Expresia din partea dreaptă a simbolului de atribuire (=) poate fi interpretată ca un circuit combinaţional sursă pentru semnal. În schimb, atribuirile secvenţiale nu modifică instantaneu valoarea unei variabile ci programează modificarea valorii acesteia. Acest mecanism poate fi înţeles ca plasarea valorii într-un registru a cărui ieşire devine vizibilă doar la momentul de timp planificat. Atribuirea în sine are durată zero, dar registrul menţine valoarea până la o nouă modificare a acesteia, chiar dacă sursa ce a generat valoarea este dezactivată. Atribuirile secvenţiale pot fi interpretate ca atribuiri declanşate cu întârziere. Evenimentul de declanşare apare când simularea execuţiei modelului HDL ajunge la acea specificaţie. Momentul la care se evaluează o atribuire secvenţială poate fi controlat prin specificaţii de control al evenimentelor, specificaţii de control al timpului, specificaţii condiţionale (if, case) sau specificaţii de iteraţii. Există două tipuri de atribuiri secvenţiale: Atribuiri secvenţiale blocante (atriburi cu simbolul =) şi Atribuiri secvenţiale neblocante (atriburi cu simbolul <=). Distincţia dintre cele două tipuri de atribuiri este uşurată dacă se asociază acestora conceptele VHDL de variabilă şi de semnal. În VHDL, variabila este un obiect ce are asociată o valoare posibil de modificat instantaneu printr-o atribuire specifică. Variabila este un obiect abstract, folosit doar ca obiect de stocare temporară a unei valori, pe parcursul descrierii unui algoritm secvenţial. Semnalul în VHDL este un obiect ce are asociat atât o valoare instantanee, cât şi un driver de semnal ( signal driver, în limba engleză). Driverul de semnal este o mulţime de cupluri valoare-timp (timpul având valori crescătoare), care modelează forma de undă planificată (programată) pentru acel semnal. O atribuire de semnal VHDL nu modifică instantaneu valoarea acestuia, ci adaugă o înregistrare la driverul acestuia. Odată cu scurgerea timpului de simulare, fiecare semnal îşi actualizează valoarea dacă în driver există o înregistrare planificată la timpul curent de simulare. VHDL precizează reguli explicite referitoare la gestiunea înregistrărilor din driverul unui semnal, în funcţie de momentele de apariţie şi de timpii relativi asociaţi acestora. Aceleaşi concepte pot fi aplicate, deşi nu sunt explicit enunţate, şi atribuirilor blocante şi neblocante existente în Verilog. Atribuiri secvenţiale blocante. O atribuire secvenţială blocantă are sintaxa prezentată în continuare. Se remarcă simbolul de atribuire =. S <semnal> = <control_timp> <expresie> O atribuire blocantă este similară ca şi acţiune cu variabilele VHDL. Modificarea valorii unui semnal printr-o atribuire blocantă se face imediat, în momentul execuţiei acesteia, înainte de execuţia specificaţiilor secvenţiale care îi urmează într-un bloc secvenţial. Câmpul <semnal> din stânga operatorului = poate desemna un singur semnal, o porţiune dintr-un vector sau o concatenare de semnale.

59 2.7. Specificaţii secvenţiale 49 Câmpul <control_timp> este opţional şi poate consta dintr-un control temporal (#2) sau control de eveniment clk)). În lipsa unui control temporal se consideră condiţia îndeplinită la momentul executării atribuirii blocante. Operatorul = este similar cu cel folosit la atribuirile concurente. Atribuiri secvenţiale neblocante. O atribuire secvenţială neblocantă are sintaxa prezentată în continuare. Se remarcă simbolul de atribuire <=. S <semnal> <= <control_timp> <expresie> Atribuirile secvenţiale neblocante permit programarea unor atribuiri unui semnal, făra a opri (bloca) fluxul de execuţie a specificaţilor secvenţiale ce îi urmează. Câmpul <semnal> din stânga operatorului <= poate desemna un singur semnal, o porţiune dintr-un vector sau o concatenare de semnale. Câmpul <control_timp> este opţional şi poate consta dintr-un control temporal (#2) sau control de eveniment (@(posedge clk)). În lipsa unui control temporal se consideră condiţia îndeplinită la momentul executării atribuirii blocante. Operatorul <= este similar cu operatorul relaţional mai mic sau egal. Dacă operatorul <= apare într-o expresie, simulatorul îl interpretează ca operator relaţional. Dacă operatorul <= apare într-o construcţie de atribuire secvenţială, simulatorul îl interpretează ca operator de atribuire secvenţială neblocantă. Simulatorul evaluează atribuirile neblocante în două etape. În prima etapă, simulatorul evaluează expresia din dreapta simbolului <=. Simultan, se evaluează controlul temporal. Ca efect, se planifică o schimbare a valorii semnalului la valoarea şi momentul de timp determinate. Fără a schimba valoarea curentă a semnalului, simulatorul îşi continuă executarea specificaţiilor secvenţiale. La sfârşitul evenimentelor asociate timpului curent de simulare, înainte de a incrementa timpul de simulare, simulatorul verifică planificările existente şi actualizează valorile semnalelor ce au planificări la timpul curent de simulare. Apoi timpul de simulare este incrementat. Exemplul care urmează prezintă diferenţele dintre cele două tipuri de atribuiri secvenţiale. S module blockingnonblocking (); reg a, b, c, d, e, f; initial

60 50 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL begin // valori initiale a = 1 b0; b = 1 b0; c = 1 b0; // modificari ale valorilor cu atribuiri blocante a = #10 1 b1; b = #2 1 b1; c = #4 1 b1; #50 a = #10 1 b0; b = #2 1 b0; c = #4 1 b0; initial begin // valori initiale d <= 1 b0; e <= 1 b0; f <= 1 b0; // modificari ale valorilor cu atribuiri neblocante d <= #10 1 b1; e <= #2 1 b1; f <= #4 1 b1; #50 d <= #10 1 b0; e <= #2 1 b0; f <= #4 1 b0; // monitorizarea modificarilor initial begin $monitor("%m %t a=%b, b=%b, c=%b, d=%b, e=%b, f=%b", $time, a, b, c, d, e, f); #100 $display("%m %t NOTE: Simularea s-a sfarsit.", $time); $stop; module Mesajele generate sunt: # blockingnonblocking 0 a=0, b=0, c=0, d=0, e=0, f=0 # blockingnonblocking 2 a=0, b=0, c=0, d=0, e=1, f=0 # blockingnonblocking 4 a=0, b=0, c=0, d=0, e=1, f=1 # blockingnonblocking 10 a=1, b=0, c=0, d=1, e=1, f=1

61 2.7. Specificaţii secvenţiale 51 # blockingnonblocking 12 a=1, b=1, c=0, d=1, e=1, f=1 # blockingnonblocking 16 a=1, b=1, c=1, d=1, e=1, f=1 # blockingnonblocking 52 a=1, b=1, c=1, d=1, e=0, f=1 # blockingnonblocking 54 a=1, b=1, c=1, d=1, e=0, f=0 # blockingnonblocking 60 a=1, b=1, c=1, d=0, e=0, f=0 # blockingnonblocking 76 a=0, b=1, c=1, d=0, e=0, f=0 # blockingnonblocking 78 a=0, b=0, c=1, d=0, e=0, f=0 # blockingnonblocking 82 a=0, b=0, c=0, d=0, e=0, f=0 # blockingnonblocking 100 NOTA: Simularea s-a sfarsit. Formele de undă ale semnalelor sunt prezentate în figura 2.1. Se remarcă faptul că semnalele c, d, e, care au fost atribuite cu specificaţii neblocante, îşi modifică valorile la timpul 0ns (respectiv 50ns) plus întârzierea planificată (10ns, 2ns şi 4ns). În acest caz, întârzierile sunt relative la acelaşi moment de timp. În schimb, semnalele care au fost atribuite cu specificaţii neblocante, îşi modifică valorile la timpi ce trebuie însumaţi. a îşi modifică valoarea la 10ns după timpul curent, b la 2ns după modificarea lui a, iar c la încă 4ns după schimbarea semnalului b. Figura 2.1 Forme de undă pentru exemplificarea atribuirilor secvenţiale blocante şi neblocante. În codul RTL, se recomandă evitarea folosirii specificaţiilor de atribuire blocante şi folosirea exclusivă a celor neblocante. Unele sintetizatoare nu acceptă specificaţii always în care apar ambele tipuri de specificaţii, generând mesaje de atenţionare referitoare la posibilitatea comportamentului diferit al modelului la nivel de poartă logică generat faţă de codul sursă RTL. Pentru exemplificarea acestei recomandări, este prezentat cazul a două specificaţii always, una modelând specificaţii de atribuire blocante, iar alta modelând specificaţii de atribuire neblocante. Specificaţia always este o specificaţie concurentă. Din acest motiv, ordinea în care apar diverse specificaţii always în codul sursă nu ar trebui să aibă vreo importanţă. Totuşi, datorită naturii secvenţiale a parcurgerii fişierului sursă, specificaţiile always sunt evaluate secvenţial de către simulator (chiar dacă la acelaşi timp de simulare ). Utilizarea în acelaşi modul a atribuirilor blocante şi neblocante generează comportamente diferite ale unui cod sursă, în funcţie de ordinea specificaţiilor concurente (always) în fişierul sursă. Comportamentul evidenţiat depinde de simulator, dar este evident că nici un proiectant nu doreşte scrierea unui cod care să se comporte diferit în funcţie de simulatorul utilizat.

62 52 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL T // atribuire blocanta plasata inaintea celei neblocante clk) sigbloc_b1 = sigbloc_b1 + 1; clk) signebloc_b1 <= sigbloc_b1; // atribuire neblocanta plasata inaintea celei blocante clk) signebloc_b2 <= sigbloc_b2; clk) sigbloc_b2 = sigbloc_b2 + 1; Să presupunem cazul iniţial, când toate semnalele au valoarea 0. În primul caz, specificaţia always cu atribuire blocantă apare în fişierul sursă înaintea celei ce foloseşte atribuire neblocantă. Semnalul sigbloc_b1 îşi va actualiza valoarea imediat (sigbloc_b1=1). Semnalul signebloc_b1 îşi planifică schimbarea valorii în sigbloc_b1=1, dar schimbarea efectivă se va petrece la sfârşitul ciclului curent de simulare. În al doilea caz, specificaţia always cu atribuire blocantă apare în fişierul sursă după cea care foloseşte atribuire neblocantă. Semnalul signebloc_b2 îşi planifică schimbarea valorii în sigbloc_b2=0, dar schimbarea efectivă se va petrece la sfârşitul ciclului curent de simulare. În schimb, semnalul sigbloc_b2 îşi va actualiza valoarea imediat (sigbloc_b2=1). Ca efect, după primul front activ al semnalului de ceas, valorile celor patru semnale vor fi: sigbloc_b1 = 1 signebloc_b1 = 1 signebloc_b2 = 0 sigbloc_b2 = 1 Se recomandă rularea testului pe un simulator Verilog pas-cu-pas şi observarea ordinii efective în care se execută specificaţiile always (specificaţii concurente din punct de vedere al limbajului HDL). A se observa momentul când se avansează timpul de simulare în raport cu ordinea de execuţie a specificaţiilor always). Pentru a se facilita înţelegerea, se reia codul cu comentarii referitoare la execuţia iniţială, la primul front pozitiv al semnalului de ceas. // atribuire blocanta plasata inaintea celei neblocante // aici sigbloc_b1 = 0, signebloc_b1 = 0 clk) sigbloc_b1 = sigbloc_b1 + 1; // aici sigbloc_b1 = 1, signebloc_b1 = 0 // sigbloc_b1 si-a modificat deja valoarea clk) signebloc_b1 <= sigbloc_b1; // aici sigbloc_b1 = 1, signebloc_b1 = 0 // s-a planificat o modificare a valorii signebloc_b1 (1, 0ns) // noua valoare va deveni valoare curenta doar la terminarea // ciclului curent de simulare

63 2.7. Specificaţii secvenţiale 53 // atribuire neblocanta plasata inaintea celei blocante clk) signebloc_b2 <= sigbloc_b2; // aici sigbloc_b2 = 0, signebloc_b2 = 0 // s-a planificat o modificare a valorii signebloc_b1 (0, 0ns) // noua valoare va deveni valoare curenta doar la terminarea // ciclului curent de simulare clk) sigbloc_b2 = sigbloc_b2 + 1; // aici sigbloc_b2 = 1, signebloc_b2 = 0 // sigbloc_b2 si-a modificat valoarea // inainte de a se relua executia specificatiilor always, // se actualizeaza semnalele pe baza atribuirilor planificate: // sigbloc_b1 = 1, signebloc_b1 = 1 // sigbloc_b2 = 1, signebloc_b2 = 0 // apoi se avanseaza ciclul de simulare si se continua simularea Se remarcă faptul că unele sintetizatoare nu fac distincţie între simbolurile de atribuire secvenţiale ceea ce conduce la sintetizarea defectuoasă. La simularea netlistului postsinteză se va observa un comportament diferit de cel al surselor RTL. Structura generată de către sintetizator este prezentată în figura 2.2. Figura 2.2 Structură generată de către sintetizator pentru exemplul cu specificaţii blocante şi neblocante. T Simularea comparativă a modulului RTL şi a celui produs după sinteză evidenţiază eroarea în comportamentul celor două modele. Figura 2.3 prezintă formele de undă ale celor două module (RTL şi la nivel de poartă logică) instanţiate în acelaşi mediu de test Specificaţii condiţionale Sintaxa specificaţiilor condiţionale (if) este următoarea:

64 54 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL Figura 2.3 Forme de undă la simularea comparativă RTL - netlist post-sinteză. S if (<conditie>) begin <specificatii_secventiale1> [ <specificatii_secventiale0> ] Execuţia specificaţiei if constă în evaluarea condiţiei urmată de executarea unui grup de specificaţii, în funcţie de valoarea de adevăr a acesteia. Un caz particular, dar foarte întâlnit, este cel al specificaţiei condiţionale în care, indiferent de valoarea de adevăr a condiţiei, se atribuie valori aceluiaşi semnal. În acest caz, specificaţia if modelează comportamentul unui multiplexor: condiţia reprezintă circuitul combinaţional de generare a intrării de selecţie. De exemplu, sintetizatorul produce structura din figura 2.4 pornind de la codul sursă următor: if (a_i && b_i) begin // selectia este AND intre doua intrari y_o <= c_i ^ d_i; y_i <= e_i f_i; Specificaţiile condiţionale pot fi incluse unele în altele. În acest caz, se recomandă folosirea delimitatorilor begin şi pentru evitarea ambiguităţilor (cărui if îi corespunde else?). Alternativa else este opţională. Exemplul următor prezintă folosirea specificaţiilor condiţionale pentru modelarea unui registru cu funcţie completă. Tabelul de funcţionare este descris în continuare: // nr. reset clk en ld cnt sh up lf out++ // // 1 0 X X X X X X X 0 // 2 1 ^ 0 X X X X X out // 3 1 ^ 1 1 X X X X data // 4 1 ^ X 1 X out+1 // 5 1 ^ X 0 X out-1 // 6 1 ^ X 1 out<<1 // 7 1 ^ X 0 out>>1 // 8 1 ^ X X out

65 2.7. Specificaţii secvenţiale 55 Figura 2.4 Structură de multiplexor plus logică sintetizată din specificaţia condiţională. Codul Verilog ce implementează această funcţie prezintă specificaţii condiţionale multiple, incluse unele în altele, unele cu alternativă else. clk_i or negedge reset_ni) begin if (!reset_ni) begin registru_o <= 8 b0; // linia nr. 1 if (enable_i) begin // linia nr if (load_i) begin registru_o <= data_i; // linia nr. 3 if (count_i) begin if (up_i) begin // linia nr. 4 5 registru_o <= registru_o + 1; // linia nr. 4 registru_o <= registru_o - 1; // linia nr. 5 // linia nr. 6 7 if (sh_i) begin if (left_i) begin registru_o <= registru_o << 1; // linia nr. 6 registru_o <= registru_o >> 1; // linia nr. 7 // linia nr. 8 ("if (sh_i)" nu are "else")

66 56 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL // linia nr.2 ("if (enable_i)" nu are "else") Specificaţii de selecţie Specificaţiile de selecţie permit evaluarea unei expresii şi deciderea pe baza valorii acesteia a specificaţiilor ce urmează a se executa. Sintaxa specificaţiilor case este următoarea: S case (<expresie>) valoare{, valoare}: <specificatii_secventiale> [default: <specificatii_secventiale>] case Specificaţiile alternative casex şi casez permit existenţa valorilor x şi z în expresiile valorilor. Acestea sunt cazuri care trebuie folosite cu grijă deoarece ascund potenţiale pericole la sinteză. Execuţia specificaţiei case începe cu evaluarea expresiei. Valoarea evaluată se compară secvenţial, începând cu prima valoare ce apare în listă. Dacă se găseşte o identitate, se execută specificaţiile secvenţiale ce îi corespund şi apoi se încheie execuţia specificaţiei case. Ca o consecinţă, dacă două valori sunt egale, se execută grupul de specificaţii asociat primei apariţii a acelei valori. Dacă valoarea la care a fost evaluată expresia nu a fost găsită, se execută specificaţiile care apar după cuvântul rezervat default. Folosirea default nu este obligatorie. Se recomandă folosirea acesteia pentru evitarea buclelor nedorite ce pot apărea în circuitele combinaţionale modelate incorect. Ca exemplu, este prezentată modelarea unei unităţi logico-aritmetice. // opcod-uri asociate operatiilor define ADD 3 b000 // suma operanzilor define SUB 3 b001 // diferenta operanzilor define XOR 3 b010 // XOR pe biti intre operanzi define AND 3 b011 // AND pe biti intre operanzi define PASS_L 3 b100 // trece operand stanga define NEG_L 3 b101 // trece operand stanga negat bit cu bit module caseex ( func_i, leftop_i, rightop_i, rez_o ); // functie // operand stanga // operand dreapta // rezultat input[2:0] func_i;

67 2.7. Specificaţii secvenţiale 57 input[7:0] input[7:0] output[7:0] reg[7:0] leftop_i; rightop_i; rez_o; rez_o; or leftop_i or rightop_i) begin case (func_i) ADD : rez_o <= leftop_i + rightop_i; SUB : rez_o <= leftop_i - rightop_i; XOR : rez_o <= leftop_i ^ rightop_i; AND : rez_o <= leftop_i & rightop_i; PASS_L : rez_o <= leftop_i; NEG_L : rez_o <= ~leftop_i; default : rez_o <= 8 b0; case module Specificaţii de iteraţii Există patru tipuri de specificaţii pentru iteraţii. Sintaxa acestora este prezentată în continuare. S forever <specificatii_secventiale> repeat (<expresie>) <specificatii_secventiale> while (<expresie>) <specificatii_secventiale> for (<atribuire_initiala>; <expresie>; <atribuire_pas>) <specificatii_secventiale> Specificaţia forever se execută până la apariţia unei specificaţii disable. Pentru a nu se repeta la acelaşi moment al simulării, specificaţia forever trebuie să includă un control temporal. Cu acestă specificaţie se poate modela un semnal de ceas, după cum urmează: reg clk; initial begin clk <= 1 b0; #5 forever // primul front la 5ns #10 clk <= ~clk; // complementeaza la fiecare 10ns

68 58 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL Specificaţia repeat se execută de numărul de ori precizat de o expresie. Câteva exemple sunt prezentate în continuare. // deplaseaza stanga cu 5 pozitii repeat (5) shreg <= shreg << 1; // asteapta scurgerea a nrperioade de ceas repeat clk); Specificaţia while se execută atâta timp cât expresia evaluată este adevărată. Această specificaţie este foarte utilizată pentru modelarea acţiunilor de aşteptare sau de sincronizare între procese. De exemplu, modelul de nivel înalt al unui procesor folosit pentru generarea unor stimuli pentru un sistem hardware comandat, include proceduri (definite ca task-uri) de scriere, de citire şi de pauză (nici o acţiune). O procedură software de polling impune scrierea unui registru care determină execuţia unei comenzi urmată de citirea unui registru de stare până când un anumit bit este găsit setat. Acesta este semnalul că acţiunea iniţiată a fost terminată şi că procesorul poate iniţia noi comenzi. define ADS_COMANDA 8 h20 define ADS_INDICATORI 8 h20 write( ADS_INDICATORI, 16 h0000); // anuleaza starea indicatorilor write( ADS_COMANDA, 16 h0001); // bit0=1 semnifica "lanseaza comanda..." break(2); // asteapta 2 perioade de ceas read( ADS_INDICATORI); // citeste adresa registrului de indicatori while (mpudata_i[15]) // testeaza bit15 al datelor citite read( ADS_INDICATORI); break(2); // executa alte actiuni... // bit15=1 semnifica "comanda terminata" // continua citirea indicatorilor // pana cand actiunea este terminata // (bit15=1) Specificaţia for se execută de un număr precizat de ori. În plus faţă de specificaţia repeat, această specificaţie permite accesarea de către specificaţiile secvenţiale a indexului iteraţiei. Indexul trebuie explicit declarat ca integer. Indexul are o valoare iniţială şi se modifică la fiecare iteraţie conform atribuire_pas. La fiecare iteraţie se verifică starea de adevăr a unui expresii în care intră indexul. Specificaţia for este folosită frecvent atât la iniţializarea matricilor ce modelează structuri de memorie, cât şi la modelarea diverşilor algoritmi ce necesită controlul iteraţiilor. parameter adsdim_p = 10; // latimea bus-ului de adrese

69 2.7. Specificaţii secvenţiale 59 parameter datadim_p = 16; // latimea bus-ului de date // declaratie de memorie de dimensiune parametrizabila // 2^adsDim_p x datadim_p // implicit de dimensiune 2^10 x 16 // (spatiu de adrese intre 0 si 1023) reg[datadim_p-1:0] memory[(1<<adsdim_p)-1 : 0]; integer init_mirror; // index pentru specificatia "for" // initializare memorie initial begin for (init_mirror = 0; init_mirror < (1<<adsDim_p); // valoare initiala // conditie // actualizare index init_mirror = init_mirror + 1); begin if (init_mirror == 0) begin // plasarea unui "marcher" la o anumita adresa memorie[init_mirror] <= 16 hdead_beef; // intializarea datei cu valoarea adresei memorie[init_mirror] <= init_mirror; Deşi nu este cel mai indicat mod de descriere, operaţiile efectuate la adunarea numerelor binare pot fi exprimate cu o specificaţie for, după cum urmează: parameter width_p = 4; integer i; reg tmp; // transport temporar or b_i or ci_i) begin tmp = ci_i; for (i = 0; i < width_p; i = i + 1) begin s_o[i] = a_i[i] ^ b_i[i] ^ tmp; tmp = (a_i[i] & b_i[i]) (a_i[i] & tmp) (b_i[i] & tmp); co_o = tmp; Specificaţii de control temporal Unei specificaţii secvenţiale i se poate asocia un mecanism de control al temporizării. Controlul întârzierii;

70 60 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL Controlul evenimentelor. Controlul întârzierii constă din specificarea unui interval de timp între momentul apariţiei specificaţiei şi momentul executării efective a acesteia. O întârziere a execuţiei specificaţiei secvenţiale este marcată în cod prin precedarea acesteia de simbolul # şi de un număr ce reprezintă numărul de unităţi de timp cu care va fi întârziată execuţia. S #<intarziere> <specificatie_secventiala> Specificaţia ce are asociată o întârziere trebuie înţeleasă ca aşteaptă întârzierea impusă înainte de execuţia specificaţiei asociate. Exemplu: S initial begin #5 semnal = 1; // specificatia 1 #6 semnal = 2; // specificatia 2 #2 semnal = 3; // specificatia 3 Specificaţia initial îşi începe execuţia la timpul 0. La acel moment, semnal nu primeşte nici o valoare, deci va avea valoarea x. După 5 unităţi de timp se execută specificaţia 1, iar semnal va lua valoarea 1. După încă 6 unităţi de timp (deci la 11 unităţi de la începutul simulării) semnal ia valoarea 2. După încă 2 unităţi de timp (deci la 13 unităţi de la începutul simulării) semnal ia valoarea 3, pe care o păstrează până la sfârşitul simulării. Specificarea întârzierii se poate face chiar în lipsa unei specificaţii asociate. În acest caz, semnificaţia este aşteaptă întârzierea impusă înainte de execuţia următoarei specificaţii. S #<intarziere> ; Un caz particular, dar nu lipsit de utilitate practică, îl reprezintă întârzierea explicită cu 0 unităţi de timp: #0 ; Semnificaţia acesteia este: nu se avansează timpul de simulare până la terminarea tuturor evenimentelor programate a avea loc la acest moment de timp. De exemplu, următoarele cupluri de specificaţii au comportamente diferite: // atribuire blocanta plasata inaintea celei neblocante clk) sigbloc_b1 = sigbloc_b1 + 1; clk) signebloc_b1 <= sigbloc_b1;

71 2.7. Specificaţii secvenţiale 61 // atribuire blocanta plasata inaintea celei neblocante // cu intarziere zero explicita clk) #0 sigbloc_b1 = sigbloc_b1 + 1; clk) signebloc_b1 <= sigbloc_b1; Controlul evenimentelor constă din specificarea unei condiţii bazate pe semnale care determină execuţia specificaţiei asociate. Evenimentele pot fi controlate de fronturi de semnale sau de niveluri de semnale. Controlul evenimentului asociat unei specificaţii secvenţiale determină întârzierea execuţiei specificaţiei până la îndeplinirea condiţiei impuse. Controlul evenimentelor pe bază de fronturi poate acţiona pe frontul pozitiv, pe cel negativ sau pe ambele. Fronturile se precizează prin cuvintele rezervate posedge şi negedge. Lipsa unuia din aceste cuvinte semnifică ambele fronturi. Fronturile sunt asociate evenimentelor prezentate în tabelul 2.3. Front negativ Front pozitiv 1 -> x 0 -> x 1 -> z 0 -> x 1 -> 0 0 -> 1 x -> 0 x -> 1 z -> 0 z -> 1 Tabelul 2.3 Asocierea fronturilor unui semnal cu evenimentele acestuia. <eveniment> <specificatie_secventiala> clk) semnal <= semnal + clk or negedge reset_n) semnal <= 8 or semnalb) semnal <= bz; În exemplul anterior, cuvântul rezervat or nu reprezintă un operator logic ci un liant pentru o condiţie cu semnale multiple. Următorul modul implementează un generator parametrizabil pentru semnale de ceas şi de reset (sincronizat cu semnalul de ceas). V timescale 1ns/1ps module clkreset_nogen( clk_o, // semnal de ceas

72 62 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL reset_no // semnal de reset activ in 0 ); // perioada de ceas parameter tckper_p = 10; // implicit frecventa de 100 MHz parameter phaseck_p = 0; // faza initiala a ceasului parameter phaserst_p = 4; // faza activarii reset-ului // masurata in perioade de ceas parameter resetwidth_p = 3; // latimea semnalului de reset masurata // in perioade de ceas output output reg reg clk_o; reset_no; clk_o; reset_no; // generare semnal de ceas initial begin // valoare initiala clk_o <= 1 b0; // asteapta intarzierea determinata de faza initiala #(phaseck_p); // complementeaza la fiecare semi-perioada forever #(tckper_p/2) clk_o <= ~clk_o; // generare semnal de reset activ in 0 initial begin reset_no <= 1 b1; // asteapta activarea reset-ului clk_o); // activeaza reset reset_no <= 1 b0; // asteapta dezactivarea reset-ului clk_o); // dezactiveaza reset reset_no <= 1 b1; module Controlul evenimentelor pe bază de niveluri implementează un mecanism de întârziere a execuţiei unei specificaţii până la îndeplinirea unei condiţii complexe. Dacă la apariţia specificaţiei, condiţia este deja adevărată, execuţia specificaţiei asociate întârzierii are loc imediat. Altfel, execuţia specificaţiei asociate este amânată până la îndeplinirea condiţiei impuse. S

73 2.8. Directive de compilare 63 wait (<expresie>) <specificatie_secventiala> Exemple: wait (counter > 22) counter = 0; wait (rdy) data = intreg; wait (reset_ni); 2.8 Directive de compilare Directivele de compilare nu descriu sisteme hardware, ci transmit simulatorului a- numite informaţii utilizate în procesul de simulare. La compilarea unei directive de compilare, efectul acesteia rămâne până la terminarea procesului de compilare, care poate conţine chiar mai multe fişiere. Directivele de compilare se identifică în cod prin cuvintele cheie rezervate precedate de caracterul ( ). Efectul unor directive de compilare poate fi întrerupt de directive de compilare complementare. Lista directivelor de compilare Verilog este prezentată în continuare: define şi undefine: utilizate pentru substituţie de texte, similar cu utilizarea directivei C #define. O substituţie impusă cu define este valabilă până la apariţia directivei undefine sau până la compilarea tuturor fişierelor. ifdef, ifndef, else, if: utilizate pentru compilări condiţionate. default_nettype: utilizată pentru stabilirea tipului de sârmă implicit, în cazul nedeclarării acestora. În lipsa acestei directive, sârma implicită este de tip wire pe 1 bit. include: utilizată pentru includerea in-line a textului dintr-un fişier în codul sursă, în locul apariţiei directivei. resetall: utilizată pentru anularea tuturor directivelor de compilare anterioare. timescale: utilizată pentru asocierea unei valori absolute unităţii de timp Verilog. unconnected_drive, nounconnected_drive: utilizată pentru asocierea implicită a porturilor de intrare neconectate cu valori logice 0 sau 1. cell_define, cell_define: utilizată pentru declararea unui modul ca celulă posibil de accesat din rutine PLI define şi undefine Directiva de compilare define este utilizată pentru substituţia de texte. Alternativ, ea poate fi utilizată pentru a controla compilarea condiţionată a unor porţiuni de cod. Exemple:

74 64 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL define WIDTH 32 // definire latime bus reg[ WIDTH-1:0] databus; // declarare bus de latime configurabila // definire adrese relative pentru un set de registre define SDRAM_MODE_ADDR 8 h00... define WR_ADDR 8 h08 reg[3:0] sdrammode; // registru de mod al controlerului SDRAM reg[15:0] wraddr; // registru pentru adresa de scriere // scriere registre mpuclk_i or posedge mpureset_ni) begin if (mpureset_ni) begin sdrammode <= 4 b110_0; //incarca sdrammode din bitii de date 6, 5, 4 si 0 if (load && (mpuaddr_i == SDRAM_MODE_ADDR)) begin sdrammode <= {mpudata_i[6:4], mpudata_i[0]}; mpuclk_i or posedge mpureset_ni) begin if (mpureset_ni) begin wraddr <= 16 b0; if (load && (mpuaddr_i == WR_ADDR)) begin wraddr <= mpudata_i; // citire registre mpuclk_i or posedge mpureset_ni) begin if (mpureset_ni) begin mpudata_o <= 16 b0; case (mpuaddr_i) SDRAM_MODE_ADDR: mpudata_o <= {9 b0, sdrammode[3:1], 3 b0, sdrammode[0]};... WR_ADDR: mpudata_o <= wraddr;...

75 2.8. Directive de compilare 65 default: case mpudata_o <= 16 hdead; // adresa neimplementata ifdef, ifndef, else, if Aceste directive de compilare sunt utilizate pentru compilări condiţionate. De e- xemplu, în cazul în care sistemul va fi implementat ca ASIC, dar se va face înainte un prototip de validare implementat pe FPGA, anumite module specifice tehnologiei (memorii, circuite PLL, circuite aritmetice specifice) vor trebui înlocuite. Este însă de dorit a se menţine un singur set de fişiere sursă. Folosind directive de compilare se poate face un număr minim de schimbări pentru a configura un singur cod sursă specific pentru fiecare tehnologie. Porţiunea de cod de mai jos va fi inclusă într-un fişier separat, (inclus în codul sursă cu directiva include) şi semnalat ca fiind modul de alegere a tehnologiei pe care se va face implementarea: define FPGA_tech // define ASIC_tech // decomentati linia ce corespunde tehnologiei În codul sursă, componentele specifice tehnologiei se vor instanţia condiţionat de definirea sau nu a tehnologiei corespunzătoare: ifdef FPGA_tech // instanta de PLL specifica tehnologiei FPGA pllblk UpllBlk (.inclk (ddrclk ),.shclk (shclk ),.clk ( ),.resyncclk (resyncclk ),.SDR_CK (SDR_CK ),.SDR_CK_N (SDR_CK_N ) ); if ifdef ASIC_tech // declaratii de sarme nefolosite wire nc0, nc1; // instanta de DLL specifica tehnologiei ASIC ASIC_DLL UASIC_DLL(.CLK (ddrclk ),.DQS (1 b0 ),.RST (~ddrreset_n ),.CLK360 ({resyncclk, SDR_CK} ),.CLK270 ({shclk,nc0} ), // iesirea este pe 2 biti, dar.clk180 ({SDR_CK_N, nc1} ), // numai unul este folosit.clk90 ( ) ); if

76 66 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL Evitarea unor re-definiri succesive în cazul includerii unui fişier în mai multe surse se poate face prin folosirea directivei ifndef sau a directivelor ifdef şi else. ifndef WIDTH ifdef WIDE_MODE define WIDTH 16 else define WIDTH 8 if if include Directiva include este utilizată pentru includerea in-line a textului dintr-un fişier în codul sursă, în locul apariţiei directivei. Textul ce apare în fişierul inclus poate conţine orice specificaţii Verilog, nu neapărat un modul întreg. Această directivă se poate apela atât din afara, cât şi în interiorul descrierii unui modul. Este recomandată menţinerea într-un fişier separat a directivelor de definire. De multe ori se doreşte doar compilarea unui fişier, iar includerea fişierului de definiţii în fiecare fişier sursă ar determina o eroare de redefinire. Redefinirile multiple pot fi evitate dacă în fişierul inclus, înainte de secţiunea de definiri, se verifică dacă definirile nu au fost deja făcute (ca efect al includerii într-un fişier sursă compilat anterior). Conţinutul unui fişier (incl.h) este prezentat în continuare: ifndef DEFINED_ONCE // indicator care daca a fost definit // determina saltul peste sectiunea de // definiri define DEFINED_ONCE 1 // la prima includere se defineste // indicatorulastfel incat la urmatoarele // includeri sa se gaseasca falsa // conditia de intrare in aceasta // sectiune define GAIN_ADDRESS 6 // definiri define OFFSET_ADDRESS 7... if În unul sau mai multe fişiere sursă poate fi inclus fişierul incl.h astfel: include "incl.h" timescale În Verilog toate întârzierile sunt exprimate în unităţi de timp. Directiva timescale este utilizată pentru asocierea unei valori absolute unităţii de timp Verilog. S

77 2.9. Stil şi calitate 67 timescale <unitate_timp> / <precizie> Directiva timescale specifică unitatea de măsură a timpului pentru întârzieri şi precizia întârzierilor menţionate în toate modulele, până la apariţia unei alte asemenea directive. Este recomandat ca toate fişierele aparţinând unui proiect să conţină aceeaşi directivă timescale. <unitate_timp> precizează valoarea absolută a unităţii de timp. <precizie> specifică precizia cu care se vor rotunji valorile fracţionale. Exemplu: timescale 1ns / 100ps Directiva stabileşte valoarea absolută a unităţii de timp la 1ns şi precizia de rotunjire a valorilor ce reprezintă timp la 100ps. assign #3.14 A = B & C // intarziere 3.1 ns assign #3.1 A = B & C // intarziere 3.1 ns assign #3 A = B & C // intarziere 3 ns 2.9 Stil şi calitate Acest paragraf îşi propune să prezinte recomandările autorilor referitoare la modul de scriere a codului Verilog. Nerespectarea acestor recomandări nu înseamnă că este un cod scris greşit. Dar, orice firmă impune tuturor proiectanţilor un anumit stil al codului sursă în scopul uşurării înţelegerii ulterioare a acestuia. Regulile menţionate în continuare vor fi folosite la scrierea codului sursă prezentat în această carte. Numele identificatorilor. Modul de alegere a numelor pentru obiectele Verilog este un semn al maturităţii şi al experienţei inginerului. În experinţa didactică, autorii au întâlnit multe module scrise foarte bine de către studenţi, dar cu nume care nu sugerează nici pe departe ce modelează acele module. Nume de module ca: test, lab_meu, raspuns_paul, sx2005 sau altele similare, nu dau nici cea mai mică indicaţie asupra comportamentului sau structurii modulului Verilog. Este de dorit ca numele identificatorilor să fie sugestive pentru rolul acestora în cadrul modelului Verilog. De exemplu, identificatorul counter nu sugerează prea multe despre rolul pe care îl are numărătorul modelat în cadrul sistemului. Nici counter16 nu aduce prea multă informaţie pentru că, oricum, numărul de biţi al numărătorului se poate vedea din declaraţia acestuia (reg[15:0] counter16;). O denumire mai sugestivă ar fi rdaddr (adresă de citire a unei memorii) sau pulsecounter (un numărător al unor pulsuri) sau delaycntr (un numărător folosit pentru contorizarea unei întârzieri). Cu totul nerecomandate sunt denumirile derutante, care sugerează ceva diferit de ceea ce modelează de fapt. De exemplu, denumirea counter asociată ieşirii unui circuit combinaţional. De multe ori nu este uşor de exprimat cu puţine litere semnificaţia unui semnal. Nu trebuie totuşi exagerat cu denumiri extrem de lungi de genul numelor de indieni : adresa_de_citire_a_memoriei_fifo_din_blocul_de_receptie. O

78 68 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL denumire mai potrivită, cu prescurtarea unor cuvinte, ar fi: rd_ads_rec. Se iveşte problema delimitării porţiunilor de litere. Nu este la fel ca un semnal să fie denumit rdadsrec sau rd_ads_rec sau rdadsrec. Evident, prima formă este nerecomandată. Cea de-a două formă presupune separarea atomilor ce prescurtează cuvinte diferite prin caracterul de subliniere (_). Este o decizie bună, însă determină artificial lungirea numelor. Acest lucru scade productivitatea scriitorului de cod şi determină ca liniile de cod să fie uneori prea lungi. A treia formă, denumită în jargon incaps, presupune folosirea majusculelor pe post de delimitatori. În acest caz, numele identificatorilor este scurtat la minim. Cu puţin exerciţiu, această formă devine foarte intuitivă pentru cititorul unui cod scris de altcineva. Se remarcă faptul că Verilog face distincţie între numele identificatorilor scrise cu litere mari şi mici. De exemplu, următorii identificatori desemnează obiecte diferite: rdadsrec, rdadsrec, RdAdsRec, rdadsrec. Evident, apariţia unor asemenea nume poate fi o greşeală de tastare şi va fi imediat semnalată la analiza sintactică a codului Verilog. Dar dacă proiectantul a declarat cu intenţie un semnal cu numele rdadsrec şi altul cu numele rdadsrec atunci o eroare de tastare nu mai este semnalată ca eroare de sintaxă şi va fi mai greu de depistat. Numele porturilor şi ale parametrilor. O atenţie particulară trebuie acordată alegerii numelor pentru porturi şi parametrii deoarece acestea reprezintă imaginea exterioară a modulului proiectat. Semnalele au vizibilitate doar în interiorul modulului. Denumirile porturilor şi ale parametrilor vor fi însă văzute şi vor trebui înţelese, de către alţi ingineri care folosesc (instanţiază) acel modul. În plus, este foarte util pentru un scriitor de cod Verilog să ştie imediat dacă un identificator reprezintă un parametru, un port de intrare, un port de ieşire sau un semnal intern acelui modul. De exemplu, se va putea imediat constata o eroare într-o specificaţie de genul assign width_p = 1 b0 dacă se va ştii că identificatorul width_p este de fapt un parametru căruia nu i se poate atribui o valoare folosind specificaţia assign. Sau, o specificaţie de genul assign data_o = data_i va sugera imediat că este vorba nu doar de o simplă atribuire de semnale, ci de modelarea unei sârme care trece prin modul fără nici o prelucrare (dacă data_o este port de ieşire, iar data_i este port de intrare). Asemenea tip de conexiune ( feed-through, în limba engleză) nu este ilegal, dar trebuie folosit cu atenţie. Pentru uşoara identificare a obiectului denumit, se recomandă stabilirea unor convenţii de denumire a porturilor şi a parametrilor. Codul prezentat în acestă carte se conformează următoarelor reguli: Porturile de intrare au nume sufixate cu caracterele _i (dacă este intrare activă în 1) şi _ni (dacă este intrare activă în 0). Exemple: data_i, reset_ni, flag_i, rdrq_i, rdaddr_i. Porturile de ieşire au nume sufixate cu caracterele _o (dacă este ieşire activă în 1) şi _no (dacă este ieşire activă în 0). Exemple: data_o, stat_o, rdrq_o, rdaddr_o, ras_no, cas_no, cs_no. Porturile bidirecţionale au nume sufixate cu caracterele _io. Exemple: data_io, cpudata_io.

79 2.9. Stil şi calitate 69 Parametrii au nume sufixate cu caracterele _p. Exemple: width_p, length_p, messageon_p. Semnalele interne, fiind cu vizibilitate locală şi fiind atât citite, cât şi atribuite în interiorul modulelor, nu vor avea nici un sufix. Se recomandă evitarea terminării numelor identificatorilor cu caracterul de subliniere (_) deoarce multe programe EDA îl folosesc pentru a delimina porţiuni de caractere la formarea automată a numelor. Acest lucru poate produce nu doar confuzie, dar şi erori foarte greu de găsit în netlistul obţinut prin sinteză. Un caz particular îl constituie identificatorii definiţi în directive de compilare define. Directiva define implementează un mecanism de substituire de text şi este similară cu directiva #define din limbajul C. Directiva define poate să apară şi în afara specificaţiilor de module şi are vizibilitate asupra tuturor fişierelor sursă ce se compilează în continuare. Pentru a identifica mai uşor denumirile macro-urilor asociate prin această directivă se recomandă folosirea majusculelor pentru numele acestora. // coduri de comenzi define CMD_IDLE 3 h0 define CMD_WRITE 3 h1 define CMD_READ 3 h2 define CMD_BCAST 3 h7 //Adresa de start a setului de registre define REGS_START_ADDRESS 16 h2000 //Adresele relative ale registrelor define ADDR_CH_CNTRL 8 h00 define ADDR_CH1_CNTRL 8 h02 define ADDR_CH2_CNTRL 8 h03 Folosirea delimitatorilor begin şi. Deşi folosirea acestor demitatori nu este necesară dacă se include o singură specificaţie, este o bună practică a se folosi aceştia în toate cazurile. Ca rezultat, se obţine un cod cu un aspect uniform, uşor de urmărit şi de corectat sintactic. Pentru a alinia cuvintele cheie ce aparţin aceleiaşi specificaţii (if, else) şi a specificaţiilor secvenţiale dintr-un bloc se recomandă folosirea a două caractere spaţiu sau a caracterului tabulator. Recomandarea este exemplificată prin următoarea porţiune de cod. cpuclk_i) begin if (!cpureset_ni) begin outrange <= 1 b0; startop <= 1 b0; if (devsel && (cpuaddr_i == ADDR_STATUS)) begin outrange <= cpud_i[0]; startop <= cpud_i[1];

80 70 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL if (setoutrange) begin outrange <= 1 b1; if (resetstartop) begin startop <= 1 b0; Fără respectarea acestei recomandări, aceeaşi porţiune poate fi scrisă, (perfect legal) după cum urmează: cpuclk_i) if (!cpureset_ni) begin outrange <= 1 b0; startop <= 1 b0; else if (devsel && (cpuaddr_i == ADDR_STATUS)) begin outrange <= cpud_i[0]; startop <= cpud_i[1]; if (setoutrange) outrange <= 1 b1; if (resetstartop) startop <= 1 b0; Deşi cele două porţiuni de cod sunt echivalente, în exemplul recomandat se remarcă uşurinţa cu care se verifică închiderea tuturor delimitatorilor begin cu delimitatori corespunzători ca număr. Ca test, se propune găsirea erorii existente în codul următor. Care delimitator begin nu are corepondent? cpuclk_i) begin if (!cpureset_ni) begin outrange <= 1 b0; startop <= 1 b0; if (devsel && (cpuaddr_i == ADDR_STATUS)) begin outrange <= cpud_i[0]; startop <= cpud_i[1];

81 2.9. Stil şi calitate 71 if (setoutrange) begin outrange <= 1 b1; if (resetstartop) startop <= 1 b0; Un alt argument în favoarea respectării acestei recomandări este eliminarea ambiguităţii ramurilor else în cazul unor specificaţii if imbricate. clk_i) if (!reset_ni) rdaddr <= 1 b0; else if (en) if (ld) rdaddr <= 1 b0; else if (inc) rdaddr <= rdaddr + 1; // primul if // al doilea if // carui if apartine acest else? Codul recomandat este următorul: clk_i) begin if (!reset_ni) begin rdaddr <= 1 b0; if (en) begin if (ld) begin rdaddr <= 1 b0; if (inc) begin rdaddr <= rdaddr + 1; O alternativă de scriere mai condensată, în cazul specificaţiilor always care atribuie valori doar unui semnal este prezentată în continuare: cpuclk_i) if (!cpureset_ni) outrange <= 1 b0; else

82 72 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL if (devsel && (cpuaddr_i == ADDR_STATUS)) outrange <= cpud_i[0]; else if (setoutrange) outrange <= 1 b1; cpuclk_i) if (!cpureset_ni) startop <= 1 b0; else if (devsel && (cpuaddr_i == ADDR_STATUS)) startop <= cpud_i[1]; else if (resetstartop) startop <= 1 b0; Existenţa unui antet al fişierului. Este recomandată existentă unor informaţii la începutul fiecărui fişier sursă, marcate ca fiind comentarii în Verilog. Forma grafică a acestui antet ( header, în limba engleză) nu este importantă. În schimb, este important ca antetul să fie simplu, dar să conţină toate informaţiile relevante necesare: Numele proiectului din care face parte fişierul; Numele autorului; Numele fişierului (pentru a apărea în cazul imprimării codului sursă); Scurtă descriere a modulului descris în acel fişier; Tabelul modificărilor asupra codului (cu siguranţă codul va fi modificat în timp pentru a adăuga noi caracteristici sau a rezolva defectele observate). Ca exemplu, în continuare se prezintă formatul antetul utilizat pentru fişierele ce însoţesc această carte. /************************************************************ * Proiect: Carte "Electronica digitala" * Autor: Dan NICULA (DN) * dan.nicula@vega.unitbv.ro * Nume fisier: updncounter.v * Descriere: Numarator reversibil * Revizii: * Data Autor Modificari * Aug 20, 2005 DN Versiune initiala * Aug 27, 2005 DN Adaugat optiune de preset sincron *************************************************************/ De remarcat că, în antetul propus, nu s-au adăugat caracterele * şi la sfârşitul fiecărei linii. Deşi ar părea frumos, adăugarea de texte ulterior ar impune realinierea caracterelor *, ceea ce ar consuma un timp preţios. Comentarii. Este recomandată adăugarea comentariilor în cod simultan cu scrierea codului, nu ulterior. Există două feluri de comentarii: comentarii pe linii multiple, referitoare la blocuri mari de cod şi comentarii pe un singur rând sau la sfârşitul rândului, referitoare la o anumită expresie sau specificaţie.

83 2.9. Stil şi calitate 73 Comentariile trebuie să aibă următoarele caracteristici: să fie scurte; să fie relevante; să fie plasate înaintea porţiunii de cod la care se face referire. Lista porturilor unui modul se recomandă a fi scrisă câte un singur port pe un rând. În acest fel, se poate scrie în dreptul fiecărui port o scurtă descriere, ca şi comentariu. module add1c ( a, // primul operand b, // al doilea operand ci, // transport de intrare s, // rezultatul co // transport de iesire ); Comentariile trebuie să fie relevante pentru specificaţia sau identificatorul la care face referire. De exemplu, următoarele comentarii nu sunt foarte relevante: clk or negedge reset_n) if (!reset_n) rd_addr <= 16 b0; else if (updt_cnt) rd_addr <= rd_addr + 1; // reseteaza rd_addr // incrementeza rd_addr Este evident (din specificaţia existentă pe acelaşi rând cu comentariul) că rd_addr se incrementează. Este evidentă şi condiţia de incrementare a acestui registru. Ce nu este evident, şi ar trebui să fie precizat printr-un comentariu, este semnificaţia registrului rd_addr în cadrul sistemului. De exemplu, în continuare se prezintă acelaşi cod cu comentarii considerate relevante: // rd_addr: adresa de citire a memoriei de stocare // a datelor acceptate clk or negedge reset_n) if (!reset_n) rd_addr <= 16 b0; else // updt_cnt: semnal generat de blocul de receptie if (updt_cnt) rd_addr <= rd_addr + 1; Asocierea explicită a porturilor cu semnalele, la instanţierea unui modul. Alternativa asocierii prin poziţie nu este recomandată deoarece poate genera erori nu numai în cazul asocierii greşite, ci şi în cazul adăugării sau eliminării unor porturi ale modulului. În plus, este recomandată plasarea pe o linie de cod a unui singur cuplu port-semnal actual cu posibilitatea de a adăuga un comentariu la sfârşitul liniei. În cazul prezentat în continuare, asocierea dintre porturi şi semnale se face prin poziţie. Va fi greu de găsit greşeala pentru că, în anumite cazuri, răspunsul este corect chiar dacă au fost făcute conexiuni greşite.

84 74 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL add1c U0_add1C( a[0], b[0], 1 b0, su1[0], cou1); add1c U1_add1C( a[1], b[1], cou1, cou2, su2[1]); Dacă pentru unele porturi denumirea semnalelor asociată este sugestivă, pentru a vedea ce port este conectat la masă (asociat cu 1 b0) trebuie să se deschidă un alt fişier şi să se verifice ordinea porturilor la declararea modulului add1c. Modul recomandat de instanţierea unui modul este ca în exemplul următor: add1c U2_add1C(.a (a[2] ),.b (b[2] ),.ci (cou2 ), // transport provenit de la U2_add1C.s (su3[2] ),.co (cou3 ) // transportul se propaga la U4_add1C ); Conţinutul unui fişier sursă. Se recomandă ca un fişier să conţină descrierea unui singur modul. În plus, dacă numele fişierului este identic cu numele modulului descris în acel fişier, căutarea descrierii unui modul este mult uşurată. Excepţie de la această recomandare o fac fişierele ce conţin descrierea unor biblioteci de componente. În acest caz, mai multe descrieri de module sunt incluse în acelaşi fişier şi sunt compilate printr-o singură comandă. Este total neinspirată includerea a două module cu cod Verilog în acelaşi fişier deoarece căutarea celui de-al doilea modul (a cărui început se află undeva prin mijlocul fişierului) va fi foarte anevoioasă. Uneori, se recomandă includerea unor fişiere cu directiva de compilare include. Este cazul plasării unor parametri posibil de configurat separat de codul sursă ce nu trebuie modificat. Aceste fişiere se recomandă a fi denumite cu altă extensie decât.v pentru a nu fi selectate alături de fişierele ce conţin declaraţii de module. Extensia acestor fişiere nu este impusă, dar se recomandă a fi.h. Se recomandă păstrarea fişierelor sursă Verilog în directoare distincte, în funcţie de rolul lor. În folderul src se vor păstra fişierele Verilog ce descriu sistemul proiectat, fişiere care în final se vor sintetiza. Fişierele care modelează mediul de simulare, vor fi plasate într-un alt folder, denumit sim. Fişierele ce conţin date referitoare la sinteză (constrângeri de timp, asocieri de pini) vor fi plasate într-un folder separat denumit syn. Această ordine a fişierelor permite altor membrii ai echipei de proiectare un acces rapid la fişiere. Totodată, fişierele generate de diverse produse software vor fi plasate automat în folderele corespunzătoare: folderul sim fişiere generate la simulare şi folderul syn fişiere generate la sinteză. Transmiterea parametrilor cu directive defparam. Funcţionarea sau structura unui modul poate fi modificată prin folosirea unor parametri. Parametrii reprezintă constante pentru instanţierea modulelor şi au valori implicite, precizate în cadrul declaraţiei de module. Valorile implicite ale parametrilor pot fi modificate în momentul instanţierii modulelor sau prin directive de compilare defparam. A doua metodă, dacă este suportată de programele de sinteză, are câteva avantaje. Avantajul principal constă în faptul că se pot schimba numai

85 2.9. Stil şi calitate 75 anumite valori ale parametrilor, fără a se cunoaşte ordinea definirii acestora în module. În plus, folosirea directivei defparam produce o mai bună documentare a codului sursă. În continuare sunt prezentate două exemple de transmitere a parametrilor. Transmiterea parametrilor la instanţierea modulelor: wire[7:0] a; wire[7:0] b; wire[7:0] s1; wire[7:0] s2; wire[3:0] s3; wire co1, c02, c03; // sumator pe 8 biti addxc #(8) Sum1(.a (a ),.b (b ),.ci (1 b0 ),.s (s1 ),.co (co1 ) ); Transmiterea parametrilor cu directive defparam: defparam Sum2.width = 8; defparam Sum3.width = 4; // sumator pe 8 biti addxc Sum2(.a (a ),.b (b ),.ci (1 b0 ),.s (s2 ),.co (co2 ) ); // sumator pe 4 biti addxc Sum3(.a (a[3:0] ),.b (b[3:0] ),.ci (1 b0 ),.s (s3 ),.co (co3 ) ); Declararea sârmelor la începutul modulului. Declararea variabilelor care modelează sârme (wire şi reg) se poate face oriunde în cod. Singura condiţie este ca declaraţia să preceadă prima referire la sârma respectivă. Totuşi, este recomandată plasarea grupată, imediat după declararea porturilor, a tuturor declaraţiilor de sârme. Nerespectarea aceastei reguli ar putea determina ca, la

86 76 CAPITOLUL 2. FUNDAMENTELE LIMBAJULUI VERILOG HDL mutarea unor specificaţii, declaraţia unor sârme să rămână mai jos producând inutile erori de sintaxă. Verilog permite declararea implicită a unui tip de sârmă, de obicei sârma de tip wire de un bit. Se recomandă totuşi declararea explicită a tuturor sârmelor şi totodată adăugarea unui mic comentariu despre semnificaţia acestora. Scrierea a maxim 80 de caractere pe o linie de cod. Deşi în marea majoritate a timpului codul sursă este vizualizat pe monitor, uneori este utilă imprimarea acestuia pe hârtie. Pentru a evita consumarea timpului cu formatarea codului astfel încât să se tipărească în întregime, este de preferat scrierea codului cu nu mai mult de 80 de caractere pe linie. În Verilog, o specificaţie poate fi scrisă pe mai multe linii, fără a fi necesară o delimitare explicită. Nefolosirea constantelor numerice în cod. Se recomandă evitarea folosirii constantelor numerice în codul sursă. O constantă folosită direct în cod este foarte puţin vizibilă la depanarea codului. În schimb, dacă mărimile constante se asociază unui identificator cu o denumire sugestiv aleasă, acestea pot fi uşor localizate în cod. Actualizarea valorii constante într-un singur loc se va propaga automat în cod, în cazul apelării acestei valori de către mai multe specificaţii. Declararea constantelor se face prin directiva de compilare define. Se recomandă folosirea majusculelor pentru identificatorii ce definesc constante. // Numar de biti de adresa si de date define ADDR_BIT_NO 8 define DATA_BIT_NO 8 // Adresele relative ale registrelor define ADDR_CH_CNTRL 8 h00 define ADDR_CH1_CNTRL 8 h02 define ADDR_CH2_CNTRL 8 h03... output[data_bit_no-1:0] cpudata_o; reg[data_bit_no-1:0] cpudata_o;... reg[data_bit_no-1:0] devctrl; reg[data_bit_no-1:0] devch1ctrl; reg[data_bit_no-1:0] devch2ctrl;... // scrierea registrului de control de catre CPU assign wrctrl = devsel_i & (cpuaddr_i[addr_bit_no-1:0] == ADDR_CH_CNTRL); cpuclk_i) if (!cpureset_ni) devctrl <= b0; else if (wrctrl) devctrl <= cpudata_i; // citirea registrelor de catre CPU cpuclk_i) if (!cpureset_ni) cpudata_o <= b0; else case (cpuaddr_i[addr_bit_no-1:0])

87 2.9. Stil şi calitate 77 ADDR_CH_CNTRL : cpudata_o <= devctrl; ADDR_CH1_CNTRL: cpudata_o <= devch1ctrl; ADDR_CH2_CNTRL: cpudata_o <= devch2ctrl;... case Se remarcă faptul că modificarea spaţiului de adrese sau chiar a numărului de biţi de adrese sau de date, se poate face prin modificarea valorilor definite, fără modificări în codul sursă.

88

89 Capitolul 3 MODELAREA CIRCUITELOR ELEMENTARE Acest capitol prezintă modalitatea uzuală de modelare a blocurilor digitale în vederea sintetizabilităţii. Alte modalităţi de modelare, a bibliotecilor de componente primitive sau a mediilor de testare, sunt considerate noţiuni avansate şi sunt tratate separat în capitolul 4. Altfel spus, se prezintă în acest capitol modelarea RTL a diverselor structuri întâlnite în circuitele integrate digitale. 3.1 Circuite combinaţionale Porţile logice şi circuitele logice în general se pot modela individual cu specificaţii de atribuire continuă (assign) sau cu specificaţii de atribuire procedurale (always). Alternativ, circuitele logice secvenţiale pot fi modelate în cadrul specificaţiilor always care descriu simultan registrele şi logica ce determină starea lor viitoare (cazuri prezentate în secţiunile 3.7 şi 3.8) Modelarea circuitelor logice cu assign Circuitul logic combinaţional caracterizat de funcţia AOI (And-Or-Invert) F = A.B + C.D poate fi descris astfel: wire A, B, C, D; wire F; // iesirea se declara ca wire assign F = ~(A&B C&D); // se folosesc regulile de precedenta ale // operatorilor Modelarea cu assign are avantajul unei descrieri concise, foarte apropiată de realizarea fizică şi foarte intuitivă. Semnalele care apar în stânga sunt ieşirile, iar semnalele care apar în dreapta simbolului de atribuire (=) sunt intrările circuitului combinaţional. 79

90 80 CAPITOLUL 3. MODELAREA CIRCUITELOR ELEMENTARE Un lucru important la modelarea pentru sintetizabilitate este conştientizarea numărului de intrări ale unui circuit combinaţional. wire[7:0] abus; // semnale de 8 biti wire[7:0] bbus; wire G, H, I, J, K; assign G = (abus == 8 h78); // 8 intrari, functia este 1 daca // intrarea este egala cu 8 h78 assign H = (abus == bbus); // 16 intrari, functia este 1 daca // intrarea abus (8 biti) este egala cu // intrarea bbus (8 biti) assign I = ( abus); // 8 biti, OR pe biti, // echivalent cu (abus!= 0) assign J = (~ (abus~^bbus)); // 16 biti, echivalent cu (abus==bbus) assign K = (abus[0] & &bbus); // 7 biti, AND intre toti bitii // semnalului bbus si bitul [0] // al semnalului abus, // echivalent cu &{abus[0], bbus} Modelarea circuitelor logice cu always Modelarea circuitelor logice cu specificaţii always are avantajul posibilităţii folosirii specificaţiilor secvenţiale (if, case) pentru definirea unor funcţii mai complexe. Însă, modelarea circuitelor logice cu specificaţii procedurale necesită o atenţie sporită deoarece conţine o redundanţă. Lista de senzitivităţi a specificaţiei always trebuie să conţină toate semnalele ce apar în dreapta simbolurilor de atribuire procedurală. Neapariţia unui semnal de intrare în lista de descriere a evenimentului asociat specificaţiei always poate determina apariţia unui latch în urma sintezei. Dacă vectorii de test sunt bine aleşi, defectul se poate pune în evidenţă şi la nivel RTL. Circuitul logic combinaţional caracterizat de funcţia AOI (And-Or-Invert) F = A.B + C.D poate fi descris astfel: wire A, B, C, D; reg L; // iesirea se declara ca reg or B or C or D) // cuvantul or este doar "liantul" // pentru lista de senzitivitati // (nu semnifica operatorul logic OR) L <= ~(A&B C&D); Cum se sintetizează următoarea specificaţie? or B or C) M <= ~(A&B C&D); // lipseste intrarea D Se observă că ieşirea M nu se re-evaluează dacă se modifică intrarea D deoarece aceasta nu este prezentă in lista de senzitivităţi. Sintetizatoarele actuale recunosc o potenţială greşeală şi emit mesaje de atenţionare sensitivity list - assuming variable D is not in sensitivity list

91 3.2. Circuite de multiplexare 81 WARNING: The signals <D> are missing in the sensitivity list of always block. Unul din motivele cele mai frecvente pentru modelarea circuitelor combinaţionale cu specificaţie always este cazul modelării multiplexoarelor cu multe intrări de selecţie, cu specificaţie secvenţială case. Trebuie acordată atenţie existenţei specificaţiei default. Altfel, circuitul rezultat din sinteză va conţine un latch. Se remarcă faptul că lista intrărilor conţine atât intrările de date, cât şi intrarea de selecţie. wire[1:0] sel; wire i0, i1, i2, i3; reg mux; or i0 or i1 or i2 or i3) case (sel) 2 b00: mux <= i0; 2 b01: mux <= i1; 2 b10: mux <= i2; default: mux <= i3; case Figura 3.1 prezintă structurile hardware sintetizate din codul prezentat în această secţiune. 3.2 Circuite de multiplexare Circuitul multiplexor 2:1 poate fi modelat cu operatorul condiţional: dacă selecţia este 1, la ieşire se propagă intrarea de date 1, altfel la ieşire se propagă intrarea de date 0. wire mux assign mux = sel? i1 : i0; Alternativa secvenţială permite utilizarea specificaţiei if: reg mux; or i0 or i1) if (sel) mux <= i0; else mux <= i1; Circuitele de multiplexare cu număr mai mare de intrări de selecţie pot fi modelate cu specificaţia case, aşa cum a fost prezentat în secţiunea Codificator/decodificator Modelarea codificatoarelor se poate face folosind specificaţia case, pornind de la tabelul de adevăr al acestor funcţii: codificarea în binar a indexului bitului egal cu 1

92 82 CAPITOLUL 3. MODELAREA CIRCUITELOR ELEMENTARE Figura 3.1 Structuri obţinute prin sinteza modelelor de circuite combinaţionale prezentate în secţiunea 3.1.

93 3.3. Codificator/decodificator 83 în vectorul de intrare. Circuitul codificator descris în exemplul următor presupune existenţa unui singur bit egal cu 1 între cei 8 biţi de intrare. case(a) 8 b1000_0000: Y <= 3 b111; // 7 8 b0100_0000: Y <= 3 b110; // 6 8 b0010_0000: Y <= 3 b101; // 5 8 b0001_0000: Y <= 3 b100; // 4 8 b0000_1000: Y <= 3 b011; // 3 8 b0000_0100: Y <= 3 b010; // 2 8 b0000_0010: Y <= 3 b001; // 1 8 b0000_0001: Y <= 3 b000; // 0 default: Y <= 3 bx; // nici o intrare activa // sau mai mult de o intrare activa case În cazul acceptării la intrare a mai multor biţi egali cu 1, circuitul codificator trebuie să impună o prioritate. Modelarea priorităţilor se poate face cu specificaţia casex. Spre deosebire de specificaţia case, specificaţia casex acceptă descrierea intrărilor indiferente ( don t care, în limba engleză). De remarcat că, în cazul în care expresia de selecţie corespunde mai multor opţiuni casex, este executată specificaţia ce corespunde primei coincidenţe dintre variabila de selecţie şi expresiile listate. casex(a) 8 b1xxx_xxxx: Y <= 3 b111; // 7 8 b01xx_xxxx: Y <= 3 b110; // 6 8 b001x_xxxx: Y <= 3 b101; // 5 8 b0001_xxxx: Y <= 3 b100; // 4 8 b0000_1xxx: Y <= 3 b011; // 3 8 b0000_01xx: Y <= 3 b010; // 2 8 b0000_001x: Y <= 3 b001; // 1 8 b0000_0001: Y <= 3 b000; // 0 default: Y <= 3 bx; // nici o intrare activa case În continuare este prezentat modelul unui circuit codificator cu prioritate cu intrare şi ieşire de validare. T V module encoder( A_i, E_i, Y_o, E_o ); // intrarea codificatorului // validare intrare // iesirea codificatorului // validare iesire

94 84 CAPITOLUL 3. MODELAREA CIRCUITELOR ELEMENTARE input[7:0] A_i; // intrare de date input E_i; // intrare de validare output[2:0] Y_o; output E_o; reg[2:0] reg Y_o; E_o; or E_i) // intrari codificator if (E_i) begin casex(a_i) 8 b1xxx_xxxx: {E_o, Y_o} <= 4 b1_111; // 7 8 b01xx_xxxx: {E_o, Y_o} <= 4 b1_110; // 6 8 b001x_xxxx: {E_o, Y_o} <= 4 b1_101; // 5 8 b0001_xxxx: {E_o, Y_o} <= 4 b1_100; // 4 8 b0000_1xxx: {E_o, Y_o} <= 4 b1_011; // 3 8 b0000_01xx: {E_o, Y_o} <= 4 b1_010; // 2 8 b0000_001x: {E_o, Y_o} <= 4 b1_001; // 1 8 b0000_0001: {E_o, Y_o} <= 4 b1_000; // 0 default: {E_o, Y_o} <= 4 b0_000; // nici o intrare activa case // circuit nevalidat la intrare {E_o, Y_o} <= 4 b0_000; module Circuitul decodificator se poate descrie folosind operatorul de deplasare stânga, pornind de la interpretarea funcţiei decodificatorului: deplasează spre stânga un bit 1 pe ieşire cu numărul de poziţii precizat la intrare. wire[2:0] A; wire[7:0] Y; assign Y = (1 b1 << A); Se observă că dacă A=3 b000, atunci Y=8 b0000_0001. Dacă A=3 b001, atunci Y=(8 b0000_0001 << 1)=8 b0000_0010. Dacă A=3 b111, atunci Y=(8 b0000_0001 << 7)=8 b1000_0000. Următorul model prezintă un circuit decodificator cu intrare de validare. module decoder( A_i, E_i, Y_o ); // intrarea decodificatorului // validare intrare // iesirea decodificatorului input[2:0] A_i;

95 3.4. Latch D 85 input output[7:0] reg[7:0] E_i; Y_o; Y_o; or E_i) if (E_i) Y_o <= (1 b1 << A_i); else Y_o <= 8 b0; // intrari codificator // circuit nevalidat la intrare module 3.4 Latch D Circuitele latch trebuie modelate cu un semnal de menţinere a stării. O atenţie deosebită trebuie acordată modelării nedorite a unor structuri de tip latch. Următorul cod Verilog modelează un circuit multiplexor, similar celui prezentat în figura 3.2. or in0 or in1 or in2 or in3) case (sel) 2 b00 : y <= in0; 2 b01 : y <= in1; 2 b10 : y <= in2; 2 b11 : y <= in3; case Figura 3.2 Multiplexor 4:1. O linie lipsă în codul anterior, determină apariţia după sinteză a unui latch nedorit, prezentat în figura 3.3.

96 86 CAPITOLUL 3. MODELAREA CIRCUITELOR ELEMENTARE or in0 or in1 or in2 or in3) case (sel) 2 b00 : y <= in0; 2 b01 : y <= in1; 2 b10 : y <= in2; //2 b11 : y <= in3; // optiune lipsa case Figura 3.3 Latch nedorit apărut în urma unei specificaţii case incomplete. Modelul circuitului latch elementar este prezentat în continuare. Se observă faptul că latch-ul re-evaluează ieşirea condiţionat de semnalul de ceas şi de semnalul de date. Dacă semnalul de ceas este 1, atunci ieşirea copiază intrarea. Altfel, ieşirea nu este re-evaluată şi, în consecinţă, valoarea acesteia este păstrată (conform definiţiei semnalului de tip reg). // latch D or d) if (clk) q <= d; 3.5 Bistabil D/RS Bistabilul este circuitul elementar pe care se bazează sistemele secvenţiale. Modelarea acestuia se face cu specificaţie always pornind de la descrierea funcţionării acestuia: în momentele determinate de frontul pozitiv al semnalului de ceas, bistabilul memorează intrarea. // bistabil D clk) q <= d; Se observă că specificaţia q <= d; se execută numai în momentele apariţiei unui front pozitiv de ceas (@(posedge clk)). Valoarea iniţială a bistabilului, înainte de primul front activ, este neprecizată, fiind x în modelul de simulare. Pentru a modela un semnal de reset asincron, modelul trebuie modificat astfel:

97 3.5. Bistabil D/RS 87 // bistabil D cu reset asincron activ high clk or posedge reset) if (reset) q <= 1 b0; else q <= d; Se observă că modificarea valorii bistabilului q este posibilă la activarea semnalului de reset, indiferent de semnalul de ceas. Dacă semnalul de reset este inactiv (reset=0), modelul se reduce la cel al unui bistabil D elementar. Bistabilele cu set şi reset asincrone se recomandă a fi evitate în proiectare. La modelarea acestora trebuie observată necesitatea priorităţii tratării intrărilor asincrone. Bistabilele cu intrări de set şi/sau reset sincrone sunt cazuri particulare de circuite secvenţiale şi se modelează corespunzător. // bistabil D cu reset sincron activ high clk) // reset sincron => nu apare in lista // clk resetsync q+ // de senzitivitati (descrierea // // evenimentului de declansare a // ^ 1 0 // specificatiei always) // ^ 0 d if (resetsync) q <= 1 b0; else q <= d; // bistabil D cu reset sincron activ low // clk resetsync q+ // // ^ 0 0 // ^ 1 d clk) if (~resetsync_n) q <= 1 b0; else q <= d; // bistabil D cu set si reset sincron active low // clk setsync_n resetsync_n q+ // // ^ 0 x 1 // ^ // ^ 1 1 d clk) if (~setsync_n) q <= 1 b1; else // set prioritar if (~resetsync_n) q <= 1 b0; else q <= d; // bistabil D cu set si reset sincron active low si // reset asincron activ low // resetasync_n clk setsync_n resetsync_n q+ // // 0 x x x 0 // 1 ^ 0 x 1

98 88 CAPITOLUL 3. MODELAREA CIRCUITELOR ELEMENTARE // 1 ^ // 1 ^ 1 1 d clk or negedge resetasync_n) if (~resetasync_n) q <= 1 b0; else // reset asincron // (exista in lista de // descriere a evenimentului) if (~setsync_n) if (~resetsync_n) q <= 1 b1; else // set prioritar q <= 1 b0; else q <= d; // bistabil D cu set si reset sincron active low si // reset asincron activ low // resetasync_n clk setsync_n resetsync_n q+ // // 0 x x x 0 // 1 ^ 0 x 1 // 1 ^ // 1 ^ 1 1 q (pastreaza starea) clk or negedge resetasync_n) if (~resetasync_n) q <= 1 b0; else // reset asincron if (~setsync_n) q <= 1 b1; else // set prioritar if (~resetsync_n) q <= 1 b0; // nu exista else, // pastreaza starea 3.6 Bistabil T/JK Bistabilul T se modelează similar cu bistabilul D, considerând descrierea funcţionării acestuia: dacă în momentul unui front activ al semnalului de ceas intrarea este egală cu 1, atunci bistabilul T îşi complementează starea, altfel bistabilul T îşi păstrează starea. // clk t q+ // // ^ 1 ~q // ^ 0 q // implicit clk) if (t) q <= ~q; Se remarcă faptul că bistabilul T porneşte din starea x şi are doar posibilitatea de a-şi complementa starea. Ca o consecinţă, modelul anterior va prezenta tot timpul q=x. Pentru iniţializarea bistabilului T este necesară modelarea unei condiţii de resetare, sincronă sau asincronă. // bistabil T cu reset asincron activ low // reset_n clk t q+ // // 0 x x 0

99 3.7. Numărătoare sincrone 89 // 1 ^ 1 ~q // 1 ^ 0 q // implicit clk or negedge reset_n) if (~reset_n) q <= 1 b0; else if (t) q <= ~q; // bistabil T cu reset sincron activ low // clk reset_n t q+ // // ^ 0 x 0 // ^ 1 1 ~q // ^ 1 0 q // implicit clk) if (~reset_n) q <= 1 b0; else if (t) q <= ~q; Bistabilul JK are un model dedus din tabelul de funcţionare a acestuia, lăsând implicit cazul când ieşirea se păstrează. // bistabil JK cu reset asincron activ low // reset_n clk j k q+ // // 0 x x x 0 // 1 ^ 0 0 q // implicit // 1 ^ // 1 ^ // 1 ^ 1 1 ~q clk or negedge reset_n) if (~reset_n) q <= 1 b0; else case({j,k}) 2 b01 : q <= 1 b0; 2 b10 : q <= 1 b1; 2 b11 : q <= ~q; default: ; // nu atribuie nimic, pastreaza valoarea case 3.7 Numărătoare sincrone Numărătoarele sunt circuite foarte des folosite în circuitele integrate digitale. Modelul unui numărător poate fi descris similar cu cel al unui registru cu particularizarea că intrarea provine dintr-un circuit combinaţional de incrementare a ieşirii. reg[7:0] count; clk or negedge reset_n) if (~reset_n) count <= 8 b0; // initializarea asincrona a numaratorului

100 90 CAPITOLUL 3. MODELAREA CIRCUITELOR ELEMENTARE else count <= count + 1; // starea viitoare este (starea curenta + 1) Un numărator cu facilităţi de numărare în sens crescător şi în sens descrescător este prezentat în continuare. În plus, a fost prevăzută o intrare suplimentară de validare a numărării. // numarator in sens crescator/descrescator si validare a numararii // reset_n clk en up count+ // // 0 x x x 0 // 1 ^ 0 x count (pastreaza starea) // 1 ^ 1 1 count+1 (numara in sens crescator) // 1 ^ 1 0 count-1 (numara in sens descrescator) reg[7:0] count; clk or negedge reset_n) if (~reset_n) begin count <= 8 b0; // initializarea asincrona a numaratorului if (en) begin if (up) begin count <= count + 1; // starea viitoare este // (starea curenta + 1) count <= count - 1; // starea viitoare este // (starea curenta - 1) // daca en=0, pastreaza starea De remarcat faptul că numărarea se face în binar pe numărul de biţi pe care a fost declarat semnalul count. După 8 b1111_1111 urmează în sens crescător 8 b0000_0000. Ca exemplu, este prezentat în continuare modelul unui numărător în binar în sens crescător sau descrescător, cu modificare dinamică a valorii de terminare a numărării. Caracteristicile numărătorului sunt: Lăţime parametrizabilă; Indicator de terminare a numărării pentru comparare cu valoarea impusă; Valoare de terminare a numărării implementată ca intrare în numărător; Control al sensului de numărare; Reset asincron; Semnal de încărcare sincronă.

101 3.7. Numărătoare sincrone 91 Figura 3.4 Simbolul bloc al numărătorului. Simbolul bloc al numărătorului este prezentat în figura 3.4. Descrierea porturilor este prezentată în tabelul 3.1: Descrierea funcţionării numărătorului este realizată prin tabelul 3.2. Când valoarea numărătorului este egală cu valoarea de la portul count_to, semnalul tercnt ( terminal count, în limba engleză) este activat. Semnalul tercnt poate fi conectat la intrarea load printr-un inversor pentru a iniţializa sincron numărătorul la valoarea predefinită de la portul data. Numărătorul are un număr de biţi parametrizabil (width) şi 2 width stări, de la , până la Numărătorul este activ pe frontul crescător al semnalului de ceas clk. Semnalul reset implementează aducerea asincronă la zero a numărătorului. Intrarea count_to are width biţi. Când ieşirea numărătorului ajunge la count_to, ieşirea tercnt devine 1 pentru o perioadă de ceas. Intrarea up_dn controlează dacă numărătorul numără în sens crescător (up_dn = 1) sau în sens descrescător (up_dn = 0), începând cu următorul front activ de ceas. Numărătorul este încărcat cu valoarea data prin aplicarea valorii logice 0 pe intrarea load. Operaţia de încărcare este sincronă cu frontul pozitiv al semnalului de ceas. Intrarea de validare, cen este activă în 1. Când cen = 1, numărarea este activată. Când cen = 0, numărarea este inhibată, valoarea count rămânând neschimbată. Modelul Verilog este prezentat în continuare: T V module counter( data, count_to,

102 92 CAPITOLUL 3. MODELAREA CIRCUITELOR ELEMENTARE Port Dimensiune Direcţie Funcţie data width intrare data de încărcare count_to width intrare limita numărării up_dn 1 intrare 1 = numărare în sens crescător, 0 = numărare în sens descrescător load 1 intrare semnal de încărcare, activ în 0 cen 1 intrare validare numărare, activ în 1 clk 1 intrare semnal de ceas reset 1 intrare reset asincron, activ în 1 count width ieşire ieşirea numărătorului tercnt 1 ieşire indicator de terminare a numărării, activ în 1 Descrierea porturilor numărătorului. Tabelul 3.1 reset load cen up_dn Funcţie 0 x x x iniţializează 1 0 x x încarcă x păstrează starea numără în sens descrescător numără în sens crescător Descrierea funcţionării numărătorului. Tabelul 3.2 up_dn, load, cen, clk, reset, count, tercnt ); parameter width = 8; input[width-1 : 0] input[width-1 : 0] input input input input input output[width-1 : 0] data; count_to; up_dn; load; cen; clk; reset; count; // valoare implicita a numarului de biti

103 3.7. Numărătoare sincrone 93 output reg[width-1 : 0] tercnt; count; clk or posedge reset) if (reset) begin count <= b0; // initializare asincrona if (load) begin count <= data; // incarcare sincrona if (cen) begin if (up_dn) begin count <= count + 1; // numarare in sens crescator count <= count - 1; // numarare in sens descrescator // indicator de terminare numarare assign tercnt = (count == count_to); module Figura 3.5 prezintă o aplicaţie a numărătorului pentru width=5. Figura 3.5 Aplicaţie a numărătorului pentru width=5. Formele de undă ale numărătorului sunt prezentate în figura 3.6. Schema provenită din sinteza codului Verilog ce descrie numărătorul este prezentată în figura 3.7.

104 94 CAPITOLUL 3. MODELAREA CIRCUITELOR ELEMENTARE Figura 3.6 Formele de undă ale numărătorului. Figura 3.7 Numărător: structură sintetizată. 3.8 Automate secvenţiale sincrone Automatele secvenţiale sincrone sunt circuite esenţiale pentru descrierea părţii de control a unui sistem digital. În funcţie de necesităţi, automatele se pot proiecta de tip Mealy sau Moore. Codarea stărilor este foarte importantă pentru frecvenţa maximă de funcţionare a automatului proiectat. Pentru frecvenţe mari, se recomandă codificarea stărilor cu un bit pentru fiecare stare ( one-hot, în limba engleză). Acest stil de codificare este foarte utilizat deoarece asigură obţinerea unei frecvenţe de lucru mari chiar dacă numărul de bistabile de stare este mai mare decât cel minim. În continuare se prezintă diverse descrieri de automate şi modelele Verilog asociate. Automatele sincrone pot fi modelate în Verilog folosind specificaţia case inclusă în corpul unei specificaţii always. Informaţia de stare va fi stocată într-un registru. În cadrul fiecărei ramuri a specificaţiei case va fi descris comportamentul automatului pentru starea respectivă Semi-automat descris cu o singură specificaţie Figura 3.8 prezintă graful de tranziţii al unui semi-automat. Codul Verilog, prezintă codificarea stărilor modelată cu parametru. Acest lucru permite ulterior o modificare rapidă a codurilor stărilor, fără a fi necesară revizuirea întregului cod sursă. În cazul unor decizii mai complexe, se pot utiliza specificaţii if, operatori condiţionali?: sau chiar specificaţii case cu selecţia pe bază de intrări. Structura rezultată din sinteză este prezentată în figura 3.9. V module semiautomat(

105 3.8. Automate secvenţiale sincrone 95 Figura 3.8 Graf de tranziţii al unui semi-automat. clk_i, reset_ni, a_i, stare_o ); // intrare de ceas // intrare de reset // intrare a semi-automatului // starea semi-automatului input clk_i; input reset_ni; input a_i; output[1:0] stare_o; //definirea codurilor starilor automatului parameter s0_p = 2 b00; parameter s1_p = 2 b01; parameter s2_p = 2 b10; parameter s3_p = 2 b11; //registrul de stare reg[1:0] stare_o; //modelarea tranzitiilor

106 96 CAPITOLUL 3. MODELAREA CIRCUITELOR ELEMENTARE clk_i or negedge reset_ni) if (~reset_ni) begin stare_o <= s0_p; // stare initiala case (stare_o) s0_p: if (a_i) begin stare_o <= s0_p; stare_o <= s1_p; s1_p: stare_o <= a_i? s0_p : s2_p; s2_p: stare_o <= s3_p; s3_p: stare_o <= s0_p; default: stare_o <= s0_p; case module Modelarea ieşirilor automatelor În funcţie de cum sunt proiectate ieşirile, automatele pot fi clasificate în: Mealy: ieşirile depind de atât de starea curentă, cât şi de intrările automatului; Moore: ieşirile depind exclusiv de starea curentă a automatului. În funcţie de latenţa ieşirilor, automatele pot fi clasificate în: Automate imediate: ieşirile depind combinaţional de starea curentă; Automate cu întârziere: ieşirile depind cu o întârziere de un ceas faţă de starea curentă. Cele patru moduri de modelare a ieşirilor sunt exemplificate în continuare. wire reg wire reg reg mealyimediat1_o; mealyimediat2_o; mooreimediat_o; mealyintarziere_o; mooreintarziere_o; assign mealyimediat1_o = ((stare_o == s1_p) & a_i) ((stare_o == s3_p) & ~a_i); or a_i) case (stare_o)

107 3.8. Automate secvenţiale sincrone 97 Figura 3.9 Structura sintetizată a semi-automatului. s0_p: if (a_i) begin mealyimediat2_o <= 1 b1; mealyimediat2_o <= 1 b0; s1_p: mealyimediat2_o <= 1 b0; s2_p: mealyimediat2_o <= 1 b0; s3_p: mealyimediat2_o <= ~a_i; default: mealyimediat2_o <= 1 b0; case clk_i or negedge reset_ni) if (~reset_ni) begin mealyintarziere_o <= 1 b0;

108 98 CAPITOLUL 3. MODELAREA CIRCUITELOR ELEMENTARE mealyintarziere_o <= ((stare_o == s1_p) & a_i) ((stare_o == s3_p) & ~a_i); assign mooreimediat_o = (stare_o == s1_p) (stare_o == s2_p) (stare_o == s3_p); clk_i or negedge reset_ni) if (~reset_ni) begin mooreintarziere_o <= 1 b0; mooreintarziere_o <= (stare_o == s1_p) (stare_o == s2_p) (stare_o == s3_p); Modelarea automatelor ca registru de stare şi circuit combinaţional O alternativă de modelare a automatelor constă în modelarea structurilor elementare ce compun automatul: registru de stare şi circuite logice combinaţionale. În acest caz, există o declaraţie explicită a unui registru de stare însoţit de o specificaţie care determină schimbarea stării în momentul frontului activ al semnalului de ceas. T module semafor ( clk_i, reset_ni, senzor_i, rosu_o, galben_o, verde_o ); V input input input output output output clk_i; reset_ni; senzor_i; rosu_o; galben_o; verde_o; // codificarea starilor parameter wait_p = 2 b00;

109 3.8. Automate secvenţiale sincrone 99 parameter start_p = 2 b01; parameter run_p = 2 b10; reg[1:0] reg[1:0] reg reg reg starecurenta; stareviitoare; rosu_o; galben_o; verde_o; // registru de stare clk_i or negedge reset_ni) if (~reset_ni) starecurenta <= wait_p; else starecurenta <= stareviitoare; // circuit combinational pentru stare viitoare si iesiri or senzor_i) begin case (starecurenta) wait_p: begin rosu_o <= 1 b1; galben_o <= 1 b0; verde_o <= 1 b0; if (senzor_i) begin stareviitoare <= start_p; stareviitoare <= wait_p; start_p: begin rosu_o <= 1 b1; galben_o <= 1 b1; verde_o <= 1 b0; stareviitoare <= run_p; run_p: begin rosu_o <= 1 b0; galben_o <= 1 b0; verde_o <= 1 b1; if (senzor_i) begin stareviitoare <= run_p; stareviitoare <= wait_p; default: begin rosu_o <= 1 b1;

110 100 CAPITOLUL 3. MODELAREA CIRCUITELOR ELEMENTARE case module galben_o <= 1 b0; verde_o <= 1 b0; stareviitoare <= wait_p; Automat cu stări codificate one-hot O alternativă foarte utilizată este codificarea stărilor cu un bit pentru fiecare stare. Ca o consecinţă, modelarea se poate face la nivel de bistabil. În acest caz, structura de automat nu mai este aşa de evidentă. Modelarea one-hot a semaforului este prezentată în continuare. Se observă definirea unui bistabil (cu nume propriu) pentru fiecare stare. Starea iniţială este stabilită prin proiectarea valorilor primite de bistabilele de stare la reset. Bineînţeles, totdeauna va exista un singur bistabil cu valoare 1. Structura rezultată din sinteză este prezentată în figura Figura 3.10 Structura rezultată din sinteză pentru automatul modelat one-hot. V module semaforonehot ( clk_i, reset_ni, senzor_i, rosu_o, galben_o, verde_o ); input input input output output output clk_i; reset_ni; senzor_i; rosu_o; galben_o; verde_o;

111 3.8. Automate secvenţiale sincrone 101 // declarare bistabile de stare reg wait_st; // 1=automat in starea wait reg start_st; // 1=automat in starea start reg run_st; // 1=automat in starea run // bistabile de stare clk_i or negedge reset_ni) if (~reset_ni) wait_st <= 1 b1; else // stare initiala wait_st <= (wait_st & ~senzor_i) (run_st & ~senzor_i); clk_i or negedge reset_ni) if (~reset_ni) start_st <= 1 b0; else start_st <= (wait_st & senzor_i); clk_i or negedge reset_ni) if (~reset_ni) run_st <= 1 b0; else // stare initiala run_st <= start_st (run_st & senzor_i); // iesiri imediate assign rosu_o = wait_st start_st; assign galben_o = start_st; assign verde_o = run_st; // verificare: doar o singura stare activa la un moment dat clk_i) if ((wait_st + start_st + run_st)!= 1 b1) begin $display ("%M %t EROARE: Stare FSM eronata (wait=%b, start=%b, run=%b)", $time, wait_st, start_st, run_st); $stop; module

112

113 Capitolul 4 NOŢIUNI AVANSATE DE VERILOG 4.1 Task-uri şi funcţii Task-urile şi funcţiile permit execuţia unor proceduri în mai multe locuri ale descrierii hardware. De asemenea, ele permit partajarea unor descrieri de dimensiuni mari în proceduri mai mici, mai uşor de citit şi de depanat în codul sursă. Atât task-urile, cât şi funcţiile pot lucra cu argumente de tip intrare, ieşire sau bidirecţionale. Diferenţele între task-uri şi funcţii sunt următoarele: O funcţie se execută la un singur moment al simulării. Un task poate conţine specificaţii de control temporal. O funcţie trebuie să aibă cel puţin un parametru de intrare. Un task poate avea zero sau mai multe argumente de orice tip. O funcţie întoarce o valoare. Un task nu întoarce o valoare. O funcţie este utilizată ca un operand într-o expresie. Un task întoarce o valoare într-un argument de ieşire. Task-urile şi funcţiile pot fi folosite atât pentru modelarea modulelor sintetizabile, cât şi pentru modelarea modulelor folosite în mediul de testare. T De exemplu, se pot defini o funcţie şi un task pentru calculul valorii negate a unei mărimi întregi. Un task întoarce rezultatul într-un argument de ieşire. Apelul unui task va fi: negare(valoareinitiala, valoarenegata); Task-ul va primi parametrul de intrare valoareinitiala va determina valoarea negată şi o va atribui parametrului de ieşire valoarenegata. O funcţie care va face acelaşi lucru va întoarce direct valoarea negată. Apelul funcţiei va fi: 103

114 104 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG valoarenegata = negare(valoareinitiala); S Sintaxa definirii unui task este următoarea: <task> ::= task <nume_task>; <declaratii_task> <specificatii> task <declaratii_task> ::= <declaratii_parametrii> = <declaratii_intrari> = <declaratii_iesiri> = <declaratii_bidirectionale> = <declaratii_reg> = <declaratii_timp> = <declaratii_intregi> = <declaratii_reali> = <declaratii_evenimente> Ca exemplu, sunt prezentate task-urile ce modelează citirea şi scrierea unui set de registre printr-o interfaţă de către un procesor. Aceste task-uri nu sunt sintetizabile. Ele modelează comportamentul unui procesor care furnizează stimuli circuitului proiectat pentru sintetizabilitate. task write; // parametrii formali ai task-ului input[15:0] addr; input[15:0] data; begin // pregatire valori pentru semnalele de control mpucs_no <= 1 b0; mputs_no <= 1 b0; mpurdwr_no <= 1 b0; mpuaddr_o <= addr; mpudata_o <= mpuclk_i); mputs_no <= 1 b1; // interogare indicator de validare a scrierii while mpuclk_i); // scrierea a fost efectuata, inactivare comanda mpucs_no <= 1 b1; mpurdwr_no <= 1 b1; // mesaj pentru depanare $display("%m %t NOTA: Scriere de catre CPU (addr=%hh, data=%hh).", $time, addr, mpuclk_i);

115 4.1. Task-uri şi funcţii 105 task task read; input[15:0] addr; begin // pregatire valori pentru semnalele de control mpucs_no <= 1 b0; mputs_no <= 1 b0; mpurdwr_no <= 1 b1; mpuaddr_o <= addr; mpudata_o <= 16 mpuclk_i); mputs_no <= 1 b1; // interogare indicator de validare a citirii while mpuclk_i); // citirea a fost efectuata, inactivare comanda mpucs_no <= 1 b1; mputs_no <= 1 mpuclk_i); // mesaj pentru depanare (data citita) $display("%m %t NOTA: Citire de catre CPU (addr=%hh, data=%hh).", $time, addr, mpudata_i); $stop; task Apelarea task-urilor se face din interiorul unei specificaţii initial: initial begin // write(adresa, data); write(16 h0, 16 h0039); // read (adresa); read (16 h0); write( sdram_mode_addr, 16 h0060); // adresa definita cu define // interogheaza un indicator pana cand este gasit 0 read( rdaddr_addrl); while (mpudata_i[15]) read( rdaddr_addrl);... T Formele de undă rezultate în urma simulării modulului MPU descris cu task-uri sunt prezentate în figura 4.1. S Sintaxa definirii unei funcţii este următoarea:

116 106 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG Figura 4.1 Forme de undă rezultate în urma simulării modulului MPU descris cu task-uri. <function> ::= function <domeniu_sau_tip>? <nume_functie> ; <declaratii_functie>+ <specificatii> function <domeniu_sau_tip> ::= <domeniu> = integer = real <declaratii_functie> ::= <declaratii_parametrii> = <declaratii_intrari> = <declaratii_iesiri> = <declaratii_bidirectionale> = <declaratii_reg> = <declaratii_timp> = <declaratii_intregi> = <declaratii_reali> = <declaratii_evenimente> Precizarea domeniului (dimensiunii în biţi a valorii întoarse) este opţională. Implicit, funcţiile întorc un bit. Definirea funcţiei conţine o declaraţie implicită a unei variabile de tip reg, internă funcţiei, având numele funcţiei. Dimensiunea acestei variabile este specificată ca <domeniu> al funcţiei. În definiţia funcţiei trebuie să existe o atribuire de valoare către această variabilă. La ieşirea din funcţie, valoarea variabilei având numele funcţiei se consideră ca fiind valoarea la care s-a evaluat funcţia. Exemplul următor prezintă definirea şi utilizarea unei funcţii de calcul a valorii absolute a unui vector ce reprezintă un număr întreg cu semn. // definirea functiei modulo function [7:0] modulo; // parametrii formali ai functiei input[7:0] formalinitial; begin if (~formalinitial[7]) // MSB=0 => numar pozitiv modulo = formalinitial;

117 4.2. Modelarea memoriilor 107 else // MSB=1 => numar negativ modulo = ~formalinitial + 1; // complement fata de 2 function // declararea unei sarme wire[7:0] valoaremodulo; // apelul functiei modulo assign valoaremodulo = modulo(valoareintrare); V Structura rezultată în urma sintezei unui modul al cărui comportament este descris cu funcţia modulo este prezentată în figura 4.2. Figura 4.2 Structura rezultată în urma sintezei unui modul a cărui comportament este descris cu funcţia modulo. 4.2 Modelarea memoriilor În marea majoritate a cazurilor, sistemele digitale integrate actuale includ o memorie sau au acces la o memorie externă. Memoriile integrate pe chip se generează, de obicei, cu programe specializate sub forma unei descrieri fizice şi a uneia comportamentale. Modelul comportamental este utilizat de către proiectantul RTL pentru a simula întreg chip-ul. Modelul fizic se utilizează în etapa de realizare fizică a chip-ului. În cazul folosirii unor chip-uri externe de memorie este necesară o simulare globală a chip-ului proiectat interconectat la memorie. Din acest motiv este necesar un model comportamental al memoriei. De obicei producătorii de chip-uri de memorie oferă (gratuit sau contra cost) modelele comportamentale ale memoriilor produse. Se poate concluziona că mulţi ingineri au ocazia să scrie (sau măcar să înţeleagă şi să modifice) modele de memorie, fie ca angajat al firmelor producătoare de memorii, fie ca proiectanţi utilizatori de chip-uri de memorie sau memorii integrate. În continuare este prezentat modelul unei memorii RAM sincrone dual-port. Memoria este parametrizată ca lăţime şi ca adâncime.

118 108 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG S-au prevăzut două opţiuni de iniţializare: toată memoria înscrisă cu 0 sau memoria înscrisă cu datele existente într-un fişier extern. În acest ultim caz, datele sunt citite din fişier în variabila de memorie cu funcţia sistem $readmemh, prezentată în secţiunea 4.6. V module dpmem ( clk_i, // semnal de ceas // port de scriere wraddr_i, // adresa de scriere we_ni, // validare scriere (write enable), activ low data_i, // date de intrare // port de citire rdaddr_i, // adresa de citire re_ni, // validare citire (read enable), activ low data_o // date de iesire ); parameter width_p = 32; // latime date parameter addrbits_p= 10; // numar de biti de adresa parameter meminit_p = 1 b1; // 1=memorie initializata, // 0=memorie neinitializata parameter memzero_p = 1 b1; // 1=memorie initializata cu 0, // 0=memorie initializata cu // date din fisier // nume fisier cu date de initializare parameter filename_p = "dpmem1kx32.dat"; input // port de scriere input[addrbits_p-1:0] input input[width_p-1:0] // port de citire input[addrbits_p-1:0] input output[width_p-1:0] reg[width_p-1:0] clk_i; wraddr_i; we_ni; data_i; rdaddr_i; re_ni; data_o; data_o; // matrice de memorie ((2^addrBits_p) x width_p) reg[width_p-1:0] mem[(1<<addrbits_p)-1:0]; // initializare memorie integer i; // index pentru specificatia for initial begin if (meminit_p) begin

119 4.3. Generarea structurilor hardware 109 // matricea de memorie este initializata if (memzero_p) begin // matricea de memorie este initializata cu 0 for (i=0;i<(1<<addrbits_p);i=i+1) mem[i] = b0; // matricea de memorie este initializata cu date din fisier $readmemh(filename_p, mem); // scriere memorie clk_i) if (~we_ni) mem[wraddr_i] <= data_i; // citire memorie clk_i) data_o <= (~re_ni)? mem[rdaddr_i] : bz; module T Modele comportamentale pentru memorii SDRAM/DDR pot fi găsite pe situl firmei Micron Technology ( sau pe pagina web a cărţii. Aceste modele nu sunt sintetizabile. 4.3 Generarea structurilor hardware Versiunea 2001 a standardului Verilog introduce o facilitate de a genera instanţe multiple de module şi primitive. Modulele generate pot fi create condiţional sau particularizate prin specificaţii de decizie (if) sau de selecţie (case). Patru noi cuvinte cheie au fost adăugate limbajului Verilog cu această ocazie: generate: cuvânt cheie de început a specificaţiei; generate: cuvânt cheie de sfârşit a specificaţiei; genvar: declaraţie de index (valoare pozitivă) a specificaţiei generate; localparam: constantă locală. Pentru exemplificarea utilizării specificaţiei generate se prezintă modelul unui modul de memorie realizat din 4 chip-uri de memorie de 512Mb (32M x 16) folosit pentru stocarea datelor şi un chip de memorie de 256Mb (32M x 8) folosit pentru stocarea sumelor de control. Memoria rezultată are dimensiunea 2Gb (32M x 64). Fiecare locaţie de 64 de biţi are asociaţi 8 biţi (câte 1 bit pentru fiecare byte) pentru o sumă de control.

120 110 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG Pentru memorii se utilizează modelele firmei Micron. Modelul modulului de memorie este prezentat în continuare: V // modul SDRAM 2Gb (32Mx64) module sdrammodule ( sdrck_i, // semnal de ceas sdrcke_i, // validare ceas (clock enable) sdrdq_io, // date sdrecc_io, // date de control (Error Correction Code) sdraddr_i, // adresa sdrbank_i, // banca sdrcs_i, // selectie chip (chip select) sdrras_i, // ras sdrcas_i, // cas sdrwe_i, // validare scriere (write enable) sdrdm_i // masca de date ); inout[63:0] sdrdq_io; inout[7:0] sdrecc_io; input[12:0] sdraddr_i; input[1:0] sdrbank_i; input sdrck_i; input sdrcke_i; input sdrcs_i; input sdrras_i; input sdrcas_i; input sdrwe_i; input[8:0] sdrdm_i; genvar i; generate // variabila folosita ca index de specificatia generate // 4 instante SDRAM 512Mb (32M x 16) pentru memoria de date for (i=0;i<4;i=i+1) begin: Usdram // activeaza mesajele doar de la un chip de memorie defparam UsdramDate.Debug = (i==0? 1 : 0); mt48lc32m16a2 UsdramDate(.Dq (sdrdq_io[16*i+15:16*i] ),.Addr (sdraddr_i ),.Ba (sdrbank_i ),.Clk (sdrck_i ),.Cke (sdrcke_i ),.Cs_n (sdrcs_i ),.Ras_n (sdrras_i ),.Cas_n (sdrcas_i ),

121 4.3. Generarea structurilor hardware 111.We_n (sdrwe_i ),.Dqm (sdrdm_i[2*i+1:2*i] ) ); // o instanta SDRAM 256Mb (32M x 8) // pentru memoria de sume de control defparam UsdramEcc.Debug = 0; mt48lc32m8a2 UsdramEcc(.Dq (sdrecc_io ),.Addr (sdraddr_i ),.Ba (sdrbank_i ),.Clk (sdrck_i ),.Cke (sdrcke_i ),.Cs_n (sdrcs_i ),.Ras_n (sdrras_i ),.Cas_n (sdrcas_i ),.We_n (sdrwe_i ),.Dqm (sdrdm_i[8] ) ); generate module Reprezentarea grafică a ierarhiei modulului sdrammodule este prezentată în figura 4.3. Figura 4.3 Reprezentarea grafică a ierarhiei modulului de memorie SDRAM. Specificaţia generate poate genera şi structuri sintetizabile, aşa cum este cazul exemplului unui sumator de 32 de biţi format din 4 sumatoare de câte 8 biţi. Structura rezultată din sinteză este prezentată în figura 4.4. V module addgen (

122 112 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG Figura 4.4 Structura rezultată din sinteză sumatorului de 32 de biţi descris cu specificaţie de generare. a_i, // primul operand b_i, // al doilea operand ci_i, // transport de intrare s_o, // rezultatul co_o // transport de iesire ); input[31:0] input[31:0] input output[31:0] output a_i; b_i; ci_i; s_o; co_o; // declara bitii de transport wire[4:0] carry; // bitul zero reprezinta transportul de intrare la LSB (=0) assign carry[0] = 1 b0; // bitul MSB este transportul final al sumatorului assign co_o = carry[4]; genvar i; // variabila folosita ca index de specificatia generate generate // 4 instante addxc for (i=0;i<4;i=i+1) begin: Uadder defparam Uadd.width = 8; addxc Uadd(.a_i (a_i[8*i+7:8*i] ),.b_i (b_i[8*i+7:8*i] ),.ci_i (carry[i] ),.s_o (s_o[8*i+7:8*i] ),.co_o (carry[i+1] ) ); generate

123 4.4. Modelarea la nivel de poartă logică 113 module 4.4 Modelarea la nivel de poartă logică Verilog este un limbaj ce conţine descrierea următoarelor modele ce corespund porţilor logice: Porţi cu intrări multiple (and, nand, or, nor, xor, xnor); Porţi cu ieşiri multiple (buf, not); Porţi cu ieşiri în trei stări (bufif0, bufif1, notif0, notif1); Porţi cu ieşiri fixe (pullup, pulldown) Porţi cu intrări multiple Porţile cu intrări multiple modelează porţi logice având o singură ieşire şi un număr neprecizat de intrări. Funcţia logică implementată corespunde cuvintelor rezervate: and, nand, or, nor, xor, xnor. S Sintaxa instanţierii porţilor cu intrări multiple este următoarea: <tip_poarta> [nume_instanta] (iesire, intrare1, intrare2,...); Primul terminal este ieşirea, restul terminalelor, oricâte la număr, sunt asociate intrărilor. Tabelele de adevăr asociate acestor porţi sunt prezentate în tabelul 4.1: Porţi cu ieşiri multiple Porţile cu ieşiri multiple modelează porţi logice având o singură intrare şi un număr neprecizat de ieşiri. Funcţia logică implementată corespunde cuvintelor rezervate: buf şi not. Aceste porţi sunt folosite pentru stabilirea explicită a fan-out-ului unei porţi logice fizice. S Sintaxa instanţierii porţilor cu ieşiri multiple este următoarea: buf [nume_instanta] (intrare, iesire1, iesire2,...); not [nume_instanta] (intrare, iesire1, iesire2,...); Primul terminal este intrarea, restul terminalelor, oricâte la număr, sunt asociate ieşirilor. Tabelele de adevăr asociate acestor porţi sunt prezentate în tabelul 4.2.

124 114 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG and 0 1 x z nand 0 1 x z x x x x x 1 x x x x 0 x x x z 1 x x x z 0 x x x or 0 1 x z nor 0 1 x z x x x x x x 1 x x x x 0 x x z x 1 x x z x 0 x x xor 0 1 x z xnor 0 1 x z x x x x x x x x x x x x x x x x x x z x x x x z x x x x Tabelul 4.1 Tabelul de adevăr ale porţilor logice cu intrări multiple. buf 0 1 x z not 0 1 x z ieşire 0 1 x x ieşire 1 0 x x Tabelul 4.2 Tabelul de adevăr ale porţilor logice cu ieşiri multiple Porţi cu ieşiri în trei stări Porţile cu ieşiri în trei stări modelează porţi logice având o intrare de validare care determină trecerea ieşirii în stare de înaltă impedanţă. Funcţia logică implementată corespunde cuvintelor rezervate: bufif0, bufif1, notif0, notif1. S Sintaxa instanţierii porţilor cu ieşiri în trei stări este următoarea: <tip_poarta> [nume_instanta] (iesire, intrare, control); Tabelele de adevăr asociate acestor porţi sunt prezentate în tabelul 4.3. Valorile alternative 0/z şi 1/z semnifică cele două valori ale ieşirii, în funcţie de tăria semnalelor de date şi de control Porţi cu ieşiri fixe Porţile cu ieşiri fixe modelează porţi logice fără intrare, având o singură ieşire. Pot fi interpretate ca generatoare de 0 sau de 1 logic. Conectarea unei asemenea porţi la o sârmă determină menţinerea stării logice a acelei sârme, în absenţa altei surse

125 4.5. Modelarea la nivel de tranzistor 115 bufif0 Control bufif1 Control 0 1 x z 0 1 x z 0 0 z 0/z 0/z 0 z 0 0/z 0/z Data 1 1 z 1/z 1/z Data 1 z 1 1/z 1/z x x z x x x z x x x z x z x x z z x x x notif0 Control notif1 Control 0 1 x z 0 1 x z 0 1 z 1/z 1/z 0 z 1 1/z 1/z Data 1 0 z 0/z 0/z Data 1 z 0 0/z 0/z x z z x x x z x x x z z z x x z z x x x Tabelul 4.3 Tabelul de adevăr ale porţilor cu ieşiri în trei stări. de semnal. De obicei, se folosesc asemenea porţi conectate în interiorul modulului pe intrările care pot fi lăsate neconectate la instanţierea modulului respectiv. Existenţa unei porţi cu ieşire fixă pe intrare nu va permite propagarea stării x în interiorul modulului. Există două tipuri de asemenea porţi: pullup ( trage semnalul la valoarea sursei de alimentare, echivalentă stării logice 1) şi pulldown ( trage semnalul la masă, echivalentă stării logice 0). De remarcat că aceste trageri sunt slabe. Existenţa unei alte surse de semnal, va anula efectul porţii cu ieşire fixă. S Sintaxa instanţierii porţilor cu ieşiri fixe este următoarea: pullup [nume_instanta] (iesire); pulldown [nume_instanta] (iesire); 4.5 Modelarea la nivel de tranzistor Verilog este un limbaj ce conţine descrierea următoarelor modele ce corespund tranzistoarelor MOS (unidirecţionale): nmos, pmos, cmos, rnmos, rpmos, rcmos. S Sintaxa instanţierii tranzistoarelor MOS este următoarea: pmos [nume_instanta] (iesire, intrare, control); nmos [nume_instanta] (iesire, intrare, control); cmos [nume_instanta] (iesire, intrare, controln, controlp); rpmos [nume_instanta] (iesire, intrare, control); rnmos [nume_instanta] (iesire, intrare, control); rcmos [nume_instanta] (iesire, intrare, controln, controlp); De remarcat că deşi tranzistoarele MOS reale sunt simetrice, modelele Verilog sunt unidirecţionale, având pentru date intrare şi iesire.

126 116 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG Dispozitivele ale căror nume încep cu litera r modelează dispozitive rezistive. În cazul trecerii unui semnal prin aceste dispozitive, tăria semnalului se diminuează. Tabelul 4.4 descrie funcţionarea modelelor de tranzistoare MOS. pmos Control nmos Control rpmos 0 1 x z rnmos 0 1 x z 0 0 z 0/z 0/z 0 z 0 0/z 0/z Data 1 1 z 1/z 1/z Data 1 z 1 1/z 1/z x x z x x x z x x x z z z z z z z z z z Tabelul de adevăr ale tranzistoarelor MOS. Tabelul 4.4 În plus, sunt descrise în limbaj şi următoarele porţi de transmisiune bidirecţionale: tran, tranif0, tranif1, rtran, rtranif0, rtranif1. S Sintaxa instanţierii porţilor de transmisiune MOS este următoarea: tran [nume_instanta] (porta, portb); rtran [nume_instanta] (porta, portb); tranif0 [nume_instanta] (porta, portb, control); tranif1 [nume_instanta] (porta, portb, control); rtranif0 [nume_instanta] (porta, portb, control); rtranif1 [nume_instanta] (porta, portb, control); Modelarea la nivel de tranzistor este utilizată de producătorii de tehnologii electronice sau de inginerii care simulează funcţionarea circuitului integrat pe baza structurii fizice, pentru a valida un netlist înainte de fabricaţie. Ca exemplificare, se prezintă cazul modelării a două multiplexoare 2:1 descrise la nivel de tranzistor MOS. Ca metodologie de lucru, schema s-a desenat cu un editor grafic capabil să genereze automat modelul Verilog. Schema este prezentată în figura 4.5. Fişierele generate automat sunt prezentate în continuare: T inv.v V /* Verilog model created from schematic inv.sch -- Feb 17, :21 */ module inv( IN, OUT ); input IN; output OUT; wire VDD = 1 b1;

127 4.5. Modelarea la nivel de tranzistor 117 Figura 4.5 Schema a două multiplexoare 2:1 la nivel de tranzistor. wire GND = 1 b0; nmos N ( OUT, GND, IN ); pmos P ( OUT, VDD, IN ); module // inv nand3.v /* Verilog model created from schematic nand3.sch -- Feb 17, :21 */ module nand3( IN1, IN2, IN3, OUT ); input IN1, IN2, IN3; output OUT; wire VDD = 1 b1; wire GND = 1 b0; wire N_1; wire N_2; nmos N1 ( OUT, N_1, IN1 ); nmos N2 ( N_1, N_2, IN2 ); nmos N3 ( N_2, GND, IN3 ); pmos P3 ( OUT, VDD, IN3 ); pmos P2 ( OUT, VDD, IN2 ); pmos P1 ( OUT, VDD, IN1 );

128 118 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG module // nand3 xfer.v /* Verilog model created from schematic xfer.sch -- Feb 17, :21 */ module xfer( D, GN, GP, S ); output D; input GN, GP, S; pmos P ( D, S, GP ); nmos N ( D, S, GN ); module // xfer muxtranzlev.v /* Verilog model created from schematic muxtranzlev.sch -- Feb 17, :21 */ module muxtranzlev( I0A, I0B, I1A, I1B, SEL, SEL_C, YA, YB ); input I0A, I0B, I1A, I1B; input [2:0] SEL; output SEL_C, YA, YB; wire N_116; wire N_117; wire N_115; wire N_94; wire N_95; nand3 I108 (.IN1(SEL[2]),.IN2(SEL[1]),.IN3(SEL[0]),.OUT(N_115)); xfer I118 (.D(N_95),.GN(SEL_C),.GP(N_115),.S(I1B) ); xfer I119 (.D(N_94),.GN(SEL_C),.GP(N_115),.S(I1A) ); xfer I73 (.D(N_94),.GN(N_115),.GP(SEL_C),.S(I0A) ); xfer I74 (.D(N_95),.GN(N_115),.GP(SEL_C),.S(I0B) ); inv I82 (.IN(N_116),.OUT(YB) ); inv I79 (.IN(N_117),.OUT(YA) ); inv I78 (.IN(N_95),.OUT(N_116) ); inv I77 (.IN(N_94),.OUT(N_117) ); inv I109 (.IN(N_115),.OUT(SEL_C) ); module // muxtranzlev 4.6 Task-uri şi funcţii de sistem Verilog conţine câteva task-uri şi funcţii predefinite în limbaj. Nu toate acestea sunt foarte folosite. În această secţiune sunt prezentate doar cele folosite mai des în testarea

129 4.6. Task-uri şi funcţii de sistem 119 sistemelor descrise în Verilog. Task-urile şi funcţiile sistem nu sunt sintetizabile ci oferă doar suport pentru testare. Task-uri de afişare: $display, $write, $strobe, $monitor; Task-uri de accesare a fişierelor: $fopen, $fdisplay, $readmemb, $readmemh; Task-uri pentru controlul simulării: $stop, $finish; Task-uri pentru verificări temporale: $period, $skew, $recovery; $setup, $hold, $setuphold, $width, Funcţii referitoare la timpul simulării: $time; Funcţii pentru generarea numerelor aleatorii: $random Task-uri de afişare Task-urile de sistem pentru afişare sunt utilizate pentru afişarea mesajelor în fereastra de mesaje a simulatorului. $display: afişează un mesaj formatat în momentul execuţiei specificaţiei. $strobe: task similar cu $display dar cu execuţie amânată până la sfârşitul ciclului curent de simulare. Afişează valorile actualizate ale semnalelor cu atribuiri blocante. $write: task similar cu $display dar fără a trece la linie nouă la sfârşitul mesajului. Posibil de folosit pentru compunerea secvenţială a mesajelor ce vor apărea pe un singur rând. $monitor: afişează un mesaj formatat la fiecare modificare a valorii unui semnal. Acest task este apelat o singură dată şi are efect pe tot parcursul simulării. Taskul poate fi activat şi dezactivat explicit prin apelul task-urilor $monitoroff şi $monitoron. Exemplu: clock) // afiseaza un mesaj la fiecare front de ceas $display(%m %t: a=%b b=%b, $time, a, b); initial // afiseaza un mesaj la fiecare modificare a semnalelor a sau b $monitor(%m %t: a=%b b=%bb, $time, a, b); Modul de reprezentare a mărimilor afişate de către task-urile de afişare poate fi controlat prin opţiuni: %b - valoare exprimată în baza 2 %o - valoare exprimată în baza 8

130 120 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG %d - valoare exprimată în baza 10 %h - valoare exprimată în baza 16 %e - valoare exprimată ca real în format exponenţial %f - valoare exprimată ca real în format zecimal %g - valoare exprimată ca real în formatul cel mai scurt %c - caracter ASCII %s - şir de caractere %m - numele modulului ce a generat mesajul şi a ierarhiei acestuia în cadrul proiectului %t - timpul curent de simulare \n - caracter special rând nou \t - caracter special tab \\ - caracter special \ \" - caracter special " %% - caracter special % Task-uri de accesare a fişierelor De foarte multe ori, pentru verificarea proiectelor este necesară preluarea unor date din fişiere: iniţializarea memoriilor, controlarea setului de stimuli generaţi. $fopen deschide un fişier pentru scriere. Funcţia întoarce un pointer la fişier (32 de biţi). $fmonitor, $fdisplay, $fstrobe şi $fwrite scriu mesajele în fişier similar task-urilor $monitor, $display, $strobe, $write. $fclose închide un fişier şi eliberează pointerul la fişier. $readmemb, $readmemh se folosesc pentru citirea datelor dintr-un fişier într-o variabilă de memorie de tip matrice bidimensională. Datele sunt exprimate în binar dacă citirea se face cu $readmemb sau în hexazecimal dacă citirea se face cu $readmemh. Exemplul 1: // parametrii de configurare a generatorului de stimuli parameter param1_p = 1; parameter param2_p = 2; parameter param3_p = 3;

131 4.6. Task-uri şi funcţii de sistem 121 parameter cmdfile_p = "cmdfile.mem"; // fisier de comenzi, deschis // pentru citire parameter logfile_p = "log.out"; // fisier de mesaje, descris // pentru scriere reg[23:0] cmdmem[99:0]; // memorie de stocare a comenziilor integer logptr; // pointer la fisier de mesaje initial begin logptr = $fopen(logfile_p); // deschide fisier pentru scriere $readmemb(cmdfile_p, cmdmem); // initializeaza matricea cmdmem cu // continutul fisierului cu numele // transmis prin parametrul cmdfile_p // scrie in fisierul de mesaje valorile parametrilor cu care a fost // instantiat modulul $fdisplay(logptr, "%M NOTE: parametrul 1 = %0d", param1_p); $fdisplay(logptr, "%M NOTE: parametrul 2 = %0d", param2_p); $fdisplay(logptr, "%M NOTE: parametrul 3 = %0d", param3_p); Exemplul 2: parameter initon_p = 1 b1; // 0 = memorie neinitializata, // 1 = memorie initializata parameter initfile_p = 1 b1; // 0 = initializare (date=adresa) // 1 = initializare din fisier parameter filename_p = "mem1kx32.mem"; // fisier cu date de initializare // 1024 de linii a cate 8 cifre hexa reg[31:0] mem[(1<<10)-1:0];// memorie (1K X 32) integer i; // variabila index pentru specificatia for // initializarea memoriei initial begin if (initon_p) begin // memorie initializata if(initfile_p) begin // memorie initializata din fisier $readmemh(filename_p, mem); // memorie initializata (data=adresa) for (i=0;i<1024;i=i+1) mem[i] = i;

132 122 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG Task-uri pentru controlul simulării $stop: determină susparea simulării. Ulterior se pot lansa comenzi în mod interactiv cu scop de depanare sau repornirea simulării din punctul în care a fost suspată. Apelarea acestui task se face la momentele de timp la care se doreşte oprirea temporară a simulării pentru verificarea unor semnale sau condiţii. $finish: determină terminarea simulării şi a programului de simulare, cu întoarcerea controlului sistemului de operare. Apelarea acestui task se face la rularea simulării fără interfaţă grafică, eventual cu apeluri succesive ale simulării cu parametri diferiţi Task-uri pentru verificări temporale Task-urile de sistem pentru verificări temporale pot fi apelate în cadrul unui test-bench (modul generator de vectori de test) sau în cadrul unui bloc specify din interiorul unui modul. $setup (eveniment_date, eveniment_ref, limita); Violarea timpului de setup este raportată dacă timpul scurs de la eveniment_date până la eveniment_ref este mai scurt decât limita. Exemplu: $setup (data, posedge clk, 5); $hold (eveniment_ref, eveniment_date, limita); Violarea timpului de hold este raportată dacă timpul scurs de la eveniment_ref până la eveniment_date este mai scurt decât limita. Exemplu: $hold (posedge clk, data, 2); $setuphold (eveniment_date, eveniment_ref, limita_s, limita_h); Efectul acestui task reprezintă o însumare a efectelor $setup şi $hold. Exemplu: $setuphold (data, posedge clk, 5, 2); $period (eveniment_ref, limita); Violarea perioadei este raportată dacă timpul scurs între două evenimente succesive este mai scurt decât limita. Exemplu: $period (posedge clk, 16); $width (eveniment_ref, limita); Violarea de lăţime este raportată dacă timpul scurs între un eveniment şi următorul eveniment complementar este mai scurt decât limita. Exemplu: $width (posedge clk, 8); $skew (eveniment_1, eveniment_2, limita); Violarea de skew este raportată dacă timpul scurs între eveniment_1 şi eveniment_2 este mai lung decât limita. Exemplu: $skew (posedge clk1, posedge clk2, 3);

133 4.6. Task-uri şi funcţii de sistem 123 $recovery (eveniment_ref, eveniment_date, limit); Violarea este raportată dacă timpul scurs între eveniment_ref şi eveniment_date este mai lung decât limita. Exemplu: $recovery (posedge set, data, 5); Funcţii referitoare la timpul simulării Funcţia de sistem $time întoarce valoarea timpului de simulare reprezentată ca un întreg de 64 de biţi scalată cu valoarea absolută a unităţii de timp asociată modulului în care a fost apelată funcţia. Funcţia $time poate fi apelată ca parametru din taskuri de afişare cu opţiunea %t. Forma de afişare a timpului poate fi modificată prin apelul task-ului de sistem $timeformat. Exemplu: // verificarea parametrilor transmisi la instantiere initial begin $display("%m %t EROARE: Valoare interzisa pentru parametrul 1 (%0d).", $time, param1_p); $stop; // verificarea protocolului cerere-confirmare clk) if (ack &&!rq) begin $display("%m %t EROARE: Confirmare fara cerere.", $time); $stop; Mesajele produse în fereastra de mesaje sunt: # readmemsim 0 EROARE: Valoare interzisa pentru parametrul 1 (10). # readmemsim 135 EROARE: Confirmare fara cerere Funcţii pentru generarea numerelor aleatorii Funcţia $random întoarce un număr aleatoriu întreg reprezentat pe 32 de biţi. Specificarea valorii iniţiale ( seed, în limba engleză) este opţională. Apelarea funcţiei $random având ca parametru aceeaşi valoare iniţială va întoarce aceeaşi valoare la fiecare simulare. Pentru a restrânge domeniul numerelor aleatorii se poate folosi operatorul modulo (%). Exemple: integer a; a = $random % 10; // intoarce un numar intre -9 si 9 integer b;

134 124 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG b = {$random} % 10; // intoarce un numar intre 0 si 9 // operatorul de concatenare interpreteaza // valoarea intoarsa de $random ca fiind // pozitiva, fara semn reg[7:0] c; c = $random; // doar cei 8 LSB intorsi de $random se // atribuie lui c (poate fi interpretat ca // un numar pozitiv cu valori intre 0 si 255) reg[63:0] d; d = {$random, $random}; // numar aleatoriu pe 64 de biti parameter seed = 1; initial semnal = $random(seed); // valoare de initializare a generatorului de // numere aleatorii 4.7 Primitive definite de utilizator // atribuie semnalului o valoare aleatorie, // pe baza parametrului seed Modelarea unei biblioteci de tehnologie presupune proiectarea unui model comportamental al fiecărei componente primitive. Complexitatea sistemelor actuale, cu milioane de porţi logice, determină necesitatea unei mari puteri de calcul în cazul simulării la nivel de poartă logică, după sinteză, sau în final, după plasare şi rutare. Din acest motiv, este binevenită posibilitatea de a proiecta modele mai rapide pentru componente ce au o funcţie relativ simplă şi apar instanţiate de foarte multe ori. Este cazul primitivelor din bibliotecile de tehnologie. Primitivele definite de către utilizator furnizează suportul pentru lărgirea setului de componente elementare folosite în descrierea structurală a unui proiect. Trebuie remarcat faptul că în simulare modelul unei primitive se execută mult mai rapid decât modelul RTL echivalent. Instanţierea primitivelor definite de către utilizator poate fi făcută similar cu instanţierea oricărui modul. Există două tipuri de primitive definite de către utilizator: primitive combinaţionale; primitive secvenţiale. O primitivă definită de către utilizator are o singură ieşire şi una sau mai multe intrări. Ieşirea poate primi valorile 0, 1 sau x (valoarea z nu este admisă). Primitivele definite de către utilizator sunt indepente de module şi pot e- xista exclusiv în afara acestora. Sintaxa definirii unei primitive este prezentată în continuare. Cuvintele cheie ce includ o declaraţie de primitivă sunt primitive şi primitive. S <UDP> ::=primitive<nume>(<nume_terminal_iesire>,

135 4.7. Primitive definite de utilizator 125 <nume_terminal_intrare> <,<nume_terminal_intrare>>*); <declaratie_udp>+ <specificatie_udp_initial>? <tabela_definitie> primitive V T Ca exemple, sunt prezentate un multiplexor şi un bistabil D modelate cu primitive definite de către utilizator. // multiplexor 2:1 primitive multiplexer (mux, control, dataa, datab); output mux; input control, dataa, datab; table //control dataa datab mux : 1; : 1; 0 1 x : 1; : 0; : 0; 0 0 x : 0; : 1; : 1; 1 x 1 : 1; : 0; : 0; 1 x 0 : 0; x 0 0 : 0; x 1 1 : 1; table primitive // Bistabil activ pe front crescator si iesire negata primitive p_ff (Q, D, CP); output Q; reg Q; input D, CP; table // D CP : Qt : Qt+1 1 (01) :? : 1; // front pozitiv de ceas, D=1 0 (01) :? : 0; // front pozitiv de ceas, D=0 1 (x1) : 1 : 1; // comutarea ceasului din sau in x 0 (x1) : 0 : 0; 1 (0x) : 1 : 1; 0 (0x) : 0 : 0;? (?0) :? : -; // nici o schimbare pe front negativ

136 126 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG (??)? :? : -; // ignora fronturile intrarii D table primitive 4.8 Accesarea semnalelor în ierarhie Limbajul Verilog asociază fiecărui identificator un nume unic al ierarhiei în cadrul proiectului. Acest lucru face posibilă apelarea identificatorului şi din afara modulului în care a fost declarat acesta. Numele ierarhic este format din ataşarea tuturor modulelor din ierarhie despărţite prin caracterul punct (.). Accesarea unor identificatori din afara modulului în care au fost definiţi se utilizează la spionarea unor semnale din modulul RTL în scopul verificării unor condiţii logice, menţinând codul de verificare în afara modulului ce urmează a fi sintetizat. // module ce va fi sintetizat module rtlmodule( a,... ); input[7:0] a;... submodule U_subModule(... );... module // submodul al modulului ce va fi sintetizat module submodule(... );... reg eroare; clk) begin... eroare <= 1 b0;... eroare <= 1 b1; module // modulul de varf, fara porturi module testtop();

137 4.9. Funcţii PLI 127 rtlmodule U_rtlModule (.a (a ),... ); tbmodule U_tbModule (.a (a ),... ); // instantiere a modulului proiectat // instantiere a generatorului de semnal clk) // daca semnalul "eroare" din submodulul "U_subModule" inclus in // "U_rtlModule" este atunci se afiseaza un mesaj if (U_rtlModule.U_subModule.eroare) begin $display("%m %t NOTA: eroare generata in...", $time); $stop; module 4.9 Funcţii PLI Verilog oferă posibilitatea de extindere a funcţionalităţii unui simulator prin PLI ( Programming Language Interface, în limba engleză). Prin PLI se oferă posibilitatea simulatorului de Verilog să apeleze programe externe, să realizeze schimburi de informaţii şi să sincronizeze execuţia programelor externe cu cea a simulatorului. Interfaţa PLI este specifică doar limbajului de descriere hardware Verilog. Prin folosirea aplicaţiilor PLI se rezolvă într-un mod facil o serie întreagă de probleme cum ar fi: Încapsularea unor module prin abstractizare şi descriere în limbajul C pentru a le proteja împotriva copierii structurii modulului sau pentru a îmbunătăţi viteza de simulare. Accesarea unor biblioteci de funcţii complexe puse la dispoziţie de limbajele de programare de nivel înalt (de exemplu, bibliotecile matematice ale limbajului C). Citirea unor fişiere ce conţin date de intrare pentru un anumit modul. Capabilităţile limbajului Verilog de a citi fişiere ce conţin descrieri ale unor stimuli de intrare sunt medii, iar pentru structuri mai complexe ale fişierelor şi vectorilor de intrare folosirea aplicaţiilor PLI devine necesară. Prelucrarea în mod particular a datelor de ieşire. Majoritatea simulatoarelor oferă medii grafice pentru afişarea semnalelor din proiect, dar uneori apar situaţii în care se doreşte o formatare diferită a datelor de ieşire. De exemplu, în simularea unui controller video pentru un monitor, o aplicaţie PLI poate extrage

138 128 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG datele necesare şi transmite unui program extern. Acesta poate afişa în timp real imaginea, similar unui monitor adevărat. Co-simularea unor module mixte (digital-analogice). În acest caz aplicaţiile PLI funcţionează precum un canal de legatură între diferitele tipuri de simulatoare care rulează indepent, fiecare simulând porţiunile din proiect corespunzătoare. Depanarea unor proiecte complexe uneori nu este uşor de realizat doar cu facilităţile oferite de simulatoare. De aceea, uneori, este mult mai eficient să se apeleze la aplicaţii PLI care să extragă anumite informaţii specifice procesului de depanare Crearea unei aplicaţii PLI O aplicaţie PLI este un program scris de către utilizator folosind limbajul C/C++, care este executat de către simulatorul Verilog. Aplicaţia PLI interacţionează cu simulatorul prin citirea şi modificarea valorilor semnalelor din cadrul proiectului simulat. Etapele creării unei aplicaţi PLI sunt următoarele: Definirea numelui pentru funcţia sau task-ul prin intermediul cărora se apelează aplicaţia PLI. Definirea unor rutine C/C++ care să fie rulate de către simulator la apelul sau la compilarea funcţiei/task-ului din codul Verilog. Înregistrarea funcţiei/task-ului Verilog şi a rutinelor C/C++ asociate în structurile specifice simulatorului Verilog. Prin procesul de înregistrare se face o legatură între numele funcţiei/task-ului şi rutinele ce urmează a fi executate. Compilarea surselor C/C++ ale aplicaţiei PLI pentru a obţine o bibliotecă dinamică urmând ca aceasta să fie încărcată de compilatorul Verilog la pornirea simulării. Ca exemplu de aplicaţie PLI se prezintă o funcţie Verilog care calculează logaritmul în baza 2 al argumentului de intrare. Definirea numelui pentru funcţia sau task-ul prin intermediul căreia se apelează aplicaţia PLI. Se alege un nume sugestiv, log2(n), unde argumentul n poate fi o constantă, parametru, sau net (wire sau reg). Ca limbaj de dezvoltare se alege ANSI C. Limbajul ANSI C este preferat limbajului C++ datorită portabilităţii acestuia pe diferite platforme (Windows, Linux, Solaris). Toate funcţiile care compun interfaţa PLI sunt specifice simulatorului şi sunt oferite sub forma de bibliotecă statică însoţită de un fişier header în care se specifică antetele funcţiilor din interfaţa PLI. Pentru această aplicaţie se folosesc rutinele VPI care au asociate fişierul vpi_user.h. /*************************************************************** * Fisiere incluse ***************************************************************/

139 4.9. Funcţii PLI 129 #include <stdlib.h> /* biblioteca standard ANSI C */ #include <stdio.h> /* biblioteca in/out standard ANSI C */ #include <string.h> /* biblioteca de siruri standard ANSI C */ #include <math.h> #include <time.h> #include "vpi_user.h" /* biblioteca PLI VPI IEEE 1364 */ Definirea unor rutine C/C++ care să fie rulate de către simulator la apelul sau la compilarea funcţiei/task-ului din codul Verilog. Rutina apelată de către simulator în momentul compilării - log2_compiletf. Această rutină este apelată înainte de începerea simulării. Scopul ei este de a verifica corectitudinea folosirii funcţiei/task-ului: număr de parametri, tipul parametrilor, blocul din care a fost apelată. La folosirea acestei rutine trebuie să se ţină seama de faptul că, fiind înainte de începerea simulării, structura internă a simulatorului nu este iniţializată. De aceea, orice încercare de a citi sau modifica valori ale semnalelor interne modulului va genera erori. Rutina parcurge lista argumentelor folosind un iterator (o structura specială specifică interfeţei PLI) şi verifică numărul şi tipul argumentelor. /************************************************************ * Rutina compiletf ***********************************************************/ int log2_compiletf (char *user_data) { vpihandle systf_handle, arg_itr, arg_handle; int arg_type; // citeste parametrii task-ului si verifica argumentul NULL systf_handle = vpi_handle(vpisystfcall, NULL); arg_itr = vpi_iterate(vpiargument, systf_handle); if (arg_itr == NULL) { vpi_printf("eroare: functia $log2 trebuie sa aiba \ un argument.\n"); return (0); } // verifica daca primul argument este NULL arg_handle = vpi_scan(arg_itr); if (arg_handle == NULL) { vpi_printf("eroare: functia $log2 trebuie sa aiba \ un argument.\n"); return (0); } // determina tipul argumentului arg_type = vpi_get(vpitype, arg_handle);

140 130 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG } if (arg_type!= vpiintegervar && arg_type!= vpiconstant && arg_type!= vpireg && arg_type!= vpiparameter && arg_type!= vpinet) { vpi_printf("eroare: argumentul functiei $log2 trebuie \ sa fie un intreg, un parametru, \ un semnal reg sau un semnal wire.\n"); return(0); } // verifica alte argumente arg_handle = vpi_scan(arg_itr); if (arg_handle!= NULL) { vpi_printf("eroare: functia $log2 accepta \ un singur argument.\n"); return(0); } return (0); Rutina apelată de simulator pentru a determina lungimea, în număr de biţi, a rezultatului întors de către funcţie - log2_sizetf. În cazul task-urilor, această funcţie nu este necesară. /*********************************************************** * Rutina sizetf **********************************************************/ int log2_sizetf (char *user_data) { // functia intoarce o valoare reprezentata pe 32 de biti return (32); } Rutina apelată de către simulator în momentul simulării, la apelul unei funcţii /task în codul Verilog - log2_calltf. Rutina obţine un handle (pointer tipic interfeţei PLI care identifică obiectele din baza de date internă a simulatorului) către primul argument. Citirea valorii unui obiect (acţiune posibilă doar în cazul obiectelor care permit stocarea unei valori) se poate realiza în mai multe formate. În cazul acestei funcţii este necesară obţinerea valorii ca număr întreg. După calculul logaritmului în baza 2 a datei de intrare, aplicaţia trebuie să returneze valoarea calculată. Acest lucru se realizează prin modificarea valorii obiectului corespunzător funcţiei Verilog (identificat prin handle-ul systf_handle). Citirea sau modificarea unei valori a unui obiect se realizează cu ajutorul unor structuri de date specializate şi specifice interfeţei PLI s_vpi_value. /*********************************************************** * Rutina calltf **********************************************************/ int log2_calltf (char *user_data) { vpihandle systf_handle, arg_itr, arg_handle;

141 4.9. Funcţii PLI 131 } s_vpi_value arg_val, ret_val; // formateaza iesirea ret_val.format = vpiintval; // citeste argumentul functiei utilizand un iterator systf_handle = vpi_handle(vpisystfcall, NULL); arg_itr = vpi_iterate(vpiargument,systf_handle); arg_handle = vpi_scan(arg_itr); arg_val.format = vpiintval; vpi_get_value(arg_handle, &arg_val); // calculaeza logaritmul in baza 2 al // argumentului de intrare ret_val.value.integer = (int) ceil(log(arg_val.value.integer)/log(2)); // intoarce rezultatul vpi_put_value(systf_handle, &ret_val, NULL, vpinodelay); return (0); Înregistrarea funcţiei/task-ului Verilog şi a rutinelor C/C++ asociate în structurile specifice simulatorului Verilog. Înregistrarea se realizează folosind o structură de date tipică interfeţei PLI - s_vpi_systf_data. Fiecărei noi funcţii/task adăugate aplicaţiei PLI îi va corespunde o asemenea structură ai cărei membri sunt iniţializaţi într-o funcţie separată. Aceste structuri trebuie transmise simulatorului, proces realizat cu ajutorului unui şir global de pointeri (adrese) care conţine toate funcţiile care iniţializează structurile de tipul s_vpi_systf_data. În cazul exemplului propus există o singură funcţie. /*************************************************************** * Inregistrarea functiei $log2 **************************************************************/ void log2_register() { s_vpi_systf_data tf_data; tf_data.type = vpisysfunc; // tipul PF al rutinei PLI tf_data.sysfunctype = vpisysfuncint; // tipul de data intors tf_data.tfname = "$log2"; // numele task-ului Verilog tf_data.calltf = log2_calltf; // numele functiei C // apelate la rulate tf_data.compiletf = log2_compiletf; // numele functiei C // apelate la compilare tf_data.sizetf = log2_sizetf; // dimensiunea intoarsa vpi_register_systf(&tf_data); }

142 132 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG /**************************************************************** * Structura necesara initializarii rutinelor VPI ***************************************************************/ void (*vlog_startup_routines[])() = { log2_register, 0 }; Compilarea surselor C/C++ ale aplicaţiei PLI pentru a obţine o bibliotecă dinamică urmând ca aceasta să fie încărcată de compilatorul Verilog la pornirea simulării. Compilarea fişierelor C se realizează cu orice compilator C, folosind un mediu integrat sau apeluri la linie de comandă. În faza de link-editare a fişierelor, trebuie precizată calea către biblioteca statică ce conţine funcţiile interfeţei PLI. Această bibliotecă se găseşte în distribuţia fiecărui compilator Verilog ce oferă suport PLI. În mod particular, s-a folosit simulatorul ModelSim pe o platformă Windows. Simulatorul ModelSim oferă biblioteca numită mtipli.lib. Pentru o compilare la linie de comandă pentru platforme Windows, se poate folosi următoarea secvenţă de comenzi (calea către distribuţia de ModelSim nu este absolută, ci este specifică fiecărui utilizator): cl -c -IC:\modeltech_5.7g\include log2.c link -dll -export:vlog_startup_routines log2.obj c:\modeltech_5.7g\win32\mtipli.lib /out:log2.dll Ca rezultat, se obţine o bibliotecă dinamică (log2.dll, în cazul platformei Windows) care trebuie încărcată de către simulator la încărcarea proiectului. Modalitatea de încărcare a unei aplicaţii PLI este specifică fiecărui tip de simulator. În cazul particular al simulatorului ModelSim, trebuie specificat în fişierul de iniţializare (modelsim.ini) calea către bibiotecile dinamice ce conţin aplicaţii PLI prin intermediul variabilei Veriuser: ; List of dynamically loaded objects for Verilog PLI applications Veriuser =./log2.dll Încărcarea proiectului în simulator se face asemănător cu situaţiile în care nu sunt implicate aplicaţii PLI Apelarea aplicaţiei PLI Aplicaţia PLI este apelată prin intermediul funcţiilor din codul Verilog. Un exemplu de modul Verilog în care se apelează funcţia PLI $log2 este prezentat în continuare. Se observă apelarea funcţiei cu diferite tipuri de obiecte, transmise ca argument. T

143 4.10. Noutăţi introduse de standardul IEEE Verilog module tstpli(); parameter param = 230; wire[7:0] wire_sig; reg[7:0] reg_sig; integer int = 279; wire[7:0] wire[7:0] wire[7:0] wire[7:0] rez_param; rez_wire; rez_reg; rez_int; initial begin reg_sig = 63; assign wire_sig = 15; assign rez_param = $log2(param); // log2(230) = 8 assign rez_wire = $log2(wire_sig); // log2(15) = 4 assign rez_reg = $log2(reg_sig); // log2(63) = 6 assign rez_int = $log2(int); // log2(279) = 9 module 4.10 Noutăţi introduse de standardul IEEE Verilog bloc de configurare specificaţie generate funcţii care întorc constante adresarea indexată a vectorilor matrici multidimensionale selecţia unui domeniu al matricilor aritmetică cu numere cu semn operator de ridicare la putere task-uri şi funcţii re-entrante operator ce desemnează o listă de senzitivităţi completă liste de senzitivităţi cu caracter de despărţire virgulă (,)

144 134 CAPITOLUL 4. NOŢIUNI AVANSATE DE VERILOG funcţii extinse de acces la fişiere extensie automată a lăţimii peste 32 de biţi definirea explicită a parametrilor la instanţiere combinarea declaraţiilor de porturi şi de direcţie combinarea declaraţiilor de direcţie şi de tip atribuire iniţială pentru semnale de tip reg înlocuirea termenului registru cu termenul variabilă directive de compilare condiţională îmbunătăţite directiva de compilare line atribute

145 Capitolul 5 PROBLEME REZOLVATE Acest capitol prezintă câteva probleme avansate de proiectare, care nu se rezolvă întotdeauna cu soluţia clasică. Toate problemele au fost întâlnite în practica de zi cu zi la firma easic. Din acest motiv, unele rezolvări fac apel la metodologia de proiectare a circuitelor integrate digitale în această tehnologie. Bibliotecile complete pentru simulare şi sinteză se găsesc pe situl firmei easic ( 5.1 Circuite de prelucrare a impulsurilor De foarte multe ori modulele de control transmit comenzi sub forma unor impulsuri. Într-un sistem sincron, se poate defini impulsul ca fiind un semnal cu o durată activă mult mai scurtă decât perioada inactivă. Într-un sistem sincron, lăţimea semnalului este întotdeauna un număr întreg de perioade de ceas Circuite formatoare de impulsuri Acest paragraf prezintă proiectarea unui circuit secvenţial sincron având o intrare şi o ieşire. Intrarea este generată de un sistem sincron şi este activă în starea 1 un număr oarecare Ni de perioade de ceas. Ieşirea este întotdeauna activă un număr par No de perioade de ceas, astfel: dacă Ni este par, atunci No = Ni ; dacă Ni este impar, atunci No = Ni + 1. Pentru exemplificare, figura 5.1 prezintă descrierea sistemului prin forme de undă. Se presupune că există cel puţin două perioade de ceas pauză între două pulsuri consecutive. Figura 5.1 Formele de undă pentru generatorul de impulsuri. 135

146 136 CAPITOLUL 5. PROBLEME REZOLVATE Problema poate fi rezolvată cu un automat de tip Mealy imediat, pornind de la o interpretare echivalentă a funcţionării: dacă intrarea este găsită 1, ieşirea este activată pentru două perioade de ceas succesive; intrarea este indiferentă (nu se testează) în cea de-a doua perioadă de ceas. Graful de tranziţii al unui automat Mealy imediat, a cărui funcţionare se bazează pe observaţia anterioară, este prezentat în figura /1 0/0 S0 /1 S1 Figura 5.2 Graful de tranziţie al automatului care generează un impuls de lăţime număr par de perioade de ceas. Se observă că automatul are numai două stări între care comută. acestui automat este prezentată în continuare: Descrierea reg stare; ck) begin case (stare) 1 b0: if (puls_i) begin stare <= 1 b1; stare <= 1 b0; 1 b1: begin stare <= 1 b0; default: stare <= 1 b0; case // activeaza pulsul de iesire daca stare=1 sau daca puls_i=1 assign puls_o = stare? 1 b1 : puls_i; Se remarcă faptul că automatul definit anterior nu are semnal de reset. În practică, în cazul acestui exemplu nici nu este necesar. În simulare însă, automatul trebuie adus într-o stare cunoscută. Acest lucru se poate face prin existenţa clauzei default pentru specificaţia case, fie prin iniţializarea variabilei reg stare = 1 b0;.

147 5.1. Circuite de prelucrare a impulsurilor 137 Evident, un automat cu două stări poate fi implementat cu un singur bistabil. În figura 5.3 se prezintă forma de undă a ieşirii unui bistabil comandat astfel: dacă puls_i=1 b0 atunci toggle = 1 b0 (resetare); dacă puls_i=1 b1 atunci toggle = ~toggle (complementare). Ieşirea puls_o este obţinută printr-o poartă logică SAU având ca intrări puls_i şi toggle. Funcţionarea circuitului poate fi descrisă astfel: semnalul puls_o este activat dacă semnalul puls_i este activat sau dacă semnalul toggle este activat (prin aceasta înţelegând că lăţimea semnalului puls_i a fost un număr impar de pulsuri de ceas). Figura 5.3 Formele de undă pentru generatorul de impulsuri şi bistabilul toggle. Codul Verilog care descrie sistemul este prezentat în continuare: reg assign toggle; puls_o = puls_i toggle; ck) toggle <= puls_i & ~toggle; Schema rezultată după sinteză este prezentată figura 5.4. Figura 5.4 Generatorul de impulsuri descris ca bistabil T. Schemă după sinteză. Dacă se doreşte ieşirea direct din registru, atunci codul trebuie modificat astfel: reg reg toggle; puls_o; ck) begin toggle <= puls_i & ~toggle; puls_o <= puls_i toggle;

148 138 CAPITOLUL 5. PROBLEME REZOLVATE În acest caz, schema rezultată după sinteză este similară cu cea prezentată în figura 5.5. Ieşirea va fi întârziată cu un tact faţă de cea din implementarea precedentă (figura 5.4). Figura 5.5 Generatorul de impulsuri descris ca bistabil T, cu ieşire din registru. Schemă după sinteză. Se observă că, deşi schemele rezultate (figurile 5.4 şi 5.5) prezintă structura unor automate (buclă peste un registru/bistabil), modelul Verilog nu este similar celui propus pentru descrierea automatelor în general. Pentru automate cu puţine stări, este uneori preferată scrierea modelului rezultat din transcrierea în Verilog a ecuaţiilor de tranziţie a ieşirilor Generarea unui semnal în avans sau cu întârziere Acest paragraf prezintă proiectarea unui circuit secvenţial sincron ce are la bază un bistabil RS. Se face ipoteza că semnalele R şi S nu sunt active simultan şi că există cel puţin două tacte consecutive în care nici unul nu este activ. Este necesară generarea a două semnale cu formă de undă identică cu cea a ieşirii bistabilului RS. Primul semnal trebuie să fie întârziat cu un tact iar al doilea în avans cu un tact faţă de semnalul de referinţă (ieşirea bistabilului RS). În plus, este necesară monitorizarea valorii de adevăr a ipotezei că R şi S nu sunt active simultan. Formele de undă ce descriu sistemul sunt prezentate în figura 5.6. Figura 5.6 Forme de undă ce descriu bistabilul RS. Semnalul întârziat se obţine din ieşirea bistabilului RS trecută printr-un bistabil de tip D. Semnalul în avans va trebui obţinut combinaţional. Din analiza formelor de undă prezentate în figura 5.6, reiese ecuaţia logică: iesire_avans = S (iesire_rs & ~R) Codul Verilog care modelează acest circuit este prezentat în continuare:

149 5.1. Circuite de prelucrare a impulsurilor 139 V T module rs( ck, reset_ni, r_i, s_i, rs_o, rsavans_o, rsintarziat_o ); input ck; input reset_ni; input r_i; input s_i; output rs_o; output rsavans_o; output rsintarziat_o; reg reg rs_o; rsintarziat_o; ck) if (~reset_ni) begin rs_o <= 1 b0; if (r_i) begin rs_o <= 1 b0; if (s_i) begin rs_o <= 1 b1; // iesire in avans assign rsavans_o = s_i (rs_o & ~r_i); // iesire intarziata ck) if (~reset_ni) begin rsintarziat_o <= 1 b0; rsintarziat_o <= rs_o;

150 140 CAPITOLUL 5. PROBLEME REZOLVATE module Schema rezultată prin sinteză este prezentată în figura 5.7. Figura 5.7 Schema rezultată prin sinteză (bistabil RS cu semnale întârziate şi în avans). Există două ipoteze asociate intrărilor: intrările R şi S nu sunt niciodată active simultan; există cel puţin două tacte în care nici o intrare nu este activă, între activarea uneia dintre cele două intrări. Verificarea primei ipoteze este echivalentă cu a spune că funcţia logică AND între cele două intrări nu are niciodată valoarea de adevăr 1. ck) begin if (r_i && s_i) begin $display("%m %t EROARE: R si S sunt simultan active", $time); $stop; Verificarea celei de-a doua ipoteze presupune existenţa unor informaţii despre istoria semnalelor în ultimele două perioade de ceas. Figura 5.8 prezintă formele de undă ale semnalelor utilizate la verificarea ipotezei. Ecuaţiile logice ale acestora sunt: rors = r_i s_i; rors_r1 este versiunea întârziată cu un tact a semnalului rors; rors_r2 este versiunea întârziată cu un tact a semnalului rors_r1;

151 5.1. Circuite de prelucrare a impulsurilor 141 Figura 5.8 Formele de undă ale semnalelor utilizate la verificarea ipotezei asupra intrărilor RS. rors_intarziat = rors_r1 rors_r2; eroare = rors_intarziat & rors. Codul Verilog care modelează aceste ecuaţii este: wire rors; // SAU logic intre intrari assign rors = r_i s_i; reg rors_r1; reg rors_r2; wire rors_intarziat; // intarzieri ck) begin rors_r1 <= rors; rors_r2 <= rors_r1; // semnal activ doua tacte "in umbra" semnalelor R sau S assign rors_intarziat = rors_r1 rors_r2; reg eroare; // verificare conditie eroare si emitere mesaj ck) begin if (rors_intarziat && rors) begin eroare <= 1 b1; $display("%m %t EROARE: R si S sunt activate incorect", $time); $stop; eroare <= 1 b0;

152 142 CAPITOLUL 5. PROBLEME REZOLVATE Logica echivalentă circuitului de generare a erorii este prezentată în figura 5.9. Figura 5.9 Logica echivalentă circuitului de generare a erorii. 5.2 Circuit secvenţial pentru recunoaştere de pattern Specificaţiile de proiectare ale acestui circuit sunt: Sistem sincron, cu reset sincron activ în 0; Recunoaşte pattern-ul secvenţial prin activarea ieşirii potrivire_o pentru un tact. Numără apariţiile pattern-ului şi activează ieşirea depasire_o la peste 99 de apariţii. Ieşirea depasire_o odată setată nu mai este resetată decât prin activarea intrării de reset sincron. Recunoaşterea pattern-ului se realizează şi după activarea ieşirii depasire_o. Formele de undă ce descriu funcţionarea circuitului sunt prezentate în figura Figura 5.10 Formele de undă ce descriu funcţionarea circuitului de recunoaştere de pattern. Abordarea clasică a acestui proiect presupune implementarea circuitului de recunoaştere a secvenţei printr-un automat. Organigrama sau graful de tranziţie care descriu funcţionarea acestuia vor fi depente de secvenţa care se doreşte a fi recunoscută. Cu alte cuvinte, dacă ulterior proiectării, beneficiarul schimbă secvenţa ce trebuie recunoscută, atunci tot procesul de proiectare se reia de la început. În continuare este prezentată proiectarea sistemului după metodologia clasică de implementare cu automat. Graful de tranziţie este prezentat în figura Automatul are o intrare de date şi o ieşire cu semnificaţia potrivire_o. Automatul proiectat este de tip Moore. Secvenţa de recunoscut este codată în graful de tranziţie al automatului. Numărarea potrivirilor se face cu un numărător în sens crescător care este incrementat la fiecare activare a ieşirii potrivire_o. Un comparator monitorizează

153 5.2. Circuit secvenţial pentru recunoaştere de pattern S0 reset_n S S S S2 0 0 S3 1 Figura 5.11 Graful de tranziţie al automatului pentru recunoaştere de pattern. valoarea numărătorului şi setează un bistabil în cazul în care această valoare este 100. Incrementarea ulterioară a numărătorului este inhibată prin condiţionarea acesteia de depasire_o=0. Schema bloc a întregului circuit este prezentată în figura Codul Verilog care modeleză circuitul conţine specificaţii corespunzătoare blocurilor proiectate. V T // starile automatului define S0 3 b000 define S1 3 b001 define S2 3 b010 define S3 3 b011 define S4 3 b100 define S5 3 b101 module recpatt( ck, reset_ni, datain_i, potrivire_o, depasire_o );

154 144 CAPITOLUL 5. PROBLEME REZOLVATE datain_i Automat potrivire_o CU Numarator sens crescator 7 =100 reset_ni S R depasire_o Figura 5.12 Schema bloc a circuitului de recunoaştere de pattern, implementat cu automat. input input input output output ck; reset_ni; datain_i; potrivire_o; depasire_o; reg potrivire_o; reg depasire_o; reg[6:0] numarator; reg[2:0] stare; ck) begin if (!reset_ni) begin stare <= S0; case (stare) S0: if (!datain_i) begin stare <= S0; stare <= S1; S1: if (!datain_i) begin stare <= S0;

155 5.2. Circuit secvenţial pentru recunoaştere de pattern 145 stare <= S2; S2: if (!datain_i) begin stare <= S0; stare <= S3; S3: if (!datain_i) begin stare <= S4; stare <= S3; S4: if (!datain_i) begin stare <= S5; stare <= S1; S5: if (!datain_i) begin stare <= S0; stare <= S1; default: stare <= S0; case ck) if (!reset_ni) begin potrivire_o <= 1 b0; potrivire_o <= (stare == S4) & (~datain_i); ck) if (!reset_ni) begin numarator <= 7 b0; if (potrivire_o && ~depasire_o) begin numarator <= numarator + 1;

156 146 CAPITOLUL 5. PROBLEME REZOLVATE ck) if (!reset_ni) begin depasire_o <= 1 b0; if (numarator==7 d100) begin depasire_o <= 1 b1; module O abordare alternativă a acestei probleme porneşte de la observaţia că o secvenţă de date poate fi memorată într-un lanţ de bistabile, pentru a se avea acces la o istorie a semnalului. Având la dispoziţie istoria semnalului, la fiecare moment se poate decide dacă secvenţa impusă a fost recunoscută sau nu. Schimbarea ulterioară a secvenţei nu va modifica decât existenţa unor inversoare (care codifică informaţia despre pattern). Schema bloc a circuitului care implementează acest principiu este prezentată în figura Circuitul este format dintr-un lanţ de bistabile ale căror ieşiri sunt inversate sau nu, conform patternului ce trebuie recunoscut. Ulterior aceste semnale sunt colectate într-o poartă AND pentru a genera semnalul potrivire_o. datain_i D O D O D O D O D O potrivire_o Figura 5.13 Schema bloc a circuitului de deplasare pentru implementarea recunoaşterii de pattern. Codul Verilog care modelează circuitul de deplasare este prezentat în continuare. V reg[3:0] data_r; ck) if (!reset_ni) begin data_r <= 4 b0; potrivire_o <= 1 b0; data_r <= {data_r[2:0], datain_i}; // urmatoarea linie codifica patternul prin pozitia inversoarelor potrivire_o <= &{data_r[3], data_r[2], data_r[1], ~data_r[0],

157 5.3. Verificator de protocol de comunicaţie 147 ~datain_i}; Se remarcă claritatea sporită a codului propus în varianta cu registru de deplasare faţă de varianta cu automat. 5.3 Verificator de protocol de comunicaţie Un protocol uzual de comunicare între două module ale unui sistem digital este protocolul bazat pe cerere şi confirmare. Modulul sursă trimite o cerere către modulul destinaţie prin activarea unui semnal cerere. Acest semnal este ţinut activ până când modulul destinaţie validează cererea. Cererea este validată când modulul destinaţie activează pentru o perioadă de tact semnalul confirmare. Se presupune că modulul sursă menţine cererea activă până la primirea confirmării iar modulul destinaţie emite întotdeaunda (mai devreme sau mai târziu) un puls de validare asociat fiecărei cereri recepţionate. Aceste ipoteze pot fi infirmate în cazul în care unul dintre module are o anomalie de proiectare. Acest lucru este mai neplăcut în cazul în care cele două module, sursă şi destinaţie, sunt proiectate de către proiectanţi diferiţi. Se justifică astfel existenţa unui monitor/verificator de protocol care să spioneze semnalele de cerere şi de confirmare şi să semnaleze abaterile de la protocolul impus. Câteva cazuri de abateri de la protocol sunt prezentate în figura 5.14: cerere abandonată înainte de primirea confirmării; cerere menţinută după primirea confirmării; confirmare emisă fără cerere; confirmare emisă simultan cu cererea. Figura 5.14 Protocol bazat pe cerere şi confirmare. Poziţia unui modul de monitorizare a protocolului în cadrul unui mediu de simulare este prezentată grafic în figura Se observă faptul că modulul are doar intrări, provenite de la cererea modulului sursă şi confirmarea modulului destinaţie. Modulul de verificare nu trebuie să aibă ieşiri, mesajele de eroare putând fi prezentate ca mesaje text. Ca o alternativă, se poate proiecta o ieşire cu semnificaţia eroare de protocol. Această ieşire ar putea fi folosită, într-un sistem cu microprocesor, la activarea unei întreruperi. Abordarea proiectării acestui circuit porneşte de la observaţia că toate erorile sunt depistate prin corelarea valorilor curente ale cererii şi confirmării cu valorile anterioare (din tactul precedent) ale acestora. Este nevoie ca cele două semnale să fie memorate în două bistabile. Ieşirile celor două bistabile, împreună cu valorile curente

158 148 CAPITOLUL 5. PROBLEME REZOLVATE cerere Modul sursa confirmare Modul destinatie Modul verificare protocol mesaj de eroare eroare Figura 5.15 Poziţia unui modul de monitorizare a protocolului în cadrul unui mediu de simulare. ale cererii şi confirmării vor intra într-un circuit combinaţional care va face distincţia între cazurile corecte şi cazurile eronate. Codul Verilog este prezentat în continuare iar schema obţinută prin sinteză este prezentată în figura Figura 5.16 Schema sintetizată pentru modulul de verificare a protocolului de comunicare între două module. V T module monprotocol( ck_i, reset_ni, cerere_i, confirmare_i, eroare_o );

159 5.3. Verificator de protocol de comunicaţie 149 input ck_i; input reset_ni; input cerere_i; input confirmare_i; output eroare_o; reg reg reg cerere_r; confirmare_r; eroare_o; ck_i) if (!reset_ni) begin cerere_r <= 1 b0; confirmare_r <= 1 b0; cerere_r <= cerere_i; confirmare_r <= confirmare_i; ck_i) if (!reset_ni) begin eroare_o <= 1 b0; case({cerere_i, cerere_r, confirmare_i, confirmare_r}) 4 b0000: eroare_o <= 1 b0; 4 b0001: eroare_o <= 1 b1; 4 b0010: eroare_o <= 1 b1; 4 b0011: eroare_o <= 1 b1; 4 b0100: eroare_o <= 1 b1; 4 b0101: eroare_o <= 1 b0; 4 b0110: eroare_o <= 1 b1; 4 b0111: eroare_o <= 1 b1; 4 b1000: eroare_o <= 1 b0; 4 b1001: eroare_o <= 1 b1; 4 b1010: eroare_o <= 1 b1; 4 b1011: eroare_o <= 1 b1; 4 b1100: eroare_o <= 1 b0; 4 b1101: eroare_o <= 1 b1; 4 b1110: eroare_o <= 1 b0; 4 b1111: eroare_o <= 1 b1; default: eroare_o <= 1 b1; case

160 150 CAPITOLUL 5. PROBLEME REZOLVATE ck_i) if (eroare_o) $display("%m %t eroare_o de protocol", $time); module 5.4 Generarea semnalului de transport al unui numărător sincron Se consideră proiectarea unui numărător sincron prevăzut cu o ieşire de semnalizare a depăşirii ( overflow, în limba engleză). Soluţia banală constă în conectarea tuturor ieşirilor unui numărător la o poartă SAU-NU. Descrierea Verilog a acestui caz este prezentată în continuare. V T Ck) begin counter <= counter + 1; ovf <= ~ counter; Schema rezultată după sinteză este prezentată în figura Figura 5.17 Schema sintetizată pentru numărătorul cu semnalizare a depăşirii. Un dezavantaj constă în faptul că numărul de intrări în poarta OR este egal cu numărul de biţi ai numărătorului. O soluţie indepentă de numărul de biţi ai numărătorului este prezentată în continuare. Soluţia se bazează pe observaţia că la comutarea din în este singura dată când bitul cel mai semnificativ comută din 1 în 0. Altfel spus, depăşirea este marcată de starea 0 a celui mai semnificativ bit, dacă în tactul anterior acest bit a fost 1. V reg[msb:0] counter; Ck) begin counter <= counter + 1;

161 5.5. Modelarea registrelor 151 counter_msb_r <= counter[msb]; ovf <= counter_msb_r & ~counter[msb]; Schema rezultată după sinteză (figura 5.18) prezintă un bistabil pentru întârzierea celui mai semnificativ bit urmat de o poartă AND (cu o intrare inversată). Soluţia este indepentă de numărul de biţi ai numărătorului. Figura 5.18 Schema recomandată pentru numărătorul cu semnalizare a depăşirii. 5.5 Modelarea registrelor Registrul paralel Schema bloc a unui registru de deplasare, cu încărcare şi ieşire în paralel, este prezentată în figura ld sh ck d q Figura 5.19 Schema bloc a unui registru de deplasare, cu încărcare şi ieşire în paralel. Registrul funcţionează astfel: Dacă semnalul de încărcare ld (Load) este activ, atunci datele de intrare di sunt stocate în registru. Dacă semnalul de deplasare sh (Shift) este activ, atunci cuvântul memorat de registru este deplasat spre stânga cu un bit. Tabelul 5.1 prezintă acţiunile registrului. Descrierea Verilog a unui astfel de registru este prezentată în continuare:

162 152 CAPITOLUL 5. PROBLEME REZOLVATE ld sh ck q Semnificaţie 1 X d Încărcare 0 1 q << 1 Deplasare stânga 0 0 X q Păstrare stare Tabelul 5.1 Tabelul de adevăr al registrului de deplasare paralel. V T module paralelreg ( ck, ld, sh, di, do ); input input input input[3:0] output[3:0] reg[3:0] ck; ld; sh; di; do; do; ck) begin if (ld) begin do <= di; if (sh) begin // deplasare stanga realizata prin concatenarea celor mai putini // semnificativi biti ai registrului cu un bit zero. do <= {do[2:0], 1 b0}; module Schema acestui registru, sintetizat, este prezentată în figura Registrul cu reacţie, LFSR LFSR (Linear Feed-back Shift Register) este un registru de deplasare care are o reacţie realizată cu o poartă XOR. Acest tip de construcţie poate genera o secvenţă de stări pseudoaleatorii. Numărul de stări generate de un LFSR cu lăţime de N biţi este de 2 N 1 (în cazul în care polinomul caracteristic este prim). Diferenţa între LFSR şi un

163 5.5. Modelarea registrelor 153 Figura 5.20 Registru de deplasare, cu încărcare şi ieşire în paralel, schemă după sinteză. numărător, care are 2 N stări, constă în faptul că circuitul combinaţional al LFSR este mult mai mic (deci circuitul are arie mai mică şi funcţionează mai rapid). Circuitele LFSR se utilizează când se doreşte o secvenţă de numărare aleatorie sau o secvenţă indiferentă dar de dimensiuni maxime pentru un anumit cost de hardware. La intrarea porţii XOR se introduc biţii corespunzători polinomului care caracterizează circuitul. Acest polinom este depent de lăţimea registrului. De exemplu, pentru o lăţime de 8 biţi, polinomul caracteristic este: f(x) = x 8 + x 6 + x 5 + x + 1. Schema bloc a unui LFSR de 8 biţi este prezentată în figura CK D Q D Q D Q D Q D Q D Q D Q D Q [7] [6] [5] [4] [3] [2] [1] [0] Figura 5.21 Schema bloc a unui LFSR de 8 biţi. Descrierea Verilog a unui astfel de registru este prezentată în continuare: V module lfsr8( ck_i, reset_ni, en_i, data_o ); input ck_i;

164 154 CAPITOLUL 5. PROBLEME REZOLVATE input reset_ni; input en_i; output[7:0] data_o; reg[7:0] data_o; // registru de deplasare cu MSB format din XOR pe vectori // polinom caracteristic x8+x6+x5+x+1 ck_i) begin if (~reset_ni) begin data_o <= b1; if (en_i) begin data_o <= {~^{data_o[6], data_o[5], data_o[1], data_o[0]}, data_o[7:1]}; module În continuare este prezentat un model de LFSR parametrizabil. Modelul are avantajul că permite menţinerea unui cod unic şi transmiterea dimensiunii registrului doar în momentul instanţierii acestuia. Codul are ca parametru dimensiunea registrului exprimată în număr de biţi. Pe baza dimensiunii, se determină printr-o funcţie constantă polinomul caracteristic. Ulterior, funcţia XNOR se aplică între biţii registrului mascaţi cu polinomul asociat. Modelarea are la bază ideea că poarta AND permite trecerea unei intrări dacă cealaltă este 1 sau blochează intrarea (0) dacă cealaltă intrare este 0. Funcţiile constante sunt o caracteristică introdusă de Verilog V module lfsr( ck_i, reset_ni, en_i, data_o ); parameter width = 4; input ck_i; input reset_ni; input en_i; output[width-1:0] data_o; reg[width-1:0] data_o; // functia de asociere a polinomului cu latimea LFSR function integer lfsrpoly (input integer width);

165 5.5. Modelarea registrelor 155 begin case (width) 1: lfsrpoly = 1 b1; 2: lfsrpoly = 2 b11; 3: lfsrpoly = 3 b011; 4: lfsrpoly = 4 b0011; 5: lfsrpoly = 5 b00101; 6: lfsrpoly = 6 b000001; 7: lfsrpoly = 7 b ; 8: lfsrpoly = 8 b ; 9: lfsrpoly = 9 b ; 10: lfsrpoly = 10 b ; 11: lfsrpoly = 11 b ; 12: lfsrpoly = 12 b ; 13: lfsrpoly = 13 b ; 14: lfsrpoly = 14 b ; 15: lfsrpoly = 15 b ; 16: lfsrpoly = 16 b ; 17: lfsrpoly = 17 b ; 18: lfsrpoly = 18 b ; 19: lfsrpoly = 19 b ; 20: lfsrpoly = 20 b ; 21: lfsrpoly = 21 b ; 22: lfsrpoly = 22 b ; 23: lfsrpoly = 23 b ; 24: lfsrpoly = 24 b ; 25: lfsrpoly = 25 b ; 26: lfsrpoly = 26 b ; 27: lfsrpoly = 27 b ; 28: lfsrpoly = 28 b ; 29: lfsrpoly = 29 b ; 30: lfsrpoly = 30 b ; 31: lfsrpoly = 31 b ; 32: lfsrpoly = 32 b ; 33: lfsrpoly = 33 b ; 34: lfsrpoly = 34 b ; 35: lfsrpoly = 35 b ; 36: lfsrpoly = 36 b ; 37: lfsrpoly = 37 b ; 38: lfsrpoly = 38 b ; 39: lfsrpoly = 39 b ; 40: lfsrpoly = 40 b ; 41: lfsrpoly = 41 b ; 42: lfsrpoly = 42 b ; 43: lfsrpoly = 43 b ; 44: lfsrpoly = 44 b ; 45: lfsrpoly = 45 b ;

166 156 CAPITOLUL 5. PROBLEME REZOLVATE 46: lfsrpoly = 46 b ; 47: lfsrpoly = 47 b ; 48: lfsrpoly = 48 b ; 49: lfsrpoly = 49 b ; 50: lfsrpoly = 50 b ; default : lfsrpoly = 1 b1; case function wire[width-1:0] polynom; // asociaza dimensiunii polinomul caracteristic assign polynom = lfsrpoly(width); // registru de deplasare cu MSB format din XOR pe vectori ck_i) begin if (~reset_ni) begin data_o <= b1; if (en_i) begin data_o <= {~^(data_o & polynom), data_o[width-1:1]}; module T În mediul de testare s-a instanţiat modulul lfsr cu diverşi parametrii, ca în exemplul următor: wire[2:0] wire[3:0] data3; data4; // instantiere LFSR de 3 biti lfsr #(3) lfsr3(.ck_i (ck ),.reset_ni (reset_n ),.en_i (en ),.data_o (data3 ) ); // instantiere LFSR de 4 biti lfsr #(4) lfsr4(.ck_i (ck ),.reset_ni (reset_n ),

167 5.5. Modelarea registrelor 157.en_i (en ),.data_o (data4 ) ); T În continuare sunt prezentate fişiere intermediare obţinute în cursul implementării unui LSFR în tehnologie easic. Fişierele cu bibliotecile necesare simulării se află pe situl de web al cărţii. Întregul set de biblioteci poate fi găsit pe situl firmei easic. În urma sintezei modulului lfsr cu parametrul width = 4, se obţine un netlist cu instanţieri de primitive din biblioteca specifică de tehnologie. Fişierul rezultat, prezentat în continuare, poate fi simulat cu condiţia compilării bibliotecii de tehnologie ce conţine descrierea comportamentului tuturor primitivelor. module lfsr_syn ( ck_i, reset_ni, en_i, data_o ); output [3:0] data_o; input ck_i, reset_ni, en_i; wire N13, n2, n3, n4, n6, n8, n9, n11, n12; dffe data_o_reg1 (.Q(data_o[1]),.CK(ck_i),.D(n2),.EN(N13) ); dffe data_o_reg2 (.Q(data_o[2]),.CK(ck_i),.D(n3),.EN(N13) ); dffe data_o_reg3 (.Q(data_o[3]),.CK(ck_i),.D(n4),.EN(N13) ); dffe data_o_reg0 (.Q(data_o[0]),.CK(ck_i),.D(n12),.EN(N13) ); l3i_40_x3 U8 (.Y(n8),.A(data_o[1]),.B(n9),.C(n6) ); inv U9 (.Y(n9),.A(data_o[0]) ); inv U16 (.Y(n6),.A(n11) ); l3j_45_x3 U18 (.Y(n4),.A(n8),.B(n11),.C1(data_o[0]),.C2(data_o[1]) ); l2c_dd_x3 U19 (.Y(n3),.A(data_o[3]),.B(n11) ); l2c_dd_x3 U20 (.Y(n2),.A(data_o[2]),.B(n11) ); l3i_4c_x3 U21 (.Y(n12),.A(data_o[1]),.B(reset_ni),.C(n6) ); l2c_77_x3 U22 (.Y(n11),.A(reset_ni),.B(en_i) ); l2c_77_x3 U23 (.Y(N13),.A(reset_ni),.B(n11) ); module Ulterior, netlist-ul ce conţine primitive de nivel înalt este asociat cu resursele logice existente, plasat şi în final rutat. La finalul implementării se generează un fişier netlist cu informaţii specifice resurselor folosite în tehnologia aleasă. Acest fişier poate fi simulat în acelaşi mediu de testare, cu sau fără informaţie de timp de propagare prin logică şi pe sârme. Formele de undă rezultate în urma simulării celor trei modele (RTL, post sinteză şi post map-are/plasare/rutare) sunt prezentate în figura În figura 5.23, se prezintă o imagine mărită a formelor de undă, imagine în care se observă includerea informaţiilor temporale în modelul post map-are/plasare/rutare. T // // Generated by emap Ver etools Build Fri 05/28/05

168 158 CAPITOLUL 5. PROBLEME REZOLVATE Figura 5.22 Formele de undă rezultate în urma simulării celor trei modele (RTL, post sinteză şi post map-are/plasare/rutare) ale LFSR pe 4 biţi. Figura 5.23 Imagine mărită a formelor de undă rezultate în urma simulării. Se remarcă întârzierile modelului post map-are/plasare/rutare. // technology FA250L // Current time: 25_07_ :40:49 // // // Top module // module core_lfsr ( data_o, ck_i, reset_ni, en_i ); output [3:0] data_o; input ck_i, reset_ni, en_i; wire n32, n31, n30, n29, n28, n27, n26, n25, n24, n23, n22, n21, n19, n17, n16, n15; supply1 N_VCC; assign data_o[3] = n19; assign data_o[2] = n23; assign data_o[1] = n28; assign data_o[0] = n21; assign n15 = ck_i; assign n16 = reset_ni; assign n17 = en_i;

Titlul lucrării propuse pentru participarea la concursul pe tema securității informatice

Titlul lucrării propuse pentru participarea la concursul pe tema securității informatice Titlul lucrării propuse pentru participarea la concursul pe tema securității informatice "Îmbunătăţirea proceselor şi activităţilor educaţionale în cadrul programelor de licenţă şi masterat în domeniul

More information

Structura și Organizarea Calculatoarelor. Titular: BĂRBULESCU Lucian-Florentin

Structura și Organizarea Calculatoarelor. Titular: BĂRBULESCU Lucian-Florentin Structura și Organizarea Calculatoarelor Titular: BĂRBULESCU Lucian-Florentin Chapter 3 ADUNAREA ȘI SCĂDEREA NUMERELOR BINARE CU SEMN CONȚINUT Adunarea FXP în cod direct Sumator FXP în cod direct Scăderea

More information

MS POWER POINT. s.l.dr.ing.ciprian-bogdan Chirila

MS POWER POINT. s.l.dr.ing.ciprian-bogdan Chirila MS POWER POINT s.l.dr.ing.ciprian-bogdan Chirila chirila@cs.upt.ro http://www.cs.upt.ro/~chirila Pornire PowerPoint Pentru accesarea programului PowerPoint se parcurg următorii paşi: Clic pe butonul de

More information

Textul si imaginile din acest document sunt licentiate. Codul sursa din acest document este licentiat. Attribution-NonCommercial-NoDerivs CC BY-NC-ND

Textul si imaginile din acest document sunt licentiate. Codul sursa din acest document este licentiat. Attribution-NonCommercial-NoDerivs CC BY-NC-ND Textul si imaginile din acest document sunt licentiate Attribution-NonCommercial-NoDerivs CC BY-NC-ND Codul sursa din acest document este licentiat Public-Domain Esti liber sa distribui acest document

More information

Metrici LPR interfatare cu Barix Barionet 50 -

Metrici LPR interfatare cu Barix Barionet 50 - Metrici LPR interfatare cu Barix Barionet 50 - Barionet 50 este un lan controller produs de Barix, care poate fi folosit in combinatie cu Metrici LPR, pentru a deschide bariera atunci cand un numar de

More information

Versionare - GIT ALIN ZAMFIROIU

Versionare - GIT ALIN ZAMFIROIU Versionare - GIT ALIN ZAMFIROIU Controlul versiunilor - necesitate Caracterul colaborativ al proiectelor; Backup pentru codul scris Istoricul modificarilor Terminologie și concepte VCS Version Control

More information

Semnale şi sisteme. Facultatea de Electronică şi Telecomunicaţii Departamentul de Comunicaţii (TC)

Semnale şi sisteme. Facultatea de Electronică şi Telecomunicaţii Departamentul de Comunicaţii (TC) Semnale şi sisteme Facultatea de Electronică şi Telecomunicaţii Departamentul de Comunicaţii (TC) http://shannon.etc.upt.ro/teaching/ssist/ 1 OBIECTIVELE CURSULUI Disciplina îşi propune să familiarizeze

More information

Excel Advanced. Curriculum. Școala Informală de IT. Educație Informală S.A.

Excel Advanced. Curriculum. Școala Informală de IT. Educație Informală S.A. Excel Advanced Curriculum Școala Informală de IT Tel: +4.0744.679.530 Web: www.scoalainformala.ro / www.informalschool.com E-mail: info@scoalainformala.ro Cuprins 1. Funcții Excel pentru avansați 2. Alte

More information

Calculatoare Numerice II Interfaţarea unui dispozitiv de teleghidare radio cu portul paralel (MGSH Machine Guidance SHell) -proiect-

Calculatoare Numerice II Interfaţarea unui dispozitiv de teleghidare radio cu portul paralel (MGSH Machine Guidance SHell) -proiect- Universitatea Politehnica Bucureşti Facultatea de Automaticăşi Calculatoare Calculatoare Numerice II Interfaţarea unui dispozitiv de teleghidare radio cu portul paralel (MGSH Machine Guidance SHell) -proiect-

More information

2. Setări configurare acces la o cameră web conectată într-un router ZTE H218N sau H298N

2. Setări configurare acces la o cameră web conectată într-un router ZTE H218N sau H298N Pentru a putea vizualiza imaginile unei camere web IP conectată într-un router ZTE H218N sau H298N, este necesară activarea serviciului Dinamic DNS oferit de RCS&RDS, precum și efectuarea unor setări pe

More information

Ghid identificare versiune AWP, instalare AWP şi verificare importare certificat în Store-ul de Windows

Ghid identificare versiune AWP, instalare AWP şi verificare importare certificat în Store-ul de Windows Ghid identificare versiune AWP, instalare AWP 4.5.4 şi verificare importare certificat în Store-ul de Windows Data: 28.11.14 Versiune: V1.1 Nume fişiser: Ghid identificare versiune AWP, instalare AWP 4-5-4

More information

Auditul financiar la IMM-uri: de la limitare la oportunitate

Auditul financiar la IMM-uri: de la limitare la oportunitate Auditul financiar la IMM-uri: de la limitare la oportunitate 3 noiembrie 2017 Clemente Kiss KPMG in Romania Agenda Ce este un audit la un IMM? Comparatie: audit/revizuire/compilare Diferente: audit/revizuire/compilare

More information

Reflexia şi refracţia luminii. Aplicaţii. Valerica Baban

Reflexia şi refracţia luminii. Aplicaţii. Valerica Baban Reflexia şi refracţia luminii. Aplicaţii. Sumar 1. Indicele de refracţie al unui mediu 2. Reflexia şi refracţia luminii. Legi. 3. Reflexia totală 4. Oglinda plană 5. Reflexia şi refracţia luminii în natură

More information

CERERI SELECT PE O TABELA

CERERI SELECT PE O TABELA SQL - 1 CERERI SELECT PE O TABELA 1 STUD MATR NUME AN GRUPA DATAN LOC TUTOR PUNCTAJ CODS ---- ------- -- ------ --------- ---------- ----- ------- ---- 1456 GEORGE 4 1141A 12-MAR-82 BUCURESTI 2890 11 1325

More information

Lucrarea de laborator nr. 4

Lucrarea de laborator nr. 4 Metode merice - Lucrarea de laborator 4 Lucrarea de laborator nr. 4 I. Scopul lucrării Elemente de programare în MAPLE II. III. Conţinutul lucrării 1. Atribuirea. Decizia. Structuri repetitive. 2. Proceduri

More information

Procesarea Imaginilor

Procesarea Imaginilor Procesarea Imaginilor Curs 11 Extragerea informańiei 3D prin stereoviziune Principiile Stereoviziunii Pentru observarea lumii reale avem nevoie de informańie 3D Într-o imagine avem doar două dimensiuni

More information

Reţele Neuronale Artificiale în MATLAB

Reţele Neuronale Artificiale în MATLAB Reţele Neuronale Artificiale în MATLAB Programul MATLAB dispune de o colecţie de funcţii şi interfeţe grafice, destinate lucrului cu Reţele Neuronale Artificiale, grupate sub numele de Neural Network Toolbox.

More information

Mecanismul de decontare a cererilor de plata

Mecanismul de decontare a cererilor de plata Mecanismul de decontare a cererilor de plata Autoritatea de Management pentru Programul Operaţional Sectorial Creşterea Competitivităţii Economice (POS CCE) Ministerul Fondurilor Europene - Iunie - iulie

More information

Aspecte controversate în Procedura Insolvenţei şi posibile soluţii

Aspecte controversate în Procedura Insolvenţei şi posibile soluţii www.pwc.com/ro Aspecte controversate în Procedura Insolvenţei şi posibile soluţii 1 Perioada de observaţie - Vânzarea de stocuri aduse în garanţie, în cursul normal al activității - Tratamentul leasingului

More information

Documentaţie Tehnică

Documentaţie Tehnică Documentaţie Tehnică Verificare TVA API Ultima actualizare: 27 Aprilie 2018 www.verificaretva.ro 021-310.67.91 / 92 info@verificaretva.ro Cuprins 1. Cum funcţionează?... 3 2. Fluxul de date... 3 3. Metoda

More information

Dispozitive Electronice şi Electronică Analogică Suport curs 02 Metode de analiză a circuitelor electrice. Divizoare rezistive.

Dispozitive Electronice şi Electronică Analogică Suport curs 02 Metode de analiză a circuitelor electrice. Divizoare rezistive. . egimul de curent continuu de funcţionare al sistemelor electronice În acest regim de funcţionare, valorile mărimilor electrice ale sistemului electronic sunt constante în timp. Aşadar, funcţionarea sistemului

More information

Constructii sintetizabile in verilog

Constructii sintetizabile in verilog Constructii sintetizabile in verilog Introducere Programele verilog se împart în două categorii: cod pentru simulare și cod sintetizabil. Codul scris pentru simulare (testul) nu este sintetizabil. Codul

More information

.. REGISTRE Registrele sunt circuite logice secvenţiale care primesc, stochează şi transferă informaţii sub formă binară. Un registru este format din mai multe celule bistabile de tip RS, JK sau D şi permite

More information

Propuneri pentru teme de licență

Propuneri pentru teme de licență Propuneri pentru teme de licență Departament Automatizări Eaton România Instalație de pompare cu rotire în funcție de timpul de funcționare Tablou electric cu 1 pompă pilot + 3 pompe mari, cu rotirea lor

More information

Modalitǎţi de clasificare a datelor cantitative

Modalitǎţi de clasificare a datelor cantitative Modalitǎţi de clasificare a datelor cantitative Modul de stabilire a claselor determinarea pragurilor minime şi maxime ale fiecǎrei clase - determinǎ modul în care sunt atribuite valorile fiecǎrei clase

More information

REVISTA NAŢIONALĂ DE INFORMATICĂ APLICATĂ INFO-PRACTIC

REVISTA NAŢIONALĂ DE INFORMATICĂ APLICATĂ INFO-PRACTIC REVISTA NAŢIONALĂ DE INFORMATICĂ APLICATĂ INFO-PRACTIC Anul II Nr. 7 aprilie 2013 ISSN 2285 6560 Referent ştiinţific Lector univ. dr. Claudiu Ionuţ Popîrlan Facultatea de Ştiinţe Exacte Universitatea din

More information

La fereastra de autentificare trebuie executati urmatorii pasi: 1. Introduceti urmatoarele date: Utilizator: - <numarul dvs de carnet> (ex: "9",

La fereastra de autentificare trebuie executati urmatorii pasi: 1. Introduceti urmatoarele date: Utilizator: - <numarul dvs de carnet> (ex: 9, La fereastra de autentificare trebuie executati urmatorii pasi: 1. Introduceti urmatoarele date: Utilizator: - (ex: "9", "125", 1573" - se va scrie fara ghilimele) Parola: -

More information

APLICAŢIA 7 CIRCUITE SECVENŢIALE REGISTRUL CU ÎNCĂRCARE PARALELĂ

APLICAŢIA 7 CIRCUITE SECVENŢIALE REGISTRUL CU ÎNCĂRCARE PARALELĂ APLICAŢIA 7 CIRCUITE SECVENŢIALE REGISTRUL CU ÎNCĂRCARE PARALELĂ 1. Rezumat Acest laborator își propune implementarea unui cicuit secvențial simplu: registrul pe 4 biți cu încărcare paralelă. Pentru aceasta

More information

Managementul Proiectelor Software Metode de dezvoltare

Managementul Proiectelor Software Metode de dezvoltare Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Managementul Proiectelor Software Metode de dezvoltare 2 Metode structurate (inclusiv metodele OO) O mulțime de pași și

More information

Proiectarea şi Verificarea cu HDL a Circuitelor Digitale

Proiectarea şi Verificarea cu HDL a Circuitelor Digitale Proiectarea şi Verificarea cu HDL a Circuitelor Digitale Danuţ Burdia Facultatea de Electronică, Telecomunicaţii şi Tehnologia Informaţiei Universitatea Tehnică Gh. Asachi din Iaşi 1 Cuprins I. Introducere.

More information

INFORMAȚII DESPRE PRODUS. FLEXIMARK Stainless steel FCC. Informații Included in FLEXIMARK sample bag (article no. M )

INFORMAȚII DESPRE PRODUS. FLEXIMARK Stainless steel FCC. Informații Included in FLEXIMARK sample bag (article no. M ) FLEXIMARK FCC din oțel inoxidabil este un sistem de marcare personalizată în relief pentru cabluri și componente, pentru medii dure, fiind rezistent la acizi și la coroziune. Informații Included in FLEXIMARK

More information

INSTRUMENTE DE MARKETING ÎN PRACTICĂ:

INSTRUMENTE DE MARKETING ÎN PRACTICĂ: INSTRUMENTE DE MARKETING ÎN PRACTICĂ: Marketing prin Google CUM VĂ AJUTĂ ACEST CURS? Este un curs util tuturor celor implicați în coordonarea sau dezvoltarea de campanii de marketingși comunicare online.

More information

Mods euro truck simulator 2 harta romaniei by elyxir. Mods euro truck simulator 2 harta romaniei by elyxir.zip

Mods euro truck simulator 2 harta romaniei by elyxir. Mods euro truck simulator 2 harta romaniei by elyxir.zip Mods euro truck simulator 2 harta romaniei by elyxir Mods euro truck simulator 2 harta romaniei by elyxir.zip 26/07/2015 Download mods euro truck simulator 2 harta Harta Romaniei pentru Euro Truck Simulator

More information

GHID DE TERMENI MEDIA

GHID DE TERMENI MEDIA GHID DE TERMENI MEDIA Definitii si explicatii 1. Target Group si Universe Target Group - grupul demografic care a fost identificat ca fiind grupul cheie de consumatori ai unui brand. Toate activitatile

More information

3.2 Arhitectura setului de instrucţiuni ISA. Copyright Paul GASNER

3.2 Arhitectura setului de instrucţiuni ISA. Copyright Paul GASNER 3.2 Arhitectura setului de instrucţiuni ISA Copyright Paul GASNER Programarea CPU Programele scrise în limbaje de nivel înalt trebuie compilate pentru a obţine un program executabil Din punctul de vedere

More information

Subiecte Clasa a VI-a

Subiecte Clasa a VI-a (40 de intrebari) Puteti folosi spatiile goale ca ciorna. Nu este de ajuns sa alegeti raspunsul corect pe brosura de subiecte, ele trebuie completate pe foaia de raspuns in dreptul numarului intrebarii

More information

MODELUL UNUI COMUTATOR STATIC DE SURSE DE ENERGIE ELECTRICĂ FĂRĂ ÎNTRERUPEREA ALIMENTĂRII SARCINII

MODELUL UNUI COMUTATOR STATIC DE SURSE DE ENERGIE ELECTRICĂ FĂRĂ ÎNTRERUPEREA ALIMENTĂRII SARCINII MODELUL UNUI COMUTATOR STATIC DE SURSE DE ENERGIE ELECTRICĂ FĂRĂ ÎNTRERUPEREA ALIMENTĂRII SARCINII Adrian Mugur SIMIONESCU MODEL OF A STATIC SWITCH FOR ELECTRICAL SOURCES WITHOUT INTERRUPTIONS IN LOAD

More information

ARBORI AVL. (denumiti dupa Adelson-Velskii si Landis, 1962)

ARBORI AVL. (denumiti dupa Adelson-Velskii si Landis, 1962) ARBORI AVL (denumiti dupa Adelson-Velskii si Landis, 1962) Georgy Maximovich Adelson-Velsky (Russian: Гео ргий Макси мович Адельсо н- Ве льский; name is sometimes transliterated as Georgii Adelson-Velskii)

More information

Lucrare de laborator nr. 6 Modelarea structurală ordonată şi modelarea comportamentală în VHDL

Lucrare de laborator nr. 6 Modelarea structurală ordonată şi modelarea comportamentală în VHDL Lucrare de laborator nr. 6 Modelarea structurală ordonată şi modelarea comportamentală în VHDL 1. Scopul lucrării Însuşirea principiilor pentru descrierea circuitelor cu structură ordonată de componente

More information

DECLARAȚIE DE PERFORMANȚĂ Nr. 101 conform Regulamentului produselor pentru construcții UE 305/2011/UE

DECLARAȚIE DE PERFORMANȚĂ Nr. 101 conform Regulamentului produselor pentru construcții UE 305/2011/UE S.C. SWING TRADE S.R.L. Sediu social: Sovata, str. Principala, nr. 72, judetul Mures C.U.I. RO 9866443 Nr.Reg.Com.: J 26/690/1997 Capital social: 460,200 lei DECLARAȚIE DE PERFORMANȚĂ Nr. 101 conform Regulamentului

More information

Limbajul VHDL. Circuite integrate numerice. Limbajul VHDL

Limbajul VHDL. Circuite integrate numerice. Limbajul VHDL Limbajul VHDL VHDL este unul dintre limbajele standard folosite în industrie la ora actuală, pentru a descrie sistemele numerice. VHDL înseamnă VHSIC (Very High Speed Integrated Circuits) Hardware Description

More information

PROIECTAREA CU CIRCUITE LOGICE PROGRAMABILE

PROIECTAREA CU CIRCUITE LOGICE PROGRAMABILE Arhitectura calculatoarelor - Lucrarea de laborator Nr. 6 1 PROIECTAREA CU CIRCUITE LOGICE PROGRAMABILE 1. Scopul lucrării Lucrarea prezintă principalele tipuri de circuite programabile, etapele din cadrul

More information

COMUNICAȚII INFORMATIZARE

COMUNICAȚII INFORMATIZARE COMUNICAȚII INFORMATIZARE 120 Migrare servicii telefonie la Vodafone S-a asigurat suportul tehnic și s-a colaborat cu echipele Vodafone la portarea numerelor UPT și migrarea infrastructuri: 1200 linii

More information

DESCRIEREA ÎN VHDL A CIRCUITELOR SECVENȚIALE. DEFINIREA CONSTRÂNGERILOR DE TIMP

DESCRIEREA ÎN VHDL A CIRCUITELOR SECVENȚIALE. DEFINIREA CONSTRÂNGERILOR DE TIMP Circuite Logice Programabile LABORATOR 4 DESCRIEREA ÎN VHDL A CIRCUITELOR SECVENȚIALE. DEFINIREA CONSTRÂNGERILOR DE TIMP SCOPUL LUCRĂRII Logica secvențială este termenul generic folosit pentru proiectele

More information

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Proiect nr. 154/323 cod SMIS 4428 cofinanțat de prin Fondul European de Dezvoltare Regională Investiții pentru viitorul

More information

Ierarhia memoriilor Tipuri de memorii Memorii semiconductoare Memoria cu unități multiple. Memoria cache Memoria virtuală

Ierarhia memoriilor Tipuri de memorii Memorii semiconductoare Memoria cu unități multiple. Memoria cache Memoria virtuală Ierarhia memoriilor Tipuri de memorii Memorii semiconductoare Memoria cu unități multiple Memoria cache Memoria virtuală 1 Memorii RAM: datele sunt identificate cu ajutorul unor adrese unice Memorii asociative:

More information

CAIETUL DE SARCINI Organizare evenimente. VS/2014/0442 Euro network supporting innovation for green jobs GREENET

CAIETUL DE SARCINI Organizare evenimente. VS/2014/0442 Euro network supporting innovation for green jobs GREENET CAIETUL DE SARCINI Organizare evenimente VS/2014/0442 Euro network supporting innovation for green jobs GREENET Str. Dem. I. Dobrescu, nr. 2-4, Sector 1, CAIET DE SARCINI Obiectul licitaţiei: Kick off,

More information

Laborator 1. Programare declarativă. Programare logică. Prolog. SWI-Prolog

Laborator 1. Programare declarativă. Programare logică. Prolog. SWI-Prolog Laborator 1 Programare declarativă O paradigmă de programare în care controlul fluxului de execuție este lăsat la latitudinea implementării limbajului, spre deosebire de programarea imperativă în care

More information

R O M Â N I A CURTEA CONSTITUŢIONALĂ

R O M Â N I A CURTEA CONSTITUŢIONALĂ R O M Â N I A CURTEA CONSTITUŢIONALĂ Palatul Parlamentului Calea 13 Septembrie nr. 2, Intrarea B1, Sectorul 5, 050725 Bucureşti, România Telefon: (+40-21) 312 34 84; 335 62 09 Fax: (+40-21) 312 43 59;

More information

INTERPRETOARE DE COMENZI

INTERPRETOARE DE COMENZI Rularea lui determin afişarea mesajului hello world la consola 3.2. Facilităţi ale interpretoarelor de comenzi 3.1. Introducere Capitolul 3 INTERPRETOARE DE COMENZI Interpretorul de comenzi este un program

More information

Managementul referinţelor cu

Managementul referinţelor cu TUTORIALE DE CULTURA INFORMAŢIEI Citarea surselor de informare cu instrumente software Managementul referinţelor cu Bibliotecar Lenuţa Ursachi PE SCURT Este gratuit Poţi adăuga fişiere PDF Poţi organiza,

More information

Class D Power Amplifiers

Class D Power Amplifiers Class D Power Amplifiers A Class D amplifier is a switching amplifier based on pulse-width modulation (PWM) techniques Purpose: high efficiency, 80% - 95%. The reduction of the power dissipated by the

More information

Nume şi Apelativ prenume Adresa Număr telefon Tip cont Dobânda Monetar iniţial final

Nume şi Apelativ prenume Adresa Număr telefon  Tip cont Dobânda Monetar iniţial final Enunt si descriere aplicatie. Se presupune ca o organizatie (firma, banca, etc.) trebuie sa trimita scrisori prin posta unui numar (n=500, 900,...) foarte mare de clienti pe care sa -i informeze cu diverse

More information

Circuite Logice Programabile LABORATOR 1

Circuite Logice Programabile LABORATOR 1 Circuite Logice Programabile LABORATOR 1 INTRODUCERE ÎN MEDIUL INTEGRAT XILINX ISE. PROIECTAREA UNUI SUMATOR PE UN BIT INTRODUCERE Softwarele CAD (Computer Aided Design) de proiectare cu circuite logice

More information

Metode de descriere a sistemelor numerice

Metode de descriere a sistemelor numerice UNIVERSITATEA TEHNICĂ din CLUJ-NAPOCA FACULTATEA de AUTOMATICĂ şi CALCULATOARE CATEDRA de CALCULATOARE Metode de descriere a sistemelor numerice Referat de doctorat Conducător ştiinţific, Prof. Dr. Ing.

More information

ISBN-13:

ISBN-13: Regresii liniare 2.Liniarizarea expresiilor neliniare (Steven C. Chapra, Applied Numerical Methods with MATLAB for Engineers and Scientists, 3rd ed, ISBN-13:978-0-07-340110-2 ) Există cazuri în care aproximarea

More information

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Proiect nr. 154/323 cod SMIS 4428 cofinanțat de prin Fondul European de Dezvoltare Regională Investiții pentru viitorul

More information

Proceduri stocate. Crearea procedurilor stocate. Varianta 1 În Management Studio se dă clic pe New Query ca în imaginea de mai jos: Fig.

Proceduri stocate. Crearea procedurilor stocate. Varianta 1 În Management Studio se dă clic pe New Query ca în imaginea de mai jos: Fig. Proceduri stocate Crearea procedurilor stocate. Varianta 1 În Management Studio se dă clic pe New Query ca în imaginea de mai jos: Fig. 1 Odată cu deschiderea editorului SQL, apare și bara de instrumente

More information

METODE DE EVALUARE A IMPACTULUI ASUPRA MEDIULUI ŞI IMPLEMENTAREA SISTEMULUI DE MANAGEMENT DE MEDIU

METODE DE EVALUARE A IMPACTULUI ASUPRA MEDIULUI ŞI IMPLEMENTAREA SISTEMULUI DE MANAGEMENT DE MEDIU UNIVERSITATEA POLITEHNICA BUCUREŞTI FACULTATEA ENERGETICA Catedra de Producerea şi Utilizarea Energiei Master: DEZVOLTAREA DURABILĂ A SISTEMELOR DE ENERGIE Titular curs: Prof. dr. ing Tiberiu APOSTOL Fond

More information

9. Memoria. Procesorul are o memorie cu o arhitectură pe două niveluri pentru memoria de program și de date.

9. Memoria. Procesorul are o memorie cu o arhitectură pe două niveluri pentru memoria de program și de date. 9. Memoria Procesorul are o memorie cu o arhitectură pe două niveluri pentru memoria de program și de date. Primul nivel conține memorie de program cache (L1P) și memorie de date cache (L1D). Al doilea

More information

Olimpiad«Estonia, 2003

Olimpiad«Estonia, 2003 Problema s«pt«m nii 128 a) Dintr-o tabl«p«trat«(2n + 1) (2n + 1) se ndep«rteaz«p«tr«telul din centru. Pentru ce valori ale lui n se poate pava suprafata r«mas«cu dale L precum cele din figura de mai jos?

More information

Proiectarea Sistemelor Software Complexe

Proiectarea Sistemelor Software Complexe Proiectarea Sistemelor Software Complexe Curs 3 Principii de Proiectare Orientată pe Obiecte Principiile de proiectare orientată pe obiecte au fost formulate pentru a servi ca reguli pentru evitarea proiectării

More information

Update firmware aparat foto

Update firmware aparat foto Update firmware aparat foto Mulţumim că aţi ales un produs Nikon. Acest ghid descrie cum să efectuaţi acest update de firmware. Dacă nu aveţi încredere că puteţi realiza acest update cu succes, acesta

More information

Normalizarea tăriei sonore şi nivelul maxim permis al semnalelor audio

Normalizarea tăriei sonore şi nivelul maxim permis al semnalelor audio EBU Recomandarea R 128 Normalizarea tăriei sonore şi nivelul maxim permis al semnalelor audio Status: Recomandare EBU This informal translation of EBU R 128 into Romanian has been kindly provided by Mr

More information

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic Proiect nr. 154/323 cod SMIS 4428 cofinanțat de prin Fondul European de Dezvoltare Regională Investiții pentru viitorul

More information

MANAGEMENTUL CALITĂȚII - MC. Proiect 5 Procedura documentată pentru procesul ales

MANAGEMENTUL CALITĂȚII - MC. Proiect 5 Procedura documentată pentru procesul ales MANAGEMENTUL CALITĂȚII - MC Proiect 5 Procedura documentată pentru procesul ales CUPRINS Procedura documentată Generalități Exemple de proceduri documentate Alegerea procesului pentru realizarea procedurii

More information

SIMULAREA DESCRIERILOR VHDL

SIMULAREA DESCRIERILOR VHDL 1 SIMULAREA DESCRIERILOR VHDL În prima parte a acestei lucrări de laborator se prezintă principiul simulatoarelor și al simulării asistate de calculator pentru sistemele digitale. În continuare, sunt descrise

More information

Lucrarea Nr.1. Sisteme de operare. Generalitati

Lucrarea Nr.1. Sisteme de operare. Generalitati Lucrarea Nr.1 Sisteme de operare. Generalitati Scopul lucrarii Lucrarea îsi propune familiarizarea studentilor cu sistemele de operare disponibile în laborator, respectiv acele sisteme de operare cu ajutorul

More information

Grafuri bipartite. Lecție de probă, informatică clasa a XI-a. Mihai Bărbulescu Facultatea de Automatică și Calculatoare, UPB

Grafuri bipartite. Lecție de probă, informatică clasa a XI-a. Mihai Bărbulescu Facultatea de Automatică și Calculatoare, UPB Grafuri bipartite Lecție de probă, informatică clasa a XI-a Mihai Bărbulescu b12mihai@gmail.com Facultatea de Automatică și Calculatoare, UPB Colegiul Național de Informatică Tudor Vianu București 27 februarie

More information

Mai bine. Pentru c putem.

Mai bine. Pentru c putem. 1 CUPRINS: 1. SUMAR APLICAŢIE...... 3 1.1 Introducere... 3 1.2 Tipul de aplicaţie... 3 2. SPECIFICAŢII FUNCŢIONALE... 3 3. INSTALARE... 3 3.1 Introducere... 3 3.2 Ce trebuie să verificaţi înainte de a

More information

Candlesticks. 14 Martie Lector : Alexandru Preda, CFTe

Candlesticks. 14 Martie Lector : Alexandru Preda, CFTe Candlesticks 14 Martie 2013 Lector : Alexandru Preda, CFTe Istorie Munehisa Homma - (1724-1803) Ojima Rice Market in Osaka 1710 devine si piata futures Parintele candlesticks Samurai In 1755 a scris The

More information

ANTICOLLISION ALGORITHM FOR V2V AUTONOMUOS AGRICULTURAL MACHINES ALGORITM ANTICOLIZIUNE PENTRU MASINI AGRICOLE AUTONOME TIP V2V (VEHICLE-TO-VEHICLE)

ANTICOLLISION ALGORITHM FOR V2V AUTONOMUOS AGRICULTURAL MACHINES ALGORITM ANTICOLIZIUNE PENTRU MASINI AGRICOLE AUTONOME TIP V2V (VEHICLE-TO-VEHICLE) ANTICOLLISION ALGORITHM FOR VV AUTONOMUOS AGRICULTURAL MACHINES ALGORITM ANTICOLIZIUNE PENTRU MASINI AGRICOLE AUTONOME TIP VV (VEHICLE-TO-VEHICLE) 457 Florin MARIAŞIU*, T. EAC* *The Technical University

More information

Evoluția pieței de capital din România. 09 iunie 2018

Evoluția pieței de capital din România. 09 iunie 2018 Evoluția pieței de capital din România 09 iunie 2018 Realizări recente Realizări recente IPO-uri realizate în 2017 și 2018 IPO în valoare de EUR 312.2 mn IPO pe Piața Principală, derulat în perioada 24

More information

Software Process and Life Cycle

Software Process and Life Cycle Software Process and Life Cycle Drd.ing. Flori Naghiu Murphy s Law: Left to themselves, things tend to go from bad to worse. Principiile de dezvoltare software Principiul Calitatii : asigurarea gasirii

More information

manivelă blocare a oglinzii ajustare înclinare

manivelă blocare a oglinzii ajustare înclinare Twister MAXVIEW Twister impresionează prin designul său aerodinamic și înălțime de construcție redusă. Oglinda mai mare a îmbunătăți gama considerabil. MaxView Twister este o antenă de satelit mecanică,

More information

VIRTUAL INSTRUMENTATION IN THE DRIVE SUBSYSTEM MONITORING OF A MOBIL ROBOT WITH GESTURE COMMANDS

VIRTUAL INSTRUMENTATION IN THE DRIVE SUBSYSTEM MONITORING OF A MOBIL ROBOT WITH GESTURE COMMANDS BULETINUL INSTITUTULUI POLITEHNIC DIN IAŞI Publicat de Universitatea Tehnică Gheorghe Asachi din Iaşi Tomul LIV (LVIII), Fasc. 3-4, 2008 Secţia AUTOMATICĂ şi CALCULATOARE VIRTUAL INSTRUMENTATION IN THE

More information

LIDER ÎN AMBALAJE EXPERT ÎN SISTEMUL BRAILLE

LIDER ÎN AMBALAJE EXPERT ÎN SISTEMUL BRAILLE LIDER ÎN AMBALAJE EXPERT ÎN SISTEMUL BRAILLE BOBST EXPERTFOLD 80 ACCUBRAILLE GT Utilajul ACCUBRAILLE GT Bobst Expertfold 80 Aplicarea codului Braille pe cutii a devenit mai rapidă, ușoară și mai eficientă

More information

LINEAR CURRENT-TO-FREQUENCY CONVERTER WITH WIDE OUTPUT RANGE

LINEAR CURRENT-TO-FREQUENCY CONVERTER WITH WIDE OUTPUT RANGE BULETINUL INSTITUTULUI POLITEHNIC DIN IAŞI Publicat de Universitatea Tehnică Gheorghe Asachi din Iaşi Volumul 62 (66), Numărul 1, 2016 Secţia ELECTROTEHNICĂ. ENERGETICĂ. ELECTRONICĂ LINEAR CURRENT-TO-FREQUENCY

More information

Laborator 07. Procesorul MIPS versiune pe 16 biți, cu un ciclu de ceas pe instrucțiune

Laborator 07. Procesorul MIPS versiune pe 16 biți, cu un ciclu de ceas pe instrucțiune Laborator 07 Procesorul MIPS versiune pe 16 biți, cu un ciclu de ceas pe instrucțiune Unitatea de Instruction Execute EX / Unitatea de Memorie MEM / Unitatea Write-Back WB 0. Resurse minimale necesare!

More information

3. CLOUD COMPUTING Sisteme de calcul distribuite

3. CLOUD COMPUTING Sisteme de calcul distribuite 3. CLOUD COMPUTING Cloud Computing (CC) calcul în nori, în traducere mot a mot, sau, mai corect, calcul în Internet este un concept aflat în directă legătură cu transformările către se produc în domeniu

More information

2. SCHEME LOGICE ŞI PSEUDOCOD

2. SCHEME LOGICE ŞI PSEUDOCOD REPREZENTRE LGORITMILOR PRIN PSEUDOCOD 2. SCHEME LOGICE ŞI PSEUDOCOD 2.1 Reprezentarea algoritmilor prin scheme logice Primitivele utilizate în schemele logice sunt simboluri grafice, cu funcţiuni (reprezentând

More information

Proiectarea bazelor de date # 11. PL/SQL Funcții în PL/SQL (partea a II-a) Adrian Runceanu

Proiectarea bazelor de date # 11. PL/SQL Funcții în PL/SQL (partea a II-a) Adrian Runceanu Proiectarea bazelor de date # 11 PL/SQL Funcții în PL/SQL (partea a II-a) 2018 Adrian Runceanu www.runceanu.ro/adrian Curs 11 Funcţii în PL/SQL (partea II) Proiectarea bazelor de date 2 Cuprins Funcţii

More information

Metoda BACKTRACKING. prof. Jiduc Gabriel

Metoda BACKTRACKING. prof. Jiduc Gabriel Metoda BACKTRACKING prof. Jiduc Gabriel Un algoritm backtracking este un algoritm de căutare sistematică și exhausivă a tuturor soluțiilor posibile, dintre care se poate alege apoi soluția optimă. Problemele

More information

Figura x.1 Ecranul de pornire al mediului de dezvoltare

Figura x.1 Ecranul de pornire al mediului de dezvoltare x. Mediul de dezvoltare MICROSOFT VISUAL C++ În cadrul acestui capitol vom prezenta Microsoft Visual C++, din cadrul suitei Microsoft Visual Studio 2012, care este un mediu de programare care suportă dezvoltarea

More information

Studiul numărătoarelor

Studiul numărătoarelor Studiul numărătoarelor În acest laborator se va studia funcţionarea unui numărător programabil alcătuit din decodificatorul 74LS138 şi numărătorul hexazecimal SN74193 (CDB4193). Numărătoare: generalităţi

More information

CERERI SELECT PE MAI MULTE TABELE

CERERI SELECT PE MAI MULTE TABELE SQL - 2 CERERI SELECT PE MAI MULTE TABELE 1 STUD MATR NUME AN GRUPA DATAN LOC TUTOR PUNCTAJ CODS ---- ------- -- ------ --------- ---------- ----- ------- ---- 1456 GEORGE 4 1141A 12-MAR-82 BUCURESTI 2890

More information

Universitatea George Bariţiu, Braşov

Universitatea George Bariţiu, Braşov LUCRUL CU BAZE DE DATE ÎN JAVA Lect.univ.dr.ing. IOAN-GHEORGHE RAŢIU Lect.univ. NICOLETA DAVID Universitatea George Bariţiu, Braşov Rezumat O bază de date reprezintă o modalitate de stocare a unor informaţii

More information

PROIECT. La Baze de date. Evidența activității pentru o firmă IT. Îndrumător: ș. l. dr. ing. Mirela Danubianu. Efectuat de: Grigoriev Sergiu gr.

PROIECT. La Baze de date. Evidența activității pentru o firmă IT. Îndrumător: ș. l. dr. ing. Mirela Danubianu. Efectuat de: Grigoriev Sergiu gr. PROIECT La Baze de date Evidența activității pentru o firmă IT Îndrumător: ș. l. dr. ing. Mirela Danubianu Efectuat de: Grigoriev Sergiu gr. 1131B Suceava 2011 Cuprins 1. DESCRIERE 3 2. MODELAREA CONCEPTUALĂ

More information

1. INTRODUCERE ÎN MODELARE ŞI SIMULARE

1. INTRODUCERE ÎN MODELARE ŞI SIMULARE 1. INTRODUCERE ÎN MODELARE ŞI SIMULARE 1.1. INTRODUCERE Majoritatea sistemelor din cele mai diverse ramuri ale ştiinţei (fizică, chimie, inginerie, economie, sociologie, etc.) prezintă un grad mare de

More information

Generatorul cu flux axial cu stator interior nemagnetic-model de laborator.

Generatorul cu flux axial cu stator interior nemagnetic-model de laborator. Generatorul cu flux axial cu stator interior nemagnetic-model de laborator. Pentru identificarea performanţelor la funţionarea în sarcină la diferite trepte de turaţii ale generatorului cu flux axial fară

More information

Contact Center, un serviciu cri/c!

Contact Center, un serviciu cri/c! Contact Center, un serviciu cri/c! CASE STUDY: Apa Nova Cisco Unified Contact Center Enterprise Agenda Prezentării Ø Perspec/va de business Ø Despre noi Ø Cerinţe de business Ø Opţiunea Apa Nova Ø Beneficii

More information

Buletinul AGIR nr. 3/2012 iunie-august. Assis. Eng. Ciprian AFANASOV PhD. University "Ştefan cel Mare" Suceava

Buletinul AGIR nr. 3/2012 iunie-august. Assis. Eng. Ciprian AFANASOV PhD. University Ştefan cel Mare Suceava STEP-DOWN VOLTAGE CONVERTER FOR STUDENTS STUDY STEP-DOWN VOLTAGE CONVERTER FOR STUDENTS STUDY Assis. Eng. Ciprian AFANASOV PhD University "Ştefan cel Mare" Suceava REZUMAT. În cadrul lucrării s-au s studiat

More information

A NOVEL ACTIVE INDUCTOR WITH VOLTAGE CONTROLLED QUALITY FACTOR AND SELF-RESONANT FREQUENCY

A NOVEL ACTIVE INDUCTOR WITH VOLTAGE CONTROLLED QUALITY FACTOR AND SELF-RESONANT FREQUENCY BULETINUL INSTITUTULUI POLITEHNIC DIN IAŞI Publicat de Universitatea Tehnică Gheorghe Asachi din Iaşi Tomul LX (LXIV), Fasc. 4, 2014 Secţia ELECTROTEHNICĂ. ENERGETICĂ. ELECTRONICĂ A NOVEL ACTIVE INDUCTOR

More information

Baze de date distribuite și mobile

Baze de date distribuite și mobile Universitatea Constantin Brâncuşi din Târgu-Jiu Facultatea de Inginerie Departamentul de Automatică, Energie şi Mediu Baze de date distribuite și mobile Lect.dr. Adrian Runceanu Curs 3 Model fizic şi model

More information

X-Fit S Manual de utilizare

X-Fit S Manual de utilizare X-Fit S Manual de utilizare Compatibilitate Acest produs este compatibil doar cu dispozitivele ce au următoarele specificații: ios: Versiune 7.0 sau mai nouă, Bluetooth 4.0 Android: Versiune 4.3 sau mai

More information

Ghid pentru configurarea şi utilizarea aplicaţiei clicksign Demo

Ghid pentru configurarea şi utilizarea aplicaţiei clicksign Demo Ghid pentru configurarea şi utilizarea aplicaţiei clicksign Demo 2.6.9.223 Cuprins 1 Cadru general...2 2 Obţinerea unui certificat digital...3 3 Configurarea aplicaţiei clicksign...5 4 Utilizarea aplicaţiei

More information

METODE FIZICE DE MĂSURĂ ŞI CONTROL NEDISTRUCTIV. Inspecţia vizuală este, de departe, cea mai utilizată MCN, fiind de obicei primul pas într-o

METODE FIZICE DE MĂSURĂ ŞI CONTROL NEDISTRUCTIV. Inspecţia vizuală este, de departe, cea mai utilizată MCN, fiind de obicei primul pas într-o Cuprins: 1. Introducere 2. Inspecţia vizuală 6. Testarea ultrasonică 7. Radiografia 3. Metoda lichidului penetrant 4. Inspecţia cu particule magnetice 5. Testarea folosind curenţii Eddy 1 Inspecţia vizuală

More information

Updating the Nomographical Diagrams for Dimensioning the Concrete Slabs

Updating the Nomographical Diagrams for Dimensioning the Concrete Slabs Acta Technica Napocensis: Civil Engineering & Architecture Vol. 57, No. 1 (2014) Journal homepage: http://constructii.utcluj.ro/actacivileng Updating the Nomographical Diagrams for Dimensioning the Concrete

More information

NOTE PRIVIND MODELAREA MATEMETICĂ ÎN REGIM CVASI-DINAMIC A UNEI CLASE DE MICROTURBINE HIDRAULICE

NOTE PRIVIND MODELAREA MATEMETICĂ ÎN REGIM CVASI-DINAMIC A UNEI CLASE DE MICROTURBINE HIDRAULICE NOTE PRIVIND MODELAREA MATEMETICĂ ÎN REGIM CVASI-DINAMIC A UNEI CLASE DE MICROTURBINE HIDRAULICE Eugen DOBÂNDĂ NOTES ON THE MATHEMATICAL MODELING IN QUASI-DYNAMIC REGIME OF A CLASSES OF MICROHYDROTURBINE

More information

Eficiența energetică în industria românească

Eficiența energetică în industria românească Eficiența energetică în industria românească Creșterea EFICIENȚEI ENERGETICE în procesul de ardere prin utilizarea de aparate de analiză a gazelor de ardere București, 22.09.2015 Karsten Lempa Key Account

More information