Differenze
Queste sono le differenze tra la revisione selezionata e la versione attuale della pagina.
| Entrambe le parti precedenti la revisione Revisione precedente Prossima revisione | Revisione precedente | ||
|
vlsi:workbook2:sdf [05/06/2014 23:52] pacher |
vlsi:workbook2:sdf [06/06/2014 12:30] (versione attuale) 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 16: | Linea 17: | ||
| [[http://www.pldworld.com/_hdl/2/_ref/se_html/manual_html/c_sdf.html]] | [[http://www.pldworld.com/_hdl/2/_ref/se_html/manual_html/c_sdf.html]] | ||
| + | [[http://www.eda.org/sdf/]] | ||
| Cadence Incisive documentation: | Cadence Incisive documentation: | ||
| Linea 21: | Linea 23: | ||
| * //SDF Timing Annotation// (''SDFAnnotation.pdf'') | * //SDF Timing Annotation// (''SDFAnnotation.pdf'') | ||
| * //SDF Annotator Guide// (''sdfuser.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> | ||
| + | |||
| ====== ====== | ====== ====== | ||