PageRenderTime 55ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/orion/SIM_time.c

https://gitlab.com/pranith/macsim
C | 1095 lines | 623 code | 223 blank | 249 comment | 39 complexity | 8a8d456dd9c7ec828f5e75428f76a0d5 MD5 | raw file
  1. /*-------------------------------------------------------------------------
  2. * ORION 2.0
  3. *
  4. * Copyright 2009
  5. * Princeton University, and Regents of the University of California
  6. * All Rights Reserved
  7. *
  8. *
  9. * ORION 2.0 was developed by Bin Li at Princeton University and Kambiz Samadi at
  10. * University of California, San Diego. ORION 2.0 was built on top of ORION 1.0.
  11. * ORION 1.0 was developed by Hangsheng Wang, Xinping Zhu and Xuning Chen at
  12. * Princeton University.
  13. *
  14. * If your use of this software contributes to a published paper, we
  15. * request that you cite our paper that appears on our website
  16. * http://www.princeton.edu/~peh/orion.html
  17. *
  18. * Permission to use, copy, and modify this software and its documentation is
  19. * granted only under the following terms and conditions. Both the
  20. * above copyright notice and this permission notice must appear in all copies
  21. * of the software, derivative works or modified versions, and any portions
  22. * thereof, and both notices must appear in supporting documentation.
  23. *
  24. * This software may be distributed (but not offered for sale or transferred
  25. * for compensation) to third parties, provided such third parties agree to
  26. * abide by the terms and conditions of this notice.
  27. *
  28. * This software is distributed in the hope that it will be useful to the
  29. * community, but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  31. *
  32. *-----------------------------------------------------------------------*/
  33. /*------------------------------------------------------------
  34. * Copyright 1994 Digital Equipment Corporation and Steve Wilton
  35. * All Rights Reserved
  36. *
  37. * Permission to use, copy, and modify this software and its documentation is
  38. * hereby granted only under the following terms and conditions. Both the
  39. * above copyright notice and this permission notice must appear in all copies
  40. * of the software, derivative works or modified versions, and any portions
  41. * thereof, and both notices must appear in supporting documentation.
  42. *
  43. * Users of this software agree to the terms and conditions set forth herein,
  44. * and hereby grant back to Digital a non-exclusive, unrestricted, royalty-
  45. * free right and license under any changes, enhancements or extensions
  46. * made to the core functions of the software, including but not limited to
  47. * those affording compatibility with other hardware or software
  48. * environments, but excluding applications which incorporate this software.
  49. * Users further agree to use their best efforts to return to Digital any
  50. * such changes, enhancements or extensions that they make and inform Digital
  51. * of noteworthy uses of this software. Correspondence should be provided
  52. * to Digital at:
  53. *
  54. * Director of Licensing
  55. * Western Research Laboratory
  56. * Digital Equipment Corporation
  57. * 100 Hamilton Avenue
  58. * Palo Alto, California 94301
  59. *
  60. * This software may be distributed (but not offered for sale or transferred
  61. * for compensation) to third parties, provided such third parties agree to
  62. * abide by the terms and conditions of this notice.
  63. *
  64. * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  65. * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  66. * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
  67. * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  68. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  69. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  70. * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  71. * SOFTWARE.
  72. *------------------------------------------------------------*/
  73. #include <math.h>
  74. #include <assert.h>
  75. #include <stdio.h>
  76. #include "SIM_parameter.h"
  77. #include "SIM_time.h"
  78. #include "SIM_array.h"
  79. static double logtwo(double x)
  80. {
  81. assert(x > 0);
  82. return log10(x)/log10(2);
  83. }
  84. /*----------------------------------------------------------------------*/
  85. /*
  86. * width - gate width in um (length is Leff)
  87. * wirelength - poly wire length going to gate in lambda
  88. * return gate capacitance in Farads
  89. */
  90. double SIM_gatecap(double width,double wirelength)
  91. {
  92. double overlapCap;
  93. double gateCap;
  94. double l = 0.1525;
  95. #if defined(Pdelta_w)
  96. overlapCap = (width - 2*Pdelta_w) * PCov;
  97. gateCap = ((width - 2*Pdelta_w) * (l * LSCALE - 2*Pdelta_l) *
  98. PCg) + 2.0 * overlapCap;
  99. return gateCap;
  100. #endif
  101. return(width*Leff*PARM(Cgate)*SCALE_T+wirelength*Cpolywire*Leff * SCALE_T);
  102. /* return(width*Leff*PARM(Cgate)); */
  103. /* return(width*CgateLeff+wirelength*Cpolywire*Leff);*/
  104. }
  105. /*
  106. * width - gate width in um (length is Leff)
  107. * wirelength - poly wire length going to gate in lambda
  108. *
  109. * return gate capacitance in Farads
  110. */
  111. double SIM_gatecappass(double width, double wirelength)
  112. {
  113. return(SIM_gatecap(width,wirelength));
  114. /* return(width*Leff*PARM(Cgatepass)+wirelength*Cpolywire*Leff); */
  115. }
  116. /*----------------------------------------------------------------------*/
  117. /* Routine for calculating drain capacitances. The draincap routine
  118. * folds transistors larger than 10um */
  119. /*
  120. * width - um
  121. * nchannel - whether n or p-channel (boolean)
  122. * stack - number of transistors in series that are on
  123. *
  124. * return drain cap in Farads
  125. */
  126. double SIM_draincap(double width, int nchannel, int stack)
  127. {
  128. double Cdiffside,Cdiffarea,Coverlap,cap;
  129. double overlapCap;
  130. double swAreaUnderGate;
  131. double area_peri;
  132. double diffArea;
  133. double diffPeri;
  134. double l = 0.4 * LSCALE;
  135. diffArea = l * width;
  136. diffPeri = 2 * l + 2 * width;
  137. #if defined(Pdelta_w)
  138. if(nchannel == 0) {
  139. overlapCap = (width - 2 * Pdelta_w) * PCov;
  140. swAreaUnderGate = (width - 2 * Pdelta_w) * PCjswA;
  141. area_peri = ((diffArea * PCja)
  142. + (diffPeri * PCjsw));
  143. return(stack*(area_peri + overlapCap + swAreaUnderGate));
  144. }
  145. else {
  146. overlapCap = (width - 2 * Ndelta_w) * NCov;
  147. swAreaUnderGate = (width - 2 * Ndelta_w) * NCjswA;
  148. area_peri = ((diffArea * NCja * LSCALE)
  149. + (diffPeri * NCjsw * LSCALE));
  150. return(stack*(area_peri + overlapCap + swAreaUnderGate));
  151. }
  152. #endif
  153. Cdiffside = (nchannel) ? PARM(Cndiffside) : PARM(Cpdiffside);
  154. Cdiffarea = (nchannel) ? PARM(Cndiffarea) : PARM(Cpdiffarea);
  155. //Coverlap = (nchannel) ? (PARM(Cndiffovlp)+PARM(Cnoxideovlp)) :
  156. // (PARM(Cpdiffovlp)+PARM(Cpoxideovlp));
  157. Coverlap = (nchannel) ? PARM(Cnoverlap) : PARM(Cpoverlap);
  158. /* calculate directly-connected (non-stacked) capacitance */
  159. /* then add in capacitance due to stacking */
  160. if (width >= 10) {
  161. cap = 3.0*Leff*width/2.0*Cdiffarea + 6.0*Leff*Cdiffside +
  162. width*Coverlap;
  163. cap += (double)(stack-1)*(Leff*width*Cdiffarea +
  164. 4.0*Leff*Cdiffside + 2.0*width*Coverlap);
  165. } else {
  166. cap = 3.0*Leff*width*Cdiffarea + (6.0*Leff+width)*Cdiffside +
  167. width*Coverlap;
  168. cap += (double)(stack-1)*(Leff*width*Cdiffarea +
  169. 2.0*Leff*Cdiffside + 2.0*width*Coverlap);
  170. }
  171. return(cap * SCALE_T);
  172. }
  173. /*----------------------------------------------------------------------*/
  174. /* The following routines estimate the effective resistance of an
  175. on transistor as described in the tech report. The first routine
  176. gives the "switching" resistance, and the second gives the
  177. "full-on" resistance */
  178. /*
  179. * width - um
  180. * nchannel - whether n or p-channel (boolean)
  181. * stack - number of transistors in series
  182. *
  183. * return resistance in ohms
  184. */
  185. double SIM_transresswitch(double width, int nchannel, int stack)
  186. {
  187. double restrans;
  188. restrans = (nchannel) ? (Rnchannelstatic):
  189. (Rpchannelstatic);
  190. /* calculate resistance of stack - assume all but switching trans
  191. have 0.8X the resistance since they are on throughout switching */
  192. return((1.0+((stack-1.0)*0.8))*restrans/width);
  193. }
  194. /*----------------------------------------------------------------------*/
  195. /*
  196. * width - um
  197. * nchannel - whether n or p-channel (boolean)
  198. * stack - number of transistors in series
  199. *
  200. * return resistance in ohms
  201. */
  202. double SIM_transreson(double width, int nchannel, int stack)
  203. {
  204. double restrans;
  205. restrans = (nchannel) ? Rnchannelon : Rpchannelon;
  206. /* calculate resistance of stack. Unlike transres, we don't
  207. multiply the stacked transistors by 0.8 */
  208. return(stack*restrans/width);
  209. }
  210. /*----------------------------------------------------------------------*/
  211. /* This routine operates in reverse: given a resistance, it finds
  212. * the transistor width that would have this R. It is used in the
  213. * data wordline to estimate the wordline driver size. */
  214. /*
  215. * res - resistance in ohms
  216. * nchannel - whether n or p-channel (boolean)
  217. *
  218. * return width in um
  219. */
  220. double SIM_restowidth(double res, int nchannel)
  221. {
  222. double restrans;
  223. restrans = (nchannel) ? Rnchannelon : Rpchannelon;
  224. return(restrans/res);
  225. }
  226. /*----------------------------------------------------------------------*/
  227. /*
  228. * inputramptime - input rise time
  229. * tf - time constant of gate
  230. * vs1 - threshold voltages
  231. * vs2 - threshold voltages
  232. * rise - whether INPUT rise or fall (boolean)
  233. */
  234. double SIM_horowitz(double inputramptime, double tf, double vs1, double vs2, int rise)
  235. {
  236. double a,b,td;
  237. a = inputramptime/tf;
  238. if (rise==RISE) {
  239. b = 0.5;
  240. td = tf*sqrt(fabs( log(vs1)*log(vs1)+2*a*b*(1.0-vs1))) +
  241. tf*(log(vs1)-log(vs2));
  242. } else {
  243. b = 0.4;
  244. td = tf*sqrt(fabs( log(1.0-vs1)*log(1.0-vs1)+2*a*b*(vs1))) +
  245. tf*(log(1.0-vs1)-log(1.0-vs2));
  246. }
  247. return(td);
  248. }
  249. /*======================================================================*/
  250. /*
  251. * This part of the code contains routines for each section as
  252. * described in the tech report. See the tech report for more details
  253. * and explanations */
  254. /*----------------------------------------------------------------------*/
  255. /* Decoder delay: (see section 6.1 of tech report) */
  256. double SIM_decoder_delay(int C, int B, int A, int Ndwl, int Ndbl, int Nspd, int Ntwl, int Ntbl, int Ntspd, double *Tdecdrive,
  257. double *Tdecoder1, double *Tdecoder2, double *outrisetime)
  258. {
  259. double Ceq,Req,Rwire,rows,tf,nextinputtime,vth = 0,tstep,m,a,b,c;
  260. int numstack;
  261. double z = 0.0;
  262. /* Calculate rise time. Consider two inverters */
  263. Ceq = SIM_draincap(Wdecdrivep,PCH,1)+SIM_draincap(Wdecdriven,NCH,1) +
  264. SIM_gatecap(Wdecdrivep+Wdecdriven,0.0);
  265. tf = Ceq*SIM_transreson(Wdecdriven,NCH,1);
  266. nextinputtime = SIM_horowitz(z,tf,PARM(VTHINV100x60),PARM(VTHINV100x60),FALL)/
  267. (PARM(VTHINV100x60));
  268. Ceq = SIM_draincap(Wdecdrivep,PCH,1)+SIM_draincap(Wdecdriven,NCH,1) +
  269. SIM_gatecap(Wdecdrivep+Wdecdriven,0.0);
  270. tf = Ceq*SIM_transreson(Wdecdriven,NCH,1);
  271. nextinputtime = SIM_horowitz(nextinputtime,tf,PARM(VTHINV100x60),PARM(VTHINV100x60),
  272. RISE)/
  273. (1.0-PARM(VTHINV100x60));
  274. /* First stage: driving the decoders */
  275. rows = C/(8*B*A*Ndbl*Nspd);
  276. Ceq = SIM_draincap(Wdecdrivep,PCH,1)+SIM_draincap(Wdecdriven,NCH,1) +
  277. 4*SIM_gatecap(Wdec3to8n+Wdec3to8p,10.0)*(Ndwl*Ndbl)+
  278. Cwordmetal*0.25*8*B*A*Ndbl*Nspd;
  279. Rwire = Rwordmetal*0.125*8*B*A*Ndbl*Nspd;
  280. tf = (Rwire + SIM_transreson(Wdecdrivep,PCH,1))*Ceq;
  281. *Tdecdrive = SIM_horowitz(nextinputtime,tf,PARM(VTHINV100x60),PARM(VTHNAND60x90),
  282. FALL);
  283. nextinputtime = *Tdecdrive/PARM(VTHNAND60x90);
  284. /* second stage: driving a bunch of nor gates with a nand */
  285. numstack =
  286. (int)(ceil((1.0/3.0)*logtwo( (double)((double)C/(double)(B*A*Ndbl*Nspd)))));
  287. if (numstack==0) numstack = 1;
  288. if (numstack>5) numstack = 5;
  289. Ceq = 3*SIM_draincap(Wdec3to8p,PCH,1) +SIM_draincap(Wdec3to8n,NCH,3) +
  290. SIM_gatecap(WdecNORn+WdecNORp,((numstack*40)+20.0))*rows +
  291. Cbitmetal*rows*8;
  292. Rwire = Rbitmetal*rows*8/2;
  293. tf = Ceq*(Rwire+SIM_transreson(Wdec3to8n,NCH,3));
  294. /* we only want to charge the output to the threshold of the
  295. nor gate. But the threshold depends on the number of inputs
  296. to the nor. */
  297. switch(numstack) {
  298. case 1: vth = PARM(VTHNOR12x4x1); break;
  299. case 2: vth = PARM(VTHNOR12x4x2); break;
  300. case 3: vth = PARM(VTHNOR12x4x3); break;
  301. case 4: vth = PARM(VTHNOR12x4x4); break;
  302. case 5: vth = PARM(VTHNOR12x4x4); break;
  303. default: printf("error:numstack=%d\n",numstack);
  304. }
  305. *Tdecoder1 = SIM_horowitz(nextinputtime,tf,PARM(VTHNAND60x90),vth,RISE);
  306. nextinputtime = *Tdecoder1/(1.0-vth);
  307. /* Final stage: driving an inverter with the nor */
  308. Req = SIM_transreson(WdecNORp,PCH,numstack);
  309. Ceq = (SIM_gatecap(Wdecinvn+Wdecinvp,20.0)+
  310. numstack*SIM_draincap(WdecNORn,NCH,1)+
  311. SIM_draincap(WdecNORp,PCH,numstack));
  312. tf = Req*Ceq;
  313. *Tdecoder2 = SIM_horowitz(nextinputtime,tf,vth,PARM(VSINV),FALL);
  314. *outrisetime = *Tdecoder2/(PARM(VSINV));
  315. return(*Tdecdrive+*Tdecoder1+*Tdecoder2);
  316. }
  317. /*----------------------------------------------------------------------*/
  318. /* Decoder delay in the tag array (see section 6.1 of tech report) */
  319. double SIM_decoder_tag_delay(int C, int B, int A, int Ndwl, int Ndbl, int Nspd, int Ntwl, int Ntbl, int Ntspd,
  320. double *Tdecdrive, double *Tdecoder1, double *Tdecoder2, double *outrisetime)
  321. {
  322. double Ceq,Req,Rwire,rows,tf,nextinputtime,vth = 0,tstep,m,a,b,c;
  323. int numstack;
  324. /* Calculate rise time. Consider two inverters */
  325. Ceq = SIM_draincap(Wdecdrivep,PCH,1)+SIM_draincap(Wdecdriven,NCH,1) +
  326. SIM_gatecap(Wdecdrivep+Wdecdriven,0.0);
  327. tf = Ceq*SIM_transreson(Wdecdriven,NCH,1);
  328. nextinputtime = SIM_horowitz(0.0,tf,PARM(VTHINV100x60),PARM(VTHINV100x60),FALL)/
  329. (PARM(VTHINV100x60));
  330. Ceq = SIM_draincap(Wdecdrivep,PCH,1)+SIM_draincap(Wdecdriven,NCH,1) +
  331. SIM_gatecap(Wdecdrivep+Wdecdriven,0.0);
  332. tf = Ceq*SIM_transreson(Wdecdriven,NCH,1);
  333. nextinputtime = SIM_horowitz(nextinputtime,tf,PARM(VTHINV100x60),PARM(VTHINV100x60),
  334. RISE)/
  335. (1.0-PARM(VTHINV100x60));
  336. /* First stage: driving the decoders */
  337. rows = C/(8*B*A*Ntbl*Ntspd);
  338. Ceq = SIM_draincap(Wdecdrivep,PCH,1)+SIM_draincap(Wdecdriven,NCH,1) +
  339. 4*SIM_gatecap(Wdec3to8n+Wdec3to8p,10.0)*(Ntwl*Ntbl)+
  340. Cwordmetal*0.25*8*B*A*Ntbl*Ntspd;
  341. Rwire = Rwordmetal*0.125*8*B*A*Ntbl*Ntspd;
  342. tf = (Rwire + SIM_transreson(Wdecdrivep,PCH,1))*Ceq;
  343. *Tdecdrive = SIM_horowitz(nextinputtime,tf,PARM(VTHINV100x60),PARM(VTHNAND60x90),
  344. FALL);
  345. nextinputtime = *Tdecdrive/PARM(VTHNAND60x90);
  346. /* second stage: driving a bunch of nor gates with a nand */
  347. numstack =
  348. (int)(ceil((1.0/3.0)*logtwo( (double)((double)C/(double)(B*A*Ntbl*Ntspd)))));
  349. if (numstack==0) numstack = 1;
  350. if (numstack>5) numstack = 5;
  351. Ceq = 3*SIM_draincap(Wdec3to8p,PCH,1) +SIM_draincap(Wdec3to8n,NCH,3) +
  352. SIM_gatecap(WdecNORn+WdecNORp,((numstack*40)+20.0))*rows +
  353. Cbitmetal*rows*8;
  354. Rwire = Rbitmetal*rows*8/2;
  355. tf = Ceq*(Rwire+SIM_transreson(Wdec3to8n,NCH,3));
  356. /* we only want to charge the output to the threshold of the
  357. nor gate. But the threshold depends on the number of inputs
  358. to the nor. */
  359. switch(numstack) {
  360. case 1: vth = PARM(VTHNOR12x4x1); break;
  361. case 2: vth = PARM(VTHNOR12x4x2); break;
  362. case 3: vth = PARM(VTHNOR12x4x3); break;
  363. case 4: vth = PARM(VTHNOR12x4x4); break;
  364. case 5: vth = PARM(VTHNOR12x4x4); break;
  365. case 6: vth = PARM(VTHNOR12x4x4); break;
  366. default: printf("error:numstack=%d\n",numstack);
  367. }
  368. *Tdecoder1 = SIM_horowitz(nextinputtime,tf,PARM(VTHNAND60x90),vth,RISE);
  369. nextinputtime = *Tdecoder1/(1.0-vth);
  370. /* Final stage: driving an inverter with the nor */
  371. Req = SIM_transreson(WdecNORp,PCH,numstack);
  372. Ceq = (SIM_gatecap(Wdecinvn+Wdecinvp,20.0)+
  373. numstack*SIM_draincap(WdecNORn,NCH,1)+
  374. SIM_draincap(WdecNORp,PCH,numstack));
  375. tf = Req*Ceq;
  376. *Tdecoder2 = SIM_horowitz(nextinputtime,tf,vth,PARM(VSINV),FALL);
  377. *outrisetime = *Tdecoder2/(PARM(VSINV));
  378. return(*Tdecdrive+*Tdecoder1+*Tdecoder2);
  379. }
  380. /*----------------------------------------------------------------------*/
  381. /* Data array wordline delay (see section 6.2 of tech report) */
  382. double SIM_wordline_delay(int B, int A, int Ndwl, int Nspd, double inrisetime, double *outrisetime)
  383. {
  384. double Rpdrive,nextrisetime;
  385. double desiredrisetime,psize,nsize;
  386. double tf,nextinputtime,Ceq,Req,Rline,Cline;
  387. int cols;
  388. double Tworddrivedel,Twordchargedel;
  389. cols = 8*B*A*Nspd/Ndwl;
  390. /* Choose a transistor size that makes sense */
  391. /* Use a first-order approx */
  392. desiredrisetime = krise*log((double)(cols))/2.0;
  393. Cline = (SIM_gatecappass(Wmemcella,0.0)+
  394. SIM_gatecappass(Wmemcella,0.0)+
  395. Cwordmetal)*cols;
  396. Rpdrive = desiredrisetime/(Cline*log(PARM(VSINV))*-1.0);
  397. psize = SIM_restowidth(Rpdrive,PCH);
  398. if (psize > Wworddrivemax) {
  399. psize = Wworddrivemax;
  400. }
  401. /* Now that we have a reasonable psize, do the rest as before */
  402. /* If we keep the ratio the same as the tag wordline driver,
  403. the threshold voltage will be close to VSINV */
  404. nsize = psize * Wdecinvn/Wdecinvp;
  405. Ceq = SIM_draincap(Wdecinvn,NCH,1) + SIM_draincap(Wdecinvp,PCH,1) +
  406. SIM_gatecap(nsize+psize,20.0);
  407. tf = SIM_transreson(Wdecinvn,NCH,1)*Ceq;
  408. Tworddrivedel = SIM_horowitz(inrisetime,tf,PARM(VSINV),PARM(VSINV),RISE);
  409. nextinputtime = Tworddrivedel/(1.0-PARM(VSINV));
  410. Cline = (SIM_gatecappass(Wmemcella,(BitWidth-2*Wmemcella)/2.0)+
  411. SIM_gatecappass(Wmemcella,(BitWidth-2*Wmemcella)/2.0)+
  412. Cwordmetal)*cols+
  413. SIM_draincap(nsize,NCH,1) + SIM_draincap(psize,PCH,1);
  414. Rline = Rwordmetal*cols/2;
  415. tf = (SIM_transreson(psize,PCH,1)+Rline)*Cline;
  416. Twordchargedel = SIM_horowitz(nextinputtime,tf,PARM(VSINV),PARM(VSINV),FALL);
  417. *outrisetime = Twordchargedel/PARM(VSINV);
  418. return(Tworddrivedel+Twordchargedel);
  419. }
  420. /*----------------------------------------------------------------------*/
  421. /* Tag array wordline delay (see section 6.3 of tech report) */
  422. double SIM_wordline_tag_delay(int C, int A, int Ntspd, int Ntwl, double inrisetime, double *outrisetime)
  423. {
  424. double tf,m,a,b,c;
  425. double Cline,Rline,Ceq,nextinputtime;
  426. int tagbits;
  427. double Tworddrivedel,Twordchargedel;
  428. /* number of tag bits */
  429. tagbits = PARM(ADDRESS_BITS)+2-(int)logtwo((double)C)+(int)logtwo((double)A);
  430. /* first stage */
  431. Ceq = SIM_draincap(Wdecinvn,NCH,1) + SIM_draincap(Wdecinvp,PCH,1) +
  432. SIM_gatecap(Wdecinvn+Wdecinvp,20.0);
  433. tf = SIM_transreson(Wdecinvn,NCH,1)*Ceq;
  434. Tworddrivedel = SIM_horowitz(inrisetime,tf,PARM(VSINV),PARM(VSINV),RISE);
  435. nextinputtime = Tworddrivedel/(1.0-PARM(VSINV));
  436. /* second stage */
  437. Cline = (SIM_gatecappass(Wmemcella,(BitWidth-2*Wmemcella)/2.0)+
  438. SIM_gatecappass(Wmemcella,(BitWidth-2*Wmemcella)/2.0)+
  439. Cwordmetal)*tagbits*A*Ntspd/Ntwl+
  440. SIM_draincap(Wdecinvn,NCH,1) + SIM_draincap(Wdecinvp,PCH,1);
  441. Rline = Rwordmetal*tagbits*A*Ntspd/(2*Ntwl);
  442. tf = (SIM_transreson(Wdecinvp,PCH,1)+Rline)*Cline;
  443. Twordchargedel = SIM_horowitz(nextinputtime,tf,PARM(VSINV),PARM(VSINV),FALL);
  444. *outrisetime = Twordchargedel/PARM(VSINV);
  445. return(Tworddrivedel+Twordchargedel);
  446. }
  447. /*----------------------------------------------------------------------*/
  448. /* Data array bitline: (see section 6.4 in tech report) */
  449. double SIM_bitline_delay(int C, int A, int B, int Ndwl, int Ndbl, int Nspd, double inrisetime, double *outrisetime)
  450. {
  451. double Tbit,Cline,Ccolmux,Rlineb,r1,r2,c1,c2,a,b,c;
  452. double m,tstep;
  453. double Cbitrow; /* bitline capacitance due to access transistor */
  454. int rows,cols;
  455. Cbitrow = SIM_draincap(Wmemcella,NCH,1)/2.0; /* due to shared contact */
  456. rows = C/(B*A*Ndbl*Nspd);
  457. cols = 8*B*A*Nspd/Ndwl;
  458. if (Ndbl*Nspd == 1) {
  459. Cline = rows*(Cbitrow+Cbitmetal)+2*SIM_draincap(Wbitpreequ,PCH,1);
  460. Ccolmux = 2*SIM_gatecap(WsenseQ1to4,10.0);
  461. Rlineb = Rbitmetal*rows/2.0;
  462. r1 = Rlineb;
  463. } else {
  464. Cline = rows*(Cbitrow+Cbitmetal) + 2*SIM_draincap(Wbitpreequ,PCH,1) +
  465. SIM_draincap(Wbitmuxn,NCH,1);
  466. Ccolmux = Nspd*Ndbl*(SIM_draincap(Wbitmuxn,NCH,1))+2*SIM_gatecap(WsenseQ1to4,10.0);
  467. Rlineb = Rbitmetal*rows/2.0;
  468. r1 = Rlineb +
  469. SIM_transreson(Wbitmuxn,NCH,1);
  470. }
  471. r2 = SIM_transreson(Wmemcella,NCH,1) +
  472. SIM_transreson(Wmemcella*Wmemcellbscale,NCH,1);
  473. c1 = Ccolmux;
  474. c2 = Cline;
  475. tstep = (r2*c2+(r1+r2)*c1)*log((Vbitpre)/(Vbitpre-Vbitsense));
  476. /* take input rise time into account */
  477. m = Vdd/inrisetime;
  478. if (tstep <= (0.5*(Vdd-Vt)/m)) {
  479. a = m;
  480. b = 2*((Vdd*0.5)-Vt);
  481. c = -2*tstep*(Vdd-Vt)+1/m*((Vdd*0.5)-Vt)*
  482. ((Vdd*0.5)-Vt);
  483. Tbit = (-b+sqrt(b*b-4*a*c))/(2*a);
  484. } else {
  485. Tbit = tstep + (Vdd+Vt)/(2*m) - (Vdd*0.5)/m;
  486. }
  487. *outrisetime = Tbit/(log((Vbitpre-Vbitsense)/Vdd));
  488. return(Tbit);
  489. }
  490. /*----------------------------------------------------------------------*/
  491. /* Tag array bitline: (see section 6.4 in tech report) */
  492. double SIM_bitline_tag_delay(int C, int A, int B, int Ntwl, int Ntbl, int Ntspd, double inrisetime, double *outrisetime)
  493. {
  494. double Tbit,Cline,Ccolmux,Rlineb,r1,r2,c1,c2,a,b,c;
  495. double m,tstep;
  496. double Cbitrow; /* bitline capacitance due to access transistor */
  497. int rows,cols;
  498. Cbitrow = SIM_draincap(Wmemcella,NCH,1)/2.0; /* due to shared contact */
  499. rows = C/(B*A*Ntbl*Ntspd);
  500. cols = 8*B*A*Ntspd/Ntwl;
  501. if (Ntbl*Ntspd == 1) {
  502. Cline = rows*(Cbitrow+Cbitmetal)+2*SIM_draincap(Wbitpreequ,PCH,1);
  503. Ccolmux = 2*SIM_gatecap(WsenseQ1to4,10.0);
  504. Rlineb = Rbitmetal*rows/2.0;
  505. r1 = Rlineb;
  506. } else {
  507. Cline = rows*(Cbitrow+Cbitmetal) + 2*SIM_draincap(Wbitpreequ,PCH,1) +
  508. SIM_draincap(Wbitmuxn,NCH,1);
  509. Ccolmux = Ntspd*Ntbl*(SIM_draincap(Wbitmuxn,NCH,1))+2*SIM_gatecap(WsenseQ1to4,10.0);
  510. Rlineb = Rbitmetal*rows/2.0;
  511. r1 = Rlineb +
  512. SIM_transreson(Wbitmuxn,NCH,1);
  513. }
  514. r2 = SIM_transreson(Wmemcella,NCH,1) +
  515. SIM_transreson(Wmemcella*Wmemcellbscale,NCH,1);
  516. c1 = Ccolmux;
  517. c2 = Cline;
  518. tstep = (r2*c2+(r1+r2)*c1)*log((Vbitpre)/(Vbitpre-Vbitsense));
  519. /* take into account input rise time */
  520. m = Vdd/inrisetime;
  521. if (tstep <= (0.5*(Vdd-Vt)/m)) {
  522. a = m;
  523. b = 2*((Vdd*0.5)-Vt);
  524. c = -2*tstep*(Vdd-Vt)+1/m*((Vdd*0.5)-Vt)*
  525. ((Vdd*0.5)-Vt);
  526. Tbit = (-b+sqrt(b*b-4*a*c))/(2*a);
  527. } else {
  528. Tbit = tstep + (Vdd+Vt)/(2*m) - (Vdd*0.5)/m;
  529. }
  530. *outrisetime = Tbit/(log((Vbitpre-Vbitsense)/Vdd));
  531. return(Tbit);
  532. }
  533. /*----------------------------------------------------------------------*/
  534. /* It is assumed the sense amps have a constant delay
  535. (see section 6.5) */
  536. double SIM_sense_amp_delay(double inrisetime,double *outrisetime)
  537. {
  538. *outrisetime = tfalldata;
  539. return(tsensedata);
  540. }
  541. /*--------------------------------------------------------------*/
  542. double SIM_sense_amp_tag_delay(double inrisetime, double *outrisetime)
  543. {
  544. *outrisetime = tfalltag;
  545. return(tsensetag);
  546. }
  547. /*----------------------------------------------------------------------*/
  548. /* Comparator Delay (see section 6.6) */
  549. double SIM_compare_time(int C, int A, int Ntbl, int Ntspd, double inputtime, double *outputtime)
  550. {
  551. double Req,Ceq,tf,st1del,st2del,st3del,nextinputtime,m;
  552. double c1,c2,r1,r2,tstep,a,b,c;
  553. double Tcomparatorni;
  554. int cols,tagbits;
  555. /* First Inverter */
  556. Ceq = SIM_gatecap(Wcompinvn2+Wcompinvp2,10.0) +
  557. SIM_draincap(Wcompinvp1,PCH,1) + SIM_draincap(Wcompinvn1,NCH,1);
  558. Req = SIM_transreson(Wcompinvp1,PCH,1);
  559. tf = Req*Ceq;
  560. st1del = SIM_horowitz(inputtime,tf,PARM(VTHCOMPINV),PARM(VTHCOMPINV),FALL);
  561. nextinputtime = st1del/PARM(VTHCOMPINV);
  562. /* Second Inverter */
  563. Ceq = SIM_gatecap(Wcompinvn3+Wcompinvp3,10.0) +
  564. SIM_draincap(Wcompinvp2,PCH,1) + SIM_draincap(Wcompinvn2,NCH,1);
  565. Req = SIM_transreson(Wcompinvn2,NCH,1);
  566. tf = Req*Ceq;
  567. st2del = SIM_horowitz(inputtime,tf,PARM(VTHCOMPINV),PARM(VTHCOMPINV),RISE);
  568. nextinputtime = st1del/(1.0-PARM(VTHCOMPINV));
  569. /* Third Inverter */
  570. Ceq = SIM_gatecap(Wevalinvn+Wevalinvp,10.0) +
  571. SIM_draincap(Wcompinvp3,PCH,1) + SIM_draincap(Wcompinvn3,NCH,1);
  572. Req = SIM_transreson(Wcompinvp3,PCH,1);
  573. tf = Req*Ceq;
  574. st3del = SIM_horowitz(nextinputtime,tf,PARM(VTHCOMPINV),PARM(VTHEVALINV),FALL);
  575. nextinputtime = st1del/(PARM(VTHEVALINV));
  576. /* Final Inverter (virtual ground driver) discharging compare part */
  577. tagbits = PARM(ADDRESS_BITS) - (int)logtwo((double)C) + (int)logtwo((double)A);
  578. cols = tagbits*Ntbl*Ntspd;
  579. r1 = SIM_transreson(Wcompn,NCH,2);
  580. r2 = SIM_transresswitch(Wevalinvn,NCH,1);
  581. c2 = (tagbits)*(SIM_draincap(Wcompn,NCH,1)+SIM_draincap(Wcompn,NCH,2))+
  582. SIM_draincap(Wevalinvp,PCH,1) + SIM_draincap(Wevalinvn,NCH,1);
  583. c1 = (tagbits)*(SIM_draincap(Wcompn,NCH,1)+SIM_draincap(Wcompn,NCH,2))
  584. +SIM_draincap(Wcompp,PCH,1) + SIM_gatecap(Wmuxdrv12n+Wmuxdrv12p,20.0) +
  585. cols*Cwordmetal;
  586. /* time to go to threshold of mux driver */
  587. tstep = (r2*c2+(r1+r2)*c1)*log(1.0/PARM(VTHMUXDRV1));
  588. /* take into account non-zero input rise time */
  589. m = Vdd/nextinputtime;
  590. if ((tstep) <= (0.5*(Vdd-Vt)/m)) {
  591. a = m;
  592. b = 2*((Vdd*PARM(VTHEVALINV))-Vt);
  593. c = -2*(tstep)*(Vdd-Vt)+1/m*((Vdd*PARM(VTHEVALINV))-Vt)*((Vdd*PARM(VTHEVALINV))-Vt);
  594. Tcomparatorni = (-b+sqrt(b*b-4*a*c))/(2*a);
  595. } else {
  596. Tcomparatorni = (tstep) + (Vdd+Vt)/(2*m) - (Vdd*PARM(VTHEVALINV))/m;
  597. }
  598. *outputtime = Tcomparatorni/(1.0-PARM(VTHMUXDRV1));
  599. return(Tcomparatorni+st1del+st2del+st3del);
  600. }
  601. /*----------------------------------------------------------------------*/
  602. /* Delay of the multiplexor Driver (see section 6.7) */
  603. double SIM_mux_driver_delay(int C, int B, int A, int Ndbl, int Nspd, int Ndwl, int Ntbl, int Ntspd, double inputtime, double *outputtime)
  604. {
  605. double Ceq,Req,tf,nextinputtime;
  606. double Tst1,Tst2,Tst3;
  607. /* first driver stage - Inverte "match" to produce "matchb" */
  608. /* the critical path is the DESELECTED case, so consider what
  609. happens when the address bit is true, but match goes low */
  610. Ceq = SIM_gatecap(WmuxdrvNORn+WmuxdrvNORp,15.0)*(8*B/PARM(BITOUT)) +
  611. SIM_draincap(Wmuxdrv12n,NCH,1) + SIM_draincap(Wmuxdrv12p,PCH,1);
  612. Req = SIM_transreson(Wmuxdrv12p,PCH,1);
  613. tf = Ceq*Req;
  614. Tst1 = SIM_horowitz(inputtime,tf,PARM(VTHMUXDRV1),PARM(VTHMUXDRV2),FALL);
  615. nextinputtime = Tst1/PARM(VTHMUXDRV2);
  616. /* second driver stage - NOR "matchb" with address bits to produce sel */
  617. Ceq = SIM_gatecap(Wmuxdrv3n+Wmuxdrv3p,15.0) + 2*SIM_draincap(WmuxdrvNORn,NCH,1) +
  618. SIM_draincap(WmuxdrvNORp,PCH,2);
  619. Req = SIM_transreson(WmuxdrvNORn,NCH,1);
  620. tf = Ceq*Req;
  621. Tst2 = SIM_horowitz(nextinputtime,tf,PARM(VTHMUXDRV2),PARM(VTHMUXDRV3),RISE);
  622. nextinputtime = Tst2/(1-PARM(VTHMUXDRV3));
  623. /* third driver stage - invert "select" to produce "select bar" */
  624. Ceq = PARM(BITOUT)*SIM_gatecap(Woutdrvseln+Woutdrvselp+Woutdrvnorn+Woutdrvnorp,20.0)+
  625. SIM_draincap(Wmuxdrv3p,PCH,1) + SIM_draincap(Wmuxdrv3n,NCH,1) +
  626. Cwordmetal*8*B*A*Nspd*Ndbl/2.0;
  627. Req = (Rwordmetal*8*B*A*Nspd*Ndbl/2)/2 + SIM_transreson(Wmuxdrv3p,PCH,1);
  628. tf = Ceq*Req;
  629. Tst3 = SIM_horowitz(nextinputtime,tf,PARM(VTHMUXDRV3),PARM(VTHOUTDRINV),FALL);
  630. *outputtime = Tst3/(PARM(VTHOUTDRINV));
  631. return(Tst1 + Tst2 + Tst3);
  632. }
  633. /*----------------------------------------------------------------------*/
  634. /* Valid driver (see section 6.9 of tech report)
  635. Note that this will only be called for a direct mapped cache */
  636. double SIM_valid_driver_delay(int C, int A, int Ntbl, int Ntspd, double inputtime)
  637. {
  638. double Ceq,Tst1,tf;
  639. Ceq = SIM_draincap(Wmuxdrv12n,NCH,1)+SIM_draincap(Wmuxdrv12p,PCH,1)+Cout;
  640. tf = Ceq*SIM_transreson(Wmuxdrv12p,PCH,1);
  641. Tst1 = SIM_horowitz(inputtime,tf,PARM(VTHMUXDRV1),0.5,FALL);
  642. return(Tst1);
  643. }
  644. /*----------------------------------------------------------------------*/
  645. /* Data output delay (data side) -- see section 6.8
  646. This is the time through the NAND/NOR gate and the final inverter
  647. assuming sel is already present */
  648. double SIM_dataoutput_delay(int C, int B, int A, int Ndbl, int Nspd, int Ndwl,
  649. double inrisetime, double *outrisetime)
  650. {
  651. double Ceq,Rwire,Rline;
  652. double aspectRatio; /* as height over width */
  653. double ramBlocks; /* number of RAM blocks */
  654. double tf;
  655. double nordel,outdel,nextinputtime;
  656. double hstack,vstack;
  657. /* calculate some layout info */
  658. aspectRatio = (2.0*C)/(8.0*B*B*A*A*Ndbl*Ndbl*Nspd*Nspd);
  659. hstack = (aspectRatio > 1.0) ? aspectRatio : 1.0/aspectRatio;
  660. ramBlocks = Ndwl*Ndbl;
  661. hstack = hstack * sqrt(ramBlocks/ hstack);
  662. vstack = ramBlocks/ hstack;
  663. /* Delay of NOR gate */
  664. Ceq = 2*SIM_draincap(Woutdrvnorn,NCH,1)+SIM_draincap(Woutdrvnorp,PCH,2)+
  665. SIM_gatecap(Woutdrivern,10.0);
  666. tf = Ceq*SIM_transreson(Woutdrvnorp,PCH,2);
  667. nordel = SIM_horowitz(inrisetime,tf,PARM(VTHOUTDRNOR),PARM(VTHOUTDRIVE),FALL);
  668. nextinputtime = nordel/(PARM(VTHOUTDRIVE));
  669. /* Delay of final output driver */
  670. Ceq = (SIM_draincap(Woutdrivern,NCH,1)+SIM_draincap(Woutdriverp,PCH,1))*
  671. ((8*B*A)/PARM(BITOUT)) +
  672. Cwordmetal*(8*B*A*Nspd* (vstack)) + Cout;
  673. Rwire = Rwordmetal*(8*B*A*Nspd* (vstack))/2;
  674. tf = Ceq*(SIM_transreson(Woutdriverp,PCH,1)+Rwire);
  675. outdel = SIM_horowitz(nextinputtime,tf,PARM(VTHOUTDRIVE),0.5,RISE);
  676. *outrisetime = outdel/0.5;
  677. return(outdel+nordel);
  678. }
  679. /*----------------------------------------------------------------------*/
  680. /* Sel inverter delay (part of the output driver) see section 6.8 */
  681. double SIM_selb_delay_tag_path(double inrisetime, double *outrisetime)
  682. {
  683. double Ceq,Tst1,tf;
  684. Ceq = SIM_draincap(Woutdrvseln,NCH,1)+SIM_draincap(Woutdrvselp,PCH,1)+
  685. SIM_gatecap(Woutdrvnandn+Woutdrvnandp,10.0);
  686. tf = Ceq*SIM_transreson(Woutdrvseln,NCH,1);
  687. Tst1 = SIM_horowitz(inrisetime,tf,PARM(VTHOUTDRINV),PARM(VTHOUTDRNAND),RISE);
  688. *outrisetime = Tst1/(1.0-PARM(VTHOUTDRNAND));
  689. return(Tst1);
  690. }
  691. /*----------------------------------------------------------------------*/
  692. /* This routine calculates the extra time required after an access before
  693. * the next access can occur [ie. it returns (cycle time-access time)].
  694. */
  695. double SIM_precharge_delay(double worddata)
  696. {
  697. double Ceq,tf,pretime;
  698. /* as discussed in the tech report, the delay is the delay of
  699. 4 inverter delays (each with fanout of 4) plus the delay of
  700. the wordline */
  701. Ceq = SIM_draincap(Wdecinvn,NCH,1)+SIM_draincap(Wdecinvp,PCH,1)+
  702. 4*SIM_gatecap(Wdecinvn+Wdecinvp,0.0);
  703. tf = Ceq*SIM_transreson(Wdecinvn,NCH,1);
  704. pretime = 4*SIM_horowitz(0.0,tf,0.5,0.5,RISE) + worddata;
  705. return(pretime);
  706. }
  707. /*======================================================================*/
  708. /* returns 1 if the parameters make up a valid organization */
  709. /* Layout concerns drive any restrictions you might add here */
  710. int SIM_organizational_parameters_valid(int rows, int cols, int Ndwl, int Ndbl, int Nspd, int Ntwl, int Ntbl, int Ntspd)
  711. {
  712. /* don't want more than 8 subarrays for each of data/tag */
  713. if (Ndwl*Ndbl>PARM(MAXSUBARRAYS)) return(0);
  714. if (Ntwl*Ntbl>PARM(MAXSUBARRAYS)) return(0);
  715. /* add more constraints here as necessary */
  716. return(1);
  717. }
  718. /*----------------------------------------------------------------------*/
  719. void SIM_calculate_time(time_result_type *result, time_parameter_type *parameters)
  720. {
  721. int Ndwl,Ndbl,Nspd,Ntwl,Ntbl,Ntspd,rows,columns,tag_driver_size1,tag_driver_size2;
  722. double access_time;
  723. double before_mux,after_mux;
  724. double decoder_data_driver,decoder_data_3to8,decoder_data_inv;
  725. double decoder_data,decoder_tag,wordline_data,wordline_tag;
  726. double decoder_tag_driver,decoder_tag_3to8,decoder_tag_inv;
  727. double bitline_data,bitline_tag,sense_amp_data,sense_amp_tag;
  728. double compare_tag,mux_driver,data_output,selb = 0;
  729. double time_till_compare,time_till_select,driver_cap,valid_driver;
  730. double cycle_time, precharge_del;
  731. double outrisetime,inrisetime;
  732. rows = parameters->number_of_sets;
  733. columns = 8*parameters->block_size*parameters->associativity;
  734. /* go through possible Ndbl,Ndwl and find the smallest */
  735. /* Because of area considerations, I don't think it makes sense
  736. to break either dimension up larger than MAXN */
  737. result->cycle_time = BIGNUM;
  738. result->access_time = BIGNUM;
  739. for (Nspd=1;Nspd<=PARM(MAXSPD);Nspd=Nspd*2) {
  740. for (Ndwl=1;Ndwl<=PARM(MAXN);Ndwl=Ndwl*2) {
  741. for (Ndbl=1;Ndbl<=PARM(MAXN);Ndbl=Ndbl*2) {
  742. for (Ntspd=1;Ntspd<=PARM(MAXSPD);Ntspd=Ntspd*2) {
  743. for (Ntwl=1;Ntwl<=1;Ntwl=Ntwl*2) {
  744. for (Ntbl=1;Ntbl<=PARM(MAXN);Ntbl=Ntbl*2) {
  745. if (SIM_organizational_parameters_valid
  746. (rows,columns,Ndwl,Ndbl,Nspd,Ntwl,Ntbl,Ntspd)) {
  747. /* Calculate data side of cache */
  748. decoder_data = SIM_decoder_delay(parameters->cache_size,parameters->block_size,
  749. parameters->associativity,Ndwl,Ndbl,Nspd,Ntwl,Ntbl,Ntspd,
  750. &decoder_data_driver,&decoder_data_3to8,
  751. &decoder_data_inv,&outrisetime);
  752. inrisetime = outrisetime;
  753. wordline_data = SIM_wordline_delay(parameters->block_size,
  754. parameters->associativity,Ndwl,Nspd,
  755. inrisetime,&outrisetime);
  756. inrisetime = outrisetime;
  757. bitline_data = SIM_bitline_delay(parameters->cache_size,parameters->associativity,
  758. parameters->block_size,Ndwl,Ndbl,Nspd,
  759. inrisetime,&outrisetime);
  760. inrisetime = outrisetime;
  761. sense_amp_data = SIM_sense_amp_delay(inrisetime,&outrisetime);
  762. inrisetime = outrisetime;
  763. data_output = SIM_dataoutput_delay(parameters->cache_size,parameters->block_size,
  764. parameters->associativity,Ndbl,Nspd,Ndwl,
  765. inrisetime,&outrisetime);
  766. inrisetime = outrisetime;
  767. /* if the associativity is 1, the data output can come right
  768. after the sense amp. Otherwise, it has to wait until
  769. the data access has been done. */
  770. if (parameters->associativity==1) {
  771. before_mux = decoder_data + wordline_data + bitline_data +
  772. sense_amp_data + data_output;
  773. after_mux = 0;
  774. } else {
  775. before_mux = decoder_data + wordline_data + bitline_data +
  776. sense_amp_data;
  777. after_mux = data_output;
  778. }
  779. /*
  780. * Now worry about the tag side.
  781. */
  782. decoder_tag = SIM_decoder_tag_delay(parameters->cache_size,
  783. parameters->block_size,parameters->associativity,
  784. Ndwl,Ndbl,Nspd,Ntwl,Ntbl,Ntspd,
  785. &decoder_tag_driver,&decoder_tag_3to8,
  786. &decoder_tag_inv,&outrisetime);
  787. inrisetime = outrisetime;
  788. wordline_tag = SIM_wordline_tag_delay(parameters->cache_size,
  789. parameters->associativity,Ntspd,Ntwl,
  790. inrisetime,&outrisetime);
  791. inrisetime = outrisetime;
  792. bitline_tag = SIM_bitline_tag_delay(parameters->cache_size,parameters->associativity,
  793. parameters->block_size,Ntwl,Ntbl,Ntspd,
  794. inrisetime,&outrisetime);
  795. inrisetime = outrisetime;
  796. sense_amp_tag = SIM_sense_amp_tag_delay(inrisetime,&outrisetime);
  797. inrisetime = outrisetime;
  798. compare_tag = SIM_compare_time(parameters->cache_size,parameters->associativity,
  799. Ntbl,Ntspd,
  800. inrisetime,&outrisetime);
  801. inrisetime = outrisetime;
  802. if (parameters->associativity == 1) {
  803. mux_driver = 0;
  804. valid_driver = SIM_valid_driver_delay(parameters->cache_size,
  805. parameters->associativity,Ntbl,Ntspd,inrisetime);
  806. time_till_compare = decoder_tag + wordline_tag + bitline_tag +
  807. sense_amp_tag;
  808. time_till_select = time_till_compare+ compare_tag + valid_driver;
  809. /*
  810. * From the above info, calculate the total access time
  811. */
  812. access_time = MAX(before_mux+after_mux,time_till_select);
  813. } else {
  814. mux_driver = SIM_mux_driver_delay(parameters->cache_size,parameters->block_size,
  815. parameters->associativity,Ndbl,Nspd,Ndwl,Ntbl,Ntspd,
  816. inrisetime,&outrisetime);
  817. selb = SIM_selb_delay_tag_path(inrisetime,&outrisetime);
  818. valid_driver = 0;
  819. time_till_compare = decoder_tag + wordline_tag + bitline_tag +
  820. sense_amp_tag;
  821. time_till_select = time_till_compare+ compare_tag + mux_driver
  822. + selb;
  823. access_time = MAX(before_mux,time_till_select) +after_mux;
  824. }
  825. /*
  826. * Calcuate the cycle time
  827. */
  828. precharge_del = SIM_precharge_delay(wordline_data);
  829. cycle_time = access_time + precharge_del;
  830. /*
  831. * The parameters are for a 0.8um process. A quick way to
  832. * scale the results to another process is to divide all
  833. * the results by FUDGEFACTOR. Normally, FUDGEFACTOR is 1.
  834. */
  835. if (result->cycle_time+1e-11*(result->best_Ndwl+result->best_Ndbl+result->best_Nspd+result->best_Ntwl+result->best_Ntbl+result->best_Ntspd) > cycle_time/PARM(FUDGEFACTOR)+1e-11*(Ndwl+Ndbl+Nspd+Ntwl+Ntbl+Ntspd)) {
  836. result->cycle_time = cycle_time/PARM(FUDGEFACTOR);
  837. result->access_time = access_time/PARM(FUDGEFACTOR);
  838. result->best_Ndwl = Ndwl;
  839. result->best_Ndbl = Ndbl;
  840. result->best_Nspd = Nspd;
  841. result->best_Ntwl = Ntwl;
  842. result->best_Ntbl = Ntbl;
  843. result->best_Ntspd = Ntspd;
  844. result->decoder_delay_data = decoder_data/PARM(FUDGEFACTOR);
  845. result->decoder_delay_tag = decoder_tag/PARM(FUDGEFACTOR);
  846. result->dec_tag_driver = decoder_tag_driver/PARM(FUDGEFACTOR);
  847. result->dec_tag_3to8 = decoder_tag_3to8/PARM(FUDGEFACTOR);
  848. result->dec_tag_inv = decoder_tag_inv/PARM(FUDGEFACTOR);
  849. result->dec_data_driver = decoder_data_driver/PARM(FUDGEFACTOR);
  850. result->dec_data_3to8 = decoder_data_3to8/PARM(FUDGEFACTOR);
  851. result->dec_data_inv = decoder_data_inv/PARM(FUDGEFACTOR);
  852. result->wordline_delay_data = wordline_data/PARM(FUDGEFACTOR);
  853. result->wordline_delay_tag = wordline_tag/PARM(FUDGEFACTOR);
  854. result->bitline_delay_data = bitline_data/PARM(FUDGEFACTOR);
  855. result->bitline_delay_tag = bitline_tag/PARM(FUDGEFACTOR);
  856. result->sense_amp_delay_data = sense_amp_data/PARM(FUDGEFACTOR);
  857. result->sense_amp_delay_tag = sense_amp_tag/PARM(FUDGEFACTOR);
  858. result->compare_part_delay = compare_tag/PARM(FUDGEFACTOR);
  859. result->drive_mux_delay = mux_driver/PARM(FUDGEFACTOR);
  860. result->selb_delay = selb/PARM(FUDGEFACTOR);
  861. result->drive_valid_delay = valid_driver/PARM(FUDGEFACTOR);
  862. result->data_output_delay = data_output/PARM(FUDGEFACTOR);
  863. result->precharge_delay = precharge_del/PARM(FUDGEFACTOR);
  864. }
  865. }
  866. }
  867. }
  868. }
  869. }
  870. }
  871. }
  872. }