====== Verilog simulation tutorials ====== == Contents == * Getting started with Incisive tools * Running a Verilog 'Hello world!' * [[vlsi:workbook:digital:hdlsim:tutorials:inverter|Simulate a simple inverter gate in Verilog]] * Simulate a synchronizer ===== Getting started with Cadence Incisive tools ===== suite utilizzata: Incisive release 10.2 Documentazione in ''/usr/cadence/Incisive_10.20/doc'' Eseguibili in ''/usr/cadence/Incisive_10.20/tools/bin'' Incisive tutorial [[ http://www.ece.virginia.edu/~mrs8n/cadence/Simulation_Tutorial/sim_tutorial.html | here ]] Importante! Cadence stesso fornisce un tutorial! ''/usr/cadence/Incisive_10.20/doc/iustutorial'' cd ~/cadence/tutorial/incisive cp -r /usr/cadence/Incisive_10.20/doc/iustutorial/examples/files ./src Stating NCLaunch: nclaunch [options] & nclaunch -help nclaunch -help >> ./doc/nclaunch.help ===== Running a Verilog 'Hello world!' ===== Un semplice **hello world** program da runnare alla command line: // hello.v Verilog hello world program module hello; initial begin $display("Hello world! \n"); $finish; end endmodule E lo posso compilare/runnare da command line ad esempio richiamando Verilog-XL: verilog hello.v Questo produce un output del tipo Tool: VERILOG-XL 08.20.001-d Oct 22, 2012 00:31:41 Copyright (c) 1995-2004 Cadence Design Systems, Inc. All Rights Reserved. Unpublished -- rights reserved under the copyright laws of the United States. Copyright (c) 1995-2004 UNIX Systems Laboratories, Inc. Reproduced with Permission. THIS SOFTWARE AND ON-LINE DOCUMENTATION CONTAIN CONFIDENTIAL INFORMATION AND TRADE SECRETS OF CADENCE DESIGN SYSTEMS, INC. USE, DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF CADENCE DESIGN SYSTEMS, INC. RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure by the Government is subject to restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and (2) of Commercial Computer Software -- Restricted Rights at 48 CFR 52.227-19, as applicable. Cadence Design Systems, Inc. 555 River Oaks Parkway San Jose, California 95134 For technical assistance please contact the Cadence Response Center at 1-877-CDS-4911 or send email to support@cadence.com For more information on Cadence's Verilog-XL product line send email to talkv@cadence.com Compiling source file "hello.v" Highest level modules: hello Hello world! L8 "hello.v": $finish at simulation time 0 0 simulation events (use +profile or +listcounts option to count) CPU time: 0.0 secs to compile + 0.0 secs to link + 0.0 secs in simulation End of Tool: VERILOG-XL 08.20.001-d Oct 22, 2012 00:31:41 ====== A simple inverter Verilog tutorial ====== Bla bla bla click [[ incisive_tutorial_inverter | here ]] ====== Simulate a synchronizer ====== Bla bla bla click [[ incisive_tutorial_synchronizer | here ]] ====== A simple multiplexer ====== Bla bla bla click [[ incisive_tutorial_multiplexer | here ]] ====== Create a D Flip-Flop ====== Bla bla bla click [[ incisive_tutorial_dff | here ]] ====== RTL simulation using Verilog-XL compiler ====== Anziche' usare nclaunch posso usare **Verilog-XL** e visualizzare le forme d'onda con **SimVision** L'eseguibile e' sotto Incisive in ''$IUS_DIR/tools/bin/verilog'' verilog -help Documentazione (Verilog-XL User Guide) sotto ''$IUS_DIR/doc/vloguser'' Posso fare tutto senza gui con verilog main.v test_main.v Attenzione all'ordine! che conta! Pay attention when specifying the files names. The files have to be specified in a particular order such that the lower-level modules are compiled before the higher-level modules. The testbench would be the last item to be compiled. Oppure da Cadence IC posso usare la Verilog Integration offerta da IC: **CIW => Tools => NC-Verilog...** or from **Schematic Editor L => Launch => Simulation => NC-Verilog** {{:vlsi:virtuoso_ncverilog_integration.png}} Documentazione in (ncveruser.pdf): ''/usr/cadence/IC_6.1.5/doc/ncveruser'' web tutorial [[ http://nanolab.ece.tufts.edu/docs/tutorial/verilog.html | here ]] DFF example: // dff.v Verilog code `timescale 1ns/100ps module DFF(D, clk, Q); input D; input clk; output Q; reg Q; always @ (posedge clk) Q <= #2 D; endmodule MUX example: Senza ritardi: module MUX2(input A, B, select, output W); assign W = (A & ~select) | (B & select); endmodule Con i ritardi, per vedere i **glitches** `timescale 1ns/100ps module MUX2(input A, B, select, output W); assign #6 n = ~select; assign #3 m = A & select; assign #3 p = B & n; assign #2 W = m | p; endmodule Sincronizzatore: // synch.v Verilog code `timescale 1ns/100ps module SYNCHRONIZER(input clk, adata, output reg synchdata); always @ (posedge clk) if ( adata == 0) synchdata <= 0; else synchdata <= 1; endmodule ===== VHDL simulation examples ===== ==== A simple Shift Register (VHDL example) [IT] ==== (work in progress...) === Organizzazione del progetto === Come primo, lapalissiano, step c'è la decisione del progetto che vogliamo sviluppare in linguaggio VHDL; per iniziare svilupperemo in questo tutorial un semplice shift register che permetta di fare i primi passi nella progettazione su ASIC. Innanzitutto è necessario provvedere alla creazione di uno spazio in cui lavorare, organizzandolo al fine di evitare confusione tra i files che ci serviranno durante tutto il digitalflow. L'ordine è fondamentale per cui è molto importante fin da subito cercare di evitare mix di files per procedure differenti: questo ci eviterà in futuro di sprecare tempo prezioso (e.g. impiegabile nel debugging o nell'ottimizzazione del dispositivo) nella ricerca spasmodica di files. Un esempio potrebbe essere quello rappresentato in figura: {{ :vlsi:workbook:digital:albero1.png?600 }} All’interno della cartella ''projects'' è stata creata una cartella ''shiftregister'' che conterrà tutti files inerenti al nostro progetto (librerie della tecnologia usata escluse). Anche se non verranno usate nell’immediato, è conveniente iniziare a preparare anche le cartelle che saranno utili negli step successivi: nella cartella ''shiftregister'' infatti vediamo: * ''lec'' (//logic equivalence check//)\\ * ''pnr_shiftregister'' (ci servirà per il //place and route//)\\ * ''syn_shiftregister'' (ci serve per la //sintesi//, ed è la cartella che prenderemo in considerazione ora).\\ All’interno di ''syn_shiftregister'' prepariamo altre cartelle dall’uso non immediato: * ''db''\\ * ''netlist_in''\\ * ''netlist_out''\\ * ''reports''\\ * ''scripts''\\ * ''sdc''\\ * ''work''\\ Ci metteremo ora nella cartella ''netlist_in'' e qui prepareremo due files vuoti con estensione ''.vhd'': • il primo lo chiameremo **shiftregister.vhd** (sarà il file sorgente),\\ • il secondo **tb_shiftregister.vhd** (sarà il file di test bench).(( Nota: per facilitarci in seguito con simulazione e sintesi e nella distinzione a colpo d’occhio della tipologia dei files all’interno delle cartelle, è conveniente nominare il file di test bench come l’entity a cui si riferiscono precedendoli dal prefisso ''tb'' eventualmente numerato nel caso si vogliano utilizzare diversi test benches, come ad esempio **tb01_shiftregister.vhd**, **tb02_shiftregister.vhd**, **tb350_shiftregister.vhd** etc. Qui svilupperemo solo un test bench, per cui il nome non appare dotato di numerazione.)) \\ === Schematizzazione del progetto e implementazione in VHDL === È fondamentale che sia ben chiaro l’obiettivo che si deve raggiungere. È buona norma quindi schematizzare ciò che vogliamo ottenere dal nostro progetto e le modalità di costruzione dello stesso da un punto di vista logico. Ad esempio, possiamo pensare di voler realizzare uno shift register; decidiamo che nè gli ingressi nè e le uscite debbano essere dei bus, per cui sono tutti definiti come ingressi/uscite standard logic. {{ :vlsi:workbook:digital:sr_scheme.png?400 }} Decidiamo in questo frangente se vogliamo usare una logica positiva oppure negativa: nel nostro caso il caso logico TRUE è 1, il caso logico FALSE è 0 (logica positiva). Per cui sarà a 1 l’uscita TRUE mentre le altre saranno a 0 (FALSE). Scriviamo quindi il modello VHDL comprensivo del processo che ci permette di selezionare l’output corretto: -- ********************************************* -- Title : 3-bit Shift-Register -- Author : Serena Panati -- File : shiftregister.vhd -- Version : 1.0 -- Generated : 09.03.2013 -- ********************************************* ---------------------------------------- -- Libraries ---------------------------------------- library ieee ; use ieee.std_logic_1164.all; ---------------------------------------- -- Entity declaration ---------------------------------------- entity shiftregister is port( data_in: in std_logic; sr_clock: in std_logic; shift: in std_logic; Q: out std_logic ); end shiftregister; ---------------------------------------- -- Architecture ---------------------------------------- architecture shiftregister_archi of shiftregister is -- inizializzazione del segnale S signal S: std_logic_vector(2 downto 0):="111"; begin process(data_in, sr_clock, shift, S) begin if sr_clock'event and sr_clock='1' then if shift = '1' then S(0) <= data_in; S(2 downto 1) <= S(1 downto 0); end if; end if; end process; Q <= S(2); end shiftregister_archi; ---------------------------------------- -- EoF ---------------------------------------- e lo salviamo. === Test bench === A questo punto è necessario preparare un file di test bench per lo shift register. Per farlo utilizziamo l’altro file vuoto precedentemente creato. -- ********************************************* -- Title : TB 3-bit Shift-Register -- Author : Serena Panati -- File : tb_shiftregister.vhd -- Version : 1.0 -- Generated : 09.03.2013 -- ********************************************* ---------------------------------------- -- Libraries ---------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; ---------------------------------------- -- Entity declaration ---------------------------------------- entity tb_shiftregister is generic ( clock_period : time := 10 ns); end tb_shiftregister; ---------------------------------------- -- Architecture ---------------------------------------- architecture tb_shiftregister_archi of tb_shiftregister is component shiftregister port( data_in: in std_logic; sr_clock: in std_logic; shift: in std_logic; Q: out std_logic ); end component; signal T_data_in: std_logic; signal T_sr_clock: std_logic; signal T_shift: std_logic; signal T_Q: std_logic; begin instance_shiftregister: shiftregister port map ( data_in => T_data_in, sr_clock => T_sr_clock, shift => T_shift, Q => T_Q); ---------------------------------------- -- clk generating process ---------------------------------------- generate_clock : process begin T_sr_clock <= '1'; wait for clock_period/2; T_sr_clock <= '0'; wait for clock_period/2; end process; ---------------------------------------- -- Values generating process ---------------------------------------- process begin wait for clock_period; T_shift <= '1'; T_data_in <= '0'; wait for clock_period; T_data_in<= '1'; wait for clock_period; T_data_in <= '0'; wait for clock_period; T_data_in <= '1'; wait for clock_period; assert FALSE report "End of simulation" severity FAILURE; end process; ---------------------------------------- end tb_shiftregister_archi; ---------------------------------------- -- Configuration File ---------------------------------------- configuration tbc_shiftregister_archi of tb_shiftregister is for tb_shiftregister_archi for all: shiftregister use entity work.shiftregister(shiftregister_archi); end for; end for; end tbc_shiftregister_archi ; ---------------------------------------- -- EoF ---------------------------------------- All’interno del test bench viene istanziato il componente che vogliamo simulare (in questo caso, l’unico componente, ma il VHDL permette l’istanziazione di molto componenti nel medesimo test bench), vengono dichiarati i segnali interni, la mappatura porta-segnale, il processo di iniezione di valori negli ingressi; nell’esempio è stata attivata l’azione di shift e ad intervalli di un periodo di clock sono stati inseriti alcuni valori di ingresso al registro (0 → 1 → 0 → 1) (vedi figura seguente)). {{ :vlsi:workbook:digital:reg.png?300 }} La riga assert FALSE report "End of simulation" severity FAILURE; rappresenta un trucco per far sì che la simulazione si blocchi al termine dell’ultimo valore forzato negli ingressi, senza dover stoppare la simulazione dall’interfaccia grafica del simulatore di Cadence. L’ultima parte riguarda il file di configurazione che collega ogni componente alla sua entity. ---------------------------------------- -- Configuration File ---------------------------------------- configuration tbc_shiftregister_archi of tb_shiftregister is for tb_shiftregister_archi for all: shiftregister use entity work.shiftregister(shiftregister_archi); end for; end for; end tbc_shiftregister_archi ; === Simulazione === Per la simulazione useremo i tools di Cadence NCLaunch e SimVision. Dalla home ci spostiamo nella cartella ''netlist_in'' cd projects/shiftregister/syn_shiftregister/netlist_in/ e digitiamo cdsterm e facciamo Invio; alla richiesta di quale tool usare scriviamo 1d e di nuovo Invio; selezioniamo poi la tecnologia che vogliamo usare; nell’esempio, Tower Jazz, perciò 5a e Invio. Nel nuovo terminale apertosi, digitiamo nclaunch & e Invio, e si aprirà la finestra a sfondo grigio mostrata in figura. {{ :vlsi:workbook:digital:nclaunch01.png?600 }} Ora, cliccando due volte direttamente su **shiftregister.vhd** (colonna a sinistra) (oppure cliccandoci sopra selezionandolo e successivamente cliccando sul tasto VHDL, cioè l’icona nella barra degli strumenti con un simbolo di ingranaggio meccanico) si compila il file. In basso, nella console, comparirà lo script del comando appena lanciato, segnali di errore (qualora ce ne fossero), uso di memoria e CPU; nel nostro caso, ad esempio: nclaunch> ncvhdl -work worklib -cdslib /export/elt78xl/disk0/users/panati/ projects/shiftregister/syn_shiftregister/netlist_in/cds.lib -logfile ncvhdl.log -errormax 15 -update -linedebug -status /export/elt78xl/ disk0/users/panati/projects/shiftregister/syn_shiftregister/ netlist_in/shiftregister.vhd ncvhdl(64): 10.20-s073: (c) Copyright 1995-2011 Cadence Design Systems, Inc. ncvhdl_p: Memory Usage - 10.4M program + 13.2M data = 23.6M total ncvhdl_cg: Memory Usage - 7.6M program + 10.7M data = 18.3M total ncvhdl: CPU Usage - 0.0s system + 0.0s user = 0.0s total (0.3s, 8.7% cpu) Vale lo stesso procedimento per il file di test bench; doppio click sul file (o selezione del file e successivo click sul tasto VHDL) e medesimo controllo nella console. Nel caso di errori, ad esempio dimenticando nella riga 49 del test bench il punto e virgola finale: T_sr_clock <= ’1’ anziché T_sr_clock <= ’1’ ; la console restituisce una serie di linee di errore recanti la tipologia (//expeting semicolon//) e la riga (49). {{ :vlsi:workbook:digital:consoleconsenzaerrori.png?600 }} In questo modo è possibile debuggare i due codici fino a quando non sono completamente privi di errori. A questo punto si passa all’elaborazione; nella colonna più a destra, sotto la cartella ''worklib'', compaiono tre simboli di circuito integrato, recanti la scritta: * **shiftregister** \\ * **tb_shiftregister** \\ * **tbc_shiftregister** \\ selezioniamo col mouse **tbc_shiftregister** (file di configurazione) e clicchiamo sul simbolo di elaborazione (bottone con un simbolo di graffetta: ''Launch Elaborator''). {{ :vlsi:workbook:digital:elaborate.png?600 }} Se non ci sono problemi, in console compariranno solo messaggi riguardanti l’uso di CPU e memoria come questo: nclaunch> ncelab -work worklib -cdslib /export/elt78xl/disk0/users/ panati/projects/shiftregister/syn_shiftregister/netlist_in/cds.lib -logfile ncelab.log -errormax 15 -access +wc -status worklib.tbc_shiftregister_archi ncelab(64): 10.20-s073: (c) Copyright 1995-2011 Cadence Design Systems, Inc. ncelab: Memory Usage - 31.7M program + 30.9M data = 62.6M total ncelab: CPU Usage - 0.0s system + 0.0s user = 0.1s total (0.7s, 10.0% cpu) Contemporaneamente, nella cartella Snapshot (seconda colonna sotto ''worklib'') comparirà un file (''worklib: tbc_shiftregister_archi:configuration''): lo si seleziona e si clicca sul bottone con la freccia verde in alto (''Launch Simulator'', a destra del ''Launch Elaborator''). {{ :vlsi:workbook:digital:launchsimulator.png?600 }} A questo punto si apriranno altre due finestre di SimVision: il //DesignBrowser// e la //Console//: {{ :vlsi:workbook:digital:simvision01.png?600 }} Consideriamo il //DesignBrowser//: nella colonna a sinistra ampliando il menu ''(WORKLIB:TB$\_$SHIFTREGISTER(TB_SHIFTREGISTER_ARCHI))'' vediamo che i due processi del test bench (''generate_clk'' e ''values_gen'') e l’istanza ''instance_shiftregister'' (unica, in questo esempio), e cioè lo shiftregister. * Cliccando su ''(WORKLIB:TB_SHIFTREGISTER(TB_SHIFTREGISTER_ARCHI))'' nella colonna di destra compariranno i segnali. {{ :vlsi:workbook:digital:designbrow01a.png?400 }} * Cliccando sull’istanza (''instance_shiftregister'') compariranno gli ingressi e le uscite (con un’eloquente simbolo illustrativo). In questo caso ad ingressi ed uscite abbiamo associato lo stesso nome. {{ :vlsi:workbook:digital:designbrow01b.png?600 }} A questo punto è possibile selezionare i segnali o i pin da simulare: in questo esempio si è deciso di simulare entrambi i gruppi. A partire da ''(WORKLIB:TB_SHIFTREGISTER(TB_SHIFTREGISTER_ARCHI))'' si selezionano col mouse i segnali dalla colonna di destra (diventeranno evidenziati in giallo) e clicco sul tasto con il simbolo di onde quadre rosse e verdi in alto a destra. Si aprirà una finestra intitolata //Waveform 1//. Se vogliamo aggiungere alla simulazione anche le porte dell’istanza, torno su //DesignBrowser//, come in precedenza seleziono le porte dell’istanza e clicco sul bottone. La finestra Waveform 1 diventa quindi: {{ :vlsi:workbook:digital:waveform01.png?600 }} Col mouse selezioniamo tutta la colonna di sinistra (diventerà evidenziata di giallo) e premo F2 dalla tastiera oppure dal Menu Simulations → Run. Verrà disegnata la waveform della simulazione. {{ :vlsi:workbook:digital:waveform02.png?600 }} === Files hdl.var e cds.lib === FIXME === SimVision Tip&Tricks === == Stampa della waverform == In caso fosse necessario esportare la waveform su formato portatile (.pdf) o postscritp (.ps), è possibile salvare tutte le forme d’onda o solo alcune in b/n o rgb andando sul menu della finestra Waveform: File → Print Window. La finestra che compare permette di scegliere il percorso del documento che verrà stampato, l’intestazione, il tipo di formato (A4, A5...), l’orientamento della pagina, le onde da stampare, il colore di stampa. {{ :vlsi:workbook:digital:print.png?600 }} == Arrangiamento visuale == Usando i tasti in alto a destra (+, -, =, lente di ingrandimento...) è possibile allargare o rimpicciolire la visuale. Il segno di uguale permette la visualizzazione completa di tutta l’onda. == Modifica di valori iniettati negli ingressi del test bench == Senza dover rifare tutta la procedura (test bench, compilazione, elaborazione, apertura del simulatore, simulazione...) è possibile cambiare i valori iniettati negli ingressi del test bench facendo ripartire la simulazione dal menu Simulation → Reinvoke simulator. In questo modo si può far ripartire il run (F2) con i nuovi valori. Nel caso il simulatore restituisse in questo frangente un errore, è necessario rifare la completa procedura. == Colori/Valori della waveform == Dalla colonna ''Cursor'' (seconda a partire da destra) cliccando col destro è possibile cambiare il colore della waveform per una migliore lettura e anche del valore del segnale (in decimale, esadecimale...). Ad esempio, il default è per gli standard logic il binario e per i bus l’esadecimale. == Tracer == Selezionando tutti i segnali e cliccando sul tasto dello ''Schematic Tracer'' (barra degli strumenti, settimo bottone a partire da destra verso sinistra, con blocchetti neri tra loro collegati) è possibile visualizzare un comodo tracer che mostra la struttura delle istanze e dei segnali e i valori nel punto in cui è posta il flag del TimeA (che, assieme al flag Baseline permettono di selezionare solo una banda di valori).Per tornare alla schermata con le forme d’onda, è sufficiente ri-cliccare sul simbolo con le onde rosse e verdi. {{ :vlsi:workbook:digital:tracer.png?600 }}