- •Contents
- •Introduction
- •About These Application Notes
- •What Is a Cell?
- •Cell Interconnect Delays
- •What Is Delay Back Annotation?
- •What Is Delay Calculation?
- •Prerequisites and Related Reading
- •Creating a Back Annotator
- •The Programming Language Interface (PLI) Mechanism
- •PLI Access Routines
- •Access Routine Families
- •Required UTILITY Routines
- •Access to Timing Information
- •Effect of Source Protection
- •Where to Look for More Information
- •Back Annotating Delays
- •Examples Used in This Chapter
- •Retrieving a Handle to the Object Associated with the Delay
- •Retrieving a Handle to a Net
- •Retrieving a Handle to a Module Path Delay
- •Retrieving a Handle to a Timing Check
- •Annotating the Delay
- •Determining How and Where to Place Delays
- •Annotating to Cells with Path Delays
- •Annotating to Cells with Lumped or Distributed Delays
- •Libraries with Mixed Cell Timing Descriptions
- •Annotating to Timing Checks
- •Calculating Delays
- •Examples Used in This Chapter
- •Scanning Cell Instances Within the Design
- •Determining the Scope of the Delay Calculation
- •Scan Methodology
- •Scanning Objects Within the Cell Instance
- •Relationship to Modeling Methodology
- •Scanning Path Delays
- •Scanning Cell Output Ports
- •Libraries with Mixed Cell Timing Descriptions
- •Types of Data Needed
- •Coding Data into Cell Descriptions (Attributes)
- •Retrieving Cell I/O Load Factors
- •Load Due to Interconnect Wire
- •Calculating and Annotating the Delays
- •Calculating the Delays
- •Annotating the Delays
- •Example Listings
- •Delay Back Annotators
- •Cell Output Nets to Lumped or Distributed Delay Cells
- •Interconnect Nets to Lumped or Distributed Delay Cells
- •Cell Output Nets to Path Delay Cells
- •Interconnect Nets to Path Delay Cells
- •Delay Calculators
- •Creating and Extracting Data From a Hash Table
- •Random Cell Scan and Cell Output Nets
- •Random Cell Scan and Cell Interconnect Nets
- •Delay Calculation Driven by Cell Output Nets
- •Delay Calculation Driven by a Cell Interconnect Nets
- •Index
Back Annotation and Delay Calculation
Example Listings
if ((net == null) || (acc_fetch_type(net) != accNet))
{
io_printf("Warning from dl_ann : net %s not found\n", net_name);
continue;
}
/*****************************************/ /*** Replace delays on all net drivers ***/
/*****************************************/ driver = null;
while (driver = acc_next_driver(net,driver))
{
if (dl_verbose)
{
double newrise, newfall; acc_fetch_delays(prim,&newrise,&newfall); io_printf("Primitive %s had added rise fall delays :
%d %d\n", acc_fetch_fullname(prim), (int)rise, (int)fall);
}
acc_append_delays(driver, rise, fall);
if (dl_verbose)
{
double newrise, newfall; acc_fetch_delays(prim,&newrise,&newfall); io_printf("New delays are : %d %d\n",
(int)newrise, (int)newfall);
}
}
}
/* clean up access routines */ acc_close();
}
s_tfcell veriusertfs[] = {
{usertask,0,
0,0, dl_read_int_delays,0, "$ba_delays",0},
{0}
};
Cell Output Nets to Path Delay Cells
Figure 5-3 on page 98 shows an example delay back annotator that requires a delay file that contains cell output net names and their associated rise and fall delays. Figure 3-5 on page 25 shows an example delay file that follows this syntax. The back annotator reads each net/ delay pair and adds the delays to all path delays within the appropriate cell instance that have the net as a path output. This back annotator must be used with designs that contain cells described with path delay timing, as does the design in Figure 3-2 on page 23 and Figure 3-3 on page 24 .
October 2000 |
97 |
Product Version 3.2 |
Back Annotation and Delay Calculation
Example Listings
Figure 5-3 Annotating from cell output nets to path delay cells
#include <stdio.h> #include "acc_user.h" #include "veriuser.h"
/* |
DEFINES */ |
|
|
|
|
|
|
|
#define |
LARGE_STRING 512 |
/* |
size |
of |
large |
strings |
*/ |
|
#define |
SMALL_STRING 64 |
/* |
size |
of |
small |
strings |
*/ |
|
/* |
VARIABLES */ |
|
|
|
|
|
|
|
char message[LARGE_STRING]; |
|
/* error message string */ |
/* checktf routine for $ba_delays() */ ba_conp_check()
{ /* ba_conp_check() */
/* check for one parameter of type string - delay file name */ if (tf_nump() != 1)
{
strcpy(message,
"incorrect number of parameters passed to $ba_delays()"); tf_error(message);
return;
}
if (tf_typep(1) != tf_string)
{
strcpy(message,"illegal parameter passed to $ba_delays()\n"); strcat(message,"parameter must be string with delay file name"); tf_error(message);
return;
}
} /* ba_conp_check() */
/* calltf routine for $ba_delays() - contains
the |
actual back-annotation |
functionality */ |
|
ba_conp_call() |
|
||
{ /* |
ba_conp_call() */ |
|
|
FILE |
*ba_fp; |
/* pointer to back-annotation file */ |
|
char |
net_name[LARGE_STRING]; |
/* hierarchical net name */ |
|
handle |
net_handle; |
/* handle to the identified net */ |
|
handle |
mod_handle; |
/* handle to parent instance */ |
|
handle |
curr_path; |
/* handle to current path delay */ |
|
double |
rise, fall; |
/* incremental delays */ |
|
int i; |
|
/* loop variable */ |
|
char |
temp[LARGE_STRING]; |
/* temporary string */ |
|
/* |
get back-annotation file |
name and open */ |
|
if |
((ba_fp = fopen(tf_getcstringp(1),"r")) == null) |
||
{ |
|
|
|
sprintf(message,"unable to open back-annotation file %s", tf_getcstringp(1));
tf_error(message); return;
}
/* initialize access routines */ acc_initialize(); acc_configure(accDevelopmentVersion,"1.5a");
October 2000 |
98 |
Product Version 3.2 |
Back Annotation and Delay Calculation
Example Listings
/* configure access routines to accept rise and fall delays */ acc_configure(accPathDelayCount,"2");
/* while there are more lines in the file, read them and back-annotate the delays */
while (fscanf(ba_fp,"%s %lf %lf",net_name,&rise,&fall) != EOF)
{
/* get handle to the net */
net_handle = acc_handle_object(net_name); if (net_handle == null)
{
sprintf(message,"illegal net name %s found in file", net_name);
tf_error(message); return;
}
/* get handle to the parent module instance */ mod_handle = acc_handle_parent(net_handle);
/* find correct path delays and annotate delays */ curr_path = null;
while (curr_path = acc_next_modpath(mod_handle,curr_path))
{
/* check for correct path and annotate delays */ if (acc_handle_pathout(curr_path) == net_handle)
{
acc_append_delays(curr_path,rise,fall);
/* set pulse control back to 100% x-generation region for new delays */
acc_set_pulsere(curr_path,0,100);
}
}
}
/* clean up access routines */ acc_close();
} /* ba_conp_call() */
s_tfcell veriusertfs[] = {
{usertask,0, ba_conp_check,0, ba_conp_call,0, "$ba_delays",0}, {0}
};
Interconnect Nets to Path Delay Cells
Figure 5-4 on page 100 shows an example delay back annotator that requires a delay file that contains interconnect net names and their associated rise and fall delays. Figure 3-6 on page 26 shows an example delay file that follows this syntax. The back annotator reads each net/delay pair and adds the delays to all path delays that have the net as a path output in all cell instances with output or inout ports connected to the net. This back annotator must be
October 2000 |
99 |
Product Version 3.2 |
Back Annotation and Delay Calculation
Example Listings
used with designs that contain cells described with path delay timing, as does the design in Figure 3-2 on page 23 and Figure 3-3 on page 24 .
Figure 5-4 Annotating from interconnect nets to path delay cells
#include <stdio.h> #include "acc_user.h" #include "veriuser.h"
/* |
DEFINES */ |
|
|
|
|
|
|
#define |
LARGE_STRING 512 |
/* size |
of |
large |
strings */ |
||
#define |
SMALL_STRING 64 |
/* |
size |
of |
small |
strings */ |
|
/* |
VARIABLES */ |
|
|
|
|
|
|
char message[LARGE_STRING]; |
/* |
error message |
string */ |
/* checktf routine for $ba_delays() */ ba_inp_nowired_check()
{/* ba_inp_nowired_check() */
/* check for one parameter of type string - delay file name */ if (tf_nump() != 1)
{
strcpy(message,
"incorrect number of parameters passed to $ba_delays()"); tf_error(message);
return;
}
if (tf_typep(1) != tf_string)
{
strcpy(message,"illegal parameter passed to $ba_delays()\n"); strcat(message,"parameter must be string with delay
file name"); tf_error(message); return;
}
} /* ba_inp_nowired_check() */
/* calltf routine for $ba_delays() - contains the back-annotation functionality */
ba_inp_nowired_call()
/* pointer to back-annotation */ /* file */
char ext_net_name[LARGE_STRING]; /* external hierarchical net */
|
/* |
name |
*/ |
|
|
handle ext_net_handle; |
/* handle |
to |
the |
external net */ |
|
handle int_net_handle; |
/* handle |
to |
the |
internal net */ |
|
handle mod_handle; |
/* handle |
to |
parent instance */ |
||
handle curr_driver; |
/* handle |
to |
the |
current driver */ |
|
handle curr_path; |
/* handle |
to |
current path delay */ |
||
double rise, fall; |
/* incremental delays */ |
||||
int i; |
/* loop variable |
*/ |
|||
char temp[LARGE_STRING]; |
/* temporary |
string */ |
|||
/* get back-annotation filename and open |
*/ |
|
|
October 2000 |
100 |
Product Version 3.2 |
Back Annotation and Delay Calculation
Example Listings
if ((ba_fp = fopen(tf_getcstringp(1),"r")) == null)
{
sprintf(message,"unable to open back-annotation file %s", tf_getcstringp(1));
tf_error(message); return;
}
/* initialize access routines */ acc_initialize(); acc_configure(accDevelopmentVersion,"1.5a");
/* configure path delay access routines to accept a rise and a fall delay */
acc_configure(accPathDelayCount,"2");
/* while there are more lines in the file, read them and back-annotate the delays */
while (fscanf(ba_fp,"%s %lf %lf",ext_net_name,&rise,&fall)!= EOF)
{
/* get handle to the external net */ ext_net_handle = acc_handle_object(ext_net_name); if (ext_net_handle == null)
{
sprintf(message,"illegal net name %s found in file", ext_net_name);
tf_error(message); return;
/* scan all modules with output ports that drive this net */ curr_driver = null;
while ((curr_driver = acc_next_driver(ext_net_handle, curr_driver)) != null)
{
/* get the connecting cell output net and the parent module */ int_net_handle = acc_handle_conn(curr_driver);
mod_handle = acc_handle_parent(int_net_handle); /* find correct path delays and annotate delays */ curr_path = null;
while (curr_path = acc_next_modpath(mod_handle,curr_path))
{
/* check for correct path and annotate delays */
if (acc_handle_pathout(curr_path) == int_net_handle)
{
acc_append_delays(curr_path,rise,fall);
/* set pulse control back to 100% x-generation region */ acc_set_pulsere(curr_path,0,100);
}
}
}
}
/* clean up access routines */ acc_close();
} /* ba_inp_nowired_call() */ s_tfcell veriusertfs[] = {
{usertask,0, ba_inp_nowired_check,0, ba_inp_nowired_call,0, "$ba_delays",0},
October 2000 |
101 |
Product Version 3.2 |
Back Annotation and Delay Calculation
Example Listings
{0}
};
Explicitly Identified Path Delays and Timing Checks
Figure 5-5 on page 102 shows an example delay back annotator that requires a delay file that contains module instance names, path input and output nets and the associated path delays, and timing check identification data and the associated timing check limits. Figure 3-4 on page 25 shows an example delay file that follows this syntax. The back annotator reads each path/delay and timing check/limit pair, adds the delays to the appropriate path delay, and adds the limit to the appropriate timing check within the identified cell instance. This back annotator must be used with designs that contain cells described with path delay timing, as does the design in Figure 3-2 on page 23 and Figure 3-3 on page 24 .
Figure 5-5 Annotating to explicitly identified path delays and timing checks
#include <stdio.h> #include "acc_user.h" #include "veriuser.h"
/* |
DEFINES */ |
|
|
|
|
|
|
#define |
LARGE_STRING 512 |
/* size |
of |
large |
strings */ |
||
#define |
SMALL_STRING 64 |
/* |
size |
of |
small |
strings */ |
|
/* |
VARIABLES */ |
|
|
|
|
|
|
char message[LARGE_STRING]; |
/* |
error message |
string */ |
/* checktf routine for $ba_delays() */ ba_ppt_check()
{/* ba_ppt_check() */
/* check for one parameter of type string - delay file name */ if (tf_nump() != 1)
{
strcpy(message,"incorrect number of parameters passed
to $ba_delays()"); tf_error(message); return;
}
if (tf_typep(1) != tf_string)
{
strcpy(message,"illegal parameter passed to $ba_delays()\n"); strcat(message,"parameter must be string with delay
filename"); tf_error(message); return;
}
/* ba_ppt_check() */
/* calltf routine for $ba_delays() - |
contains |
||
the back-annotation functionality |
*/ |
||
ba_ppt_call() |
|
|
|
{ /* |
ba_ppt_call() */ |
|
|
FILE |
*ba_fp; |
/* pointer to back-annotation file */ |
October 2000 |
102 |
Product Version 3.2 |
Back Annotation and Delay Calculation
Example Listings
char hier_name[LARGE_STRING]; /* module |
instance name */ |
|
|||||
int num_paths; |
/* number |
of path delays for a module instance */ |
|||||
handle |
mod_handle; |
/* handle |
to module instance to |
back-annotate to */ |
|||
handle |
curr_path; |
/* handle |
to |
current |
path |
delay |
*/ |
char pathin_name[SMALL_STRING]; /* name |
of |
current |
path |
input |
*/ |
char pathout_name[SMALL_STRING]; /* name |
of current path output */ |
||
double rise, fall; |
/* incremental delays */ |
||
int num_tchecks; |
/* number of timing checks for a module instance */ |
||
char sig1_str[SMALL_STRING]; |
/* timing |
check signal one */ |
|
char sig2_str[SMALL_STRING]; |
/* timing |
check signal two */ |
|
handle tcheck_handle; |
/* handle |
to timing check */ |
|
int tcheck_id; |
/* timing |
check ID */ |
|
int edge1_id; |
/* signal |
one edge ID |
*/ |
int edge2_id; |
/* signal two edge ID */ |
||
double tcheck_incdel; /* incremental delay to add to |
timing check */ |
||
int i; |
/* loop |
variable */ |
|
char temp[LARGE_STRING]; |
/* temporary string |
*/ |
/* get back-annotation filename and open */
if ((ba_fp = fopen(tf_getcstringp(1),"r")) == null)
{
sprintf(message,"unable to open back-annotation file %s", tf_getcstringp(1));
tf_error(message); return;
}
/* initialize access routines */ acc_initialize(); acc_configure(accDevelopmentVersion,"1.5a");
/* configure path delay access routines to accept a single delay for all transitions */
acc_configure(accPathDelayCount,"2");
/* while there are more lines in the file, read them and back-annotate the delays */
while (fscanf(ba_fp,"%s %d",hier_name,&num_paths) != EOF)
{
/* get handle to module instance */ mod_handle = acc_handle_object(hier_name); if (mod_handle == null)
{
sprintf(message,"illegal instance name %s found in file", hier_name);
tf_error(message); return;
}
/* read path IDs and delays and annotate the delays */ for (i = 0; i < num_paths; i++)
{
fscanf(ba_fp,"%s %s %lf %lf",pathin_name,pathout_name, &rise,&fall);
/* get a handle to the path */
curr_path =acc_handle_modpath(mod_handle, pathin_name, pathout_name);
if (curr_path == null)
{
sprintf(message,"illegal path found in file - input %s,
October 2000 |
103 |
Product Version 3.2 |
Back Annotation and Delay Calculation
Example Listings
output %s",pathin_name,pathout_name); tf_error(message);
return;
}
/* add incremental delays to path */ acc_append_delays(curr_path,rise,fall);
/* set pulse control back to 100% x-generation region for new path delays */
acc_set_pulsere(curr_path,0.0,1.0);
}
/* process timing checks */
/* next entry in file is number of timing checks */ fscanf(ba_fp,"%d",&num_tchecks);
/* only process if there are timing checks for this module */ if (num_tchecks > 0)
{
/* read in and process each timing check */ for (i = 0; i < num_tchecks; i++)
{
/* read in data for one timing check */ fscanf(ba_fp,"%d %s %d %s %d %lf",&tcheck_id,sig1_str,
&edge1_id,sig2_str,&edge2_id,&tcheck_incdel);
/* get handle to timing check and add extra delay */ tcheck_handle = acc_handle_tchk(mod_handle,tcheck_id, sig1_str,edge1_id,sig2_str,edge2_id);
if (tcheck_handle == null)
{
strcpy(message,"timing check found in file does not exist");
tf_error(message); return;
}
acc_append_delays(tcheck_handle,tcheck_incdel);
}
}
}
/* clean up access routines */ acc_close();
} /* ba_ppt_call() */
s_tfcell veriusertfs[] = { {usertask,0,
ba_ppt_check,0, ba_ppt_call,0, "$ba_delays",0}, {0} };
October 2000 |
104 |
Product Version 3.2 |