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

Back Annotation and Delay Calculation

Example Listings

{0}

};

Delay Calculation Driven by a Cell Interconnect Nets

Figure 5-10 on page 135 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 read a capacitance back annotation file that contains interconnect net names and their associated capacitance values. The entries in this file are used to drive the delay calculation process. Note that the two delay calculators share a large set of common source code.

The system tasks associated with these delay calculators require a single argument enclosed in double quotes—the name of the capacitance back annotation file. 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.

The capacitance back annotation file associated with these delay calculators must contain pairs of interconnect net names and capacitance values. Figure 4-6 on page 47 shows an example file that adheres to this syntax.

Figure 5-10 Delay calculation: cell scanning driven by capacitance file with interconnect net names

#include <stdio.h> #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_delays(); local void dl_ann_prim_delays(); local void dl_ann_path_delays();

/*** Auxiliary routines ***/

local double dl_load_factor(); local void dl_net_init(); local void dl_net_insert(); local bool dl_net_done();

/*** Global variables ***/

bool dl_verbose_flag = false; int cellout_count;

#define dlPrim 1 #define dlPath 2

#define MAX_CELLOUT_HANDLES 256

October 2000

135

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

/*** More global variables ***/

handle cellout_array[MAX_CELLOUT_HANDLES];

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

/*

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

}

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

/*

DL_INVOK

 

*/

/*

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;

int

arg_type = tf_typep(1);

char

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

char

net_filename[256];

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

October 2000

136

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

}

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

/*** Process argument to get name of capacitance file ***/

/********************************************************/ if (arg_type != tf_string)

{

io_printf("%s%s\n","Warning from delay calculation :",

" invalid argument, no delay calculation will be performed"); return;

}

if (dl_verbose_flag)

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

strcpy(net_filename, arg); /*************************************/ /*** Calculate interconnect delays ***/

/*************************************/ dl_calc_delays(prim_or_path,net_filename);

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

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

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

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

}

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

/*

DL_CALC_DELAYS

*/

/*

This routine reads a back annotation file with

*/

/*

capacitance values associated with interconnect nets

*/

/*

and performs delay calculation, placing the delays

*/

/*

on the primitives driving the associated cell output net

*/

/*

or the paths feeding the associated cell output net in all */

/*

cells with output or inout ports that feed this net.

*/

/****************************************************************/ static void dl_calc_delays(prim_or_path,net_filename)

int prim_or_path; char *net_filename;

{

handle interconnect_net, cellout_net; handle driver;

FILE *net_file; int fanout_count;

double fanout_load, wire_load; char interconnect_name[256];

/*********************************************************/ /*** Read each net/capacitance pair and calculate ***/

/*** the delays for the net ***/

/***********************************************************/ if ((net_file = fopen(net_filename,"r")) == null)

{

io_printf("Warning: Back-annotate file \"%s\" not found. %s\n", net_filename,"No delays will be calculated.");

return;

}

October 2000

137

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

while (fscanf(net_file,"%s%lf\n",interconnect_name,&wire_load) != EOF)

{

if ((interconnect_net = acc_handle_object(interconnect_name)) == null)

{

io_printf("Warning: Interconnect net \"%s\" not found.\n", interconnect_name);

continue;

}

/****************************************************/ /*** Scan all cells with ports that feed this net ***/

/****************************************************/ dl_net_init();

driver = null;

while (driver = acc_next_driver(interconnect_net,driver))

{

/**************************************/ /*** Skip if this net has been done ***/

/**************************************/ cellout_net = acc_handle_conn(driver); if (dl_net_done(cellout_net))

continue;

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

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

fanout_count = acc_count(acc_next_cell_load,cellout_net);

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

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

/*** Calculate and annotate the delays ***/

/*****************************************/ if (prim_or_path == dlPrim)

dl_ann_prim_delays(cellout_net,fanout_load,wire_load); else

dl_ann_path_delays(cellout_net,fanout_load,wire_load);

dl_net_insert(cellout_net);

}

}

}

/***************************************************************/ /* DL_ANN_PRIM_DELAYS

/* This routine accepts a handle to a cell output net and the total /* fanout loading on the net, retrieves the rise and fall strength /* associated with the net, calculates the delays for the net and /* annotates them to all drivers on the net in the current scope. /****************************************************************/ static void dl_ann_prim_delays(net,fanout_load,wire_load)

handle net;

double fanout_load, wire_load;

{

double rise_strength, fall_strength; double rise, fall;

handle driver, prim, parent;

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

October 2000

138

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

/*** Determine attributes associated with the net ***/

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

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

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

rise = rise_strength * (fanout_load + wire_load); fall = fall_strength * (fanout_load + wire_load);

/*******************************************************/ /*** Add the delays to all primitives in the current ***/

/*** module that drive this net ***/

/*******************************************************/ parent = acc_handle_parent(net);

driver = null;

while (driver = acc_next_driver(net,driver))

{

prim = acc_handle_parent(driver);

if (acc_handle_parent(prim) != parent) continue;

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

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

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

/* This routine accepts a handle to a cell output net and the total /* fanout loading on the net, retrieves the rise and fall strength /* associated with the path feeding the net, calculates the delays /* for the net and annotates them to all paths feeding the net.

/****************************************************************/ static void dl_ann_path_delays(net,fanout_load,wire_load)

handle net;

double fanout_load, wire_load;

{

handle parent, path;

double rise_strength, fall_strength, rise, fall;

October 2000

139

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

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

/*** For

each

path that feeds

the net, retrieve ***/

/***

the

strength

attributes,

calculate and

***/

/***

annotate

the

delays

 

***/

/**************************************************/ parent = acc_handle_parent(net);

path = null;

while (path = acc_next_modpath(parent,path))

{

if (acc_handle_pathout(path) != net) continue;

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

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

October 2000

140

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

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

}

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

/*

DL_NET_INIT

*/

/*

This routine initializes the global net storage

*/

/*

variables and structures.

*/

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

static void dl_net_init()

{

cellout_count = 0;

}

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

/*

DL_NET_INSERT

 

 

*/

/*

This routine accepts a handle

to a net and stores

*/

/*

the handle in

the net storage

structure.

*/

October 2000

141

Product Version 3.2

Back Annotation and Delay Calculation

Example Listings

/***************************************************************/ static void dl_net_insert(net)

handle net;

{

if (cellout_count >= MAX_CELLOUT_HANDLES - 1)

{

io_printf("Error in dl_net_insert : cell handle overflow. %s\n", "Delay calculation may contain errors");

return;

}

cellout_array[cellout_count++] = net;

}

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

/*

DL_NET_DONE

 

*/

/*

This routine accepts a handle to a net and checks whether */

/*

it exists in the net storage structure. If

so, this

*/

/*

routine returns TRUE; otherwise, it returns

FALSE.

*/

/***************************************************************/ static bool dl_net_done(net)

handle net;

{

int i;

if (cellout_count > 0)

{

for (i = 0; i < cellout_count; i++)

{

if (cellout_array[i] == net) return(TRUE);

}

}

return(FALSE);

}

s_tfcell veriusertfs[] = { {usertask,0, 0,0,

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

October 2000

142

Product Version 3.2

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