Verilog simulation tutorials

Contents

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 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

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 here

Simulate a synchronizer

Bla bla bla click here

A simple multiplexer

Bla bla bla click here

Create a D Flip-Flop

Bla bla bla click 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

Documentazione in (ncveruser.pdf):

/usr/cadence/IC_6.1.5/doc/ncveruser

web tutorial 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

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:

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).1)

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.

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)).

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.

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).

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).

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).

A questo punto si apriranno altre due finestre di SimVision: il DesignBrowser e la Console:

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.

  • 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.

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:

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.

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.

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.


1)
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.