Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
dsd1-10 / dsd-07=Verilog / backan.pdf
Скачиваний:
81
Добавлен:
05.06.2015
Размер:
697.19 Кб
Скачать

Back Annotation and Delay Calculation

Example Listings

static int dl_get_numlines(filename) char *filename;

{

int line = 0; double val; FILE *net_file; char name[256];

if ((net_file = fopen(filename,"r")) == 0)

{

io_printf("Warning: Back-annotate file \"%s\" not found.\n", filename);

return(0);

}

while (fscanf(net_file,"%s%lf\n",name,&val) != EOF) line++;

fclose(net_file); return(line);

}

Random Cell Scan and Cell Output Nets

Figure 5-7 on page 110 shows a set of routines that comprise two delay calculators: one that calculates delays for designs that use cells described with lumped or distributed (primitive output) delay timing, and one for designs that use cells described with path delay timing. Both delay calculators use acc_next_cell to randomly scan the cell instances in the design. Both also take an optional capacitance back annotation file that contains cell output net names and their associated capacitance values. Note that the two delay calculators share a large set of common source code.

The system tasks associated with these delay calculators accept zero, one, or two arguments, where the arguments specify the following information:

1.the top of the hierarchical tree for which delays are to be calculated (a module instance name)

2.the capacitance back annotation file (a file name enclosed in double quotes)

If you do not provide the first system task argument, the delay calculator will calculate delays for all cells below the scope that contains the system task call. If you do not provide the second system task argument, or if the second argument is ‘estimated,’ the delay calculator will estimate interconnect wire capacitance. For more detailed information about the operation and invocation of these delay calculators, refer to the header comments in the actual delay calculator source file provided with your Veritool release.

These delay calculators use the routines described in “Creating and Extracting Data From a Hash Table” on page 105 to parse the capacitance back annotation file and to store and retrieve the associated capacitance data. The capacitance back annotation file must contain

October 2000

109

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

cell output net names and their associated capacitance values. Figure 4-5 on page 47 shows an example file that adheres to this syntax.

Figure 5-7 Delay calculation: random cell scanning and capacitance values associated with cell output nets

#include "acc_user.h" #include "veriuser.h"

/*** System task invocation routine ***/

global dl_prim_invoke(); global dl_path_invoke(); global void dl_invoke();

/*** Main delay calculation routines ***/

local void dl_calc_prim_delays(); local void dl_calc_path_delays();

/*** Auxiliary routines ***/

local double dl_load_factor();

local double dl_estimate_capacitance(); local handle dl_handle_driving_prim();

/*** Argument processing routines ***/

local handle dl_process_scope_arg(); local bool dl_process_estimate_arg();

/*** Global variables ***/

bool dl_verbose_flag = false;

/*** Wire capacitance estimation table ***/

int wirecap_est_table_size = 10; double wirecap_est_table[] =

{1.2, 2.2, 3.4, 5.0, 6.7, 8.8, 10.2, 12.7, 15.3, 18.0};

#define dlPrim 1 #define dlPath 2

double dl_backan_fetch();

/***************************************************************/ /* System task invocation routines */ /***************************************************************/

/*

DL_PRIM_INVOKE

/*

Begin delay calculation for primitive delay based models

/***************************************************************/ exfunc dl_prim_invoke()

{

dl_invoke(dlPrim);

}

/***************************************************************/

/*

DL_PATH_INVOKE

/*

Begin delay calculation for path delay based models

/***************************************************************/ exfunc dl_path_invoke()

{

dl_invoke(dlPath);

}

/***************************************************************/

October 2000

110

Product Version 3.2

 

 

Back Annotation and Delay Calculation

 

 

 

Example Listings

 

 

 

 

/*

DL_INVOKE

*/

/*

This routine invokes delay calculation processing.

*/

/*

It accepts an argument indicating whether to begin path

*/

/*

delay

or primitive delay-based calculations

*/

/*

This routine performs the following functions:

*/

/*

>

Initialize and configure the access routines.

*/

/*

>

Process command line plusargs

*/

/*

>

Call routines to process system task arguments

*/

/*

>

Call routine to calculate interconnect delays

*/

/***************************************************************/ exfunc void dl_invoke(prim_or_path)

int prim_or_path;

{

handle dl_scope_g; int mtmparam; handle scope;

bool estimate_flag;

acc_initialize(); acc_configure(accDevelopmentVersion,"1.5a"); acc_configure(accToHiZDelay,"average"); acc_configure(accPathDelayCount,"2"); acc_configure(accDefaultAttr0,"true");

/************************************************************/ /* If "+dlverbose" appears on command line, set global flag */ /************************************************************/ if (mc_scan_plusargs("dlverbose"))

{

dl_verbose_flag = true;

if (prim_or_path == dlPrim)

io_printf("Delay calculation invoked for primitive ", "delay cells : \n");

else

io_printf("Delay calculation invoked for path delay cells : \n");

}

/********************************************************/

/***

Process argument to determine scope of delay

***/

/***

calculation

***/

/********************************************************/ scope = dl_process_scope_arg();

/******************************************************/ /*** Process argument to determine wire capacitance ***/

/*** estimation or back annotation ***/

/******************************************************/ estimate_flag = dl_process_estimate_arg();

/*************************************/ /*** Calculate interconnect delays ***/

/*************************************/ if (prim_or_path == dlPath)

dl_calc_path_delays(scope,estimate_flag); else

dl_calc_prim_delays(scope,estimate_flag); /*******************************************************/ /*** If necessary, free back-annotation table memory ***/

/*******************************************************/ if (!estimate_flag)

dl_free_backan_table();

October 2000

111

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

/******************/ /*** Aesthetics ***/

/******************/ if (dl_verbose_flag) io_printf("\n");

/***********************************/ /*** Access routine use complete ***/

/***********************************/ acc_close();

}

/***************************************************************/ /* Main delay calculation processing loops */ /***************************************************************/ /****************************************************************/

/*** DL_CALC_PRIM_DELAYS

 

 

***/

/*** This

routine accepts

a handle to

a module, scans

***/

/***

each

offspring

cell,

and performs delay calculation and

***/

/***

annotation for

each output port.

 

***/

/****************************************************************/ static void dl_calc_prim_delays(start_mod,estimate_flag)

handle

start_mod;

bool

estimate_flag;

{

 

handle

mod, term, prim, driver;

handle

portout, portout_net, portout_term;

int

fanout_count;

double

fanout_load, wire_load;

double

rise_strength, fall_strength, rise, fall;

/**********************************************************/ /*** Process each cell module instance within the scope ***/

/**********************************************************/ mod = null;

while (mod = acc_next_cell(start_mod, mod))

{

/****************************************************/ /*** Process each output port in this cell module ***/

/****************************************************/ portout = null;

while (portout = acc_next_portout(mod,portout))

{

/***********************************************/ /*** Process each net connected to this port ***/

/***********************************************/ portout_net = null;

while (portout_net = acc_next_loconn(portout,portout_net))

{

/*********************/ /*** Count fanouts ***/

/*********************/

fanout_count = acc_count(acc_next_cell_load,portout_net); if (estimate_flag && (fanout_count == 0))

continue;

/***********************************************/ /*** Determine loading on net due to fanouts ***/

/***********************************************/

October 2000

112

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

fanout_load = dl_load_factor(portout_net);

/********************************************************/ /*** Determine estimated or back-annotated wire ***/

/***capacitance ***/

/********************************************************/ if (estimate_flag)

wire_load = dl_estimate_capacitance(fanout_count); else

wire_load = dl_backan_fetch(portout_net);

/********************************************************/ /*** Determine attributes associated with portout_net ***/

/********************************************************/ rise_strength = acc_fetch_attribute(portout_net,

"RiseStrength$"); fall_strength = acc_fetch_attribute(portout_net,

"FallStrength$");

/***************************************/ /*** Calculate load dependent delays ***/

/***************************************/

rise = rise_strength * (fanout_load + wire_load); fall = fall_strength * (fanout_load + wire_load); /*************************************************/ /*** Scan the primitives which drive this port ***/

/*************************************************/ driver = null;

while (driver = acc_next_driver(portout_net,driver))

{

prim = acc_handle_parent(driver); if (acc_handle_parent(prim) != mod)

continue;

/*******************************************/ /*** Add calculated delays to the delays ***/

/*** on the driving primitive ***/

/*******************************************/ acc_append_delays(prim, rise, fall); /************************************************/ /*** If requested, print detailed calculation ***/

/************************************************/ if (dl_verbose_flag)

{

double newrise, newfall, newz; acc_fetch_delays(prim,&newrise,&newfall,&newz); io_printf("\nNet %s delays : rise = %6.2f fall =

%6.2f\n", acc_fetch_fullname(portout_net), newrise, newfall);

io_printf(" rise_strength =%6.2f fall_strength = %6.2f\n",rise_strength, fall_strength);

io_printf(" fanout_load = %6.2f wire_load = %6.2f\n", fanout_load, wire_load);

io_printf(" added rise = %6.2f added fall = %6.2f\n", rise, fall);

}

}

}

}

}

}

October 2000

113

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

/****************************************************************/

/*

DL_CALC_PATH_DELAYS

 

 

*/

/*

This

routine accepts

a handle to a module, scans

*/

/*

each

offspring

cell,

and

performs delay calculation and

*/

/*

annotation for

each path

in the cell.

*/

/****************************************************************/ static void dl_calc_path_delays(start_mod,estimate_flag)

handle

start_mod;

bool

estimate_flag;

{

 

handle

mod, path;

handle

pathout_net;

int

fanout_count;

double

fanout_load, wire_load;

double

rise_strength, fall_strength, rise, fall;

/**********************************************************/ /*** Process each cell module instance within the scope ***/

/**********************************************************/ mod = null;

while (mod = acc_next_cell(start_mod, mod))

{

/*********************************************/ /*** Process each path in this cell module ***/

/*********************************************/ path = null;

while (path = acc_next_modpath(mod,path))

{

/*********************/ /*** Count fanouts ***/

/*********************/

pathout_net = acc_handle_pathout(path);

fanout_count = acc_count(acc_next_cell_load,pathout_net); if (estimate_flag && (fanout_count == 0))

continue;

/***********************************************/ /*** Determine loading on net due to fanouts ***/

/***********************************************/ fanout_load = dl_load_factor(pathout_net);

/*********************************************************/

/***

Determine estimated or back-annotated wire

***/

/***

capacitance

***/

/*********************************************************/ if (estimate_flag)

wire_load = dl_estimate_capacitance(fanout_count); else

wire_load = dl_backan_fetch(pathout_net);

/*************************************************/ /*** Determine attributes associated with path ***/

/*************************************************/ rise_strength = acc_fetch_attribute(path, "RiseStrength$"); fall_strength = acc_fetch_attribute(path, "FallStrength$");

/***************************************/

/*** Calculate load dependent delays ***/

/***************************************/

rise = rise_strength * (fanout_load + wire_load);

October 2000

114

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

fall = fall_strength * (fanout_load + wire_load); /*****************************************/

/*** Append delays to the driving path ***/

/*****************************************/ acc_append_delays(path, rise, fall);

/**********************************************/ /*** Set pulse control to 100% x-generation ***/

/*** for new delay ***/

/**********************************************/ acc_set_pulsere(path,0.0,1.0);

/********************************************************/

/***

If requested, print detailed calculation

***/

/***

information

***/

/********************************************************/ if (dl_verbose_flag)

{

double newrise, newfall, newz; acc_fetch_delays(path,&newrise,&newfall,&newz); io_printf("\nPath %s delays : rise = %6.2f fall = %6.2f\n",

acc_fetch_fullname(path), newrise, newfall); io_printf(" rise_strength = %6.2f fall_strength =%6.2f\n",

rise_strength, fall_strength);

io_printf(" fanout_load = %6.2f wire_load = %6.2f\n", fanout_load, wire_load);

io_printf(" added rise = %6.2f added fall = %6.2f\n", rise, fall);

}

}

}

}

/****************************************************************/ /* Auxiliary routines */ /****************************************************************/

/*

DL_LOAD_FACTOR

*/

/*

This routine accepts a pointer to a net, scans

*/

/*

its connected terminals, and returns the total load

*/

/*

factor on the net. This is determined by finding

*/

/*

specify parameters called FanoutLoad$netname associated

*/

/*

with each load and driver and summing their values.

*/

/***************************************************************/ static double dl_load_factor(net)

handle net;

{

double total_lf = 0;

handle load, load_net, driver_prim, driver_mod, driver_net, driver;

/************************************/ /*** Process each cell input load ***/

/************************************/ load = null;

while (load = acc_next_cell_load(net,load))

{

/**************************************/ /*** Get net connected to this load ***/

/**************************************/ load_net = acc_handle_conn(load);

total_lf += acc_fetch_attribute(load_net, "FanoutLoad$");

}

October 2000

115

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

/*************************************************/ /*** If load has multiple drivers, scan fanin, ***/

/*** adding each lf to total_lf ***/

/*************************************************/ if (acc_count(acc_next_driver,net) > 1)

{

handle

net_mod = acc_handle_parent(net);

/*******************************/

/*** Process each net driver ***/

 

/*******************************/

 

driver

= null;

 

while (driver = acc_next_driver(net, driver))

{

/*****************************************************/ /*** Don’t include load factor of driving terminal ***/

/*****************************************************/ driver_prim = acc_handle_parent(driver);

driver_mod = acc_handle_parent(driver_prim); if (driver_mod == net_mod)

continue;

/****************************************/ /*** Get net connected to this driver ***/

/****************************************/ driver_net = acc_handle_conn(driver);

total_lf += acc_fetch_attribute(driver_net, "FanoutLoad$");

}

}

return (total_lf);

}

/***************************************************************/

/*

DL_ESTIMATE_CAPACITANCE

*/

/*

This routine accepts an integer indicating the

*/

/*

fanout count on a net, and returns the estimated wire

*/

/*

capacitance from table wirecap_est_table (defined

*/

/*

earlier in this file). If the fanout count is larger

*/

/*

than the table allows, a warning is printed, and

*/

/*

the largest value in the table is returned.

*/

/***************************************************************/ static double dl_estimate_capacitance(fanout_count)

int fanout_count;

{

if (fanout_count > wirecap_est_table_size)

{

io_printf("Warning from dl_estimate_capacitance : ", "excessive fanout\n");

fanout_count = wirecap_est_table_size;

}

return (wirecap_est_table[fanout_count-1]);

}

/*************************************************************/ /* Argument processing routines */ /*************************************************************/

/*

DL_PROCESS_SCOPE_ARG

*/

/*

Process first argument: Full hierarchical name of

*/

/*

scope to which delay calculation will be performed.

*/

/*

This routine returns the scope indicated by the

*/

/*

first argument. If the first argument is null,

*/

October 2000

116

Product Version 3.2

 

Back Annotation and Delay Calculation

 

 

Example Listings

 

 

 

 

/*

the invoking module is returned as the scope.

*/

/*

If the first argument does not represent

*/

/*

a valid scope, the invoking module is returned

*/

/*

as the scope and an error is reported. This routine

*/

/*

uses some PLI "tf_" routines and defined values.

*/

/*************************************************************/ static handle dl_process_scope_arg()

{

handle scope = acc_handle_tfarg(1); int arg_type;

if (acc_fetch_type(scope) != accModule)

{

/************************************************************/ /** if task argument is null, set scope to invoking module **/ /************************************************************/ arg_type = tf_typep(1);

if (arg_type == tf_nullparam)

scope = acc_handle_parent(tf_getinstance());

/***********************************************************/ /*** if task argument not null and is not a valid scope, ***/

/*** set scope to invoking module display error ***/

/***********************************************************/ else

{

scope = acc_handle_parent(tf_getinstance()); io_printf("%s%s","Warning from delay calculation :",

"invalid scope argument, setting scope to invoking module\n");

}

}

if (dl_verbose_flag)

io_printf(" Scope : %s\n", acc_fetch_fullname(scope));

return (scope);

}

/***************************************************************/

/*

DL_PROCESS_ESTIMATE_ARG

*/

/*

Process second argument: estimate wire capacitance

*/

/*

or read from file. Return true to indicate estimated

*/

/*

capacitance, false to indicate back-annotated

*/

/*

capacitance. This routine uses various

*/

/*

PLI "tf_" routines and defined values.

*/

/***************************************************************/ static bool dl_process_estimate_arg()

{

 

int

arg_type = tf_typep(2);

char

*arg = (char *)tf_getp(2);

char

net_filename[256];

if (arg_type != tf_string)

{

io_printf("%s%s","Warning from delay calculation :", " invalid second argument, will estimate wire capacitance\n");

/*** return true to indicate estimated capacitance ***/

return (true);

}

if ((arg == null) || (strcmp(arg, "estimate") == 0))

{

October 2000

117

Product Version 3.2

Соседние файлы в папке dsd-07=Verilog