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

Back Annotation and Delay Calculation

Example Listings

if (dl_verbose_flag)

io_printf(" Wire capacitance will be estimated\n");

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

return (true);

}

else

{

if (dl_verbose_flag)

io_printf(" Wire capacitance file : \"%s\"\n", arg);

strcpy(net_filename, arg);

if (!dl_make_backan_table(net_filename))

{

io_printf(" Wire capacitance will be estimated\n"); return(true);

}

/*** return false to indicate back annotated capacitance ***/

return (false);

}

}

s_tfcell veriusertfs[] = {

{usertask,0,

0,0, dl_prim_invoke,0, "$dcalc_prim",1}, {usertask,0, 0,0, dl_path_invoke,0, "$dcalc_path",1}, 0} };

Random Cell Scan and Cell Interconnect Nets

Figure 5-8 on page 119 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 interconnect 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)

October 2000

118

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

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 Section “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 interconnect net names and their associated capacitance values. Figure 4-6 on page 47 shows an example file that adheres to this syntax.

Figure 5-8 Delay calculation: random cell scanning and capacitance values associated with interconnect 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_icn_delays(); local void dl_calc_path_icn_delays();

/*** Auxiliary routines ***/

local double dl_load_factor();

local double dl_estimate_capacitance(); local handle dl_handle_icn();

/*** 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 routine */ /***************************************************************/

/*

DL_PRIM_INVOKE

*/

/*

Begin delay calculation for primitive delay based models

*/

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

October 2000

119

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

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);

}

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

/*

DL_INVOKE

 

*/

/*

This routine invokes delay calculation processing.

*/

/*

It accepts

an argument which indicates 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();

October 2000

120

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

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

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

dl_calc_path_icn_delays(scope,estimate_flag); else

dl_calc_prim_icn_delays(scope,estimate_flag);

/*******************************************************/ /*** If necessary, free back-annotation table memory ***/

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

dl_free_backan_table(); /******************/ /*** Aesthetics ***/

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

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

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

}

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

/*

DL_CALC_PRIM_ICN_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_icn_delays(start_mod,estimate_flag)

handle

start_mod;

bool

estimate_flag;

{

 

handle

mod, term, prim, driver;

handle

portout, portout_net, portout_term, interconnect_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 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;

October 2000

121

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

interconnect_net = null;

while (portout_net = acc_next_loconn(portout,portout_net))

{

/********************************************************/ /** If capacitance is back annotated, get interconnect **/

/**

net for this output net - break out at first

**/

/**

unconnected bit

**/

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

{

interconnect_net = acc_next_hiconn(portout, interconnect_net);

if (interconnect_net == null) break;

}

/*********************/ /*** 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 ***/

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

/********************************************************/ /* Determine estimated or backannotated wire capacitance */ /********************************************************/ if (estimate_flag)

wire_load = dl_estimate_capacitance(fanout_count); else

wire_load = dl_backan_fetch(interconnect_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 that 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 ***/

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

October 2000

122

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

acc_append_delays(prim, rise, fall);

/******************************************************/ /* If requested, print detailed calculation information */ /******************************************************/ 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);

}

}

}

}

}

}

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

/*

DL_CALC_PATH_ICN_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_icn_delays(start_mod,estimate_flag)

handle

start_mod;

bool

estimate_flag;

{

 

handle

mod, path;

handle

pathout_net, interconnect_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))

{

/*****************************/ /*** Get number of fanouts ***/

/*****************************/ pathout_net = acc_handle_pathout(path);

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

continue;

if (!estimate_flag)

interconnect_net = dl_handle_icn(mod,pathout_net);

October 2000

123

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

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

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

/*********************************************************/ /* Determine estimated or backannotated wire capacitance */ /*********************************************************/ if (estimate_flag)

wire_load = dl_estimate_capacitance(fanout_count); else

wire_load = dl_backan_fetch(interconnect_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); 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 */

October 2000

124

Product Version 3.2

 

Back Annotation and Delay Calculation

 

 

Example Listings

 

 

 

 

/*

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$");

}

/*************************************************/ /*** 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);

}

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

October 2000

125

Product Version 3.2

 

Back Annotation and Delay Calculation

 

 

Example Listings

 

 

 

 

/*

DL_HANDLE_ICN

*/

/*

This routine accepts a handle to a scope and a net,

*/

/*

and returns the interconnect net (hiconn) that the

*/

/*

net is connected to.

*/

/**************************************************************/ static handle dl_handle_icn(mod,cell_output_net)

handle mod, cell_output_net;

{

handle portout;

/*********************************************************/ /*** Scan output ports until the one fed by the net is ***/

/*** found, then return the hiconn net ***/

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

while (portout = acc_next_portout(mod,portout))

{

if (acc_next_loconn(portout,null) == cell_output_net) return(acc_next_hiconn(portout,null));

}

/******************************************************/ /*** Print warning and return null if net not found ***/

/******************************************************/ io_printf("Warning from dl_handle_icn : ", "output net \"%s\" not

found\n", acc_fetch_fullname(cell_output_net)); return(null);

}

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

/*

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 is performed. This routine

*/

/*

returns the scope indicated by the first argument. If the

*/

/*

first argument is null, 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

*/

October 2000

126

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

/***************************************************************/ 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))

{

if (dl_verbose_flag)

io_printf(" Wire capacitance will be estimated\n");

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

return (true);

}

October 2000

127

Product Version 3.2

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