Differenze
Queste sono le differenze tra la revisione selezionata e la versione attuale della pagina.
Prossima revisione | Revisione precedente | ||
vlsi:workbook2:sdf [05/06/2014 18:37] pacher creata |
vlsi:workbook2:sdf [06/06/2014 12:30] pacher |
||
---|---|---|---|
Linea 1: | Linea 1: | ||
- | ====== Standard Delay Format (SDF) back-annotation ====== | + | ====== Standard Delay Format (SDF) annotation and simulation ====== |
+ | [ __[[vlsi:home|Home]]__ ] | ||
[ __[[vlsi:workbook2|Back]]__ ] | [ __[[vlsi:workbook2|Back]]__ ] | ||
Linea 9: | Linea 10: | ||
* Introduction | * 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: | ||
+ | |||
+ | <code> | ||
+ | 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. | ||
+ | </code> | ||