Standard Delay Format (SDF) annotation and simulation

[ Home ] [ Back ]

Contents
  • Introduction

Introduction

http://www.pldworld.com/_hdl/2/_ref/se_html/manual_html/c_sdf.html

http://www.eda.org/sdf/

Cadence Incisive documentation:

  • SDF Timing Annotation (SDFAnnotation.pdf)
  • SDF Annotator Guide (sdfuser.pdf)

Note Giulio:

Note su come eseguire una simulazione VHDL con Cadence ncsim, includendo i tempi di
ritardo del file sdf post sintesi (o post routing)

Per prima cosa bisogna scrivere il file sdf con RC compiler (per la sintesi) o
Encounter (per il routing).
In RC compiler 9.1 il comando usato, da mettere alla fine della sintesi, è:

write_sdf -nonegchecks > ${_OUTPUTS_PATH}/preliminary/${DESIGN}_preliminary.sdf

L'opzione -nonegchecks serve a convertire tutti i tempi negativi a 0, altrimenti il
simulatore non può gestire i valori negativi e da dei warning.
Il file SDF ha questa struttura:
C'è un header in cui si possono leggere tutte le informazioni di come questo file è
stato generato. Tra queste è importante notare la tensione e la temperatura del
processo. Io ho usato le librerie con il worst case, quindi 1.08V e 125C. Il
Timescale invece indica il fattore moltiplicativo dei tempi che sono scritti nel
file sdf, quindi in questo caso avremo valori di 310 ps, 190 ps ecc.


(DELAYFILE
  (SDFVERSION  "OVI 3.0")
  (DESIGN      "ddr_reg")
  (DATE        "Thu Sep 19 16:27:31 CEST 2013")
  (VENDOR      "Cadence, Inc.")
  (PROGRAM     "Encounter(R) RTL Compiler")
  (VERSION     "RC9.1.203 - v09.10-s242_1")
  (DIVIDER     .)
  (VOLTAGE     ::1.08)
  (PROCESS     "::1.0")
  (TEMPERATURE ::125.0)
  (TIMESCALE   1ps)

Dopo l'header c'è l'elenco di tutte le celle con i loro tempi di ritardo. In questo
caso c'è una porta Xnor con due ingressi, A e B e l'uscita Z

  (CELL
     (CELLTYPE "XNR2M2NM")
     (INSTANCE encoder0.g2106)
     (DELAY
        (ABSOLUTE
          (PORT A (::0.0))
          (PORT B (::0.1))
          (IOPATH (posedge A) Z (::310) (::190))
          (IOPATH (negedge A) Z (::272) (::275))
          (IOPATH (posedge B) Z (::310) (::199))
          (IOPATH (negedge B) Z (::294) (::270))
        )
     )
  )
Nell'intestazione si legge che porta è e dove è usata nel nostro circuito. Poi
abbiamo i ritardi, in questo caso il ritardo di propagazione tra ingressi e uscita.
Ci sono 4 IOPATH, infatti nell'ordine, si coprono tutti i casi possibili di
commutazione dei segnali di ingresso:
1) A commuta da 0 a 1
2) A commuta da 1 a 0
3) B commuta da 0 a 1
4) B commuta da 1 a 0
Per ognuno di questi casi poi si hanno due coppie di valori indicati tra parentesi.
La prima parentesi è la commutazione di Z da 0 a 1, la seconda di Z da 1 a 0.
Inoltre in ogni parentesi ci sono 3 campi, ma nel nostro caso solo uno viene
utilizzato. Nell'ordine avremmo i valori minimo, tipico e massimo:
 IOPATH (posedge A) Z (min:typ:max) (min:typ:max))
Dato che nella sintesi, in questo esempio, ho usato le librerie del worst case, nel
file SDF sono stati scritti solo i valori massimi.
In definitiva quindi la riga 'IOPATH (posedge A) Z (::310) (::190))' indica: 
        310 ps di ritardo se A commutando da 0 a 1 commuta Z da 0 a 1 
        190 ps di ritardo se A commutando da 0 a 1 commuta Z da 1 a 0

Tutti i dettagli sulla struttura dei file sdf possono essere trovati qui: 
http://www.eda.org/sdf/sdf_3.0.pdf

Inoltre nel comando write_sdf di RC compiler ci sono varie opzioni per escludere
alcune informazioni dal file .SDF (vedere help di RC compiler). Ad esempio si può
escludere la distinzione tra posedge e negedge, che magari non è supportata da tutte
le librerie.
Nella simulazione post sintesi con ncsim, se non si include in modo opportuno il
file sdf, il simulatore considera per ogni cella un tempo di ritardo pari a una
unità del timescale impostato. Quindi se in other options dell'elaborator abbiamo
scritto:
default timescale 100ps/1ps (time unit/time precision), per ogni cella viene
aggiunto un ritardo di 100 ps. Attenzione a non scrivere anche -override_timescale,
altrimenti i tempi del file sdf vengono moltiplicati per la time unit (capire meglio
cosa fa).
Per includere il file sdf invece, bisogna prima di tutto compilarlo. Dalla finestra
file browser di nclaunch si seleziona il file, posizionandosi nella cartella
opportuna e facendo attenzione che nel campo Filters sia anche incluso *sdf,
altrimenti non si vede il file nell'elenco!
Si seleziona quindi il file sdf e lo si compila con NCSdfc. Col tasto destro del
mouse si apre il relativo menu, dove basta mettere il nome del file .sdf.X che il
compilatore andrà a creare. Inoltre nella directory in cui lo si compila se non c'è
il file hdl.var viene dato un warning.
Il file .sdf.X è quello che viene usato dal simulatore. Per includerlo bisogna
selezionare, nelle opzioni avanzate dell'Elaborator:
Annotation -> Use SDF command file
in cui andiamo a selezionare il nome del command file che abbiamo preparato (di
solito sdf.cmd). In questo command file andiamo a scrivere:

COMPILED_SDF_FILE = "../outputs/preliminary/ddr_reg_preliminary.sdf.X",
SCOPE = :UUT,
MTM_CONTROL = "MAXIMUM",
SCALE_FACTORS = "1.0:1.0:1.0",
SCALE_TYPE = "FROM_MTM";

nell'ordine:
1) il nome del file compialto .sdf.X
2) a quale componente del nostro VHDL fa riferimento
3) quale valori usare del file SDF, tra minimum, typical e maximum. Attenzione che
in questo esempio nel file SDF è presente solo il valore massimo. Se in questo
comando scrivo typical o minimum, il simulatore trova un campo vuoto e per default
mette come ritardi le unità di timescale, come descritto prima. Ma non segnala la
cosa con nessun messaggio di warning!!!
4) se vogliamo moltiplicare i valori dei file SDF per un fattore moltiplicativo
(altrimenti si lascia 1)
5) dice di scalare i valori minimo/tipico/massimo come indicato nel file sdf
Tutte queste opzioni sono descritte nel help di Cadence, nella guida
IUS9.20/Incisive HDL Simulator/SDF Annotator Guide

A questo punto eseguiamo l'Elaborator sul file nostro componente vhdl della worklib
(io uso la configuration del testbench).
Nel mio caso, usando la libreria UMC110, ho molti errori di questo tipo:

ncelab: *W,SDFNEP: Unable to annotate to non-existent path (IOPATH (posedge A) Z) of
instance :UUT.encoder0.g2110 of module ND2M2NM
<../outputs/preliminary/ddr_reg_preliminary.sdf, line 48>.

oppure
ncelab: *W,SDFNET: Unable to annotate to non-existent timing check (RECOVERY
(posedge RB) (posedge SB) (181)) of instance :UUT.\data_Nreg_reg[13]  of module
DFCQRSM2NM <../outputs/preliminary/ddr_reg_preliminary.sdf, line 10692>.
ncelab: *W,SDFNET: Unable to annotate to non-existent timing check (REMOVAL (posedge
RB) (negedge CKB) (974)) of instance :UUT.\data_Nreg_reg[13]  of module DFCQRSM2NM
<../outputs/preliminary/ddr_reg_preliminary.sdf, line 10693>.

Non vengono trovati alcuni percorsi che invece sono definiti nel file sdf. Leggendo
il datasheet della libreria infatti, pare che non venga fatta la distinzione tra
posedge e negedge dei segnali di ingresso, per il tempo di propagazione IOPATH. A
questo punto posso generare nella sintesi il file SDF con le seguenti opzioni:
write_sdf -nonegchecks -edges check_edge >
${_OUTPUTS_PATH}/preliminary/${DESIGN}_preliminary.sdf

in questo modo per le celle combinatorie, nel file SDF, non c'è più la distinzione
tra posedge e negedge dei segnali di ingresso, ma si usa il valore massimo per
entrambi. Rivedendo la cella di prima, il file SDF diventa:

(CELL
     (CELLTYPE "XNR2M2NM")
     (INSTANCE encoder0.g2106)
     (DELAY
        (ABSOLUTE
          (PORT A (::0.0))
          (PORT B (::0.1))
          (IOPATH A Z (::310) (::275))
          (IOPATH B Z (::310) (::270))
        )
     )
  )

In ncsim ora rimangono solo errori del tipo Removal e Recovery sui flip flop. Ad
esempio:

ncelab: *W,SDFNET: Unable to annotate to non-existent timing check (REMOVAL (posedge
RB) (posedge SB) (0)) of instance :UUT.encoder0.LPDL4_reg of module DFCQRSM2NM
<../outputs/preliminary/ddr_reg_preliminary.sdf, line 1471>.

C'è ancora qualche cosa che non coincide tra il file SDF e le librerie delle
standard cell. Infatti nel log file della sintesi trovo proprio warning di questo
tipo:

Info    : Promoting a hold arc to removal. [LBR-31]
        : The asynchronous input pin is DFCQRSM1NM/RB
        : Hold arcs to asynchronous input pins are not supported.

Questo significa che nella libreria delle standard cells non sono definiti i tempi
di removal, che sono l'equivalente dei setup/hold ma per i segnali asincroni.
Infine, eseguendo la simulazione, si può vedere che i tempi di ritardo descritti nel
file SDF vengono correttamente visualizzati nel simulatore.



Last update: