?? time.c.svn-base
字號:
/*------------------------------------------------------------
* CACTI 4.0
* Copyright 2005 Hewlett-Packard Development Corporation
* All Rights Reserved
*
* Permission to use, copy, and modify this software and its documentation is
* hereby granted only under the following terms and conditions. Both the
* above copyright notice and this permission notice must appear in all copies
* of the software, derivative works or modified versions, and any portions
* thereof, and both notices must appear in supporting documentation.
*
* Users of this software agree to the terms and conditions set forth herein, and
* hereby grant back to Hewlett-Packard Company and its affiliated companies ("HP")
* a non-exclusive, unrestricted, royalty-free right and license under any changes,
* enhancements or extensions made to the core functions of the software, including
* but not limited to those affording compatibility with other hardware or software
* environments, but excluding applications which incorporate this software.
* Users further agree to use their best efforts to return to HP any such changes,
* enhancements or extensions that they make and inform HP of noteworthy uses of
* this software. Correspondence should be provided to HP at:
*
* Director of Intellectual Property Licensing
* Office of Strategy and Technology
* Hewlett-Packard Company
* 1501 Page Mill Road
* Palo Alto, California 94304
*
* This software may be distributed (but not offered for sale or transferred
* for compensation) to third parties, provided such third parties agree to
* abide by the terms and conditions of this notice.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND HP DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL HP
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*------------------------------------------------------------*/
#include <math.h>
#include "def.h"
#include "areadef.h"
#include "leakage.h"
#include "basic_circuit.h"
#include "stdio.h"
//extern double calculate_area (area_type, double);
//v4.1: Earlier all the dimensions (length/width/thickness) of transistors and wires and
//all delays were calculated for the 0.8 micron process and then scaled to the input techology.
//Now all dimensions and delays are calculated directly for the input technology.
int force_tag, force_tag_size;
void reset_tag_device_widths() {
Wtdecdrivep_second= 0.0;
Wtdecdriven_second= 0.0;
Wtdecdrivep_first= 0.0;
Wtdecdriven_first= 0.0;
Wtdec3to8n = 0.0;
Wtdec3to8p = 0.0;
WtdecNORn = 0.0;
WtdecNORp = 0.0;
Wtdecinvn = 0.0;
Wtdecinvp = 0.0;
WtwlDrvn = 0.0;
WtwlDrvp = 0.0;
Wtbitpreequ= 0.0;
Wtiso= 0.0;
Wtpch= 0.0;
Wtiso= 0.0;
WtsenseEn= 0.0;
WtsenseN= 0.0;
WtsenseP= 0.0;
WtoBufN = 0.0;
WtoBufP = 0.0;
WtsPch= 0.0;
WtpchDrvp= 0.0; WtpchDrvn= 0.0;
WtisoDrvp= 0.0; WtisoDrvn= 0.0;
WtspchDrvp= 0.0; WtspchDrvn= 0.0;
WtsenseEnDrvp= 0.0; WtsenseEnDrvn= 0.0;
WtwrtMuxSelDrvn= 0.0;
WtwrtMuxSelDrvp= 0.0;
}
void reset_data_device_widths()
{
Waddrdrvn1 = 0.0;
Waddrdrvp1= 0.0;
Waddrdrvn2= 0.0;
Waddrdrvp2= 0.0;
Wdecdrivep_second = 0.0;
Wdecdriven_second = 0.0;
Wdecdrivep_first = 0.0;
Wdecdriven_first = 0.0;
Wdec3to8n = 0.0;
Wdec3to8p = 0.0;
WdecNORn = 0.0;
WdecNORp = 0.0;
Wdecinvn = 0.0;
Wdecinvp = 0.0;
WwlDrvn = 0.0;
WwlDrvp = 0.0;
Wbitpreequ= 0.0;
Wiso = 0.0;
Wpch= 0.0;
Wiso= 0.0;
WsenseEn= 0.0;
WsenseN= 0.0;
WsenseP= 0.0;
WoBufN = 0.0;
WoBufP = 0.0;
WsPch= 0.0;
WpchDrvp= 0.0; WpchDrvn= 0.0;
WisoDrvp= 0.0; WisoDrvn= 0.0;
WspchDrvp= 0.0; WspchDrvn= 0.0;
WsenseEnDrvp= 0.0; WsenseEnDrvn= 0.0;
WwrtMuxSelDrvn= 0.0;
WwrtMuxSelDrvp= 0.0;
WmuxdrvNANDn = 0.0;
WmuxdrvNANDp = 0.0;
WmuxdrvNORn = 0.0;
WmuxdrvNORp = 0.0;
Wmuxdrv3n = 0.0;
Wmuxdrv3p = 0.0;
Woutdrvseln = 0.0;
Woutdrvselp = 0.0;
Woutdrvnandn= 0.0;
Woutdrvnandp= 0.0;
Woutdrvnorn = 0.0;
Woutdrvnorp = 0.0;
Woutdrivern = 0.0;
Woutdriverp = 0.0;
}
void compute_device_widths(int C,int B,int A,int fullyassoc, int Ndwl,int Ndbl,double Nspd)
{
int rows, cols, numstack,l_predec_nor_v,l_predec_nor_h;
double desiredrisetime, Rpdrive, Cline, Cload;
double effWdecNORn,effWdecNORp,effWdec3to8n,effWdec3to8p, wire_res, wire_cap;
int l_outdrv_v,l_outdrv_h;
//int rows_fa_subarray,cols_fa_subarray, tagbits;
int tagbits;
int horizontal_edge = 0;
int nr_subarrays_left = 0, v_or_h = 0;
int horizontal_step = 0, vertical_step = 0;
int h_inv_predecode = 0, v_inv_predecode = 0;
double previous_ndriveW = 0, previous_pdriveW = 0, current_ndriveW = 0, current_pdriveW = 0;
int i;
//v4.1: Fixing double->int type conversion problems. EPSILON is added below to make sure
//the final int value is the correct one
//rows = C/(CHUNKSIZE*B*A*Ndbl*Nspd);
rows = (int) (C/(CHUNKSIZE*B*A*Ndbl*Nspd) + EPSILON);
//cols = CHUNKSIZE*B*A*Nspd/Ndwl;
cols = (int) (CHUNKSIZE*B*A*Nspd/Ndwl + EPSILON);
// Wordline capacitance to determine the wordline driver size
/* Use a first-order approx */
desiredrisetime = krise*log((double)(cols))/2.0;
/*dt: I'm changing this back to what's in CACTI (as opposed to eCacti), i.e. counting the short poly connection to the pass transistors*/
Cline = (gatecappass(Wmemcella,(BitWidth-2*Wmemcella)/2.0)+ gatecappass(Wmemcella,(BitWidth-2*Wmemcella)/2.0)+ Cwordmetal)*cols;
Rpdrive = desiredrisetime/(Cline*log(VSINV)*-1.0);
WwlDrvp = restowidth(Rpdrive,PCH);
if (WwlDrvp > Wworddrivemax) {
WwlDrvp = Wworddrivemax;
}
/* Now that we have a reasonable psize, do the rest as before */
/* If we keep the ratio the same as the tag wordline driver,
the threshold voltage will be close to VSINV */
/* assuming that nsize is half the psize */
WwlDrvn = WwlDrvp/2;
// Size of wordline
// Sizing ratio for optimal delay is 3-4.
Wdecinvn = (WwlDrvp + WwlDrvn) * SizingRatio * 1/3;
Wdecinvp = (WwlDrvp + WwlDrvn) * SizingRatio * 2/3;
// determine size of nor and nand gates in the decoder
// width of NOR driving decInv -
// effective width (NORp + NORn = Cout/SizingRatio( FANOUT))
// Cout = Wdecinvn + Wdecinvp; SizingRatio = 3;
// nsize = effWidth/3; psize = 2*effWidth/3;
numstack =
(int)ceil((1.0/3.0)*logtwo( (double)((double)C/(double)(B*A*Ndbl*Nspd))));
if (numstack==0) numstack = 1;
if (numstack>5) numstack = 5;
effWdecNORn = (Wdecinvn + Wdecinvp)*SizingRatio/3;
effWdecNORp = 2*(Wdecinvn + Wdecinvp)*SizingRatio/3;
WdecNORn = effWdecNORn;
WdecNORp = effWdecNORp * numstack;
/* second stage: driving a bunch of nor gates with a nand */
/*dt: The *8 is there because above we mysteriously divide the capacity in BYTES by the number of BITS per wordline */
l_predec_nor_v = rows*CHUNKSIZE;
/*dt: If we follow the original drawings from the TR's, then there is almost no horizontal wires, only the poly for contacting
the nor gates. The poly part we don't model right now */
l_predec_nor_h = 0;
//v4.1: Scaling the poly length to the input tech node.
//Cline = gatecap(WdecNORn+WdecNORp,((numstack*40)+20.0))*rows/8 +
//GlobalCbitmetal*(l_predec_nor_v)+GlobalCwordmetal*(l_predec_nor_h);
Cline = gatecap(WdecNORn+WdecNORp,((numstack*40 / FUDGEFACTOR)+20.0 / FUDGEFACTOR))*rows/8 +
GlobalCbitmetal*(l_predec_nor_v)+GlobalCwordmetal*(l_predec_nor_h);
Cload = Cline / gatecap(1.0,0.0);
effWdec3to8n = Cload*SizingRatio/3;
effWdec3to8p = 2*Cload*SizingRatio/3;
Wdec3to8n = effWdec3to8n * 3; // nand3 gate
Wdec3to8p = effWdec3to8p;
// size of address drivers before decoders
/* First stage: driving the decoders */
//v4.1: Fixing double->int type conversion problems. EPSILON is added below to make sure
//the final int value is the correct one
//horizontal_edge = CHUNKSIZE*B*A*Nspd;
horizontal_edge = (int) (CHUNKSIZE*B*A*Nspd + EPSILON);
previous_ndriveW = Wdec3to8n;
previous_pdriveW = Wdec3to8p;
if(Ndwl*Ndbl==1 ) {
wire_cap = GlobalCwordmetal*horizontal_edge;
wire_res = 0.5*GlobalRwordmetal*horizontal_edge;
Cdectreesegments[0] = GlobalCwordmetal*horizontal_edge;
Rdectreesegments[0] = 0.5*GlobalRwordmetal*horizontal_edge;
Cline = 4*gatecap(previous_ndriveW+previous_pdriveW,10.0 / FUDGEFACTOR)+GlobalCwordmetal*horizontal_edge;
Cload = Cline / gatecap(1.0,0.0);
current_ndriveW = Cload*SizingRatio/3;
current_pdriveW = 2*Cload*SizingRatio/3;
nr_dectreesegments = 0;
}
else if(Ndwl*Ndbl==2 || Ndwl*Ndbl==4) {
wire_cap = GlobalCwordmetal*horizontal_edge;
wire_res = 0.5*GlobalRwordmetal*horizontal_edge;
Cdectreesegments[0] = GlobalCwordmetal*horizontal_edge;
Rdectreesegments[0] = 0.5*GlobalRwordmetal*horizontal_edge;
Cline = 4*gatecap(previous_ndriveW+previous_pdriveW,10.0 / FUDGEFACTOR)+GlobalCwordmetal*horizontal_edge;
Cload = Cline / gatecap(1.0,0.0);
current_ndriveW = Cload*SizingRatio/3;
current_pdriveW = 2*Cload*SizingRatio/3;
nr_dectreesegments = 0;
}
else {
/*dt: For the critical path in an H-Tree, the metal */
nr_subarrays_left = Ndwl* Ndbl;
/*all the wires go to quads of subarrays where they get predecoded*/
nr_subarrays_left /= 4;
//v4.1: Fixing double->int type conversion problems. EPSILON is added below to make sure
//the final int value is the correct one
//horizontal_step = CHUNKSIZE*B*A*Nspd/Ndwl;
horizontal_step = (int) (CHUNKSIZE*B*A*Nspd/Ndwl + EPSILON);
//vertical_step = C/(B*A*Ndbl*Nspd);
vertical_step = (int) (C/(B*A*Ndbl*Nspd) + EPSILON);
h_inv_predecode = horizontal_step;
Cdectreesegments[0] = GlobalCwordmetal*horizontal_step;
Rdectreesegments[0] = 0.5*GlobalRwordmetal*horizontal_step;
Cline = 4*gatecap(previous_ndriveW+previous_pdriveW,10.0 / FUDGEFACTOR)+GlobalCwordmetal*horizontal_step;
Cload = Cline / gatecap(1.0,0.0);
current_ndriveW = Cload*SizingRatio/3;
current_pdriveW = 2*Cload*SizingRatio/3;
WdecdrivetreeN[0] = current_ndriveW;
nr_dectreesegments = 1;
horizontal_step *= 2;
v_or_h = 1; // next step is vertical
while(nr_subarrays_left > 1) {
previous_ndriveW = current_ndriveW;
previous_pdriveW = current_pdriveW;
nr_dectreesegments++;
if(v_or_h) {
v_inv_predecode += vertical_step;
Cdectreesegments[nr_dectreesegments-1] = GlobalCbitmetal*vertical_step;
Rdectreesegments[nr_dectreesegments-1] = 0.5*GlobalRbitmetal*vertical_step;
Cline = gatecap(previous_ndriveW+previous_pdriveW,0)+GlobalCbitmetal*vertical_step;
v_or_h = 0;
vertical_step *= 2;
nr_subarrays_left /= 2;
}
else {
h_inv_predecode += horizontal_step;
Cdectreesegments[nr_dectreesegments-1] = GlobalCwordmetal*horizontal_step;
Rdectreesegments[nr_dectreesegments-1] = 0.5*GlobalRwordmetal*horizontal_step;
Cline = gatecap(previous_ndriveW+previous_pdriveW,0)+GlobalCwordmetal*horizontal_step;
v_or_h = 1;
horizontal_step *= 2;
nr_subarrays_left /= 2;
}
Cload = Cline / gatecap(1.0,0.0);
current_ndriveW = Cload*SizingRatio/3;
current_pdriveW = 2*Cload*SizingRatio/3;
WdecdrivetreeN[nr_dectreesegments-1] = current_ndriveW;
}
if(nr_dectreesegments >= 10) {
printf("Too many segments in the data decoder H-tree. Overflowing the preallocated array!");
exit(1);
}
wire_cap = GlobalCbitmetal*v_inv_predecode + GlobalCwordmetal*h_inv_predecode;
wire_res = 0.5*(GlobalRbitmetal*v_inv_predecode + GlobalRwordmetal*h_inv_predecode);
}
Wdecdriven_second = current_ndriveW;
Wdecdrivep_second = current_pdriveW;
// Size of second driver
Wdecdriven_first = (Wdecdriven_second + Wdecdrivep_second)*SizingRatio/3;
Wdecdrivep_first = 2*(Wdecdriven_second + Wdecdrivep_second)*SizingRatio/3;
// these are the widths of the devices of dataoutput devices
// will be used in the data_senseamplifier_data and dataoutput_data functions
l_outdrv_v = 0;
l_outdrv_h = 0;
if(!fullyassoc) {
//v4.1: Fixing double->int type conversion problems. EPSILON is added below to make sure
//the final int value is the correct one
//rows = (C/(B*A*Ndbl*Nspd));
//cols = (CHUNKSIZE*B*A*Nspd/Ndwl);
rows = (int) (C/(B*A*Ndbl*Nspd) + EPSILON);
cols = (int) (CHUNKSIZE*B*A*Nspd/Ndwl + EPSILON);
}
else {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -