Progettazione VLSI - Guida rapida

L'integrazione su larga scala (VLSI) è il processo di creazione di un file integrated circuit (IC) combinando migliaia di file transistorsin un unico chip. VLSI è iniziato negli anni '70 quando era complessosemiconductor e communicationle tecnologie venivano sviluppate. Ilmicroprocessor è un dispositivo VLSI.

Prima dell'introduzione della tecnologia VLSI, la maggior parte dei circuiti integrati disponeva di una serie limitata di funzioni che potevano svolgere. Unelectronic circuit potrebbe consistere in un file CPU, ROM, RAM e altro glue logic. VLSI consente ai progettisti di circuiti integrati di aggiungere tutti questi elementi in un unico chip.

L'industria elettronica ha registrato una crescita fenomenale negli ultimi decenni, principalmente grazie ai rapidi progressi nelle tecnologie di integrazione su larga scala e nelle applicazioni di progettazione di sistemi. Con l'avvento dei progetti VLSI (Very Large Scale Integration), il numero di applicazioni di circuiti integrati (CI) nel calcolo ad alte prestazioni, nei controlli, nelle telecomunicazioni, nell'elaborazione di immagini e video e nell'elettronica di consumo è aumentato a un ritmo molto rapido.

Le attuali tecnologie all'avanguardia come le comunicazioni cellulari e video ad alta risoluzione e bassa velocità in bit forniscono agli utenti finali una quantità meravigliosa di applicazioni, potenza di elaborazione e portabilità. Questa tendenza dovrebbe crescere rapidamente, con implicazioni molto importanti sulla progettazione VLSI e sulla progettazione dei sistemi.

Flusso di progettazione VLSI

Il flusso di progettazione dei circuiti IC VLSI è mostrato nella figura seguente. I vari livelli di progettazione sono numerati ei blocchi mostrano i processi nel flusso di progettazione.

Le specifiche vengono prima di tutto, descrivono in modo astratto la funzionalità, l'interfaccia e l'architettura del circuito IC digitale da progettare.

La descrizione comportamentale viene quindi creata per analizzare il progetto in termini di funzionalità, prestazioni, conformità a determinati standard e altre specifiche.

La descrizione RTL viene eseguita utilizzando HDL. Questa descrizione RTL viene simulata per testare la funzionalità. Da qui in poi abbiamo bisogno dell'aiuto degli strumenti EDA.

La descrizione RTL viene quindi convertita in una netlist a livello di gate utilizzando strumenti di sintesi logica. Una netlist a livello di gat è una descrizione del circuito in termini di porte e connessioni tra di loro, che sono realizzate in modo tale da soddisfare le specifiche di temporizzazione, potenza e area.

Infine, viene realizzato un layout fisico, che verrà verificato e quindi inviato alla fabbricazione.

Grafico Y

Il grafico a Y di Gajski-Kuhn è un modello che cattura le considerazioni nella progettazione di dispositivi a semiconduttore.

I tre domini della carta Y di Gajski-Kuhn sono su assi radiali. Ciascuno dei domini può essere suddiviso in livelli di astrazione, utilizzando anelli concentrici.

Al livello più alto (anello esterno), consideriamo l'architettura del chip; ai livelli inferiori (anelli interni), perfezioniamo successivamente il design in un'implementazione più dettagliata -

La creazione di una descrizione strutturale da una comportamentale si ottiene attraverso processi di sintesi di alto livello o sintesi logica.

La creazione di una descrizione fisica da una strutturale si ottiene attraverso la sintesi del layout.

Gerarchia di progettazione-strutturale

La gerarchia di progettazione implica il principio di "Divide and Conquer". Non è altro che dividere l'attività in compiti più piccoli fino a quando non raggiunge il suo livello più semplice. Questo processo è il più adatto perché l'ultima evoluzione del design è diventata così semplice che la sua produzione diventa più facile.

Possiamo progettare il compito dato nel dominio del processo del flusso di progettazione (comportamentale, strutturale e geometrico). Per capirlo, facciamo un esempio di progettazione di un sommatore a 16 bit, come mostrato nella figura seguente.

Qui, l'intero chip del sommatore a 16 bit è diviso in quattro moduli di sommatori a 4 bit. Inoltre, dividendo il sommatore a 4 bit in sommatore a 1 bit o mezzo sommatore. L'aggiunta di 1 bit è il processo di progettazione più semplice e il suo circuito interno è anche facile da fabbricare sul chip. Ora, collegando tutti gli ultimi quattro sommatori, possiamo progettare un sommatore a 4 bit e andando avanti, possiamo progettare un sommatore a 16 bit.

FPGA - Introduzione

La forma completa di FPGA è "Field Programmable Gate Array". Contiene da diecimila a più di un milione di porte logiche con interconnessione programmabile. Sono disponibili interconnessioni programmabili per utenti o progettisti per eseguire facilmente determinate funzioni. Un tipico chip FPGA modello è mostrato nella figura data. Sono presenti blocchi I / O, progettati e numerati in base alla funzione. Per ogni modulo di composizione a livello logico, ci sonoCLB’s (Configurable Logic Blocks).

CLB esegue l'operazione logica assegnata al modulo. L'interconnessione tra CLB e blocchi I / O viene effettuata con l'ausilio di canali di routing orizzontale, canali di routing verticale e PSM (Multiplexer programmabili).

Il numero di CLB che contiene decide solo la complessità dell'FPGA. Le funzionalità di CLB e PSM sono progettate da VHDL o da qualsiasi altro linguaggio descrittivo dell'hardware. Dopo la programmazione, CLB e PSM vengono posizionati su chip e collegati tra loro con canali di routing.

Vantaggi

  • Richiede pochissimo tempo; partendo dal processo di progettazione al chip funzionale.
  • Non sono coinvolte fasi di produzione fisica.
  • L'unico svantaggio è che è costoso rispetto ad altri stili.

Progettazione di array di porte

Il gate array (GA)è al secondo posto dopo l'FPGA, in termini di capacità di prototipazione rapida. Sebbene la programmazione dell'utente sia importante per l'implementazione del progetto del chip FPGA, la progettazione e l'elaborazione della maschera metallica viene utilizzata per GA. L'implementazione del gate array richiede un processo di produzione in due fasi.

La prima fase si traduce in una serie di transistor non impegnati su ciascun chip GA. Questi chip non impegnati possono essere memorizzati per una successiva personalizzazione, che viene completata definendo le interconnessioni metalliche tra i transistor della matrice. La modellazione delle interconnessioni metalliche viene eseguita alla fine del processo di fabbricazione del chip, in modo che il tempo di consegna possa essere ancora breve, da pochi giorni a poche settimane. La figura riportata di seguito mostra le fasi di elaborazione di base per l'implementazione del gate array.

Le tipiche piattaforme di array di porte utilizzano aree dedicate chiamate canali, per il routing inter-cella tra righe o colonne di transistor MOS. Semplificano le interconnessioni. I modelli di interconnessione che eseguono porte logiche di base sono memorizzati in una libreria, che può quindi essere utilizzata per personalizzare le righe di transistor non impegnati in base alla netlist.

Nella maggior parte dei GA moderni, vengono utilizzati più strati di metallo per il routing dei canali. Con l'uso di più strati interconnessi, l'instradamento può essere ottenuto sulle aree di celle attive; in modo che i canali di instradamento possano essere rimossi come nei chip Sea-of-Gates (SOG). Qui, l'intera superficie del chip è coperta da transistor nMOS e pMOS non impegnati. I transistor vicini possono essere personalizzati utilizzando una maschera metallica per formare porte logiche di base.

Per l'instradamento tra le celle, alcuni dei transistor non impegnati devono essere sacrificati. Questo stile di progettazione si traduce in una maggiore flessibilità per le interconnessioni e di solito in una densità maggiore. Il fattore di utilizzo del chip GA viene misurato dall'area del chip utilizzata divisa per l'area totale del chip. È superiore a quella dell'FPGA, così come la velocità del chip.

Design basato su celle standard

Un design basato su celle standard richiede lo sviluppo di un set completo di maschere personalizzate. La cella standard è anche nota come polycell. In questo approccio, tutte le celle logiche di uso comune vengono sviluppate, caratterizzate e memorizzate in una libreria di celle standard.

Una libreria può contenere alcune centinaia di celle, inclusi inverter, porte NAND, porte NOR, AOI complessi, porte OAI, D-latch e Flip-flop. Ogni tipo di cancello può essere implementato in diverse versioni per fornire capacità di pilotaggio adeguate per diversi fan-out. Il gate dell'inverter può avere dimensioni standard, doppie e quadruple in modo che il progettista del chip possa selezionare la dimensione corretta per ottenere velocità del circuito e densità di layout elevate.

Ogni cella è caratterizzata in base a diverse categorie di caratterizzazione, come,

  • Tempo di ritardo rispetto alla capacità di carico
  • Modello di simulazione del circuito
  • Modello di simulazione temporale
  • Modello di simulazione dei guasti
  • Dati della cella per luogo e percorso
  • Dati maschera

Per il posizionamento automatico delle celle e il routing, ogni layout di cella è progettato con un'altezza fissa, in modo che un numero di celle possa essere delimitato fianco a fianco per formare righe. I binari di alimentazione e di terra corrono paralleli ai limiti superiore e inferiore della cella. In questo modo, le celle adiacenti condividono un bus di alimentazione comune e un bus di terra comune. La figura mostrata di seguito è una planimetria per la progettazione basata su celle standard.

Design completamente personalizzato

In un design completamente personalizzato, l'intero design della maschera viene rinnovato, senza l'uso di alcuna libreria. Il costo di sviluppo di questo stile di design è in aumento. Pertanto, il concetto di riutilizzo del design sta diventando famoso per ridurre i tempi del ciclo di progettazione e i costi di sviluppo.

Il design completamente personalizzato più difficile può essere il design di una cella di memoria, statica o dinamica. Per la progettazione di chip logici, è possibile ottenere una buona negoziazione utilizzando una combinazione di diversi stili di progettazione sullo stesso chip, ovvero celle standard, celle di percorso dati eprogrammable logic arrays (PLAs).

In pratica, il progettista esegue il layout completamente personalizzato, ovvero la geometria, l'orientamento e il posizionamento di ogni transistor. La produttività del progetto è generalmente molto bassa; tipicamente poche decine di transistor al giorno, per progettista. Nel CMOS digitale VLSI, il design completamente personalizzato viene utilizzato raramente a causa dell'elevato costo della manodopera. Questi stili di progettazione includono la progettazione di prodotti ad alto volume come chip di memoria, microprocessori ad alte prestazioni e FPGA.

La tecnologia Complementary MOSFET (CMOS) è ampiamente utilizzata oggi per formare circuiti in numerose e varie applicazioni. I computer, le CPU e i telefoni cellulari odierni utilizzano CMOS a causa di numerosi vantaggi chiave. CMOS offre una bassa dissipazione di potenza, velocità relativamente elevata, margini di rumore elevati in entrambi gli stati e funzionerà su un'ampia gamma di tensioni di ingresso e di sorgente (a condizione che la tensione di sorgente sia fissa)

Per i processi di cui parleremo, il tipo di transistor disponibile è il MOSFET (Metal-Oxide-Semiconductor Field Effect Transistor). Questi transistor sono formatias a ‘sandwich’costituito da uno strato semiconduttore, solitamente una fetta, o wafer, da un singolo cristallo di silicio; uno strato di biossido di silicio (l'ossido) e uno strato di metallo.

Struttura di un MOSFET

Come mostrato nella figura, la struttura MOS contiene tre strati:

  • The Metal Gate Electrode

  • The Insulating Oxide Layer (SiO2)

  • P – type Semiconductor (Substrate)

La struttura MOS forma un condensatore, con gate e substrato come due piastre e strato di ossido come materiale dielettrico. Lo spessore del materiale dielettrico (SiO 2 ) è solitamente compreso tra 10 nm e 50 nm. La concentrazione e la distribuzione della portante all'interno del substrato possono essere manipolate dalla tensione esterna applicata al gate e al terminale del substrato. Ora, per comprendere la struttura del MOS, consideriamo prima le proprietà elettriche di base del substrato semiconduttore di tipo P.

La concentrazione del vettore nel materiale semiconduttore segue sempre il Mass Action Law. La legge sull'azione di massa è data da:

$$n.p=n_{i}^{2}$$

Dove,

  • n è la concentrazione portante degli elettroni

  • p è la concentrazione portante dei buchi

  • ni è la concentrazione portante intrinseca del silicio

Supponiamo ora che il substrato sia equamente drogato con accettori (boro) concentrazione N A . Quindi, la concentrazione di elettroni e lacune nel substrato di tipo p è

$$n_{po}=\frac{n_{i}^{2}}{N_{A}}$$

$$p_{po}=N_{A}$$

Qui, concentrazione del doping NAè (da 10 15 a 10 16 cm −3 ) maggiore della concentrazione intrinseca ni. Ora, per comprendere la struttura MOS, si consideri il diagramma del livello di energia del substrato di silicio di tipo p.

Come mostrato nella figura, il gap di banda tra la banda di conduzione e la banda di valance è di 1,1 eV. Qui, il potenziale di Fermi Φ F è la differenza tra il livello di Fermi intrinseco (E i ) e il livello di Fermi (E FP ).

Dove il livello di Fermi E F dipende dalla concentrazione di drogaggio. Il potenziale di Fermi Φ F è la differenza tra il livello di Fermi intrinseco (E i ) e il livello di Fermi (E FP ).

Matematicamente,

$$\Phi_{Fp}=\frac{E_{F}-E_{i}}{q}$$

La differenza di potenziale tra banda di conduzione e spazio libero è chiamata affinità elettronica ed è indicata da qx.

Quindi, l'energia richiesta a un elettrone per spostarsi dal livello di Fermi allo spazio libero è chiamata funzione di lavoro (qΦ S ) ed è data da

$$q\Phi _{s}=(E_{c}-E_{F})+qx$$

La figura seguente mostra il diagramma delle bande di energia dei componenti che compongono il MOS.

Come mostrato nella figura sopra, lo strato isolante di SiO 2 ha un ampio intervallo di banda di energia di 8eV e la funzione di lavoro è 0,95 eV. Il cancello di metallo ha una funzione di lavoro di 4.1eV. Qui, le funzioni di lavoro sono diverse, quindi creerà una caduta di tensione attraverso il sistema MOS. La figura riportata di seguito mostra il diagramma delle bande di energia combinate del sistema MOS.

Come mostrato in questa figura, il livello di potenziale fermi del gate metallico e del semiconduttore (Si) sono allo stesso potenziale. Il potenziale di Fermi in superficie è chiamato potenziale di superficie Φ S ed è più piccolo del potenziale di Fermi Φ F in grandezza.

Funzionamento di un MOSFET

MOSFET è costituito da un condensatore MOS con due giunzioni pn poste chiuse alla regione del canale e questa regione è controllata dalla tensione di gate. Per rendere entrambe le giunzioni pn polarizzate inversamente, il potenziale del substrato viene mantenuto inferiore rispetto al potenziale degli altri tre terminali.

Se la tensione di gate verrà aumentata oltre la tensione di soglia (V GS > V TO ), verrà stabilito uno strato di inversione sulla superficie e verrà formato un canale di tipo n tra source e drain. Questo canale di tipo n trasporterà la corrente di drenaggio in base al valore V DS .

Per valori diversi di V DS , MOSFET può essere utilizzato in diverse regioni come spiegato di seguito.

Regione lineare

A V DS = 0, l'equilibrio termico esiste nella regione del canale invertito e la corrente di drain I D = 0. Ora se viene applicata una piccola tensione di drain, V DS > 0, una corrente di drain proporzionale a V DS inizierà a fluire dalla sorgente a drenare attraverso il canale.

Il canale fornisce un percorso continuo per il flusso di corrente dalla sorgente allo scarico. Questa modalità di funzionamento è chiamatalinear region. La vista in sezione trasversale di un MOSFET a canale n, operante in regione lineare, è mostrata nella figura sotto riportata.

Ai margini della regione di saturazione

Ora, se il V DS viene aumentato, le cariche nel canale e la profondità del canale diminuiscono alla fine del drenaggio. Per V DS = V DSAT , gli addebiti nel canale vengono ridotti a zero, che viene chiamatopinch – off point. La vista in sezione trasversale del MOSFET a canale n che opera al bordo della regione di saturazione è mostrata nella figura riportata di seguito.

Regione di saturazione

Per V DS > V DSAT , una superficie esaurita si forma vicino al drenaggio e aumentando la tensione di drenaggio questa regione esaurita si estende fino alla sorgente.

Questa modalità di funzionamento è chiamata Saturation region. Gli elettroni provenienti dalla sorgente all'estremità del canale, entrano nella regione di svuotamento e esaurimento e vengono accelerati verso il drenaggio in campo elettrico elevato.

MOSFET Corrente - Caratteristiche di tensione

Per comprendere la caratteristica corrente - tensione del MOSFET, viene eseguita un'approssimazione per il canale. Senza questa approssimazione, l'analisi tridimensionale del sistema MOS diventa complessa. IlGradual Channel Approximation (GCA) per la caratteristica corrente - tensione ridurrà il problema dell'analisi.

Approssimazione graduale del canale (GCA)

Si consideri la vista in sezione trasversale del MOSFET a canale n che opera in modalità lineare. Qui, sorgente e substrato sono collegati a terra. V S = V B = 0. Il cancello - di - sorgente (V GS ) e drain - di - tensione della sorgente (V DS ) tensione sono i parametri esterni che controllano l'assorbimento di corrente I D .

La tensione, V GS è impostata ad una tensione maggiore della tensione di soglia V TO , per creare un canale tra la sorgente e il pozzo. Come mostrato nella figura, la direzione x è perpendicolare alla superficie e la direzione y è parallela alla superficie.

Qui, y = 0 all'estremità della sorgente come mostrato nella figura. La tensione del canale, rispetto alla sorgente, è rappresentata daVC(Y). Supponiamo che la tensione di soglia VTO sia costante lungo la regione del canale, tra y = 0 e y = L. Le condizioni al contorno per la tensione del canale V C sono -

$$V_{c}\left ( y = 0 \right ) = V_{s} = 0 \,and\,V_{c}\left ( y = L \right ) = V_{DS}$$

Possiamo anche supporlo

$$V_{GS}\geq V_{TO}$$ e

$$V_{GD} = V_{GS}-V_{DS}\geq V_{TO}$$

Sia Q1 (y) la carica totale dell'elettrone mobile nello strato di inversione superficiale. Questa carica elettronica può essere espressa come -

$$Q1(y)=-C_{ox}.[V_{GS}-V_{C(Y)}-V_{TO}]$$

La figura sotto riportata mostra la geometria spaziale dello strato di inversione superficiale e indica le sue dimensioni. Lo strato di inversione si assottiglia mentre ci spostiamo dallo scarico alla sorgente. Ora, se consideriamo la piccola regione dy della lunghezza del canale L, allora la resistenza incrementale dR offerta da questa regione può essere espressa come -

$$dR=-\frac{dy}{w.\mu _{n}.Q1(y)}$$

Qui, il segno meno è dovuto alla polarità negativa della carica dello strato di inversione Q1 e μ n è la mobilità superficiale, che è costante. Ora, sostituisci il valore di Q1 (y) nell'equazione dR -

$$dR=-\frac{dy}{w.\mu _{n}.\left \{ -C_{ox}\left [ V_{GS}-V_{C\left ( Y \right )} \right ]-V_{TO} \right \}}$$

$$dR=\frac{dy}{w.\mu _{n}.C_{ox}\left [ V_{GS}-V_{C\left ( Y \right )} \right ]-V_{TO}}$$

Ora la caduta di tensione nella piccola regione dy può essere data da

$$dV_{c}=I_{D}.dR$$

Metti il ​​valore di dR nell'equazione precedente

$$dV_{C}=I_{D}.\frac{dy}{w.\mu_{n}.C_{ox}\left [ V_{GS}-V_{C(Y)} \right ]-V_{TO}}$$

$$w.\mu _{n}.C_{ox}\left [ V_{GS}-V_{C(Y)}-V_{TO} \right ].dV_{C}=I_{D}.dy$$

Per ottenere l'ID corrente di drain su tutta la regione del canale, l'equazione di cui sopra può essere integrata lungo il canale da y = 0 a y = L e le tensioni V C (y) = 0 a V C (y) = V DS ,

$$C_{ox}.w.\mu _{n}.\int_{V_{c}=0}^{V_{DS}} \left [ V_{GS}-V_{C\left ( Y \right )}-V_{TO} \right ].dV_{C} = \int_{Y=0}^{L}I_{D}.dy$$

$$\frac{C_{ox}.w.\mu _{n}}{2}\left ( 2\left [ V_{GS}-V_{TO} \right ] V_{DS}-V_{DS}^{2}\right ) = I_{D}\left [ L-0 \right ]$$

$$I_{D} = \frac{C_{ox}.\mu _{n}}{2}.\frac{w}{L}\left ( 2\left [ V_{GS}-V_{TO} \right ]V_{DS}-V_{DS}^{2} \right )$$

Per regione lineare V DS <V GS - V TO . Per la regione di saturazione, il valore di V DS è maggiore di (V GS - V TO ). Pertanto, per la regione di saturazione V DS = (V GS - V TO ).

$$I_{D} = C_{ox}.\mu _{n}.\frac{w}{2}\left ( \frac{\left [ 2V_{DS} \right ]V_{DS}-V_{DS}^{2}}{L} \right )$$

$$I_{D} = C_{ox}.\mu _{n}.\frac{w}{2}\left ( \frac{2V_{DS}^{2}-V_{DS}^{2}}{L} \right )$$

$$I_{D} = C_{ox}.\mu _{n}.\frac{w}{2}\left ( \frac{V_{DS}^{2}}{L} \right )$$

$$I_{D} = C_{ox}.\mu _{n}.\frac{w}{2}\left ( \frac{\left [ V_{GS}-V_{TO} \right ]^{2}}{L} \right )$$

L'inverter è veramente il nucleo di tutti i progetti digitali. Una volta che il suo funzionamento e le sue proprietà sono chiaramente comprese, la progettazione di strutture più complesse come porte NAND, sommatori, moltiplicatori e microprocessori è notevolmente semplificata. Il comportamento elettrico di questi circuiti complessi può essere ricavato quasi completamente estrapolando i risultati ottenuti per gli inverter.

L'analisi degli inverter può essere estesa per spiegare il comportamento di gate più complessi come NAND, NOR o XOR, che a loro volta costituiscono gli elementi costitutivi di moduli come moltiplicatori e processori. In questo capitolo, ci concentriamo su una singola incarnazione del gate inverter, essendo l'inverter CMOS statico o, in breve, l'inverter CMOS. Questo è sicuramente il più popolare al momento e quindi merita la nostra particolare attenzione.

Principio di funzionamento

Il simbolo logico e la tabella di verità dell'inverter ideale sono mostrati nella figura sotto riportata. Qui A è l'ingresso e B è l'uscita invertita rappresentata dalle loro tensioni di nodo. Utilizzando la logica positiva, il valore booleano della logica 1 è rappresentato da V dd e lo 0 logico è rappresentato da 0. V th è la tensione di soglia dell'inverter, che è V dd / 2, dove V dd è la tensione di uscita.

L'uscita viene commutata da 0 a V dd quando l'ingresso è inferiore a V th . Quindi, per 0 <V in <V th l' uscita è uguale all'ingresso logico 0 e V th <V in <V dd è uguale all'ingresso logico 1 per l'inverter.

Le caratteristiche mostrate in figura sono ideali. La struttura circuitale generalizzata di un inverter nMOS è mostrata nella figura seguente.

Dalla figura data, possiamo vedere che la tensione di ingresso dell'inverter è uguale alla tensione gate to source del transistor nMOS e la tensione di uscita dell'inverter è uguale alla tensione drain to source del transistor nMOS. La tensione da sorgente a substrato di nMOS è anche chiamata driver per transistor che è collegato a terra; quindi V SS = 0. Il nodo di uscita è collegato con una capacità concentrata utilizzata per VTC.

Inverter per carico resistivo

La struttura di base di un inverter con carico resistivo è mostrata nella figura riportata di seguito. Qui, il tipo di miglioramento nMOS funge da transistor driver. Il carico è costituito da un semplice lineare resistore R L . L'alimentazione del circuito è V DD e la corrente di pozzo D è uguale alla corrente di carico R .

Funzionamento del circuito

Quando l'ingresso del transistor del driver è inferiore alla tensione di soglia V TH (V in <V TH ), il transistor del driver si trova nella regione di taglio e non conduce alcuna corrente. Quindi, la caduta di tensione attraverso il resistore di carico è ZERO e la tensione di uscita è uguale a V DD . Ora, quando la tensione di ingresso aumenta ulteriormente, il transistor del driver inizierà a condurre la corrente diversa da zero e nMOS andrà nella regione di saturazione.

Matematicamente,

$$I_{D} = \frac{K_{n}}{2}\left [ V_{GS}-V_{TO} \right ]^{2}$$

Aumentando ulteriormente la tensione di ingresso, il transistor driver entrerà nella regione lineare e l'uscita del transistor driver diminuirà.

$$I_{D} = \frac{K_{n}}{2}2\left [ V_{GS}-V_{TO} \right ]V_{DS}-V_{DS}^{2}$$

VTC dell'inverter con carico resistivo, mostrato di seguito, indica la modalità di funzionamento del transistor del driver e dei punti di tensione.

Inverter con carico MOSFET di tipo N.

Il vantaggio principale dell'utilizzo del MOSFET come dispositivo di carico è che l'area di silicio occupata dal transistor è minore dell'area occupata dal carico resistivo. Qui, MOSFET è carico attivo e l'inverter con carico attivo offre prestazioni migliori rispetto all'inverter con carico resistivo.

Miglioramento Carica NMOS

Nella figura sono mostrati due inverter con dispositivo di carico di tipo potenziato. Il transistore di carico può essere azionato, nella regione di saturazione o nella regione lineare, a seconda della tensione di polarizzazione applicata al suo terminale di gate. L'inverter del carico potenziato saturo è mostrato in fig. (un). Si richiede una tensione di alimentazione singola e semplice processo di fabbricazione e quindi V OH è limitata alla V DD - V T .

L'invertitore di carico di miglioramento lineare è mostrato in fig. (b). Funziona sempre in regione lineare; quindi il livello V OH è uguale a V DD .

L'inverter a carico lineare ha un margine di rumore più elevato rispetto all'inverter con potenziamento saturo. Ma lo svantaggio dell'inverter a miglioramento lineare è che richiede due alimentatori separati ed entrambi i circuiti soffrono di un'elevata dissipazione di potenza. Pertanto, gli inverter di miglioramento non vengono utilizzati in applicazioni digitali su larga scala.

Esaurimento Carica NMOS

Gli svantaggi dell'invertitore di carico di potenziamento possono essere superati utilizzando l'inverter di carico a svuotamento. Rispetto all'invertitore del carico di potenziamento, l'inverter del carico di svuotamento richiede pochi passaggi di fabbricazione in più per l'impianto del canale per regolare la tensione di soglia del carico.

I vantaggi dell'inverter del carico di esaurimento sono: transizione VTC netta, migliore margine di rumore, alimentazione singola e area di layout complessiva più piccola.

Come mostrato in figura, il gate e il terminale di source del carico sono collegati; Quindi, V GS = 0. Pertanto, la tensione di soglia del carico è negativa. Quindi,

$$V_{GS,load}> V_{T,load}$$ è soddisfatto

Pertanto, il dispositivo di carico ha sempre un canale di conduzione indipendentemente dal livello di tensione di ingresso e di uscita.

Quando il transistor di carico è nella regione di saturazione, la corrente di carico è data da

$$I_{D,load} = \frac{K_{n,load}}{2}\left [ -V_{T,load}\left ( V_{out} \right ) \right ]^{2}$$

Quando il transistor di carico è nella regione lineare, la corrente di carico è data da

$$I_{D,load} = \frac{K_{n,load}}{2}\left [ 2\left | V_{T,load}\left ( V_{out} \right ) \right |.\left ( V_{DD}-V_{out} \right )-\left ( V_{DD}-V_{out} \right )^{2} \right ]$$

Le caratteristiche di trasferimento della tensione dell'inverter del carico a esaurimento sono mostrate nella figura sotto riportata:

Inverter CMOS - Circuito, funzionamento e descrizione

Il circuito dell'inverter CMOS è mostrato in figura. Qui, i transistor nMOS e pMOS funzionano come transistor driver; quando un transistor è acceso, l'altro è spento.

Questa configurazione è chiamata complementary MOS (CMOS). L'ingresso è collegato al terminale di gate di entrambi i transistor in modo tale che entrambi possano essere pilotati direttamente con tensioni di ingresso. Il substrato del nMOS è collegato a terra e il substrato del pMOS è collegato all'alimentazione, V DD .

Quindi V SB = 0 per entrambi i transistor.

$$V_{GS,n}=V_{in}$$

$$V_{DS,n}=V_{out}$$

E,

$$V_{GS,p}=V_{in}-V_{DD}$$

$$V_{DS,p}=V_{out}-V_{DD}$$

Quando l'ingresso di nMOS è inferiore alla tensione di soglia (V in <V TO, n ), nMOS viene interrotto e pMOS si trova nella regione lineare. Quindi, la corrente di drenaggio di entrambi i transistor è zero.

$$I_{D,n}=I_{D,p}=0$$

Pertanto, la tensione di uscita V OH è uguale alla tensione di alimentazione.

$$V_{out}=V_{OH}=V_{DD}$$

Quando la tensione di ingresso è maggiore di V DD + V TO, p , il transistor pMOS è nella regione di cutoff e nMOS è nella regione lineare, quindi la corrente di drain di entrambi i transistor è zero.

$$I_{D,n}=I_{D,p}=0$$

Pertanto, la tensione di uscita V OL è uguale a zero.

$$V_{out}=V_{OL}=0$$

Il nMOS opera nella regione di saturazione se V in > V TO e se sono soddisfatte le seguenti condizioni.

$$V_{DS,n}\geq V_{GS,n}-V_{TO,n} $$

$$V_{out}\geq V_{in}-V_{TO,n} $$

Il pMOS opera nella regione di saturazione se V in <V DD + V TO, pe se sono soddisfatte le seguenti condizioni.

$$V_{DS,p}\leq V_{GS,p}-V_{TO,p} $$

$$V_{out}\leq V_{in}-V_{TO,p} $$

Per valori diversi delle tensioni di ingresso, le regioni operative sono elencate di seguito per entrambi i transistor.

Regione V in V fuori nMOS pMOS
UN <V TO, n V OH Tagliato fuori Lineare
B V IL Alto ≈ V OH Saturazione Lineare
C V th V th Saturazione Saturazione
D V IH Basso ≈ V OL Lineare Saturazione
E > (V DD + V TO, p ) V OL Lineare Tagliato fuori

Il VTC di CMOS è mostrato nella figura seguente:

I circuiti o porte logiche combinatorie, che eseguono operazioni booleane su più variabili di ingresso e determinano le uscite come funzioni booleane degli ingressi, sono gli elementi costitutivi di base di tutti i sistemi digitali. Esamineremo semplici configurazioni circuitali come porte NAND e NOR a due ingressi e poi espanderemo la nostra analisi a casi più generali di strutture circuitali a più ingressi.

Successivamente, i circuiti logici CMOS verranno presentati in modo simile. Sottolineeremo le somiglianze e le differenze tra la logica del carico di svuotamento nMOS e i circuiti logici CMOS e sottolineeremo i vantaggi delle porte CMOS con esempi. Nella sua forma più generale, un circuito logico combinatorio, o gate, che esegue una funzione booleana può essere rappresentato come un sistema a ingressi multipli e uscita singola, come illustrato nella figura.

Le tensioni di nodo, riferite al potenziale di terra, rappresentano tutte le variabili di ingresso. Utilizzando la convenzione logica positiva, il valore booleano (o logico) di "1" può essere rappresentato da un'alta tensione di VDD e il valore booleano (o logico) di "0" può essere rappresentato da una bassa tensione di 0. L'uscita il nodo è caricato con una capacità C L , che rappresenta le capacità combinate del dispositivo parassita nel circuito.

Circuiti logici CMOS

CMOS Due ingressi NOR Gate

Il circuito è costituito da una n-net collegata in parallelo e da una p-net complementare collegata in serie. Le tensioni di ingresso V X e V Y sono applicate alle porte di un transistor nMOS e di un transistor pMOS.

Quando uno o entrambi gli ingressi sono alti, cioè quando n-net crea un percorso conduttivo tra il nodo di uscita e il suolo, il p-net viene tagliato. Se entrambe le tensioni di ingresso sono basse, ovvero n-net è interrotto, allora p-net crea un percorso conduttivo tra il nodo di uscita e la tensione di alimentazione.

Per una data combinazione di ingresso, la struttura del circuito complementare è tale che l'uscita è collegata a V DD oa terra tramite un percorso a bassa resistenza e un percorso di corrente CC tra V DD e terra non è stabilito per nessuna combinazione di ingresso. La tensione di uscita del CMOS, due porte di ingresso NOR otterrà una tensione logica bassa di V OL = 0 e una tensione logica alta di V OH = V DD . L'equazione della tensione di soglia di commutazione V th è data da

$$V_{th}\left ( NOR2 \right ) = \frac{V_{T,n}+\frac{1}{2}\sqrt{\frac{k_{p}}{k_{n}}\left ( V_{DD}-\left | V_{T,p} \right | \right )}}{1+\frac{1}{2}\sqrt{\frac{k_{p}}{k_{n}}}}$$

Layout di CMOS a 2 ingressi NOR Gate

La figura mostra un layout di esempio di gate NOR a 2 ingressi CMOS, utilizzando metallo a strato singolo e polisilicio a strato singolo. Le caratteristiche di questo layout sono:

  • Singole polilinee verticali per ogni ingresso
  • Singole forme attive rispettivamente per i dispositivi N e P.
  • Bus di metallo che corrono orizzontalmente

Il diagramma dello stick per il gate CMOS N0R2 è mostrato nella figura sotto riportata; che corrisponde direttamente al layout, ma non contiene le informazioni W e L. Le aree di diffusione sono rappresentate da rettangoli, i collegamenti metallici e le linee continue e i cerchi rappresentano rispettivamente i contatti e le strisce tratteggiate rappresentano le colonne di polisilicio. Il diagramma Stick è utile per pianificare una topologia di layout ottimale.

Gate NAND a due ingressi CMOS

Lo schema del circuito della porta NAND CMOS a due ingressi è riportato nella figura seguente.

Il principio di funzionamento del circuito è esattamente duplice del funzionamento NOR a due ingressi CMOS. La n - net composta da due transistor nMOS collegati in serie crea un percorso conduttivo tra il nodo di uscita e la massa, se entrambe le tensioni di ingresso sono logiche alte. Entrambi i transistor pMOS collegati in parallelo in p-net saranno spenti.

Per tutte le altre combinazioni di ingresso, uno o entrambi i transistor pMOS saranno accesi, mentre p - net è interrotto, creando così un percorso di corrente tra il nodo di uscita e la tensione di alimentazione. La soglia di commutazione per questa porta si ottiene come -

$$V_{th}\left ( NAND2 \right ) = \frac{V_{T,n}+2\sqrt{\frac{k_{p}}{k_{n}}\left ( V_{DD}-\left | V_{T,p} \right | \right )}}{1+2\sqrt{\frac{k_{p}}{k_{n}}}}$$

Le caratteristiche di questo layout sono le seguenti:

  • Singole linee di polisilicio per gli ingressi corrono verticalmente su entrambe le regioni attive N e P.
  • Le singole forme attive vengono utilizzate per creare sia dispositivi nMOS sia dispositivi pMOS.
  • Il bus di alimentazione funziona orizzontalmente nella parte superiore e inferiore del layout.
  • I cavi di uscita corrono orizzontalmente per un facile collegamento al circuito adiacente.

Circuiti logici complessi

Porta logica complessa del carico di esaurimento NMOS

Per realizzare funzioni complesse di più variabili di input, le strutture circuitali di base ei principi di progettazione sviluppati per NOR e NAND possono essere estesi a porte logiche complesse. La capacità di realizzare funzioni logiche complesse, utilizzando un piccolo numero di transistor è una delle caratteristiche più interessanti dei circuiti logici nMOS e CMOS. Considera la seguente funzione booleana come esempio.

$$\overline{Z=P\left ( S+T \right )+QR}$$

La porta logica complessa nMOS esaurimento-carico utilizzata per realizzare questa funzione è mostrata in figura. In questa figura, il ramo driver nMOS sinistro di tre transistor driver viene utilizzato per eseguire la funzione logica P (S + T), mentre il ramo di destra esegue la funzione QR. Collegando i due rami in parallelo e posizionando il transistor di carico tra il nodo di uscita e la tensione di alimentazioneVDD,otteniamo la funzione complessa data. Ogni variabile di input è assegnata a un solo driver.

L'ispezione della topologia del circuito fornisce semplici principi di progettazione della rete pull-down -

  • Le operazioni OR vengono eseguite da driver collegati in parallelo.
  • Le operazioni AND vengono eseguite da driver collegati in serie.
  • L'inversione è fornita dalla natura del funzionamento del circuito MOS.

Se tutte le variabili di input sono logiche nel circuito che realizza la funzione, il driver equivalente (W/L) il rapporto della rete pull-down composta da cinque transistor nMOS è

$$\frac{W}{L}=\frac{1}{\frac{1}{\left ( W/L \right )Q}+\frac{1}{\left ( W/L \right )R}}+\frac{1}{\frac{1}{\left ( W/L \right )P}+\frac{1}{\left ( W/L \right )S+\left ( W/L \right )Q}}$$

Porte logiche CMOS complesse

La realizzazione della rete n-net, o rete pull-down, si basa sugli stessi principi di progettazione di base esaminati per la porta logica complessa del carico di svuotamento nMOS. La rete pull-up pMOS deve essere la doppia rete di n-net.

Significa che tutte le connessioni parallele nella rete nMOS corrisponderanno a una connessione in serie nella rete pMOS e tutte le connessioni in serie nella rete nMOS corrispondono a una connessione parallela nella rete pMOS. La figura mostra una semplice costruzione del grafico dual p-net (pull-up) dal grafico n-net (pull-down).

Ogni transistor driver nella rete pull-down è mostrato da ai e ogni nodo è mostrato da un vertice nel grafico a discesa. Successivamente, viene creato un nuovo vertice all'interno di ciascuna area delimitata nel grafo pull ei vertici vicini sono collegati da spigoli che attraversano ogni spigolo nel grafo a discesa solo una volta. Questo nuovo grafico mostra la rete pull-up.

Tecnica di layout che utilizza il metodo del grafico di Eulero

La figura mostra l'implementazione CMOS di una funzione complessa e il suo diagramma a stick eseguito con un ordinamento arbitrario dei gate che fornisce un layout non ottimale per il gate CMOS.

In questo caso, la separazione tra le colonne di polisilicio deve consentire la separazione tra diffusione e diffusione. Ciò consuma certamente una quantità considerevole di area di silicio extra.

Utilizzando il percorso di Eulero, possiamo ottenere un layout ottimale. Il percorso di Eulero è definito come un percorso ininterrotto che attraversa ciascun bordo (ramo) del grafico esattamente una volta. Trova il percorso di Eulero sia nel grafico ad albero a tendina che nel grafico ad albero a tendina con lo stesso ordine degli input.

I circuiti logici sono divisi in due categorie: (a) circuiti combinatori e (b) circuiti sequenziali.

Nei circuiti combinatori, l'uscita dipende solo dalle condizioni degli ultimi ingressi.

Nei circuiti sequenziali, l'uscita dipende non solo dagli ultimi ingressi, ma anche dalle condizioni degli ingressi precedenti. I circuiti sequenziali contengono elementi di memoria.

I circuiti sequenziali sono di tre tipi:

Bistable- I circuiti bistabili hanno due punti operativi stabili e si troveranno in uno degli stati. Esempio: celle di memoria, latch, flip-flop e registri.

Monostable- I circuiti monostabili hanno un solo punto di funzionamento stabile e anche se temporaneamente perturbati nello stato opposto, torneranno nel tempo al loro punto di funzionamento stabile. Esempio: timer, generatori di impulsi.

Astable- i circuiti non hanno un punto di lavoro stabile e oscillano tra più stati. Esempio: oscillatore ad anello.

Circuiti logici CMOS

SR Latch basato su NOR Gate

Se l'ingresso impostato (S) è uguale alla logica "1" e l'ingresso di reset è uguale alla logica "0." quindi l'uscita Q sarà forzata a logica "1". Mentre$\overline{Q}$ è costretto alla logica "0". Ciò significa che il blocco SR verrà impostato, indipendentemente dal suo stato precedente.

Allo stesso modo, se S è uguale a "0" e R è uguale a "1" quindi l'uscita Q sarà forzata a "0" mentre $\overline{Q}$ è costretto a farlo "1". Ciò significa che il latch viene ripristinato, indipendentemente dal suo stato precedentemente mantenuto. Infine, se entrambi gli ingressi S e R sono uguali alla logica"1" quindi entrambe le uscite saranno forzate alla logica "0" che è in conflitto con la complementarità di Q e $\overline{Q}$.

Pertanto, questa combinazione di input non è consentita durante il normale funzionamento. La tabella di verità di SR Latch basato su NOR è riportata nella tabella.

S R Q $\overline{Q}$ Operazione
0 0 Q $\overline{Q}$ Aspetta
1 0 1 0 Impostato
0 1 0 1 Ripristina
1 1 0 0 Non autorizzato

Il latch CMOS SR basato sul gate NOR è mostrato nella figura sotto.

Se S è uguale a V OH e R è uguale a V OL , entrambi i transistori M1 e M2 collegati in parallelo saranno ON. La tensione sul nodo$\overline{Q}$assumerà un livello logico basso di V OL = 0.

Allo stesso tempo, sia M3 che M4 sono spenti, il che si traduce in una tensione logica alta V OH al nodo Q.Se R è uguale a V OH e S è uguale a V OL , M1 e M2 si spengono e M3 e M4 accesi.

SR Latch basato su NAND Gate

La figura mostra il diagramma a blocchi e lo schema a livello di gate del latch SR basato su NAND. I piccoli cerchi sui terminali di ingresso S e R indicano che il circuito risponde ai segnali di ingresso bassi attivi. La tabella di verità del latch SR basato su NAND è riportata nella tabella

S R Q Q ′
0 0 NC NC Nessun cambiamento. Latch è rimasto nello stato attuale.
1 0 1 0 Fermo SET.
0 1 0 1 Latch RESET.
1 1 0 0 Condizione non valida.

Se S va a 0 (mentre R = 1), Q va alto, tirando $\overline{Q}$ basso e il latch entra nello stato Set

S = 0 quindi Q = 1 (se R = 1)

Se R va a 0 (mentre S = 1), Q va alto, tirando $\overline{Q}$ basso e il latch è ripristinato

R = 0 quindi Q = 1 (se S = 1)

Lo stato di mantenimento richiede che sia S che R siano alti. Se S = R = 0, l'uscita non è consentita, poiché risulterebbe in uno stato indeterminato. La figura mostra il CMOS SR Latch basato su NAND Gate.

La figura mostra il carico a svuotamento nMOS SR Latch basato su NAND Gate. L'operazione è simile a quella del latch CMOS NAND SR. L'implementazione del circuito CMOS ha una bassa dissipazione di potenza statica e un elevato margine di rumore.

Circuiti logici CMOS

Chiusura SR con clock

La figura mostra un latch SR basato su NOR con un orologio aggiunto. Il latch risponde agli ingressi S e R solo quando CLK è alto.

Quando CLK è basso, il latch mantiene il suo stato corrente. Osserva che Q cambia stato -

  • Quando S diventa alto durante CLK positivo.
  • Sul fronte di CLK iniziale dopo i cambiamenti in S & R durante il tempo basso di CLK.
  • Un problema tecnico positivo in S mentre CLK è alto
  • Quando R diventa alto durante CLK positivo.

La figura mostra l'implementazione CMOS AOI del latch SR basato su NOR con clock. Si noti che sono necessari solo 12 transistor.

  • Quando CLK è basso, due terminali in serie nell'albero N N sono aperti e due transistor paralleli nell'albero P sono ON, mantenendo così lo stato nella cella di memoria.

  • Quando il clock è alto, il circuito diventa semplicemente un latch CMOS basato su NOR che risponderà agli ingressi S e R.

Clocked SR Latch based on NAND Gate

Il circuito è implementato con quattro porte NAND. Se questo circuito è implementato con CMOS, richiede 16 transistor.

  • Il latch risponde a S o R solo se CLK è alto.
  • Se entrambi i segnali di ingresso e i segnali CLK sono attivi alti: cioè, l'uscita latch Q verrà impostata quando CLK = "1" S = "1" e R = "0"
  • Allo stesso modo, il latch verrà ripristinato quando CLK = "1", S = "0" e

Quando CLK è basso, il latch mantiene il suo stato attuale.

Chiusura JK con orologio

La figura sopra mostra un latch JK con clock, basato su porte NAND. Lo svantaggio di un latch SR è che quando sia S che R sono alti, il suo stato di uscita diventa indeterminato. Il latch JK elimina questo problema utilizzando il feedback dall'output all'input, in modo tale che tutti gli stati di input della tabella della verità siano consentiti. Se J = K = 0, il latch manterrà il suo stato attuale.

Se J = 1 e K = 0, il latch verrà impostato sul successivo fronte di clock positivo, ovvero Q = 1, $\overline{Q}$ = 0

Se J = 0 e K = 1, il latch si resetterà al successivo fronte di clock positivo, cioè Q = 1 e $\overline{Q}$ = 0.

Se J = K = 1, il latch si attiverà al successivo fronte di clock positivo

Il funzionamento del latch JK con clock è riassunto nella tabella di verità riportata in tabella.

J

K

Q

$\overline{Q}$

S

R

Q

$\overline{Q}$

Operation

0 0 0 1 1 1 0 1 Aspetta
1 0 1 1 1 0
0 1 0 1 1 1 0 1 Ripristina
1 0 1 0 0 1
1 0 0 1 0 1 1 0 Impostato
1 0 1 1 1 0
1 1 0 1 0 1 1 0 toggle
1 0 1 0 0 1

Implementazione Latch CMOS D

Il latch D è normalmente implementato con interruttori di gate di trasmissione (TG) come mostrato in figura. L'ingresso TG si attiva con CLK mentre l'anello di retroazione latch TG si attiva con CLK. L'ingresso D viene accettato quando CLK è alto. Quando CLK va basso, l'ingresso è a circuito aperto e il latch è impostato con i dati precedenti D.

VHDL sta per linguaggio di descrizione hardware di circuiti integrati ad altissima velocità. È un linguaggio di programmazione utilizzato per modellare un sistema digitale in base al flusso di dati, allo stile comportamentale e strutturale di modellazione. Questa lingua è stata introdotta per la prima volta nel 1981 per il Dipartimento della Difesa (DoD) nell'ambito del programma VHSIC.

Descrivere un design

In VHDL viene utilizzata un'entità per descrivere un modulo hardware. Un'entità può essere descritta usando,

  • Dichiarazione di entità
  • Architecture
  • Configuration
  • Dichiarazione del pacchetto
  • Corpo del pacchetto

Vediamo cosa sono questi?

Dichiarazione di entità

Definisce i nomi, i segnali di ingresso e uscita e le modalità di un modulo hardware.

Syntax -

entity entity_name is
   Port declaration;
end entity_name;

Una dichiarazione di entità dovrebbe iniziare con "entity" e terminare con le parole chiave "end". La direzione sarà input, output o inout.

In La porta può essere letta
Su La porta può essere scritta
Dentro fuori La porta può essere letta e scritta
Buffer La porta può essere letta e scritta, può avere solo una sorgente.

Architecture -

L'architettura può essere descritta utilizzando uno stile strutturale, di flusso di dati, comportamentale o misto.

Syntax -

architecture architecture_name of entity_name 
architecture_declarative_part;

begin
   Statements;
end architecture_name;

Qui, dovremmo specificare il nome dell'entità per cui stiamo scrivendo il corpo dell'architettura. Le istruzioni dell'architettura dovrebbero essere all'interno delle parole chiave "begin" e "énd". La parte dichiarativa dell'architettura può contenere variabili, costanti o dichiarazioni di componenti.

Modellazione del flusso di dati

In questo stile di modellazione, il flusso di dati attraverso l'entità viene espresso utilizzando il segnale simultaneo (parallelo). Le istruzioni simultanee in VHDL sono WHEN e GENERATE.

Oltre a questi, per costruire codice possono essere utilizzati anche assegnazioni che utilizzano solo operatori (AND, NOT, +, *, sll, ecc.).

Infine, un tipo speciale di assegnazione, chiamato BLOCCO, può essere impiegato anche in questo tipo di codice.

Nel codice simultaneo, è possibile utilizzare quanto segue:

  • Operators
  • L'istruzione WHEN (WHEN / ELSE o WITH / SELECT / WHEN);
  • L'istruzione GENERATE;
  • L'istruzione BLOCK

Modellazione comportamentale

In questo stile di modellazione, il comportamento di un'entità come insieme di istruzioni viene eseguito sequenzialmente nell'ordine specificato. Solo le istruzioni inserite in PROCESS, FUNCTION o PROCEDURE sono sequenziali.

PROCESSI, FUNZIONI e PROCEDURE sono le uniche sezioni di codice che vengono eseguite in sequenza.

Tuttavia, nel complesso, uno qualsiasi di questi blocchi è ancora concorrente con qualsiasi altra istruzione posta al di fuori di esso.

Un aspetto importante del codice di comportamento è che non è limitato alla logica sequenziale. In effetti, con esso, possiamo costruire circuiti sequenziali così come circuiti combinatori.

Le istruzioni di comportamento sono IF, WAIT, CASE e LOOP. Anche le VARIABILI sono limitate e dovrebbero essere utilizzate solo in codice sequenziale. VARIABILE non può mai essere globale, quindi il suo valore non può essere distribuito direttamente.

Modellazione strutturale

In questa modellazione, un'entità è descritta come un insieme di componenti interconnessi. Un'istruzione di istanziazione di un componente è un'istruzione simultanea. Pertanto, l'ordine di queste affermazioni non è importante. Lo stile strutturale di modellazione descrive solo un'interconnessione di componenti (visti come scatole nere), senza implicare alcun comportamento dei componenti stessi né dell'entità che collettivamente rappresentano.

Nella modellazione strutturale, il corpo dell'architettura è composto da due parti: la parte dichiarativa (prima dell'inizio della parola chiave) e la parte dell'istruzione (dopo l'inizio della parola chiave).

Operazione logica - AND GATE

X Y Z
0 0 0
0 1 0
1 0 0
1 1 1

VHDL Code:
Library ieee;
use ieee.std_logic_1164.all;

entity and1 is
   port(x,y:in bit ; z:out bit);
end and1;

architecture virat of and1 is
begin
   z<=x and y; 
end virat;

Forme d'onda

Operazione logica - Porta OR

X Y Z
0 0 0
0 1 1
1 0 1
1 1 1

VHDL Code: 
Library ieee; 
use ieee.std_logic_1164.all;  

entity or1 is
   port(x,y:in bit ; z:out bit); 
end or1; 
 
architecture virat of or1 is
begin
   z<=x or y; 
end virat;

Forme d'onda

Operazione logica - NOT Gate

X Y
0 1
1 0

VHDL Code:
  
Library ieee; 
use ieee.std_logic_1164.all; 
 
entity not1 is
   port(x:in bit ; y:out bit); 
end not1; 
 
architecture virat of not1 is
begin
   y<=not x;
end virat;

Forme d'onda

Operazione logica - Gate NAND

X Y z
0 0 1
0 1 1
1 0 1
1 1 0

VHDL Code:
  
Library ieee; 
use ieee.std_logic_1164.all; 

entity nand1 is
   port(a,b:in bit ; c:out bit); 
end nand1; 
 
architecture virat of nand1 is
begin
   c<=a nand b; 
end virat;

Forme d'onda

Operazione logica - NOR Gate

X Y z
0 0 1
0 1 0
1 0 0
1 1 0

VHDL Code: 
 
Library ieee; 
use ieee.std_logic_1164.all; 
 
entity nor1 is
   port(a,b:in bit ; c:out bit); 
end nor1; 
 
architecture virat of nor1 is
begin
   c<=a nor b;
end virat;

Forme d'onda

Operazione logica - XOR Gate

X Y Z
0 0 1
0 1 1
1 0 1
1 1 0

VHDL Code: 
 
Library ieee; 
use ieee.std_logic_1164.all;
  
entity xor1 is
   port(a,b:in bit ; c:out bit); 
end xor1;
  
architecture virat of xor1 is
begin
   c<=a xor b; 
end virat;

Forme d'onda

Operazione logica - X-NOR Gate

X Y Z
0 0 1
0 1 1
1 0 1
1 1 0

VHDL Code: 
 
Library ieee; 
use ieee.std_logic_1164.all; 

entity xnor1 is
   port(a,b:in bit ; c:out bit); 
end xnor1; 
 
architecture virat of xnor1 is
begin
   c<=not(a xor b); 
end virat;

Forme d'onda

Questo capitolo spiega la programmazione VHDL per circuiti combinatori.

Codice VHDL per un mezzo sommatore

VHDL Code:
  
Library ieee; 
use ieee.std_logic_1164.all;
  
entity half_adder is
   port(a,b:in bit; sum,carry:out bit); 
end half_adder; 
 
architecture data of half_adder is
begin
   sum<= a xor b;  
   carry <= a and b;  
end data;

Forme d'onda

Codice VHDL per un sommatore completo

Library ieee; 
use ieee.std_logic_1164.all;
 
entity full_adder is port(a,b,c:in bit; sum,carry:out bit); 
end full_adder;
  
architecture data of full_adder is
begin
   sum<= a xor b xor c; 
   carry <= ((a and b) or (b and c) or (a and c)); 
end data;

Forme d'onda

Codice VHDL per mezzo sottrattore

Library ieee;
use ieee.std_logic_1164.all;
  
entity half_sub is
   port(a,c:in bit; d,b:out bit);
end half_sub;  

architecture data of half_sub is
begin
   d<= a xor c;
   b<= (a and (not c));
end data;

Forme d'onda

Codice VHDL per un sottrattore completo

Library ieee; 
use ieee.std_logic_1164.all;
  
entity full_sub is
   port(a,b,c:in bit; sub,borrow:out bit); 
end full_sub; 
 
architecture data of full_sub is
begin
   sub<= a xor b xor c; 
   borrow <= ((b xor c) and (not a)) or (b and c); 
end data;

Forme d'onda

Codice VHDL per un multiplexer

Library ieee; 
use ieee.std_logic_1164.all;
  
entity mux is
   port(S1,S0,D0,D1,D2,D3:in bit; Y:out bit);
end mux;
  
architecture data of mux is
begin 
   Y<= (not S0 and not S1 and D0) or 
      (S0 and not S1 and D1) or 
      (not S0 and S1 and D2) or
      (S0 and S1 and D3); 
end data;

Forme d'onda

Codice VHDL per un demultiplexer

Library ieee; 
use ieee.std_logic_1164.all;
  
entity demux is
   port(S1,S0,D:in bit; Y0,Y1,Y2,Y3:out bit); 
end demux;
  
architecture data of demux is
begin 
   Y0<=  ((Not S0) and (Not S1) and D); 
   Y1<=  ((Not S0) and S1 and D); 
   Y2<=  (S0 and (Not S1) and D); 
   Y3<=  (S0 and S1 and D); 
end data;

Forme d'onda

Codice VHDL per un codificatore 8 x 3

library ieee; 
use ieee.std_logic_1164.all; 
 
entity enc is
   port(i0,i1,i2,i3,i4,i5,i6,i7:in bit; o0,o1,o2: out bit); 
end enc; 
 
architecture vcgandhi of enc is
begin 
   o0<=i4 or i5 or i6 or i7; 
   o1<=i2 or i3 or i6 or i7; 
   o2<=i1 or i3 or i5 or i7; 
end vcgandhi;

Forme d'onda

Codice VHDL per un decodificatore 3 x 8

library ieee; 
use ieee.std_logic_1164.all;

entity dec is
   port(i0,i1,i2:in bit; o0,o1,o2,o3,o4,o5,o6,o7: out bit); 
end dec; 
 
architecture vcgandhi of dec is
begin 
   o0<=(not i0) and (not i1) and (not i2); 
   o1<=(not i0) and (not i1) and i2; 
   o2<=(not i0) and i1 and (not i2); 
   o3<=(not i0) and i1 and i2; 
   o4<=i0 and (not i1) and (not i2); 
   o5<=i0 and (not i1) and i2; 
   o6<=i0 and i1 and (not i2); 
   o7<=i0 and i1 and i2; 
end vcgandhi;

Forme d'onda

Codice VHDL - Sommatore parallelo a 4 bit

library IEEE; 
use IEEE.STD_LOGIC_1164.all;
  
entity pa is
   port(a : in STD_LOGIC_VECTOR(3 downto 0);
      b : in STD_LOGIC_VECTOR(3 downto 0);
      ca : out STD_LOGIC;
      sum : out STD_LOGIC_VECTOR(3 downto 0) 
   ); 
end pa; 
 
architecture vcgandhi of pa is
   Component fa is
      port (a : in STD_LOGIC; 
         b : in STD_LOGIC; 
         c : in STD_LOGIC; 
         sum : out STD_LOGIC; 
         ca : out STD_LOGIC
      ); 
   end component;         
   signal s : std_logic_vector (2 downto 0); 
   signal temp: std_logic;
begin 
   temp<='0'; 
   u0 : fa port map (a(0),b(0),temp,sum(0),s(0)); 
   u1 : fa port map (a(1),b(1),s(0),sum(1),s(1)); 
   u2 : fa port map (a(2),b(2),s(1),sum(2),s(2));
   ue : fa port map (a(3),b(3),s(2),sum(3),ca);  
end vcgandhi;

Forme d'onda

Codice VHDL - Controllo di parità a 4 bit

library ieee; 
use ieee.std_logic_1164.all; 
 
entity parity_checker is 
   port (a0,a1,a2,a3 : in std_logic; 
      p : out std_logic); 
end parity_checker;  

architecture vcgandhi of parity_checker is 
begin    
   p <= (((a0 xor a1) xor a2) xor a3); 
end vcgandhi;

Forme d'onda

Codice VHDL - Generatore di parità a 4 bit

library ieee;
use ieee.std_logic_1164.all;

entity paritygen is
   port (a0, a1, a2, a3: in std_logic; p_odd, p_even: out std_logic);
end paritygen;  

architecture vcgandhi of paritygen is
begin
   process (a0, a1, a2, a3)
   
	if (a0 ='0' and a1 ='0' and a2 ='0' and a3 =’0’)
      then odd_out <= "0";
      even_out <= "0";
   else
      p_odd <= (((a0 xor a1) xor a2) xor a3);
      p_even <= not(((a0 xor a1) xor a2) xor a3);  
end vcgandhi

Forme d'onda

Questo capitolo spiega come eseguire la programmazione VHDL per circuiti sequenziali.

Codice VHDL per un SR Latch

library ieee; 
use ieee.std_logic_1164.all;
  
entity srl is 
   port(r,s:in bit; q,qbar:buffer bit); 
end srl;  

architecture virat of srl is 
   signal s1,r1:bit; 
begin 
   q<= s nand qbar; 
   qbar<= r nand q; 
end virat;

Forme d'onda

Codice VHDL per un fermo D.

library ieee; 
use ieee.std_logic_1164.all;

entity Dl is 
   port(d:in bit; q,qbar:buffer bit); 
end Dl; 
 
architecture virat of Dl is 
   signal s1,r1:bit; 
begin 
   q<= d nand qbar; 
   qbar<= d nand q; 
end virat;

Forme d'onda

Codice VHDL per un flip flop SR

library ieee; 
use ieee.std_logic_1164.all;
  
entity srflip is 
   port(r,s,clk:in bit; q,qbar:buffer bit); 
end srflip;
  
architecture virat of srflip is 
   signal s1,r1:bit; 
begin 
   s1<=s nand clk; 
   r1<=r nand clk;
   q<= s1 nand qbar;
   qbar<= r1 nand q;
end virat;

Forme d'onda

Codice VHDL per un flip flop JK

library IEEE; 
use IEEE.STD_LOGIC_1164.all;  

entity jk is 
   port(
      j : in STD_LOGIC; 
      k : in STD_LOGIC; 
      clk : in STD_LOGIC; 
      reset : in STD_LOGIC; 
      q : out STD_LOGIC; 
      qb : out STD_LOGIC 
   ); 
end jk;
  
architecture virat of jk is 
begin 
   jkff : process (j,k,clk,reset) is 
   variable m : std_logic := '0'; 
   
   begin 
      if (reset = '1') then 
         m : = '0'; 
      elsif (rising_edge (clk)) then 
         if (j/ = k) then
            m : = j; 
         elsif (j = '1' and k = '1') then 
            m : = not m; 
         end if; 
      end if; 
      
      q <= m; 
      qb <= not m; 
   end process jkff; 
end virat;

Forme d'onda

Codice VHDL per un flip flop D.

Library ieee; 
use ieee.std_logic_1164.all;  

entity dflip is 
   port(d,clk:in bit; q,qbar:buffer bit); 
end dflip; 
 
architecture virat of dflip is 
   signal d1,d2:bit; 
begin 
   d1<=d nand clk; 
   d2<=(not d) nand clk; 
   q<= d1 nand qbar; 
   qbar<= d2 nand q; 
end virat;

Forme d'onda

Codice VHDL per un flip flop a T.

library IEEE; 
use IEEE.STD_LOGIC_1164.all;  

entity Toggle_flip_flop is 
   port( 
      t : in STD_LOGIC; 
      clk : in STD_LOGIC; 
      reset : in STD_LOGIC; 
      dout : out STD_LOGIC
   ); 
end Toggle_flip_flop;  

architecture virat of Toggle_flip_flop is 
begin 
   tff : process (t,clk,reset) is 
   variable m : std_logic : = '0'; 
   
   begin 
      if (reset = '1') then 
         m : = '0'; 
      elsif (rising_edge (clk)) then 
         if (t = '1') then 
            m : = not m;        
         end if; 
      end if; 
      dout < = m; 
   end process tff; 
end virat;

Forme d'onda

Codice VHDL per un contatore avanti a 4 bit

library IEEE; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all;
  
entity counter is 
   port(Clock, CLR : in std_logic; 
      Q : out std_logic_vector(3 downto 0)
   ); 
end counter;  

architecture virat of counter is 
   signal tmp: std_logic_vector(3 downto 0); 
begin 
   process (Clock, CLR) 
   
   begin 
      if (CLR = '1') then 
         tmp < = "0000"; 
      elsif (Clock'event and Clock = '1') then 
         mp <= tmp + 1; 
      end if; 
   end process; 
   Q <= tmp; 
end virat;

Forme d'onda

Codice VHDL per un contatore alla rovescia a 4 bit

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all;
  
entity dcounter is 
   port(Clock, CLR : in std_logic; 
      Q : out std_logic_vector(3 downto 0)); 
end dcounter; 
 
architecture virat of dcounter is 
   signal tmp: std_logic_vector(3 downto 0); 

begin 
   process (Clock, CLR) 
   begin 
      if (CLR = '1') then 
         tmp <= "1111"; 
      elsif (Clock'event and Clock = '1') then 
         tmp <= tmp - 1; 
      end if; 
   end process; 
   Q <= tmp; 
end virat;

Forme d'onda

Verilog è un HARDWARE DESCRIPTION LANGUAGE (HDL). È un linguaggio usato per descrivere un sistema digitale come uno switch di rete o un microprocessore, una memoria o un flip-flop. Significa che utilizzando un HDL possiamo descrivere qualsiasi hardware digitale a qualsiasi livello. I progetti, descritti in HDL, sono indipendenti dalla tecnologia, molto facili per la progettazione e il debug e sono normalmente più utili degli schemi, in particolare per i circuiti di grandi dimensioni.

Verilog supporta un design a molti livelli di astrazione. I tre principali sono:

  • Livello comportamentale
  • Livello di trasferimento del registro
  • Livello del cancello

Livello comportamentale

Questo livello descrive un sistema mediante algoritmi concorrenti (comportamentali). Ogni algoritmo è sequenziale, il che significa che consiste in un insieme di istruzioni che vengono eseguite una per una. Funzioni, compiti e blocchi sono gli elementi principali. Non c'è riguardo alla realizzazione strutturale del progetto.

Livello di trasferimento del registro

I progetti che utilizzano il livello di trasferimento del registro specificano le caratteristiche di un circuito utilizzando le operazioni e il trasferimento di dati tra i registri. La definizione moderna di un codice RTL è "Qualsiasi codice sintetizzabile è chiamato codice RTL".

Livello del cancello

All'interno del livello logico, le caratteristiche di un sistema sono descritte da collegamenti logici e dalle loro proprietà temporali. Tutti i segnali sono segnali discreti. Possono avere solo valori logici definiti ("0", "1", "X", "Z"). Le operazioni utilizzabili sono primitive logiche predefinite (porte di base). La modellazione a livello di gate potrebbe non essere un'idea corretta per la progettazione logica. Il codice a livello di gate viene generato utilizzando strumenti come strumenti di sintesi e la sua netlist viene utilizzata per la simulazione a livello di gate e per il backend.

Token lessicali

I file di testo di origine della lingua Verilog sono un flusso di token lessicali. Un token è composto da uno o più caratteri e ogni singolo carattere è esattamente in un token.

I token lessicali di base utilizzati da Verilog HDL sono simili a quelli del linguaggio di programmazione C. Verilog fa distinzione tra maiuscole e minuscole. Tutte le parole chiave sono in minuscolo.

Spazio bianco

Gli spazi bianchi possono contenere caratteri per spazi, tabulazioni, nuove righe e feed modulo. Questi personaggi vengono ignorati tranne quando servono per separare i gettoni.

I caratteri dello spazio vuoto sono Spazio vuoto, Tabulazioni, Ritorni a capo, Nuova riga e Avanzamenti modulo.

Commenti

Esistono due forme per rappresentare i commenti

  • 1) I commenti su una sola riga iniziano con il token // e finiscono con il ritorno a capo.

Es .: // questa è una sintassi a riga singola

  • 2) I commenti su più righe iniziano con il token / * e finiscono con il token * /

Es .: / * questa è la sintassi multilinea * /

Numeri

È possibile specificare un numero in formato binario, ottale, decimale o esadecimale. I numeri negativi sono rappresentati nei numeri di complimento di 2. Verilog consente numeri interi, numeri reali e numeri con segno e senza segno.

La sintassi è data da - <size> <radix> <value>

La dimensione o il numero non dimensionato possono essere definiti in <Dimensione> e <radice> definisce se è binario, ottale, esadecimale o decimale.

Identificatori

L'identificatore è il nome utilizzato per definire l'oggetto, come una funzione, un modulo o un registro. Gli identificatori devono iniziare con caratteri alfabetici o caratteri di sottolineatura. Ex. A_Z, a_z, _

Gli identificatori sono una combinazione di caratteri alfabetici, numerici, di sottolineatura e $. Possono essere lunghi fino a 1024 caratteri.

Operatori

Gli operatori sono caratteri speciali utilizzati per porre condizioni o per utilizzare le variabili. Ci sono uno, due e talvolta tre caratteri usati per eseguire operazioni sulle variabili.

Ex. >, +, ~, &! =.

Parole chiave Verilog

Le parole che hanno un significato speciale in Verilog sono chiamate parole chiave Verilog. Ad esempio, assign, case, while, wire, reg, and, or, nand e module. Non dovrebbero essere usati come identificatori. Le parole chiave di Verilog includono anche direttive del compilatore e attività e funzioni di sistema.

Modellazione a livello di gate

Verilog dispone di primitive integrate come porte logiche, porte di trasmissione e interruttori. Questi sono usati raramente per il lavoro di progettazione, ma sono usati nel mondo della post sintesi per la modellazione di cellule ASIC / FPGA.

La modellazione a livello di gate presenta due proprietà:

Drive strength- La forza delle porte di uscita è definita dalla forza motrice. L'output è più forte se c'è una connessione diretta alla sorgente. La forza diminuisce se la connessione avviene tramite un transistor conduttore e almeno quando è collegata tramite un resistivo pull-up / down. La forza del drive di solito non è specificata, nel qual caso i valori predefiniti sono strong1 e strong0.

Delays- Se i ritardi non sono specificati, le porte non hanno ritardi di propagazione; se vengono specificati due ritardi, il primo rappresenta il ritardo di salita e il secondo il ritardo di caduta; se viene specificato un solo ritardo, allora entrambi, salita e discesa sono uguali. I ritardi possono essere ignorati in sintesi.

Primitive di Porta

Le porte logiche di base che utilizzano un'uscita e molti ingressi vengono utilizzate in Verilog. GATE utilizza una delle parole chiave - and, nand, or, nor, xor, xnor da utilizzare in Verilog per N numero di input e 1 output.

Example:  
   Module gate() 
   Wire ot0; 
   Wire ot1; 
   Wire ot2; 
   
   Reg in0,in1,in2,in3; 
   Not U1(ot0,in0); 
   Xor U2(ot1,in1,in2,in3); 
   And U3(ot2, in2,in3,in0)

Primitive del cancello di trasmissione

Le primitive del gate di trasmissione includono sia buffer che inverter. Hanno un ingresso singolo e una o più uscite. Nella sintassi di istanziazione gate mostrata di seguito, GATE sta per la parola chiave buf o NOT gate.

Esempio: Not, buf, bufif0, bufif1, notif0, notif1

Non - n outout inverter

Buf - n buffer di output

Bufifo - buffer tristate, abilitazione bassa attiva

Bufif1 - buffer tristate, abilitazione alta attiva

Notifo - Inverter tristate, abilitazione bassa attiva

Notif1 - inverter tristate, abilitazione alta attiva

Example:  
   Module gate() 
   Wire out0; 
   Wire out1; 
   
   Reg in0,in1;
   Not U1(out0,in0); 
   Buf U2(out0,in0);

Tipi di dati

Valore impostato

Verilog si compone, principalmente, di quattro valori fondamentali. Tutti i tipi di dati Verilog utilizzati in Verilog memorizzano questi valori:

0 (zero logico o condizione falsa)

1 (uno logico o condizione vera)

x (valore logico sconosciuto)

z (stato di alta impedenza)

l'uso di x e z è molto limitato per la sintesi.

Filo

Un filo viene utilizzato per rappresentare un filo fisico in un circuito e viene utilizzato per il collegamento di porte o moduli. Il valore di un filo può essere solo letto e non assegnato in una funzione o blocco. Un filo non può memorizzare il valore ma è sempre guidato da un'istruzione di assegnazione continua o collegando il filo all'uscita di un cancello / modulo. Altri tipi specifici di fili sono:

Wand (wired-AND) - qui il valore di Wand dipende dall'AND logico di tutti i driver di dispositivo ad esso collegati.

Wor (wired-OR) - qui il valore di un Wor dipende dall'OR logico di tutti i driver di dispositivo ad esso collegati.

Tri (three-state) - qui tutti i driver collegati a un tri devono essere z, tranne uno solo (che determina il valore di tri).

Example: 
   Wire [msb:lsb] wire_variable_list; 
   Wirec // simple wire 
   Wand d; 
   
   Assign d = a; // value of d is the logical AND of 
   Assign d = b; // a and b 
   Wire [9:0] A; // a cable (vector) of 10 wires. 
   
   Wand [msb:lsb] wand_variable_list; 
   Wor [msb:lsb] wor_variable_list; 
   Tri [msb:lsb] tri_variable_list;

Registrati

Un reg (registro) è un oggetto dati, che contiene il valore da un assegnamento procedurale a quello successivo e viene utilizzato solo in diverse funzioni e blocchi procedurali. Un registro è un semplice Verilog, registro di tipo variabile e non può implicare un registro fisico. Nei registri multi-bit, i dati vengono memorizzati sotto forma di numeri senza segno e l'estensione del segno non viene utilizzata.

Esempio -

reg c; // singola variabile di registro a 1 bit

reg [5: 0] gemma; // un vettore a 6 bit;

reg [6: 0] d, e; // due variabili a 7 bit

Ingresso, uscita, Inout

Queste parole chiave vengono utilizzate per dichiarare le porte di input, output e bidirezionali di un'attività o di un modulo. Qui le porte di input e inout, che sono di tipo wire e la porta di output è configurata per essere di tipo wire, reg, wand, wor o tri. Sempre, l'impostazione predefinita è il tipo di filo.

Example

Module sample(a, c, b, d);  
Input c;   // An input where wire is used. 

Output a, b;  // Two outputs where wire is used. 
Output [2:0] d;  /* A three-bit output. One must declare type in a separate statement. */ 
reg [1:0] a;  // The above ‘a’ port is for declaration in reg.

Numero intero

I numeri interi vengono utilizzati nelle variabili di uso generale. Sono usati principalmente in loop-indici, costanti e parametri. Sono di tipo di dati di tipo "reg". Memorizzano i dati come numeri con segno, mentre i tipi reg dichiarati in modo esplicito li memorizzano come dati non firmati. Se il numero intero non è definito al momento della compilazione, la dimensione predefinita sarebbe 32 bit.

Se un numero intero contiene una costante, il sintetizzatore li regola alla larghezza minima necessaria al momento della compilazione.

Example

Integer c;   // single 32-bit integer 
Assign a = 63;  // 63 defaults to a 7-bit variable.

Supply0, Supply1

Supply0 definisce i fili legati alla logica 0 (massa) e supply1 definisce i fili legati alla logica 1 (alimentazione).

Example

supply0 logic_0_wires; 
supply0 gnd1;  // equivalent to a wire assigned as 0 

supply1 logic_1_wires; 
supply1 c, s;

Tempo

Il tempo è una quantità a 64 bit che può essere utilizzata insieme all'attività di sistema $ time per mantenere il tempo di simulazione. Il tempo non è supportato per la sintesi e quindi viene utilizzato solo per scopi di simulazione.

Example

time time_variable_list; 
time c; 
c = $time;   //c = current simulation time

Parametro

Un parametro definisce una costante che può essere impostata quando si utilizza un modulo, che consente la personalizzazione del modulo durante il processo di istanziazione.

Example 
Parameter add = 3’b010, sub = 2’b11; 
Parameter n = 3; 
Parameter [2:0] param2 = 3’b110; 

reg [n-1:0] jam; /* A 3-bit register with length of n or above. */ 
always @(z) 
y = {{(add - sub){z}};  

if (z)
begin 
   state = param2[1];
else
   state = param2[2]; 
end

Operatori

Operatori aritmetici

Questi operatori eseguono operazioni aritmetiche. I + e − sono usati come operatori unari (x) o binari (z − y).

Gli operatori inclusi nelle operazioni aritmetiche sono:

+ (addizione), - (sottrazione), * (moltiplicazione), / (divisione),% (modulo)

Example -

parameter v = 5;
reg[3:0] b, d, h, i, count; 
h = b + d; 
i = d - v; 
cnt = (cnt +1)%16; //Can count 0 thru 15.

Operatori relazionali

Questi operatori confrontano due operandi e restituiscono il risultato in un singolo bit, 1 o 0.

Le variabili wire e reg sono positive. Quindi (−3'd001) = = 3'd111 e (−3b001)> 3b110.

Gli Operatori inclusi nell'operazione relazionale sono:

  • == (uguale a)
  • ! = (non uguale a)
  • > (maggiore di)
  • > = (maggiore o uguale a)
  • <(minore di)
  • <= (minore o uguale a)

Example

if (z = = y) c = 1; 
   else c = 0; // Compare in 2’s compliment; d>b 
reg [3:0] d,b; 

if (d[3]= = b[3]) d[2:0] > b[2:0]; 
   else b[3]; 
Equivalent Statement 
e = (z == y);

Operatori bit per bit

Operatori bit per bit che eseguono un confronto bit per bit tra due operandi.

Gli operatori inclusi nell'operazione Bit Wise sono:

  • & (AND bit per bit)
  • | (bitwiseOR)
  • ~ (bit a bit NON)
  • ^ (XOR bit per bit)
  • ~ ^ o ^ ~ (XNOR bit per bit)

Example

module and2 (d, b, c); 
input [1:0] d, b; 
output [1:0] c; 
assign c = d & b; 
end module

Operatori logici

Gli operatori logici sono operatori bit-wise e vengono utilizzati solo per operandi a bit singolo. Restituiscono un singolo valore di bit, 0 o 1. Possono lavorare su numeri interi o gruppi di bit, espressioni e trattare tutti i valori diversi da zero come 1. Gli operatori logici sono generalmente utilizzati nelle istruzioni condizionali poiché lavorano con le espressioni.

Gli operatori inclusi nel funzionamento logico sono:

  • ! (NOT logico)
  • && (AND logico)
  • || (OR logico)

Example

wire[7:0] a, b, c; // a, b and c are multibit variables. 
reg x; 

if ((a == b) && (c)) x = 1; //x = 1 if a equals b, and c is nonzero. 
   else x = !a; // x =0 if a is anything but zero.

Operatori di riduzione

Gli operatori di riduzione sono la forma unaria degli operatori bit per bit e operano su tutti i bit di un vettore operando. Anche questi restituiscono un valore a bit singolo.

Gli operatori che sono inclusi nell'operazione di riduzione sono:

  • & (riduzione AND)
  • | (riduzione OR)
  • ~ & (riduzione NAND)
  • ~ | (riduzione NOR)
  • ^ (riduzione XOR)
  • ~ ^ o ^ ~ (riduzione XNOR)

Example

Module chk_zero (x, z); 

Input [2:0] x; 
Output z; 
Assign z = & x; // Reduction AND 
End module

Operatori di turno

Operatori di scorrimento, che spostano il primo operando del numero di bit specificato dal secondo operando nella sintassi. Le posizioni libere sono riempite con zeri per entrambe le direzioni, spostamenti a sinistra ea destra (non è possibile utilizzare l'estensione del segno).

Gli operatori inclusi nell'operazione di turno sono:

  • << (sposta a sinistra)
  • >> (sposta a destra)

Example

Assign z = c << 3; /* z = c shifted left 3 bits;

I posti vacanti sono riempiti con 0 * /

Operatore di concatenazione

L'operatore di concatenazione combina due o più operandi per formare un vettore più grande.

L'operatore incluso nell'operazione di concatenazione è - {} (concatenazione)

Example

wire [1:0] a, h; wire [2:0] x; wire [3;0] y, Z; 
assign x = {1’b0, a}; // x[2] = 0, x[1] = a[1], x[0] = a[0] 
assign b = {a, h}; /* b[3] = a[1], b[2] = a[0], b[1] = h[1], 
b[0] = h[0] */ 
assign {cout, b} = x + Z; // Concatenation of a result

Operatore di replica

L'operatore di replica sta effettuando più copie di un elemento.

L'operatore utilizzato nell'operazione di replica è: {n {item}} (replica n volte di un elemento)

Example

Wire [1:0] a, f; wire [4:0] x; 
Assign x = {2{1’f0}, a}; // Equivalent to x = {0,0,a } 
Assign y = {2{a}, 3{f}}; //Equivalent to y = {a,a,f,f} 
For synthesis, Synopsis did not like a zero replication.

For example:- 
Parameter l = 5, k = 5; 
Assign x = {(l-k){a}}

Operatore condizionale

L'operatore condizionale sintetizza in un multiplexer. È lo stesso tipo utilizzato in C / C ++ e valuta una delle due espressioni in base alla condizione.

L'operatore utilizzato nell'operazione condizionale è:

(Condizione) ? (Risultato se la condizione è vera) -

(risultato se la condizione è falsa)

Example

Assign x = (g) ? a : b; 
Assign x = (inc = = 2) ? x+1 : x-1; 
/* if (inc), x = x+1, else x = x-1 */

Operandi

Letterali

I letterali sono operandi a valori costanti utilizzati nelle espressioni Verilog. I due letterali Verilog comunemente usati sono:

  • String - Un operando letterale stringa è una matrice unidimensionale di caratteri, racchiusi tra virgolette doppie ("").

  • Numeric - Un operando di numero costante è specificato in numero binario, ottale, decimale o esadecimale.

Example

n - numero intero che rappresenta il numero di bit

F - uno dei quattro possibili formati di base -

b per binario, o per ottale, d per decimale, h per esadecimale.

“time is”  // string literal 
267        // 32-bit decimal number 
2’b01      // 2-bit binary 
20’hB36F   // 20-bit hexadecimal number 
‘062       // 32-bit octal number

Fili, reg. E parametri

Fili, registri e parametri sono i tipi di dati utilizzati come operandi nelle espressioni Verilog.

Selezione bit "x [2]" e selezione parte "x [4: 2]"

Le selezioni di bit e le selezioni di parte vengono utilizzate per selezionare rispettivamente un bit e più bit da un vettore wire, reg o parametro con l'uso di parentesi quadre "[]". Le selezioni di bit e di parte vengono utilizzate anche come operandi nelle espressioni nello stesso modo in cui vengono utilizzati i loro oggetti dati principali.

Example

reg [7:0] x, y; 
reg [3:0] z; 
reg a; 
a = x[7] & y[7];      // bit-selects 
z = x[7:4] + y[3:0];  // part-selects

Chiamate di funzione

Nelle chiamate di funzione, il valore di ritorno di una funzione viene utilizzato direttamente in un'espressione senza la necessità di assegnarlo prima a un registro oa un cavo. Posiziona semplicemente la chiamata di funzione come uno dei tipi di operandi. È necessario per assicurarti di conoscere la larghezza di bit del valore di ritorno della chiamata di funzione.

Example  
Assign x = y & z & chk_yz(z, y); // chk_yz is a function 

. . ./* Definition of the function */ 
Function chk_yz; // function definition 
Input z,y; 
chk_yz = y^z; 
End function

Moduli

Dichiarazione del modulo

In Verilog, un modulo è l'entità di progettazione principale. Indica il nome e l'elenco delle porte (argomenti). Le prossime righe che specificano il tipo di input / output (input, output o inout) e la larghezza di ciascuna porta. La larghezza della porta predefinita è solo 1 bit. Le variabili di porta devono essere dichiarate tramite filo, bacchetta magica ,. . ., reg. La variabile di porta predefinita è wire. Normalmente, gli ingressi sono cablati perché i loro dati sono bloccati all'esterno del modulo. Le uscite sono di tipo reg se i loro segnali sono memorizzati all'interno.

Example

module sub_add(add, in1, in2, out); 
input add; // defaults to wire 
input [7:0] in1, in2; wire in1, in2; 

output [7:0] out; reg out; 
... statements ... 
End module

Assegnazione continua

L'assegnazione continua in un modulo viene utilizzata per assegnare un valore a un filo, che è l'assegnazione normale utilizzata al di fuori dei blocchi sempre o iniziali. Questa assegnazione viene eseguita con un'istruzione di assegnazione esplicita o per assegnare un valore a un filo durante la sua dichiarazione. L'assegnazione continua viene eseguita continuamente al momento della simulazione. L'ordine delle istruzioni assign non lo influenza. Se si modifica un qualsiasi segnale di ingresso sul lato destro, cambierà un segnale di uscita sul lato sinistro.

Example

Wire [1:0] x = 2’y01;   // assigned on declaration 
Assign y = c | d;       // using assign statement 
Assign d = a & b; 
/* the order of the assign statements does not matter. */

Istanze del modulo

Le dichiarazioni dei moduli sono modelli per la creazione di oggetti reali. I moduli vengono istanziati all'interno di altri moduli e ogni istanziazione crea un singolo oggetto da quel modello. L'eccezione è il modulo di primo livello che è la propria istanza. Le porte del modulo devono essere abbinate a quelle definite nel modello. È specificato -

  • By name, utilizzando un punto ".template port name (nome del filo connesso alla porta)". O

  • By position, posizionando le porte nella stessa posizione negli elenchi delle porte sia del modello che dell'istanza.

Example

MODULE DEFINITION 
Module and4 (x, y, z); 
Input [3:0] x, y; 
Output [3:0] z; 
Assign z = x | y; 
End module

I modelli comportamentali in Verilog contengono istruzioni procedurali, che controllano la simulazione e manipolano le variabili dei tipi di dati. Tutte queste dichiarazioni sono contenute nelle procedure. A ciascuna procedura è associato un flusso di attività.

Durante la simulazione del modello comportamentale, tutti i flussi definiti dalle istruzioni "sempre" e "iniziale" iniziano insieme al tempo di simulazione "zero". Le istruzioni iniziali vengono eseguite una volta e le istruzioni always vengono eseguite ripetutamente. In questo modello, le variabili di registro a e b vengono inizializzate rispettivamente a 1 e 0 binari al tempo di simulazione "zero". L'istruzione iniziale viene quindi completata e non viene eseguita nuovamente durante l'esecuzione della simulazione. Questa istruzione iniziale contiene un blocco di inizio-fine (chiamato anche blocco sequenziale) di istruzioni. In questo blocco di tipo inizio-fine, a viene inizializzato per primo seguito da b.

Esempio di modellazione comportamentale

module behave; 
reg [1:0]a,b; 

initial 
begin 
   a = ’b1; 
   b = ’b0; 
end 

always 
begin 
   #50 a = ~a; 
end 

always 
begin 
   #100 b = ~b; 
end 
End module

Incarichi procedurali

Le assegnazioni procedurali servono per l'aggiornamento delle variabili reg, integer, time e memory. C'è una differenza significativa tra assegnazione procedurale e assegnazione continua come descritto di seguito -

Le assegnazioni continue guidano le variabili nette e vengono valutate e aggiornate ogni volta che un operando di input cambia valore.

Le assegnazioni procedurali aggiornano il valore delle variabili di registro sotto il controllo dei costrutti di flusso procedurale che le circondano.

Il lato destro di un'assegnazione procedurale può essere qualsiasi espressione che restituisce un valore. Tuttavia, le selezioni parziali sul lato destro devono avere indici costanti. Il lato sinistro indica la variabile che riceve l'assegnazione dal lato destro. Il lato sinistro di un incarico procedurale può assumere una delle seguenti forme:

  • register, integer, real o time variable - Un'assegnazione al riferimento al nome di uno di questi tipi di dati.

  • selezione di bit di una variabile di registro, numero intero, reale o tempo - Un'assegnazione a un singolo bit che lascia inalterati gli altri bit.

  • selezione parziale di una variabile di registro, numero intero, reale o tempo - Una selezione parziale di due o più bit contigui che lascia il resto dei bit intatti. Per il modulo di selezione parziale, solo le espressioni costanti sono legali.

  • elemento di memoria - Una singola parola di un ricordo. Notare che le selezioni di bit e di parte non sono valide sui riferimenti agli elementi di memoria.

  • concatenazione di uno qualsiasi dei precedenti - È possibile specificare una concatenazione di una qualsiasi delle quattro forme precedenti, che partiziona efficacemente il risultato dell'espressione a destra e assegna le parti di partizione, in ordine, alle varie parti della concatenazione.

Ritardo nell'assegnazione (non per la sintesi)

In un'assegnazione ritardata Δt le unità di tempo passano prima che l'istruzione venga eseguita e l'assegnazione a sinistra venga eseguita. Con il ritardo intra-assegnazione, il lato destro viene valutato immediatamente ma c'è un ritardo di Δt prima che il risultato venga posizionato nell'assegnazione a sinistra. Se un'altra procedura cambia un segnale del lato destro durante Δt, non ha effetto sull'uscita. I ritardi non sono supportati dagli strumenti di sintesi.

Sintassi

  • Procedural Assignmentvariabile = espressione

  • Delayed assignment# Δt variabile = espressione;

  • Intra-assignment delayvariabile = # Δt espressione;

Esempio

reg [6:0] sum; reg h, ziltch; 
sum[7] = b[7] ^ c[7]; // execute now. 
ziltch = #15 ckz&h; /* ckz&a evaluated now; ziltch changed 
after 15 time units. */ 

#10 hat = b&c; /* 10 units after ziltch changes, b&c is
evaluated and hat changes. */

Assegnazioni di blocco

Un'istruzione di assegnazione procedurale di blocco deve essere eseguita prima dell'esecuzione delle istruzioni che la seguono in un blocco sequenziale. Un'istruzione di assegnazione procedurale di blocco non impedisce l'esecuzione di istruzioni che la seguono in un blocco parallelo.

Sintassi

La sintassi per un'assegnazione procedurale di blocco è la seguente:

<lvalue> = <timing_control> <expression>

Dove, lvalue è un tipo di dati valido per un'istruzione di assegnazione procedurale, = è l'operatore di assegnazione e il controllo del tempo è il ritardo facoltativo all'interno dell'assegnazione. Il ritardo del controllo di temporizzazione può essere un controllo di ritardo (ad esempio, # 6) o un controllo di evento (ad esempio, @ (posedge clk)). L'espressione è il valore del lato destro che il simulatore assegna al lato sinistro. L'operatore = assegnazione utilizzato per bloccare le assegnazioni procedurali viene utilizzato anche dalle assegnazioni procedurali continue e dalle assegnazioni continue.

Esempio

rega = 0; 
rega[3] = 1;            // a bit-select 
rega[3:5] = 7;          // a part-select 
mema[address] = 8’hff;  // assignment to a memory element 
{carry, acc} = rega + regb;  // a concatenation

Assegnazioni non bloccanti (RTL)

L'assegnazione procedurale non bloccante consente di pianificare le assegnazioni senza bloccare il flusso procedurale. È possibile utilizzare l'istruzione procedurale non bloccante ogni volta che si desidera eseguire più assegnazioni di registro nello stesso passaggio temporale senza riguardo all'ordine o alla dipendenza l'una dall'altra.

Sintassi

La sintassi per un'assegnazione procedurale non bloccante è la seguente:

<lvalue> <= <timing_control> <expression>

Dove lvalue è un tipo di dati valido per un'istruzione di assegnazione procedurale, <= è l'operatore di assegnazione non bloccante e il controllo del tempo è il controllo del tempo intra-assegnazione opzionale. Il ritardo del controllo di temporizzazione può essere un controllo di ritardo o un controllo di evento (ad esempio, @ (posedge clk)). L'espressione è il valore del lato destro che il simulatore assegna al lato sinistro. L'operatore di assegnazione non bloccante è lo stesso operatore utilizzato dal simulatore per l'operatore relazionale minore di uguale. Il simulatore interpreta l'operatore <= come un operatore relazionale quando lo si utilizza in un'espressione e interpreta l'operatore <= come un operatore di assegnazione quando lo si utilizza in un costrutto di assegnazione procedurale non bloccante.

Modalità di valutazione delle assegnazioni procedurali non bloccanti da parte del simulatore Quando il simulatore incontra un'assegnazione procedurale non bloccante, il simulatore valuta ed esegue l'assegnazione procedurale non bloccante in due fasi come segue:

  • Il simulatore valuta il lato destro e pianifica l'assegnazione del nuovo valore in modo che avvenga in un momento specificato da un controllo di temporizzazione procedurale. Il simulatore valuta il lato destro e pianifica l'assegnazione del nuovo valore in modo che avvenga in un momento specificato da un controllo di temporizzazione procedurale.

  • Al termine della fase temporale, in cui è scaduto il ritardo specificato o si è verificato l'evento appropriato, il simulatore esegue l'assegnazione assegnando il valore al lato sinistro.

Esempio

module evaluates2(out); 
output out; 
reg a, b, c; 
initial 

begin 
   a = 0; 
   b = 1; 
   c = 0; 
end 
always c = #5 ~c; 
always @(posedge c) 

begin 
   a <= b; 
   b <= a; 
end 
endmodule

Condizioni

L'istruzione condizionale (o l'istruzione if-else) viene utilizzata per decidere se un'istruzione viene eseguita o meno.

Formalmente, la sintassi è la seguente:

<statement> 
::= if ( <expression> ) <statement_or_null> 
||= if ( <expression> ) <statement_or_null> 
   else <statement_or_null> 
<statement_or_null> 

::= <statement> 
||= ;

L '<espressione> viene valutata; se è vero (cioè ha un valore noto diverso da zero), viene eseguita la prima istruzione. Se è falso (ha un valore zero o il valore è xoz), la prima istruzione non viene eseguita. Se è presente un'istruzione else e <expression> è falsa, viene eseguita l'istruzione else. Poiché il valore numerico dell'espressione if viene verificato per essere zero, sono possibili alcune scorciatoie.

Ad esempio, le due affermazioni seguenti esprimono la stessa logica:

if (expression) 
if (expression != 0)

Poiché la parte else di un if-else è facoltativa, può esserci confusione quando un'altra parte viene omessa da una sequenza if nidificata. Questo viene risolto associando sempre l'altro con il precedente più vicino se manca un altro.

Esempio

if (index > 0) 
if (rega > regb) 
   result = rega; 
   else // else applies to preceding if 
   result = regb; 

If that association is not what you want, use a begin-end block statement 
to force the proper association 

if (index > 0) 
begin 

if (rega > regb) 
result = rega; 
end 
   else 
   result = regb;

Costruzione di: if-else- if

La seguente costruzione si verifica così spesso che merita una breve discussione separata.

Example

if (<expression>) 
   <statement> 
   else if (<expression>) 
   <statement> 
   else if (<expression>) 
   <statement> 
   else  
   <statement>

Questa sequenza di if (nota come costrutto if-else-if) è il modo più generale di scrivere una decisione a più vie. Le espressioni vengono valutate in ordine; se una qualsiasi espressione è vera, viene eseguita l'istruzione ad essa associata e ciò termina l'intera catena. Ogni affermazione è una singola affermazione o un blocco di istruzioni.

L'ultima parte del costrutto if-else-if gestisce il caso "nessuno dei precedenti" o predefinito in cui nessuna delle altre condizioni è stata soddisfatta. A volte non esiste un'azione esplicita per l'impostazione predefinita; in tal caso, il trailing else può essere omesso o può essere utilizzato per il controllo degli errori per catturare una condizione impossibile.

Dichiarazione del caso

L'istruzione case è una speciale istruzione decisionale a più vie che verifica se un'espressione corrisponde a una delle numerose altre espressioni e si ramifica di conseguenza. L'istruzione case è utile per descrivere, ad esempio, la decodifica di un'istruzione del microprocessore. L'istruzione case ha la seguente sintassi:

Example

<statement> 
::= case ( <expression> ) <case_item>+ endcase 
||= casez ( <expression> ) <case_item>+ endcase 
||= casex ( <expression> ) <case_item>+ endcase 
<case_item> 
::= <expression> <,<expression>>* : <statement_or_null> 
||= default : <statement_or_null> 
||= default <statement_or_null>

Le espressioni del caso vengono valutate e confrontate nell'ordine esatto in cui sono fornite. Durante la ricerca lineare, se una delle espressioni dell'elemento del caso corrisponde all'espressione tra parentesi, viene eseguita l'istruzione associata a quell'elemento del caso. Se tutti i confronti falliscono e viene fornito l'elemento predefinito, viene eseguita l'istruzione dell'elemento predefinito. Se l'istruzione predefinita non viene fornita e tutti i confronti hanno esito negativo, non viene eseguita nessuna delle istruzioni dell'elemento case.

A parte la sintassi, l'istruzione case differisce dal costrutto a più vie if-else-if in due modi importanti:

  • Le espressioni condizionali nel costrutto if-else-if sono più generali del confronto di un'espressione con molte altre, come nell'istruzione case.

  • L'istruzione case fornisce un risultato definitivo quando ci sono valori xez in un'espressione.

Dichiarazioni di ciclo

Esistono quattro tipi di istruzioni di ciclo. Forniscono un mezzo per controllare l'esecuzione di un'istruzione zero, una o più volte.

  • per sempre esegue continuamente un'istruzione.

  • repeat esegue un'istruzione un numero fisso di volte.

  • while esegue un'istruzione finché un'espressione non diventa falsa. Se l'espressione inizia falsa, l'istruzione non viene eseguita affatto.

  • per controllare l'esecuzione delle sue istruzioni associate mediante un processo in tre fasi, come segue:

    • Esegue un'assegnazione normalmente utilizzata per inizializzare una variabile che controlla il numero di cicli eseguiti

    • Valuta un'espressione: se il risultato è zero, il ciclo for termina e, se non è zero, il ciclo for esegue le istruzioni associate e quindi esegue il passaggio 3

    • Esegue un'assegnazione normalmente utilizzata per modificare il valore della variabile loopcontrol, quindi ripete il passaggio 2

Le seguenti sono le regole di sintassi per le istruzioni di ciclo:

Example

<statement> 
::= forever <statement> 
||=forever 
begin 
   <statement>+ 
end  

<Statement> 
::= repeat ( <expression> ) <statement> 
||=repeat ( <expression> ) 
begin
   <statement>+ 
end  

<statement> 
::= while ( <expression> ) <statement> 
||=while ( <expression> ) 
begin 
   <statement>+ 
end  
<statement> 
::= for ( <assignment> ; <expression> ; <assignment> ) 
<statement> 
||=for ( <assignment> ; <expression> ; <assignment> ) 
begin 
   <statement>+ 
end

Controlli del ritardo

Controllo del ritardo

L'esecuzione di un'istruzione procedurale può essere controllata in base al ritardo utilizzando la seguente sintassi:

<statement> 
::= <delay_control> <statement_or_null> 
<delay_control> 
::= # <NUMBER> 
||= # <identifier> 
||= # ( <mintypmax_expression> )

Il seguente esempio ritarda l'esecuzione dell'assegnazione di 10 unità di tempo -

# 10 rega = regb;

I prossimi tre esempi forniscono un'espressione che segue il segno del numero (#). L'esecuzione dei ritardi di assegnazione della quantità di tempo di simulazione specificato dal valore dell'espressione.

Controllo degli eventi

L'esecuzione di un'istruzione procedurale può essere sincronizzata con un cambio di valore su una rete o registro, o il verificarsi di un evento dichiarato, utilizzando la seguente sintassi di controllo degli eventi:

Example

<statement> 
::= <event_control> <statement_or_null> 

<event_control> 
::= @ <identifier> 
||= @ ( <event_expression> ) 

<event_expression> 
::= <expression> 
||= posedge <SCALAR_EVENT_EXPRESSION> 
||= negedge <SCALAR_EVENT_EXPRESSION> 
||= <event_expression> <or <event_expression>>

* <SCALAR_EVENT_EXPRESSION> è un'espressione che si risolve in un valore di un bit.

Le modifiche ai valori su reti e registri possono essere utilizzate come eventi per attivare l'esecuzione di un'istruzione. Questo è noto come rilevamento di un evento implicito. La sintassi di Verilog consente inoltre di rilevare il cambiamento in base alla direzione del cambiamento, cioè verso il valore 1 (posedge) o verso il valore 0 (negedge). Il comportamento di posedge e negedge per i valori di espressioni sconosciute è il seguente:

  • viene rilevato un negedge sulla transizione da 1 a sconosciuto e da sconosciuto a 0
  • viene rilevato un posedge sulla transizione da 0 a sconosciuto e da sconosciuto a 1

Procedure: blocchi sempre e iniziali

Tutte le procedure in Verilog sono specificate all'interno di uno dei seguenti quattro blocchi. 1) Blocchi iniziali 2) Blocchi sempre 3) Task 4) Funzione

Le istruzioni initial e always sono abilitate all'inizio della simulazione. I blocchi iniziali vengono eseguiti una sola volta e la sua attività termina quando l'istruzione è terminata. Al contrario, il blocco sempre viene eseguito ripetutamente. La sua attività muore solo quando la simulazione è terminata. Non c'è limite al numero di blocchi iniziali e sempre che possono essere definiti in un modulo. Le attività e le funzioni sono procedure abilitate da una o più posizioni in altre procedure.

Blocchi iniziali

La sintassi per l'istruzione iniziale è la seguente:

<initial_statement> 
::= initial <statement>

Il seguente esempio illustra l'uso dell'istruzione iniziale per l'inizializzazione delle variabili all'inizio della simulazione.

Initial 
Begin 
   Areg = 0; // initialize a register 
   For (index = 0; index < size; index = index + 1) 
   Memory [index] = 0; //initialize a memory 
   Word 
End

Un altro utilizzo tipico dei blocchi iniziali è la specifica delle descrizioni delle forme d'onda che vengono eseguite una volta per fornire uno stimolo alla parte principale del circuito simulato.

Initial 
Begin 
   Inputs = ’b000000; 
   // initialize at time zero 
   #10 inputs = ’b011001; // first pattern 
   #10 inputs = ’b011011; // second pattern 
   #10 inputs = ’b011000; // third pattern 
   #10 inputs = ’b001000; // last pattern 
End

Blocca sempre

L'istruzione "sempre" si ripete continuamente durante l'intera esecuzione della simulazione. La sintassi per l'istruzione always è fornita di seguito

<always_statement> 
::= always <statement>

L'istruzione "sempre", a causa della sua natura a ciclo continuo, è utile solo se utilizzata insieme a qualche forma di controllo del tempo. Se un'istruzione "always" non fornisce alcun mezzo per far avanzare il tempo, l'istruzione "always" crea una condizione di deadlock di simulazione. Il codice seguente, ad esempio, crea un ciclo infinito a ritardo zero:

Always areg = ~areg;

Fornire un controllo di temporizzazione al codice precedente crea una descrizione potenzialmente utile, come nell'esempio seguente:

Always #half_period areg = ~areg;