SystemVerilog: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
Sistemazione dei riferimenti e delle categorie |
m Typo fixing |
||
Riga 21:
== Storia ==
SystemVerilog nasce con la donazione del linguaggio Superlog ad Accellera nel 2002 da parte della startup Co-Design Automation.<ref>Rich, D. “The evolution of SystemVerilog” IEEE Design and Test of Computers, July/August 2003</ref> La maggior parte delle funzionalità di verifica si basa sul linguaggio OpenVera donato da Synopsys
Il set di funzionalità di SystemVerilog può essere suddiviso in due ruoli distinti:
Riga 28:
# SystemVerilog per la verifica: utilizza estesamente tecniche [[Programmazione orientata agli oggetti|di programmazione orientate agli oggetti]] ed è più strettamente correlato a [[Java (linguaggio di programmazione)|Java]] rispetto a Verilog. Questi costrutti generalmente non sono sintetizzabili.
Il resto di questo articolo discute le caratteristiche di SystemVerilog non presenti in [[Verilog|Verilog-2005]]
== Caratteristiche a supporto della progettazione ==
=== Durata delle variabili ===
Esistono due tipi di durata delle variabili specificate in SystemVerilog: static e automatic
Qualsiasi variabile dichiarata all'interno di un task o di una funzione senza specificare il tipo verrà considerata automatica. Per specificare che una variabile è statica si utilizza la [[Parola riservata|parola chiave]] <code>static</code> nella dichiarazione del tipo, ad esempio <code>static int x;</code>. La parola chiave <code>automatic</code> " viene utilizzata allo stesso modo.
Riga 46:
</syntaxhighlight>Il Verilog classico consente di dichiarare solo una dimensione a sinistra del nome della variabile. SystemVerilog consente qualsiasi numero di tali dimensioni "impacchettate". Una variabile di tipo array compresso mappa 1:1 su una quantità aritmetica intera. Nell'esempio precedente, ogni elemento di <code>my_pack</code> può essere utilizzato nelle espressioni come numero intero a sei bit. Le dimensioni a destra del nome (32 in questo caso) sono indicate come dimensioni "unpacked". Come in [[Verilog|Verilog-2001]], è consentito qualsiasi numero di dimensioni unpacked.
'''I tipi di dati enumerati''' (
typedef enum logic [2:0] {
RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW
Riga 55:
</syntaxhighlight>Come mostrato sopra, il progettista può specificare un tipo aritmetico sottostante ( <code>logic [2:0]</code> in questo caso) che viene utilizzato per rappresentare il valore di enumerazione. I meta-valori X e Z possono essere usati qui, possibilmente per rappresentare stati illegali. La funzione <code>name()</code> restituisce una stringa ASCII per il valore enumerato corrente, utile per la convalida e il test.
'''Nuovi tipi interi'''
'''[[Record (informatica)|Le strutture]]''' e '''le unioni''' funzionano in modo molto simile al [[C (linguaggio)|linguaggio di programmazione C.]] I miglioramenti di SystemVerilog includono l'attributo '''packed''' e l'attributo '''tagged'''
typedef struct packed {
bit [10:0] expo;
Riga 75:
no_root = (tmp < 0);
end
</syntaxhighlight>Un blocco <code>always_latch</code> modella latch sensibili al livello
always_latch
if (en) q <= d;
Riga 130:
</syntaxhighlight>Un array dinamico funziona in modo molto simile a un array unpacked, ma offre il vantaggio di essere [[Gestione della memoria|allocato dinamicamente]] in [[Run-time|fase di esecuzione]] (come mostrato sopra. ) Mentre la dimensione di un packed array deve essere nota in fase di compilazione (da una costante o espressione di costanti), la dimensione dell'array dinamico può essere inizializzata da un'altra variabile, consentendo all'array di essere dimensionato e ridimensionato arbitrariamente secondo necessità.
Un array associativo può essere considerato come un [[Albero binario di ricerca|albero di ricerca binario]] con un tipo della chiave e un tipo dei dati specificati dall'utente
Infine, una coda fornisce gran parte delle funzionalità del tipo [[deque]] della [[Standard Template Library|Standard Template Library C++]]: gli elementi possono essere aggiunti e rimossi da entrambe le estremità in modo efficiente. Queste primitive consentono la creazione di strutture di dati complesse, necessarie ad esempio per lo scoreboard di un progetto di grandi dimensioni.
=== Classi ===
SystemVerilog fornisce un modello di [[Programmazione orientata agli oggetti|programmazione orientato agli oggetti]]
In SystemVerilog, le classi supportano un modello [[Ereditarietà multipla|di ereditarietà singola]], ma possono implementare funzionalità simili all'ereditarietà multipla attraverso l'uso delle cosiddette "classi di interfaccia" (identiche nel concetto alla funzionalità <code>interface</code> di Java). Le classi possono essere parametrizzate per tipo, fornendo la funzione di base dei template C++
Le funzionalità [[Polimorfismo (informatica)|di polimorfismo]] di SystemVerilog sono simili a quelle di C++: il programmatore può definire una funzione <code>virtual</code> per fare in modo che una classe derivata [[Funzione virtuale|ottenga il controllo della funzione]].
Riga 143:
[[Incapsulamento (informatica)|L'incapsulamento]] e l'occultamento dell'informazione (''information hiding'') vengono eseguiti utilizzando le parole chiave <code>local</code> e <code>protected</code>, che devono essere applicate a qualsiasi elemento che deve essere nascosto. Per impostazione predefinita, tutte le proprietà della classe sono pubbliche.
Le istanze delle classi vengono create dinamicamente con laparola chiave <code>new</code>. È possibile definire un [[Costruttore (informatica)|costruttore]] denotandolo come <code>function new</code>
Ad esempio:<syntaxhighlight lang="systemverilog" line="1">
Riga 165:
=== Constrained random generation ===
Alle quantità intere, definite nella definizione di una classe o come variabili autonome in un certo scope lessicale, possono essere [[Generatore di numeri casuali|assegnati valori casuali]] sulla base di un insieme di vincoli. Questa funzionalità è utile per creare scenari randomizzati per la verifica
Nella definizione di una classe, i modificatori <code>rand</code> e <code>randc</code> segnalano le variabili che devono essere randomizzate. <code>randc</code> specifica che la randomizzazione deve essere basata sulla [[permutazione]], in cui una variabile assumerà tutti i possibili valori almeno una volta prima che qualsiasi valore venga ripetuto. Le variabili senza modificatori non sono randomizzate.<syntaxhighlight lang="systemverilog" line="1">
Riga 241:
Le [[Asserzione (informatica)|asserzioni]] sono utili per verificare le proprietà di un progetto che si manifestano dopo che è stata raggiunta una condizione o uno stato specifico. SystemVerilog ha un proprio linguaggio di specifica delle asserzioni, simile al Property Specification Language. Il sottoinsieme dei costrutti del linguaggio SystemVerilog che supporta le asserzioni è comunemente chiamato SystemVerilog Assertion o SVA.<ref>[http://www.project-veripage.com/sva_1.php SystemVerilog Assertion: Introduction]</ref>
Le asserzioni SystemVerilog sono costruite da '''sequenze''' e '''proprietà'''
Le sequenze sono costituite da [[Espressione booleana|espressioni booleane]] aumentate con operatori temporali. L'operatore temporale più semplice è l'operatore <code>##</code> che esegue una concatenazione: <syntaxhighlight lang="systemverilog" line="1">
Riga 257:
assert_req_gnt: assert property (req_gnt) else $error("req not followed by gnt.");
</syntaxhighlight>Questo esempio mostra un operatore '''[[Implicazione logica|di implicazione]]''' <code>|=></code>
Oltre alle asserzioni, SystemVerilog supporta [[Presupposizione (linguistica)|le ipotesi]] e la copertura delle proprietà. Un'assunzione stabilisce una condizione che uno [[Dimostrazione automatica di teoremi|strumento]] [[Logica|formale di dimostrazione logica]] [[Assioma (matematica)|deve assumere come vera]]
=== Copertura ===
'''La copertura''' (''coverage'') applicata ai linguaggi di verifica hardware si riferisce alla raccolta di statistiche basate su eventi di campionamento all'interno della simulazione. La copertura viene utilizzata per determinare quando il dispositivo sottoposto a test (DUT) è stato esposto a una varietà sufficiente di stimoli tale che vi sia un'elevata probabilità che il DUT funzioni correttamente. Si noti che questo differisce dalla copertura del codice che utilizza il codice del progetto per garantire che tutte le righe del codice nel progetto siano state eseguite. La copertura funzionale assicura che tutti i casi corner e marginali desiderati all'interno dello spazio di progettazione siano stati esplorati
Un gruppo di copertura SystemVerilog crea un database di "contenitori" (''bin'') che memorizzano un [[istogramma]] di valori di una variabile associata. È inoltre possibile definire la copertura incrociata, che crea un istogramma che rappresenta il [[prodotto cartesiano]] di più variabili.
Riga 291:
=== Sincronizzazione ===
Un ambiente di test complesso è costituito da componenti di verifica riutilizzabili che devono comunicare tra loro. La primitiva "event" di Verilog consente a diversi blocchi di istruzioni procedurali di attivarsi a vicenda, ma l'applicazione [[Sincronizzazione|della sincronizzazione]] dei thread dipende dall'uso (intelligente) da parte del programmatore. SystemVerilog offre due [[Sincronizzazione|primitive]] specifiche per la sincronizzazione tra thread: ''mailbox'' e ''[[Semaforo (informatica)|semaphore]]''. La mailbox è modellata come una coda di messaggi [[FIFO]]
== Miglioramenti generali al Verilog classico ==
Oltre alle nuove funzionalità di cui sopra, SystemVerilog migliora l'usabilità delle funzionalità linguistiche esistenti di Verilog. Di seguito sono riportati alcuni di questi miglioramenti:
* Gli [[Operatore di assegnamento|operatori di assegnazione]] procedurale (<=, =) ora possono operare direttamente sugli array
* Le definizioni delle porte (inout, input, output) sono ora espanse per supportare una più ampia varietà di [[Tipo di dato|tipi di dati]] : sono supportati i tipi [[Record (informatica)|struct]], enum, real e multidimensionali.
* Il costrutto [[Ciclo for|del ciclo for]] ora consente la dichiarazione automatica delle variabili all'interno dell'istruzione for. [[Struttura di controllo|Il controllo del flusso]] del ciclo è migliorato dalle [[Struttura di controllo|istruzioni ''continue'' e ''break'']]
* SystemVerilog aggiunge un <nowiki><i id="mwBhw">ciclo do</i></nowiki> /while al costrutto del ciclo <nowiki><i id="mwBh4"><u id="mwBh8">while</u></nowiki><nowiki></i></nowiki>
* [[Costante (informatica)|Le variabili costanti]], cioè quelle designate come non modificabili durante il runtime, possono essere designate mediante l'uso della parola chiave ''const''
* [[Inizializzazione|L'inizializzazione delle variabili]] può operare sugli array.
* Gli operatori di incremento e decremento ( <code>x++</code>, <code>++x</code>, <code>x--</code>, <code>--x</code> ) sono supportati in SystemVerilog, così come altri operatori di assegnazione composti ( <code>x += a</code>, <code>x -= a</code>, <code>x *= a</code>, <code>x /= a</code>, <code>x %= a</code>, <code>x <<= a</code>, <code>x >>= a</code>, <code>x &= a</code>, <code>x ^= a</code>, <code>x |= a</code> ) come nel linguaggio C e linguaggi discendenti
* Il preprocessore ha migliorato le capacità di sostituzione [[Direttiva (programmazione)|di macro]] `define, in particolare la sostituzione all'interno di stringhe letterali (""), così come la concatenazione di più macro-token in una singola parola
* Il costrutto fork/join è stato espanso con ''join_none'' e ''join_any''
* Le aggiunte alla direttiva `timescale consentono di controllare la scala temporale della simulazione in modo più prevedibile in un ambiente di simulazione di grandi dimensioni, con ogni [[Codice sorgente|file sorgente]] che utilizza una scala temporale locale.
* Ora le porte delle attività possono essere dichiarate ''rif''
* Le funzioni ora possono essere dichiarate ''[[Void (informatica)|void]]'', il che significa che non restituiscono alcun valore.
* [[Parametro (programmazione)|I parametri]] possono essere dichiarati di qualsiasi tipo, inclusi ''typedef'' definiti dall'utente.
|