next up previous contents
Next: Bibliography Up: Source code Previous: Optimization algorithms   Contents

Simulators


Basicnet.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "hspice.h"
7 
8  ///
9 int Hspice::BasicNetlist( const double* NewWidth, unsigned int Np, const Circuit& circuit )
10 
11 char * FileHspice;
12 char log[ 1024 ];
13 char suffix[ 8 ];
14 sprintf( suffix, "_
15 FileHspice = new char[ strlen( WorkPath ) + strlen( SimFile ) + strlen( suffix ) + 1 ];
16 strcpy( FileHspice, WorkPath );
17 strcat( FileHspice, SimFile );
18 strcat( FileHspice, suffix );
19 ofstream o_file( FileHspice );
20 ifstream i_file( NetlistFile );
21 if ( !o_file )
22 
23 sprintf( log, " ERROR opening file
24 print_log( log );
25 return NOT_FOUND;
26 
27 if ( !i_file )
28 
29 sprintf( log, " ERROR opening file
30 print_log( log );
31 return NOT_FOUND;
32 
33 char line[ 1024 ];
34 i_file.getline( line, 1023 );
35 o_file « endl « endl « endl « "****** INPUTS ******" « endl;
36 o_file « ".include inputs." « Np « endl;
37 o_file « "********************" « endl;
38 while ( i_file.getline( line, 1023 ) )
39 
40 unsigned int i = 0;
41 while ( isspace( line[ i++ ] ) );
42 char s = line[ -i ];
43 char st1[ 16 ], st2[ 16 ], st3[ 16 ];
44 int n1, n2, n3, n4;
45 if ( ( s == 'M' ) || ( s == 'm' ) || ( s == 'X' ) || ( s == 'x' ) )
46 
47 sscanf( line, "
48 int position = circuit.TranPos( st1 );
49 if ( position == -1 )
50 return NOT_FOUND;
51 o_file « st1 « " " « n1 « " " « n2 « " " « n3 « " " « n4 «
52 " " « st2 « " " « st3 « " w=" « setprecision( 4 ) « NewWidth[ position ] « "u" « endl;
53 
54 else
55 o_file « line « endl;
56 
57 o_file.close();
58 i_file.close();
59 return OK;
60 

Delayread.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "hspice.h"
7 
8  ///
9 int Hspice::DelayRead( double& del, double& energy, unsigned int Np )
10 
11 char * FileMeas;
12 char suffix[ 8 ];
13 sprintf( suffix, "_
14 FileMeas = new char[ strlen( WorkPath ) + strlen( SimFile ) + strlen( suffix ) + strlen( SuffixFileMeasure ) + 1 ];
15 if ( !FileMeas )
16 return NO_MEM;
17 strcpy( FileMeas, WorkPath );
18 strcat( FileMeas, SimFile );
19 strcat( FileMeas, suffix );
20 strcat( FileMeas, SuffixFileMeasure );
21 ifstream i_file( FileMeas );
22 if ( !i_file )
23 
24 print_log( "ERROR opening hspice measure file " );
25 return NOT_FOUND;
26 
27 char line[ 1023 ];
28 for ( unsigned int i = 0; i <= 3; i++ )
29 if ( !i_file.getline( line, 1023 ) )
30 
31 print_log( "ERROR parsing hspice measure file " );
32 return PARSE_ERROR;
33 
34 sscanf( line, "
35 i_file.close();
36 del *= 1E12;  // picosec.
37 energy *= ( 1E12);  // pJ
38 delete[] FileMeas;
39 return OK;
40 

Hspice.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "hspice.h"
7 
8  //////////////////////////////////////////////////////////////////////////////
9  // //
10  // DELAY MODULE - HSPICE //
11  // //
12  // 1998 October 9 - Politecnico di Torino - VLSI LAB //
13  // //
14  // Mariagrazia Graziano - Ph.D. Student //
15  // //
16  ////////////////////////////////////////////////////////////////////////////////
17 
18 Hspice::Hspice( const CritPathList& pathlist, const Options& options, const char* NE )
19 :
20 EvaluationAlgorithm( pathlist, options ), SimTime( 0.0 ),
21 WorkPath( 0 ), SimFile( 0 ),
22 InputFile( 0 ), NetlistFile( 0 ), SuffixFileMeasure( 0 )
23 
24 print_log( "Creating Hspice instance..." );
25 WorkPath = new char[ strlen( options.Workpath() ) + 1 ];
26 SimFile = new char[ strlen( "net2use" ) + 1 ];
27 InputFile = new char[ strlen( "inputs" ) + 1 ];
28 NetlistFile = new char[ strlen( NE ) + strlen( NetListSuffix ) + 1 ];
29 if ( !SimFile || ! InputFile || !NetlistFile )
30 
31 print_log( "FATAL ERROR:" );
32 print_log( ReturnMessage[ NO_MEM ] );
33 error( NO_MEM, errno, "HEY! " );
34 
35 strcpy( WorkPath, options.Workpath() );
36 strcpy( SimFile, "net2use" );
37 strcpy( InputFile, "inputs" );
38 strcpy( NetlistFile, NE );
39 strcat( NetlistFile, NetListSuffix );
40 SuffixFileMeasure = new char[ 5 ];
41 if ( !SimFile )
42 
43 print_log( "FATAL ERROR:" );
44 print_log( ReturnMessage[ NO_MEM ] );
45 error( NO_MEM, errno, "HEY! " );
46 
47 strcpy( SuffixFileMeasure, ".mt0" );
48 
49 
50  ///
51 Hspice:: Hspice()
52 
53 delete[] WorkPath;
54 delete[] SimFile;
55 delete[] InputFile;
56 delete[] NetlistFile;
57 delete[] SuffixFileMeasure;
58 
59 
60  ///
61 int Hspice::Run( const Circuit& circuit, const double *NewWidth, const unsigned *ValidPath )
62 
63 SimTime = options.GetSimOption( SIMTIME );
64 Calls++;
65 for ( unsigned int NP = 0; NP < NumPath; NP++ )
66 
67 if (ValidPath[NP])
68 
69 int RetCode;
70 RetCode = BasicNetlist( NewWidth, NP, circuit );
71 if ( RetCode != OK )
72 return RetCode;
73 RetCode = SetInput( NP, circuit.Valim() );
74 if ( RetCode != OK )
75 return RetCode;
76 RetCode = SimCall( NP );
77 if ( RetCode != OK )
78 return RetCode;
79 double OneDelay, OneEnergy;
80 RetCode = DelayRead( OneDelay, OneEnergy, NP );
81 if ( RetCode != OK )
82 return RetCode;
83 CPDelay[ NP ] = OneDelay;
84 CPPower[ NP ] = OneEnergy;
85 CPNoise[ NP ] = 0.0;
86 
87 
88 Area = CalcArea( NewWidth, circuit.GetNTran() );
89 return OK;
90 

HspiceArea.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "hspice.h"
7 
8  ///
9 double Hspice::CalcArea( const double *NewWidth, unsigned int NT )
10 
11 double A = 0.0;
12 for ( unsigned int i = 0; i < NT; i++ )
13 
14 A += NewWidth[ i ];
15 
16 return ( A );
17 

Setinput.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "hspice.h"
7 
8  ///
9 int Hspice::SetInput( unsigned int Np, double Val )
10 
11 char suffix[ 8 ];
12 sprintf( suffix, ".
13 char *Inputs = new char[ strlen( WorkPath ) + strlen( InputFile ) + strlen( suffix ) + 1 ];
14 if ( !Inputs )
15 return NO_MEM;
16 strcpy( Inputs, WorkPath );
17 strcat( Inputs, InputFile );
18 strcat( Inputs, suffix );
19 ofstream input_file( Inputs );
20 if ( !input_file )
21 return NOT_FOUND;
22 unsigned int node_in = pathlist[ Np ].GetNodeIn();
23 unsigned int node_out = pathlist[ Np ].GetNodeOut();
24 TransitionType TIn = pathlist[ Np ].GetTransitionIn();
25 if ( TIn == RISE )
26 input_file « endl « "v_node_in " « node_in «
27 " 0 " « " pwl(0 0 " « ( SimTime / 2.0 ) «
28 "p 0 " « ( SimTime / 2.0 ) + pathlist[ Np ].GetInTime() « "p " « Val « ")";
29 else if ( TIn == FALL )
30 input_file « endl « "v_node_in " « node_in «
31 " 0 " « " pwl(0 " « Val « " " « ( SimTime / 2.0 ) «
32 "p " « Val « " " « ( SimTime / 2.0 ) +
33 pathlist[ Np ].GetInTime() « "p 0)" ;
34 unsigned int node;
35 double nodeVal;
36 while ( pathlist[ Np ].TraverseActiveInputs( node, nodeVal ) )
37 
38 input_file « endl « "v_ACTIVE_" « node « " " «
39 node « " 0 dc " « nodeVal;
40 
41 while ( pathlist[ Np ].TraverseNoActiveInputs( node, nodeVal ) )
42 
43 input_file « endl « "v_NO_ACTIVE_" « node « " " «
44 node « " 0 dc " « nodeVal;
45 
46 while ( pathlist[ Np ].TraverseInitialConditions( node, nodeVal ) )
47 
48 input_file « endl « endl « ".ic v(" « node « ")=" «
49 nodeVal;
50 
51 TransitionType TOut = pathlist[ Np ].GetTransitionOut();
52 if ( TOut == RISE )
53 input_file « endl « endl « ".ic v(" « node_out « ")=0";
54 else if ( TOut == FALL )
55 input_file « endl « endl « ".ic v(" « node_out « ")=" « Val;
56 
57  // Delay meas.
58 input_file « endl « endl « ".measure tran path_n0_" « Np « "delay " «
59 " trig v(" « node_in « ")" « " val=" « Val*0.5 « " " « TransitionString[ TIn ] « "=1" «
60 " targ v(" « node_out « ")" « " val=" « Val * 0.5 « " " « TransitionString[ TOut ] « "=1";
61  // Power meas.
62 input_file « endl « endl « ".measure tran path_n0_" « Np « "power " «
63 " integ " « "POWER" « " from=0ps" « " to=" « SimTime « "ps ";
64 input_file « endl « endl « ".tran 10p " « SimTime « "p" « endl;
65 input_file.close();
66 return OK;
67 

Simcall.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "hspice.h"
7 
8  ///
9 int Hspice::SimCall( unsigned int Np )
10 
11 char system_string[ 512 ];
12 sprintf( system_string, "cd
13 if ( system( system_string ) == -1 )
14 
15 print_log( "ERROR invoking hspice simulator " );
16 return NO_MEM;
17 
18 return OK;
19 

Brackets.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "fast.h"
7 
8 const double FACTOR = 1.6;
9 const int NTRY = 50;
10 const double ZEPS = 1e-2;
11 
12  ///
13 int Fast::Brackets( const Circuit& circuit, unsigned int NP, unsigned int NC, double& start, double& end, TransistorType type, unsigned int j, unsigned int n, unsigned int p, const double* NewWidth, int& RetCode )
14 
15 int jj;
16 double f1, f2, x1, x2;
17 
18 if ( start == end )
19 
20 x1 = x2 = 0;
21 RetCode = NOT_FOUND;
22 return 0;
23 
24 if ( type == NMOS )
25 
26 f1 = EqN( circuit, NP, NC, start, RetCode, j, n, p, NewWidth );
27 f2 = EqN( circuit, NP, NC, end, RetCode, j, n, p, NewWidth );
28 
29 else if ( type == PMOS )
30 
31 f1 = EqP( circuit, NP, NC, start, RetCode, j, n, p, NewWidth );
32 f2 = EqP( circuit, NP, NC, end, RetCode, j, n, p, NewWidth );
33 
34 for ( jj = 1; jj <= NTRY; jj++ )
35 
36 if ( f1 * f2 < 0.0 )
37 
38 RetCode = OK;
39 return 1;
40 
41 if ( fabs ( f1 ) < fabs ( f2 ) )
42 
43 start += FACTOR * ( start - end );
44 if ( start <= 0.0 )
45 start = ZEPS;
46 if ( type == NMOS )
47 f1 = EqN( circuit, NP, NC, start, RetCode, j, n, p, NewWidth );
48 else if ( type == PMOS )
49 f1 = EqP( circuit, NP, NC, start, RetCode, j, n, p, NewWidth );
50 
51 else
52 
53 end += FACTOR * ( end - start );
54 if ( end <= 0.0 )
55 end = ZEPS;
56 if ( type == NMOS )
57 f2 = EqN( circuit, NP, NC, end, RetCode, j, n, p, NewWidth );
58 else if ( type == PMOS )
59 f2 = EqP( circuit, NP, NC, end, RetCode, j , n, p, NewWidth );
60 
61 
62 RetCode = NOT_FOUND;
63 return 0;
64 

CalcpowN.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "fast.h"
7 
8 
9  ///
10 int Fast::CalcPowerN( const Circuit& circuit, unsigned int NP, unsigned int NC, double& Ecc, double& Esc, unsigned int n, unsigned int p, const double* NewWidth )
11 
12 
13 double H_1, I_1, Vc, t0_bs, C_n;
14 double J_1, K_1, M_1, N_1;
15 double t0 = t0_n[ n ];
16 double tauo = tauo_n[ n ];
17 double tin = taui_n[ 1 ];
18 t0_bs = tin * ( VDD + TECH.Vtp0 ) / VDD;
19 double tc = (VDD * tauo_n[n] * (t0_n[n] - taui_n[n]) +
20 Vs_n[n] * taui_n[n] * (tauo_n[n] - t0_n[n])) /
21 (VDD * (t0_n[n] - taui_n[n]) + Vs_n[n] * (tauo_n[n] - t0_n[n]));
22 Esc = 0;
23 Ecc = 0;
24 if (p > 0)
25 
26 Vc = TECH.Ec_p * L_p[ p ];
27 H_1 = Vc * beta_p[ p ] * ( VDD * ( t0 - tauo ) *
28 ( 2 * Vc * ( t0 - tauo ) - Vd_n[ n ] * tin ) -
29 Vd_n[ n ] * tin * ( Vc * ( t0 - tauo ) - Vd_n[ n ] * tauo + 2 * TECH.Vtp0 * ( t0 - tauo ) ) ) /
30 ( 2 * Vd_n[ n ] * tin * ( t0 - tauo ) );
31 I_1 = Vc * beta_p[ p ] * ( 2 * VDD * ( t0 - tauo ) - Vd_n[ n ] * tin ) /
32 ( 2 * tin * ( t0 - tauo ) );
33 J_1 = ( Vc * Vc ) * beta_p[ p ] * ( t0 - tauo ) * ( 2 * ( VDD * VDD ) * ( t0 - tauo ) +
34 2 * VDD * ( Vc * ( t0 - tauo ) + Vd_n[ n ] * ( tauo - tin ) ) -
35 Vd_n[ n ] * tin * ( Vc + 2 * TECH.Vtp0 ) );
36 K_1 = 2 * Vd_n[ n ] * tin * ( VDD * ( t0 - tauo ) +
37 Vc * ( t0 - tauo ) + Vd_n[ n ] * tauo );
38 M_1 = VDD * Vc * beta_p[ p ] * ( VDD + 2 * TECH.Vtp0 ) / ( 2 * ( VDD + Vc ) );
39 N_1 = VDD * VDD * Vc * beta_p[ p ] / ( tin * ( VDD + Vc ) );
40 if ( t0_bs < tauo )
41 
42 Esc = ( J_1 * ( K_1 - 2 * Vd_n[ n ] * tin * ( VDD * ( t0 - tauo ) + Vd_n[ n ] * tauo ) ) *
43 0.25 * LOG ( 2 * Vd_n[ n ] * Vd_n[ n ] * t0 * tin - K_1 ) / ( Vd_n[ n ] * Vd_n[ n ] * Vd_n[ n ] *
44 ( tin * tin ) * ( tauo - t0 ) ) +
45 J_1 * ( K_1 - 2 * Vd_n[ n ] * tin * ( VDD * ( t0 - tauo ) + Vd_n[ n ] * tauo ) ) *
46 0.25 * LOG ( 2 * Vd_n[ n ] * Vd_n[ n ] * t0_bs * tin - K_1 ) /
47 ( Vd_n[ n ] * Vd_n[ n ] * Vd_n[ n ] * ( tin * tin ) * ( t0 - tauo ) ) +
48 ( ( t0 - t0_bs ) *
49 ( 3 * H_1 * Vd_n[ n ] * tin * ( 2 * VDD * ( t0 - tauo ) - Vd_n[ n ] * ( t0 + t0_bs - 2 * tauo ) ) +
50 I_1 * Vd_n[ n ] * tin * ( 3 * VDD * ( t0 + t0_bs ) * ( t0 - tauo ) - Vd_n[ n ] * ( 2 * ( t0 * t0 ) +
51 t0 * ( 2 * t0_bs - 3 * tauo ) + t0_bs * ( 2 * t0_bs - 3 * tauo ) ) ) - 3 * J_1 ) ) /
52 ( 6 * Vd_n[ n ] * tin * ( t0 - tauo ) ) );
53 
54 else
55 
56 Esc = ( J_1 * ( K_1 - 2 * Vd_n[ n ] * tin * ( VDD * ( t0 - tauo ) + Vd_n[ n ] * tauo ) ) *
57 0.25 * LOG ( 2 * Vd_n[ n ] * Vd_n[ n ] * t0 * tin - K_1 ) / ( Vd_n[ n ] * Vd_n[ n ] * Vd_n[ n ] *
58 ( tin * tin ) * ( tauo - t0 ) ) +
59 J_1 * ( K_1 - 2 * Vd_n[ n ] * tin * ( VDD * ( t0 - tauo ) + Vd_n[ n ] * tauo ) ) *
60 0.25 * LOG ( 2 * Vd_n[ n ] * Vd_n[ n ] * tauo * tin - K_1 ) /
61 ( Vd_n[ n ] * Vd_n[ n ] * Vd_n[ n ] * ( tin * tin ) * ( t0 - tauo ) ) +
62 ( 3 * H_1 * Vd_n[ n ] * tin * ( t0 - tauo ) * ( 2 * VDD - Vd_n[ n ] ) +
63 I_1 * Vd_n[ n ] * tin * ( t0 - tauo ) *
64 ( 3 * VDD * ( t0 + tauo ) - Vd_n[ n ] * ( 2 * t0 + tauo ) ) - 3 * J_1 ) /
65 ( 6 * Vd_n[ n ] * tin ) );
66 
67 Esc = fabs( Esc );
68 
69 const char* name;
70 unsigned int node = 0;
71 double Wjn, Wgn, Wjp, Wgp;
72 int njn, ngn, njp, ngp;
73 for ( unsigned int i = 1; i <= n; i++ )
74 
75 C_n = 0.0;
76 name = pathlist[ NP ].TransistorName( i - 1, NC );
77 if ( circuit[ name ].Source() == node )
78 
79 node = circuit[ name ].Drain();
80 Wjn = circuit.JunctionNWidth( node, njn, NewWidth );
81 Wgn = circuit.GateNWidth( node, ngn, NewWidth );
82 Wjp = circuit.JunctionPWidth( node, njp, NewWidth );
83 Wgp = circuit.GatePWidth( node, ngp, NewWidth );
84 
85 else if ( circuit[ name ].Drain() == node )
86 
87 node = circuit[ name ].Source();
88 Wjn = circuit.JunctionNWidth( node, njn, NewWidth );
89 Wgn = circuit.GateNWidth( node, ngn, NewWidth );
90 Wjp = circuit.JunctionPWidth( node, njp, NewWidth );
91 Wgp = circuit.GatePWidth( node, ngp, NewWidth );
92 
93 int nc;
94  // Cj N
95 C_n += TECH.C_nj * Wjn * TECH.Df *
96 ( Vd_n[ i ] * Vd_n[ i ] * ( TECH.mj_n - 1 ) * ( TECH.mj_n - 1 ) +
97 Vd_n[ i ] * TECH.mj_n * TECH.PB_n + TECH.PB_n * TECH.PB_n ) *
98 pow ( ( 1 + Vd_n[ i ] / TECH.PB_n ), -TECH.mj_n ) /
99 ( ( TECH.mj_n - 2 ) * ( TECH.mj_n - 1 ) );
100 C_n += TECH.C_np * 2 * ( Wjn + njn * TECH.Df ) *
101 ( Vd_n[ i ] * Vd_n[ i ] * ( TECH.mjsw_n - 1 ) * ( TECH.mjsw_n - 1 ) +
102 Vd_n[ i ] * TECH.mjsw_n * TECH.PB_n + TECH.PB_n * TECH.PB_n ) *
103 pow ( 1 + Vd_n[ i ] / TECH.PB_n, -TECH.mjsw_n ) /
104 ( ( TECH.mjsw_n - 2 ) * ( TECH.mjsw_n - 1 ) ) +
105 TECH.PB_n * TECH.PB_n * ( TECH.C_nj * Wjn * TECH.Df *
106 ( TECH.mjsw_n - 2 ) * ( TECH.mjsw_n - 1 ) +
107 TECH.C_np * 2 * ( Wjn + njn * TECH.Df ) *
108 ( TECH.mj_n - 2 ) * ( TECH.mj_n - 1 ) ) /
109 ( ( 2 - TECH.mjsw_n ) * ( TECH.mj_n - 2 ) * ( TECH.mj_n - 1 ) * ( TECH.mjsw_n - 1 ) );
110  // Cj P
111 if (p > 0)
112 
113 double x = TECH.mj_p - 1;
114 double y = TECH.mjsw_p - 1;
115 C_n += ( TECH.C_pj * Wjp * TECH.Df *
116 ( VDD * VDD * x + VDD * TECH.mj_p *
117 (TECH.PB_p - Vd_n[ i ] * x) + Vd_n[ i ] * Vd_n[ i ] * x * x -
118 Vd_n[ i ] * TECH.mj_p * TECH.PB_p + TECH.PB_p * TECH.PB_p ) *
119 pow( ( VDD - Vd_n[ i ] + TECH.PB_p ) / TECH.PB_p, -TECH.mj_p ) ) /
120 ( ( x - 1 ) * x );
121 C_n += ( TECH.C_pp * 2 * ( Wjp + njp * TECH.Df ) *
122 ( VDD * VDD * y + VDD * TECH.mjsw_p *
123 (TECH.PB_p - Vd_n[ i ] * y) + Vd_n[ i ] * Vd_n[ i ] * y * y -
124 Vd_n[ i ] * TECH.mjsw_p * TECH.PB_p + TECH.PB_p * TECH.PB_p ) *
125 pow( ( VDD - Vd_n[ i ] + TECH.PB_p ) / TECH.PB_p, -TECH.mjsw_p ) ) /
126 ( ( y - 1 ) * y );
127 C_n += ( TECH.C_pj * Wjp * TECH.Df *
128 ( VDD * VDD * x + VDD * TECH.mj_p * TECH.PB_p +
129 TECH.PB_p * TECH.PB_p ) *
130 pow( ( VDD + TECH.PB_p ) / TECH.PB_p, -TECH.mj_p ) ) /
131 ( ( 1 - x ) * x );
132 C_n += ( TECH.C_pp * 2 * ( Wjp + njp * TECH.Df ) *
133 ( VDD * VDD * y + VDD * TECH.mjsw_p * TECH.PB_p +
134 TECH.PB_p * TECH.PB_p ) *
135 pow( ( VDD + TECH.PB_p ) / TECH.PB_p, -TECH.mjsw_p ) ) /
136 ( ( 1 - y ) * y );
137 
138 C_n += circuit.CapStaticGnd( node, nc ) * Vd_n[i] * Vd_n[i] * 0.5;
139 C_n += circuit.CapStaticVdd( node, nc ) * Vd_n[i] * Vd_n[i] * 0.5;
140 C_n += Wgn * TECH.Lmin * TECH.Cox_n * Vd_n[i] * Vd_n[i] * 0.5;
141 C_n += Wgp * TECH.Lmin * TECH.Cox_p * Vd_n[i] * Vd_n[i] * 0.5;
142 if ( i < n )
143 C_n += TECH.Cgs0_n * ( ( Wjn - W_n[ i ] - W_n[ i + 1 ] ) +
144 ( njn - 2 ) * TECH.XW_n ) * 0.5 * Vd_n[i] * Vd_n[i];
145 else
146 C_n += TECH.Cgs0_n * ( ( Wjn - W_n[ i ] ) +
147 ( njn - 1 ) * TECH.XW_n ) * 0.5 * Vd_n[i] * Vd_n[i];
148 C_n += TECH.Cgs0_p * ( Wjp + njp * TECH.XW_p ) * Vd_n[i] * Vd_n[i] * 0.5;
149  // Cgd
150 if ( (( i == 1 ) && ( i < n - 1 )) || ((i == 1) && (n == 1)) )
151 
152 double Cov = TECH.Cgd0_n * ( W_n[ i ] + TECH.XW_n );
153 double Cg = Cov + 0.5 * TECH.Cox_n * W_n[ i ] * L_n[ i ];
154 int Op, SOp;
155 Op = Calct0ts1N( circuit, NP, SOp, NewWidth );
156 if ( Op == _E_ )
157 
158 Op = SOp;
159 
160 switch ( Op )
161 
162 case _A_:
163 C_n += Cg * Vd_n[i] * (Vd_n[i] * taui_n[i] *
164 (ts_n[i] - tauo_n[1]) * (ts_n[i] - tauo_n[1]) -
165 VDD * (t0_n[i] - tauo_n[1]) *
166 ((ts_n[i] * ts_n[i]) - 2 * ts_n[i] * tauo_n[1]-taui_n[i] * (taui_n[i] - 2 * tauo_n[1]))) /
167 (2 * taui_n[i] * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
168 C_n += Cov * Vd_n[i] * ((t0_n[i] - ts_n[i]) * (t0_n[i] + ts_n[i] - 2 * tauo_n[1])) *
169 (Vd_n[i] * taui_n[i] - VDD * (t0_n[i] - tauo_n[1])) /
170 (2 * taui_n[i] * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
171 break;
172 case _AA_:
173 C_n += Cg * Vd_n[i] * (ts_n[i] - tauo_n[1]) * (ts_n[i] - tauo_n[1])*
174 (Vd_n[i] * taui_n[i] - VDD * (t0_n[i] - tauo_n[1])) /
175 (2 * taui_n[i] * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
176 C_n += Cov * Vd_n[i] * (Vd_n[i] * taui_n[i]*
177 ((t0_n[i] * t0_n[i]) - 2 * t0_n[i] * tauo_n[1]-ts_n[i] * (ts_n[i] - 2 * tauo_n[1])) -
178 VDD * (t0_n[i] - tauo_n[1])*
179 ((t0_n[i] * t0_n[i]) - 2 * t0_n[i] * tauo_n[1]-taui_n[i] * (taui_n[i] - 2 * tauo_n[1]))) /
180 (2 * taui_n[i] * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
181 break;
182 case _B_:
183 C_n += Cg * Vd_n[i] * (VDD * ((t0_n[i] * t0_n[i]) - 2 * t0_n[i] * tauo_n[1]-
184 taui_n[i] * (taui_n[i] - 2 * tauo_n[1])) +
185 Vd_n[i] * taui_n[i] * (tauo_n[1]-t0_n[i])) /
186 (2 * taui_n[i] * (tauo_n[1]-t0_n[i]));
187 break;
188 case _C_:
189 C_n += Cg * Vd_n[i] * Vd_n[i] * (ts_n[i] - tauo_n[1]) *
190 (ts_n[i] - tauo_n[1]) /
191 (2 * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
192 C_n += Cov * Vd_n[i] * Vd_n[i]*
193 ((t0_n[i] * t0_n[i]) - 2 * t0_n[i] * tauo_n[1]-ts_n[i] * (ts_n[i] - 2 * tauo_n[1])) /
194 (2 * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
195 break;
196 case _D_:
197 C_n += Cg * Vd_n[i] * Vd_n[i] / 2;
198 break;
199 case _F_:
200 C_n += Cg * Vd_n[i] * (ts_n[i] - tauo_n[1]) * (ts_n[i] - tauo_n[1])*
201 (Vd_n[i] * taui_n[i] - VDD * (t0_n[i] - tauo_n[1])) /
202 (2 * taui_n[i] * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
203 C_n += Cov * Vd_n[i]*
204 ((t0_n[i] * t0_n[i]) - 2 * t0_n[i] * tauo_n[1]-ts_n[i] * (ts_n[i] - 2 * tauo_n[1]))*
205 (Vd_n[i] * taui_n[i] - VDD * (t0_n[i] - tauo_n[1])) /
206 (2 * taui_n[i] * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
207 break;
208 case _G_:
209 C_n += Cg * Vd_n[i] * (Vd_n[i] * taui_n[i] - VDD * (t0_n[i] - tauo_n[1])) /
210 (2 * taui_n[i]);
211 break;
212 case _E_:
213 default:
214 C_n += 0.0;
215 break;
216 
217 
218 else if ( ( i < n - 1 ) && ( i > 1 ) )
219 
220 C_n += ( TECH.Cgd0_n * ( W_n[ i ] + TECH.XW_n ) + 0.5 * TECH.Cox_n * W_n[ i ] * TECH.Lmin ) *
221 Vd_n[ i ] * Vd_n[ i ] * 0.5;
222 C_n += ( TECH.Cgs0_n * ( W_n[ i + 1 ] + TECH.XW_n ) + 0.5 * TECH.Cox_n * W_n[ i + 1 ] * TECH.Lmin ) *
223 Vd_n[ i ] * Vd_n[ i ] * 0.5;
224 
225 else if ( (i == 1) && (i == n - 1) )
226 
227 double Cov = TECH.Cgd0_n * ( W_n[ i ] + TECH.XW_n );
228 double Cg = Cov + 0.5 * TECH.Cox_n * W_n[ i ] * L_n[ i ];
229 int Op, SOp;
230 Op = Calct0ts1N( circuit, NP, SOp, NewWidth );
231 if ( Op == _E_ )
232 
233 Op = SOp;
234 
235 switch ( Op )
236 
237 case _A_:
238 C_n += Cg * Vd_n[i] * (Vd_n[i] * taui_n[i] *
239 (ts_n[i] - tauo_n[1]) * (ts_n[i] - tauo_n[1]) -
240 VDD * (t0_n[i] - tauo_n[1]) *
241 ((ts_n[i] * ts_n[i]) - 2 * ts_n[i] * tauo_n[1]-taui_n[i] * (taui_n[i] - 2 * tauo_n[1]))) /
242 (2 * taui_n[i] * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
243 C_n += Cov * Vd_n[i] * ((t0_n[i] - ts_n[i]) * (t0_n[i] + ts_n[i] - 2 * tauo_n[1])) *
244 (Vd_n[i] * taui_n[i] - VDD * (t0_n[i] - tauo_n[1])) /
245 (2 * taui_n[i] * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
246 break;
247 case _AA_:
248 C_n += Cg * Vd_n[i] * (ts_n[i] - tauo_n[1]) * (ts_n[i] - tauo_n[1])*
249 (Vd_n[i] * taui_n[i] - VDD * (t0_n[i] - tauo_n[1])) /
250 (2 * taui_n[i] * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
251 C_n += Cov * Vd_n[i] * (Vd_n[i] * taui_n[i]*
252 ((t0_n[i] * t0_n[i]) - 2 * t0_n[i] * tauo_n[1]-ts_n[i] * (ts_n[i] - 2 * tauo_n[1])) -
253 VDD * (t0_n[i] - tauo_n[1])*
254 ((t0_n[i] * t0_n[i]) - 2 * t0_n[i] * tauo_n[1]-taui_n[i] * (taui_n[i] - 2 * tauo_n[1]))) /
255 (2 * taui_n[i] * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
256 break;
257 case _B_:
258 C_n += Cg * Vd_n[i] * (VDD * ((t0_n[i] * t0_n[i]) - 2 * t0_n[i] * tauo_n[1]-
259 taui_n[i] * (taui_n[i] - 2 * tauo_n[1])) +
260 Vd_n[i] * taui_n[i] * (tauo_n[1]-t0_n[i])) /
261 (2 * taui_n[i] * (tauo_n[1]-t0_n[i]));
262 break;
263 case _C_:
264 C_n += Cg * Vd_n[i] * Vd_n[i] * (ts_n[i] - tauo_n[1]) *
265 (ts_n[i] - tauo_n[1]) /
266 (2 * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
267 C_n += Cov * Vd_n[i] * Vd_n[i]*
268 ((t0_n[i] * t0_n[i]) - 2 * t0_n[i] * tauo_n[1]-ts_n[i] * (ts_n[i] - 2 * tauo_n[1])) /
269 (2 * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
270 break;
271 case _D_:
272 C_n += Cg * Vd_n[i] * Vd_n[i] / 2;
273 break;
274 case _F_:
275 C_n += Cg * Vd_n[i] * (ts_n[i] - tauo_n[1]) * (ts_n[i] - tauo_n[1])*
276 (Vd_n[i] * taui_n[i] - VDD * (t0_n[i] - tauo_n[1])) /
277 (2 * taui_n[i] * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
278 C_n += Cov * Vd_n[i]*
279 ((t0_n[i] * t0_n[i]) - 2 * t0_n[i] * tauo_n[1]-ts_n[i] * (ts_n[i] - 2 * tauo_n[1]))*
280 (Vd_n[i] * taui_n[i] - VDD * (t0_n[i] - tauo_n[1])) /
281 (2 * taui_n[i] * (t0_n[i] - tauo_n[1]) * (t0_n[i] - tauo_n[1]));
282 break;
283 case _G_:
284 C_n += Cg * Vd_n[i] * (Vd_n[i] * taui_n[i] - VDD * (t0_n[i] - tauo_n[1])) /
285 (2 * taui_n[i]);
286 break;
287 case _E_:
288 default:
289 C_n += 0.0;
290 break;
291 
292 Cov = ( ( TECH.Cgs0_n * W_n[ n ] + TECH.XW_n ) + 0.5 * TECH.Cox_n * W_n[ n ] * L_n[ n ] );
293 Cg = ( ( TECH.Cgs0_n * W_n[ n ] + TECH.XW_n ) + 0.666666 * TECH.Cox_n * W_n[ n ] * L_n[ n ] );
294 Op = Calct0tsnN( n, SOp);
295 if ( Op == _E_ )
296 
297 Op = SOp;
298 
299 switch ( Op )
300 
301 case _A_:
302 C_n += Cov * Vs_n[n] * Vs_n[n] * (t0_n[i] * t0_n[i] - 2 * t0_n[i] * taui_n[n] -
303 ts_n[n] * (ts_n[n] - 2 * taui_n[n])) /
304 (2 * (t0_n[i] - taui_n[n]) * (t0_n[i] - taui_n[n]));
305 C_n += Cg * Vs_n[n] * Vs_n[n] * (ts_n[n] - taui_n[n]) * (ts_n[n] - taui_n[n]) *
306 (2 * (t0_n[i] - taui_n[n]) * (t0_n[i] - taui_n[n]));
307 break;
308 case _B_:
309 C_n += Cov * Vs_n[n] * Vs_n[n] * 0.5;
310 break;
311 case _C_:
312 C_n += -Cg * Vs_n[n] * Vs_n[n] * (tc * tc - 2 * tc * taui_n[n] -
313 ts_n[n] * (ts_n[n] - 2 * taui_n[n])) /
314 (2 * (t0_n[i] - taui_n[n]) * (t0_n[i] - taui_n[n]));
315 C_n += Cov * Vs_n[n] * Vs_n[n] * (t0_n[i] * t0_n[i] - 2 * t0_n[i] * taui_n[i] -
316 ts_n[n] * (ts_n[n] - 2 * taui_n[n])) /
317 (2 * (t0_n[i] - taui_n[n]) * (t0 - taui_n[n]));
318 break;
319 case _D_:
320 C_n += Cov * Vs_n[n] * Vs_n[n] * (t0_n[i] * t0_n[i] - 2 * t0_n[i] * taui_n[i] -
321 tc * (tc - 2 * taui_n[n])) /
322 (2 * (t0_n[i] - taui_n[n]) * (t0_n[i] - taui_n[n]));
323 break;
324 case _E_:
325 default:
326 break;
327 
328 
329 else if ( (i == n - 1) && (n > 2))
330 
331 C_n += ( TECH.Cgd0_n * ( W_n[ i ] + TECH.XW_n ) + 0.5 * TECH.Cox_n * W_n[ i ] * TECH.Lmin ) *
332 Vd_n[ i ] * ( 2 * VDD - Vd_n[ i ] ) * 0.5;
333 int Op, SOp;
334 double Cov = ( ( TECH.Cgs0_n * W_n[ n ] + TECH.XW_n ) + 0.5 * TECH.Cox_n * W_n[ n ] * L_n[ n ] );
335 double Cg = ( ( TECH.Cgs0_n * W_n[ n ] + TECH.XW_n ) + 0.666666 * TECH.Cox_n * W_n[ n ] * L_n[ n ] );
336 Op = Calct0tsnN( n, SOp);
337 if ( Op == _E_ )
338 
339 Op = SOp;
340 
341 switch ( Op )
342 
343 case _A_:
344 C_n += Cov * Vs_n[n] * Vs_n[n] * (t0_n[i] * t0_n[i] - 2 * t0_n[i] * taui_n[n] -
345 ts_n[n] * (ts_n[n] - 2 * taui_n[n])) /
346 (2 * (t0_n[i] - taui_n[n]) * (t0_n[i] - taui_n[n]));
347 C_n += Cg * Vs_n[n] * Vs_n[n] * (ts_n[n] - taui_n[n]) * (ts_n[n] - taui_n[n]) *
348 (2 * (t0_n[i] - taui_n[n]) * (t0_n[i] - taui_n[n]));
349 break;
350 case _B_:
351 C_n += Cov * Vs_n[n] * Vs_n[n] * 0.5;
352 break;
353 case _C_:
354 C_n += -Cg * Vs_n[n] * Vs_n[n] * (tc * tc - 2 * tc * taui_n[n] -
355 ts_n[n] * (ts_n[n] - 2 * taui_n[n])) /
356 (2 * (t0_n[i] - taui_n[n]) * (t0_n[i] - taui_n[n]));
357 C_n += Cov * Vs_n[n] * Vs_n[n] * (t0_n[i] * t0_n[i] - 2 * t0_n[i] * taui_n[i] -
358 ts_n[n] * (ts_n[n] - 2 * taui_n[n])) /
359 (2 * (t0_n[i] - taui_n[n]) * (t0 - taui_n[n]));
360 break;
361 case _D_:
362 C_n += Cov * Vs_n[n] * Vs_n[n] * (t0_n[i] * t0_n[i] - 2 * t0_n[i] * taui_n[i] -
363 tc * (tc - 2 * taui_n[n])) /
364 (2 * (t0_n[i] - taui_n[n]) * (t0_n[i] - taui_n[n]));
365 break;
366 case _E_:
367 default:
368 break;
369 
370 
371 
372 else if ( i == n )
373 
374 double Cov = TECH.Cgd0_n * ( W_n[ n ] + TECH.XW_n );
375 double Cg = Cov + 0.5 * TECH.Cox_n * W_n[ n ] * L_n[ n ];
376 int Op, SOp;
377 Op = Calct0tsnN(n, SOp);
378 if ( Op == _E_ )
379 
380 Op = SOp;
381 
382 switch ( Op )
383 
384 case _A_:
385 case _B_:
386 C_n += Cov *
387 Vd_n[i] * Vd_n[i] * (t0_n[i] * t0_n[i] - 2 * t0_n[i] * tauo_n[i] -
388 ts_n[i] * (ts_n[i] - 2 * tauo_n[i])) /
389 (2 * (t0_n[i] - tauo_n[i]) * (t0_n[i] - tauo_n[i]));
390 C_n += Cg *
391 Vd_n[i] * Vd_n[i] * (ts_n[i] - tauo_n[i]) * (ts_n[i] - tauo_n[i]) /
392 (2 * (t0_n[i] - tauo_n[i]) * (t0_n[i] - tauo_n[i]));
393 break;
394 case _C_:
395 C_n += Cov *
396 Vd_n[i] * Vd_n[i] * (t0_n[i] * t0_n[i] - 2 * t0_n[i] * tauo_n[i] -
397 ts_n[i] * (ts_n[i] - 2 * tauo_n[i])) /
398 (2 * (t0_n[i] - tauo_n[i]) * (t0_n[i] - tauo_n[i]));
399 C_n += -Cg *
400 Vd_n[i] * Vd_n[i] * (tc * tc - 2 * tc * tauo_n[i] -
401 ts_n[i] * (ts_n[i] - 2 * tauo_n[i])) /
402 (2 * (t0_n[i] - tauo_n[i]) * (t0_n[i] - tauo_n[i]));
403 break;
404 case _D_:
405 C_n += Cov *
406 Vd_n[i] * Vd_n[i] * (t0_n[i] * t0_n[i] - 2 * t0_n[i] - tauo_n[i] -
407 tc * (tc - 2 * tauo_n[i])) /
408 (2 * (t0_n[i] - tauo_n[i]) * (t0_n[i] - tauo_n[i]));
409 break;
410 case _E_:
411 default:
412 break;
413 
414 
415 
416 if ( C_n < 0.0 )
417 C_n *= -1;
418 Ecc += C_n;
419 
420 return OK;
421 

CalcpowP.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "fast.h"
7 
8 
9  ///
10 int Fast::CalcPowerP( const Circuit& circuit, unsigned int NP, unsigned int NC, double& Ecc, double& Esc, unsigned int n, unsigned int p, const double* NewWidth )
11 
12 double H_1, I_1, Vc, t0_bs, C_p;
13 double J_1, K_1, M_1, N_1, O_1, P_1;
14 
15 double t0 = t0_p[ p ];
16 double tauo = tauo_p[ p ];
17 double tin = taui_p[ 1 ];
18 t0_bs = tin * ( VDD - TECH.Vtn0 ) / VDD;
19 double tc = (VDD * tauo_p[p] * (t0_p[p] - taui_p[p]) +
20 Vs_p[p] * taui_p[p] * (tauo_p[p] - t0_p[p])) /
21 (VDD * (t0_p[p] - taui_p[p]) + Vs_p[p] * (tauo_p[p] - t0_p[p]));
22 Esc = 0;
23 Ecc = 0;
24 if (n > 0)
25 
26 Vc = TECH.Ec_n * L_n[ n ];
27 
28 H_1 = Vc * beta_n[ n ] * ( ( VDD * VDD ) * tin * ( t0 - 2 * tauo ) -
29 VDD * ( Vc * ( t0 - tauo ) * ( 2 * t0 - tin - 2 * tauo ) +
30 tin * ( Vd_p[ p ] * ( t0 - 3 * tauo ) + 2 * TECH.Vtn0 * ( t0 - tauo ) ) ) -
31 Vd_p[ p ] * tin * ( Vc * ( t0 - tauo ) + Vd_p[ p ] * tauo + 2 * TECH.Vtn0 * ( tauo - t0 ) ) ) /
32 ( 2 * tin * ( VDD - Vd_p[ p ] ) * ( t0 - tauo ) );
33 I_1 = Vc * beta_n[ n ] * ( VDD * ( 2 * t0 - tin - 2 * tauo ) +
34 Vd_p[ p ] * tin ) / ( 2 * tin * ( tauo - t0 ) );
35 J_1 = ( Vc * Vc ) * beta_n[ n ] * ( tauo - t0 ) *
36 ( 2 * ( VDD * VDD ) * ( t0 - tin ) + VDD * ( Vc * ( 2 * t0 - tin - 2 * tauo ) +
37 2 * ( Vd_p[ p ] * ( tin - tauo ) + TECH.Vtn0 * tin ) ) + Vd_p[ p ] * tin * ( Vc - 2 * TECH.Vtn0 ) );
38 K_1 = 2 * tin * ( VDD - Vd_p[ p ] ) * ( VDD * t0 + Vc * ( t0 - tauo ) -
39 Vd_p[ p ] * tauo );
40 M_1 = Vc * beta_n[ n ] * ( VDD * t0 + Vc * ( tauo - t0 ) - Vd_p[ p ] * tauo + 2 * TECH.Vtn0 * ( t0 - tauo ) ) / ( 2 * ( tauo - t0 ) );
41 N_1 = Vc * beta_n[ n ] * ( VDD - Vd_p[ p ] ) / ( 2 * ( t0 - tauo ) );
42 O_1 = ( Vc * Vc ) * beta_n[ n ] * ( Vc - 2 * TECH.Vtn0 ) * ( t0 - tauo );
43 P_1 = 2 * ( VDD * t0 + Vc * ( t0 - tauo ) - Vd_p[ p ] * tauo );
44 
45 if ( t0_bs < tauo )
46 
47 Esc = ( VDD * ( 3 * J_1 * ( K_1 - 2 * tin * t0 * ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) ) *
48 LOG ( 2 * t0 * tin * ( ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) ) - K_1 ) +
49 3 * J_1 * ( 2 * tin * t0 * ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) - K_1 ) *
50 LOG ( 2 * t0_bs * tin * ( ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) ) - K_1 ) +
51 2 * tin * ( ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) ) *
52 ( t0_bs - t0 ) * ( 3 * H_1 * tin * ( VDD - Vd_p[ p ] ) *
53 ( VDD - Vd_p[ p ] ) * ( t0 - t0_bs ) +
54 I_1 * tin * ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) *
55 ( t0 * t0 + t0 * t0_bs - 2 * t0_bs * t0_bs ) - 3 * J_1 ) ) /
56 ( 12 * ( tin * tin ) * ( ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) ) *
57 ( t0 - tauo ) ) );
58 
59 else
60 
61 Esc = ( ( 3 * J_1 * ( K_1 + 2 * tin * ( VDD - Vd_p[ p ] ) * ( Vd_p[ p ] * tauo - VDD * t0 ) ) *
62 LOG ( 2 * t0 * tin * ( ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) ) - K_1 ) -
63 3 * J_1 * ( K_1 + 2 * tin * ( VDD - Vd_p[ p ] ) *
64 ( Vd_p[ p ] * tauo - VDD * t0 ) ) *
65 LOG ( 2 * tauo * tin * ( ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) ) - K_1 ) +
66 2 * tin * ( ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) ) *
67 ( tauo - t0 ) * ( 3 * H_1 * tin * ( VDD - Vd_p[ p ] ) *
68 ( VDD + Vd_p[ p ] ) * ( t0 - tauo ) +
69 I_1 * tin * ( VDD - Vd_p[ p ] ) * ( t0 - tauo ) *
70 ( VDD * ( t0 + 2 * tauo ) + Vd_p[ p ] * ( 2 * t0 + tauo ) ) - 3 * J_1 ) ) /
71 ( 12 * ( tin * tin ) * ( ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) * ( VDD - Vd_p[ p ] ) ) *
72 ( t0 - tauo ) ) );
73 
74 Esc = fabs( Esc );
75 
76 const char* name;
77 unsigned int node = circuit.ValimNode();
78 int njn, ngn, njp, ngp;
79 double Wjn, Wgn, Wjp, Wgp;
80 for ( unsigned int i = 1; i <= p; i++ )
81 
82 C_p = 0.0;
83 name = pathlist[ NP ].TransistorName( n + p - i, NC );  // first there are nmos
84  // then there are the pmos, in REVERSE order
85 if ( circuit[ name ].Source() == node )
86 
87 node = circuit[ name ].Drain();
88 Wjn = circuit.JunctionNWidth( node, njn, NewWidth );
89 Wgn = circuit.GateNWidth( node, ngn, NewWidth );
90 Wjp = circuit.JunctionPWidth( node, njp, NewWidth );
91 Wgp = circuit.GatePWidth( node, ngp, NewWidth );
92 
93 else if ( circuit[ name ].Drain() == node )
94 
95 node = circuit[ name ].Source();
96 Wjn = circuit.JunctionNWidth( node, njn, NewWidth );
97 Wgn = circuit.GateNWidth( node, ngn, NewWidth );
98 Wjp = circuit.JunctionPWidth( node, njp, NewWidth );
99 Wgp = circuit.GatePWidth( node, ngp, NewWidth );
100 
101 int nc;
102  // Cj P
103 C_p += TECH.C_pj * Wjp * TECH.Df *
104 ( ( VDD * VDD + Vd_p[ i ] * Vd_p[ i ] ) * ( TECH.mj_p - 1 ) * ( TECH.mj_p - 1 ) + VDD *
105 ( TECH.mj_p * TECH.PB_p - 2 * Vd_p[ i ] * ( TECH.mj_p - 1 ) * ( TECH.mj_p - 1 ) ) -
106 Vd_p[ i ] * TECH.mj_p * TECH.PB_p + TECH.PB_p * TECH.PB_p ) *
107 pow ( ( VDD - Vd_p[ i ] + TECH.PB_p ) / TECH.PB_p, -TECH.mj_p ) /
108 ( ( TECH.mj_p - 2 ) * ( TECH.mj_p - 1 ) );
109 C_p += TECH.C_pp * 2 * ( Wjp + njp * TECH.Df ) *
110 ( ( VDD * VDD + Vd_p[ i ] * Vd_p[ i ] ) * ( TECH.mjsw_p - 1 ) * ( TECH.mjsw_p - 1 ) + VDD *
111 ( TECH.mjsw_p * TECH.PB_p - 2 * Vd_p[ i ] * ( TECH.mjsw_p - 1 ) * ( TECH.mjsw_p - 1 ) ) -
112 Vd_p[ i ] * TECH.mjsw_p * TECH.PB_p + TECH.PB_p * TECH.PB_p ) *
113 pow ( ( VDD - Vd_p[ i ] + TECH.PB_p ) / TECH.PB_p, -TECH.mjsw_p ) /
114 ( ( TECH.mjsw_p - 2 ) * ( TECH.mjsw_p - 1 ) );
115 C_p += TECH.PB_p * TECH.PB_p * ( TECH.C_pj * Wjp * TECH.Df *
116 ( TECH.mjsw_p - 2 ) * ( TECH.mjsw_p - 1 ) +
117 TECH.C_pp * 2 * ( Wjp + njp * TECH.Df ) *
118 ( TECH.mj_p - 2 ) * ( TECH.mj_p - 1 ) ) /
119 ( ( TECH.mj_p - 2 ) * ( TECH.mj_p - 1 ) * ( TECH.mjsw_p - 1 ) * ( 2 - TECH.mjsw_p ) );
120  // Cj N
121 if (n > 0)
122 
123 double x = TECH.mj_n - 1;
124 double y = TECH.mjsw_n - 1;
125 C_p += TECH.C_nj * Wjn * TECH.Df *
126 ( VDD * VDD * x + VDD * TECH.mj_n * TECH.PB_n + TECH.PB_n * TECH.PB_n ) *
127 pow( ( VDD + TECH.PB_n ) / TECH.PB_n, -TECH.mj_n ) /
128 ( ( 1 - x ) * x );
129 C_p += TECH.C_np * 2 * ( Wjn + njn * TECH.Df ) *
130 ( VDD * VDD * y + VDD * TECH.mjsw_n * TECH.PB_n + TECH.PB_n * TECH.PB_n ) *
131 pow( ( VDD + TECH.PB_n ) / TECH.PB_n, -TECH.mjsw_n ) /
132 ( ( 1 - y ) * y );
133 C_p += TECH.C_nj * Wjn * TECH.Df *
134 ( VDD * Vd_p[ i ] * (x - 1) * x -
135 Vd_p[ i ] * Vd_p[i] * x * x - TECH.PB_n * (Vd_p[i] * TECH.mj_n + TECH.PB_n)) *
136 pow( ( VDD + TECH.PB_n ) / TECH.PB_n, -TECH.mj_n ) /
137 ( ( 1 - x ) * x );
138 C_p += TECH.C_np * 2 * ( Wjn + njn * TECH.Df ) *
139 ( VDD * Vd_p[ i ] * (y - 1) * y -
140 Vd_p[ i ] * Vd_p[i] * y * y - TECH.PB_n * (Vd_p[i] * TECH.mjsw_n + TECH.PB_n) ) *
141 pow( ( VDD + TECH.PB_n ) / TECH.PB_n, -TECH.mjsw_n ) /
142 ( ( 1 - y ) * y );
143 
144 C_p += circuit.CapStaticGnd( node, nc ) * ( VDD - Vd_p[ i ] ) * ( VDD - Vd_p[ i ] ) * 0.5;
145 C_p += circuit.CapStaticVdd( node, nc ) * ( VDD - Vd_p[ i ] ) * ( VDD - Vd_p[ i ] ) * 0.5;
146 C_p += Wgn * TECH.Lmin * TECH.Cox_n * ( VDD - Vd_p[ i ] ) * ( VDD - Vd_p[ i ] ) * 0.5;
147 C_p += Wgp * TECH.Lmin * TECH.Cox_p * ( VDD - Vd_p[ i ] ) * ( VDD - Vd_p[ i ] ) * 0.5;
148 C_p += TECH.Cgs0_n * ( Wjn + njn * TECH.XW_n ) * ( VDD - Vd_p[ i ] ) * ( VDD - Vd_p[ i ] ) * 0.5;
149 if ( i < n )
150 C_p += TECH.Cgs0_p * ( ( Wjp - W_p[ i ] - W_p[ i + 1 ] ) + ( njp - 2 ) * TECH.XW_p ) *
151 ( VDD - Vd_p[ i ] ) * ( VDD - Vd_p[ i ] ) * 0.5;
152 else
153 C_p += TECH.Cgs0_p * ( ( Wjp - W_p[ i ] ) + ( njp - 1 ) * TECH.XW_p ) *
154 ( VDD - Vd_p[ i ] ) * ( VDD - Vd_p[ i ] ) * 0.5;
155  // Cgs
156 if ( (( i == 1 ) && ( i < p - 1 )) || ((i == 1) && (p == 1)) )
157 
158 double Cov = TECH.Cgd0_p * ( W_p[ i ] + TECH.XW_p );
159 double Cg = Cov + 0.5 * TECH.Cox_p * W_p[ i ] * L_p[ i ];
160 int Op, SOp;
161 Op = Calct0ts1P( circuit, NP, SOp, NewWidth );
162 if ( Op == _E_ )
163 
164 Op = SOp;
165 
166 switch ( Op )
167 
168 case _A_:
169 C_p += Cov * (Vd_p[i] - VDD) * ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * tauo_p[i] - ts_p[i]*
170 (ts_p[i] - 2 * tauo_p[i])) * (VDD * (t0_p[i] - taui_p[i] - tauo_p[i]) +
171 Vd_p[i] * taui_p[i]) /
172 (2 * taui_p[i] * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
173 C_p += -Cg * ((VDD * VDD) * ((t0_p[i] * t0_p[i]) * ((ts_p[i] * ts_p[i]) - (taui_p[i] * taui_p[i])) +
174 t0_p[i] * ((taui_p[i] * taui_p[i]) - (ts_p[i] * ts_p[i])) * (taui_p[i] + 2 * tauo_p[i]) +
175 (ts_p[i] * ts_p[i]) * tauo_p[i] * (taui_p[i] + tauo_p[i]) - (taui_p[i] * taui_p[i]) * ((taui_p[i] * taui_p[i]) -
176 taui_p[i] * tauo_p[i] + 2 * (tauo_p[i] * tauo_p[i]))) +
177 VDD * Vd_p[i] * taui_p[i] * (t0_p[i] * ((ts_p[i] * ts_p[i]) - (taui_p[i] * taui_p[i])) - (ts_p[i] * ts_p[i]) * tauo_p[i] +
178 taui_p[i] * (2 * (taui_p[i] * taui_p[i]) - 3 * taui_p[i] * tauo_p[i] + 2 * (tauo_p[i] * tauo_p[i]))) -
179 (Vd_p[i] * Vd_p[i]) * (taui_p[i] * taui_p[i]) * ((taui_p[i] * taui_p[i]) - 2 * taui_p[i] * tauo_p[i] + (tauo_p[i] * tauo_p[i]))) /
180 (2 * (taui_p[i] * taui_p[i]) * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
181 break;
182 case _AA_:
183 C_p += Cg * (VDD - Vd_p[i]) * (VDD - Vd_p[i]) * (ts_p[i] - tauo_p[i]) * (ts_p[i] - tauo_p[i]) /
184 (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
185 C_p += Cov * (Vd_p[i] - VDD) * (VDD * ((t0_p[i] * t0_p[i] * t0_p[i]) - (t0_p[i] * t0_p[i]) * (taui_p[i] +
186 3 * tauo_p[i]) - t0_p[i] * ((taui_p[i] * taui_p[i]) - 4 * taui_p[i] * tauo_p[i] - 2 * (tauo_p[i] * tauo_p[i])) +
187 taui_p[i] * ((ts_p[i] * ts_p[i]) - 2 * ts_p[i] * tauo_p[i] + tauo_p[i] * (taui_p[i] - 2 * tauo_p[i]))) +
188 Vd_p[i] * taui_p[i] * ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * tauo_p[i] - ts_p[i] * (ts_p[i] - 2 * tauo_p[i]))) /
189 (2 * taui_p[i] * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
190 break;
191 case _B_:
192 C_p += Cg * (VDD - Vd_p[i]) * (VDD * ((t0_p[i] * t0_p[i]) - t0_p[i] * (taui_p[i] + 2 * tauo_p[i]) -
193 (taui_p[i] * taui_p[i]) + 3 * taui_p[i] * tauo_p[i]) + Vd_p[i] * taui_p[i] * (t0_p[i] - tauo_p[i])) /
194 (2 * taui_p[i] * (tauo_p[i] - t0_p[i]));
195 break;
196 case _C_:
197 C_p += Cg * (VDD - Vd_p[i]) * (VDD - Vd_p[i]) * (ts_p[i] - tauo_p[i]) * (ts_p[i] - tauo_p[i]) / (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
198 C_p += Cov * (VDD - Vd_p[i]) * (VDD - Vd_p[i]) * ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * tauo_p[i] - ts_p[i] * (ts_p[i] - 2 * tauo_p[i])) /
199 (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
200 break;
201 case _D_:
202 C_p += Cg * (VDD - Vd_p[i]) * (VDD - Vd_p[i]) * (taui_p[i] - tauo_p[i]) * (taui_p[i] - tauo_p[i]) /
203 (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
204 break;
205 case _F_:
206 C_p += Cg * (Vd_p[i] - VDD) * (ts_p[i] - tauo_p[i]) * (ts_p[i] - tauo_p[i]) * (VDD * (t0_p[i] - taui_p[i] - tauo_p[i]) +
207 Vd_p[i] * taui_p[i]) / (2 * taui_p[i] * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
208 C_p += Cov * (Vd_p[i] - VDD) * ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * tauo_p[i] - ts_p[i]*
209 (ts_p[i] - 2 * tauo_p[i])) * (VDD * (t0_p[i] - taui_p[i] - tauo_p[i]) + Vd_p[i] * taui_p[i]) /
210 (2 * taui_p[i] * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
211 break;
212 case _G_:
213 C_p += Cg * (Vd_p[i] - VDD) * (VDD * (t0_p[i] - taui_p[i] - tauo_p[i]) + Vd_p[i] * taui_p[i]) / (2 * taui_p[i]);
214 break;
215 case _E_:
216 default:
217 C_p += 0.0;
218 break;
219 
220 
221 else if ( ( i < p - 1 ) && ( i > 1 ) )
222 
223 C_p += ( TECH.Cgd0_p * ( W_p[ i ] + TECH.XW_p ) + 0.5 * TECH.Cox_p * W_p[ i ] * TECH.Lmin ) *
224 ( VDD + Vd_p[ i ] ) * ( Vd_p[ i ] - VDD ) * 0.5;
225 C_p += ( TECH.Cgs0_p * ( W_p[ i + 1 ] + TECH.XW_p ) + 0.5 * TECH.Cox_p * W_p[ i + 1 ] * njp * TECH.Lmin ) *
226 ( VDD + Vd_p[ i ] ) * ( Vd_p[ i ] - VDD ) * 0.5;
227 
228 else if ( (i == 1) && (i == p - 1) )
229 
230 double Cov = TECH.Cgd0_p * ( W_p[ i ] + TECH.XW_p );
231 double Cg = Cov + 0.5 * TECH.Cox_p * W_p[ i ] * L_p[ i ];
232 int Op, SOp;
233 Op = Calct0ts1P( circuit, NP, SOp, NewWidth );
234 if ( Op == _E_ )
235 
236 Op = SOp;
237 
238 switch ( Op )
239 
240 case _A_:
241 C_p += Cov * (Vd_p[i] - VDD) * ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * tauo_p[i] - ts_p[i]*
242 (ts_p[i] - 2 * tauo_p[i])) * (VDD * (t0_p[i] - taui_p[i] - tauo_p[i]) +
243 Vd_p[i] * taui_p[i]) /
244 (2 * taui_p[i] * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
245 C_p += -Cg * ((VDD * VDD) * ((t0_p[i] * t0_p[i]) * ((ts_p[i] * ts_p[i]) - (taui_p[i] * taui_p[i])) +
246 t0_p[i] * ((taui_p[i] * taui_p[i]) - (ts_p[i] * ts_p[i])) * (taui_p[i] + 2 * tauo_p[i]) +
247 (ts_p[i] * ts_p[i]) * tauo_p[i] * (taui_p[i] + tauo_p[i]) - (taui_p[i] * taui_p[i]) * ((taui_p[i] * taui_p[i]) -
248 taui_p[i] * tauo_p[i] + 2 * (tauo_p[i] * tauo_p[i]))) +
249 VDD * Vd_p[i] * taui_p[i] * (t0_p[i] * ((ts_p[i] * ts_p[i]) - (taui_p[i] * taui_p[i])) - (ts_p[i] * ts_p[i]) * tauo_p[i] +
250 taui_p[i] * (2 * (taui_p[i] * taui_p[i]) - 3 * taui_p[i] * tauo_p[i] + 2 * (tauo_p[i] * tauo_p[i]))) -
251 (Vd_p[i] * Vd_p[i]) * (taui_p[i] * taui_p[i]) * ((taui_p[i] * taui_p[i]) - 2 * taui_p[i] * tauo_p[i] + (tauo_p[i] * tauo_p[i]))) /
252 (2 * (taui_p[i] * taui_p[i]) * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
253 break;
254 case _AA_:
255 C_p += Cg * (VDD - Vd_p[i]) * (VDD - Vd_p[i]) * (ts_p[i] - tauo_p[i]) * (ts_p[i] - tauo_p[i]) /
256 (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
257 C_p += Cov * (Vd_p[i] - VDD) * (VDD * ((t0_p[i] * t0_p[i] * t0_p[i]) - (t0_p[i] * t0_p[i]) * (taui_p[i] +
258 3 * tauo_p[i]) - t0_p[i] * ((taui_p[i] * taui_p[i]) - 4 * taui_p[i] * tauo_p[i] - 2 * (tauo_p[i] * tauo_p[i])) +
259 taui_p[i] * ((ts_p[i] * ts_p[i]) - 2 * ts_p[i] * tauo_p[i] + tauo_p[i] * (taui_p[i] - 2 * tauo_p[i]))) +
260 Vd_p[i] * taui_p[i] * ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * tauo_p[i] - ts_p[i] * (ts_p[i] - 2 * tauo_p[i]))) /
261 (2 * taui_p[i] * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
262 break;
263 case _B_:
264 C_p += Cg * (VDD - Vd_p[i]) * (VDD * ((t0_p[i] * t0_p[i]) - t0_p[i] * (taui_p[i] + 2 * tauo_p[i]) -
265 (taui_p[i] * taui_p[i]) + 3 * taui_p[i] * tauo_p[i]) + Vd_p[i] * taui_p[i] * (t0_p[i] - tauo_p[i])) /
266 (2 * taui_p[i] * (tauo_p[i] - t0_p[i]));
267 break;
268 case _C_:
269 C_p += Cg * (VDD - Vd_p[i]) * (VDD - Vd_p[i]) * (ts_p[i] - tauo_p[i]) * (ts_p[i] - tauo_p[i]) / (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
270 C_p += Cov * (VDD - Vd_p[i]) * (VDD - Vd_p[i]) * ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * tauo_p[i] - ts_p[i] * (ts_p[i] - 2 * tauo_p[i])) /
271 (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
272 break;
273 case _D_:
274 C_p += Cg * (VDD - Vd_p[i]) * (VDD - Vd_p[i]) * (taui_p[i] - tauo_p[i]) * (taui_p[i] - tauo_p[i]) /
275 (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
276 break;
277 case _F_:
278 C_p += Cg * (Vd_p[i] - VDD) * (ts_p[i] - tauo_p[i]) * (ts_p[i] - tauo_p[i]) * (VDD * (t0_p[i] - taui_p[i] - tauo_p[i]) +
279 Vd_p[i] * taui_p[i]) / (2 * taui_p[i] * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
280 C_p += Cov * (Vd_p[i] - VDD) * ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * tauo_p[i] - ts_p[i]*
281 (ts_p[i] - 2 * tauo_p[i])) * (VDD * (t0_p[i] - taui_p[i] - tauo_p[i]) + Vd_p[i] * taui_p[i]) /
282 (2 * taui_p[i] * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
283 break;
284 case _G_:
285 C_p += Cg * (Vd_p[i] - VDD) * (VDD * (t0_p[i] - taui_p[i] - tauo_p[i]) + Vd_p[i] * taui_p[i]) / (2 * taui_p[i]);
286 break;
287 case _E_:
288 default:
289 C_p += 0.0;
290 break;
291 
292 Op = Calct0tsnP( p, SOp);
293 if ( Op == _E_ )
294 
295 Op = SOp;
296 
297 Cov = ( TECH.Cgs0_p * ( W_p[ p ] + TECH.XW_p ) + 0.5 * TECH.Cox_p * W_p[ p ] * TECH.Lmin );
298 Cg = ( TECH.Cgs0_p * ( W_p[ p ] + TECH.XW_p ) + 0.66666 * TECH.Cox_p * W_p[ p ] * TECH.Lmin );
299 switch ( Op )
300 
301 case _A_:
302 C_p += Cg * (VDD - Vs_p[p]) * (VDD - Vs_p[p]) * (ts_p[p] - taui_p[p]) * (ts_p[p] - taui_p[p]) /
303 (2 * (t0_p[i] - taui_p[p]) * (t0_p[i] - taui_p[p]));
304 C_p += Cov * (VDD - Vs_p[p]) * (VDD - Vs_p[p])*
305 ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * taui_p[p] - ts_p[p] * (ts_p[p] - 2 * taui_p[p])) /
306 (2 * (t0_p[i] - taui_p[p]) * (t0_p[i] - taui_p[p]));
307 break;
308 case _B_:
309 C_p += Cov * (VDD - Vs_p[p]) * (VDD - Vs_p[p]) / 2;
310 break;
311 case _C_:
312 C_p += Cov * (VDD - Vs_p[p]) * (VDD - Vs_p[p])*
313 ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * taui_p[p] - ts_p[p] * (ts_p[p] - 2 * taui_p[p])) /
314 (2 * (t0_p[i] - taui_p[p]) * (t0_p[i] - taui_p[p]));
315 C_p += -Cg * (VDD - Vs_p[p]) * (VDD - Vs_p[p])*
316 ((tc * tc) - 2 * tc * taui_p[p] - ts_p[p] * (ts_p[p] - 2 * taui_p[p])) /
317 (2 * (t0_p[i] - taui_p[p]) * (t0_p[i] - taui_p[p]));
318 break;
319 case _D_:
320 C_p += Cov * (VDD - Vs_p[p]) * (VDD - Vs_p[p])*
321 ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * taui_p[p] - tc * (tc - 2 * taui_p[p])) /
322 (2 * (t0_p[i] - taui_p[p]) * (t0_p[i] - taui_p[p]));
323 break;
324 case _E_:
325 default:
326 break;
327 
328 
329 else if ((i == p - 1) && (p > 2))
330 
331 C_p += ( TECH.Cgd0_p * ( W_p[ i ] + TECH.XW_p ) + 0.5 * TECH.Cox_p * W_p[ i ] * TECH.Lmin ) *
332 ( VDD + Vd_p[ i ] ) * ( Vd_p[ i ] - VDD ) * 0.5;
333 int Op, SOp;
334 Op = Calct0tsnP( p, SOp);
335 if ( Op == _E_ )
336 
337 Op = SOp;
338 
339 double Cov = ( TECH.Cgs0_p * ( W_p[ p ] + TECH.XW_p ) + 0.5 * TECH.Cox_p * W_p[ p ] * TECH.Lmin );
340 double Cg = ( TECH.Cgs0_p * ( W_p[ p ] + TECH.XW_p ) + 0.66666 * TECH.Cox_p * W_p[ p ] * TECH.Lmin );
341 switch ( Op )
342 
343 case _A_:
344 C_p += Cg * (VDD - Vs_p[p]) * (VDD - Vs_p[p]) * (ts_p[p] - taui_p[p]) * (ts_p[p] - taui_p[p]) /
345 (2 * (t0_p[i] - taui_p[p]) * (t0_p[i] - taui_p[p]));
346 C_p += Cov * (VDD - Vs_p[p]) * (VDD - Vs_p[p])*
347 ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * taui_p[p] - ts_p[p] * (ts_p[p] - 2 * taui_p[p])) /
348 (2 * (t0_p[i] - taui_p[p]) * (t0_p[i] - taui_p[p]));
349 break;
350 case _B_:
351 C_p += Cov * (VDD - Vs_p[p]) * (VDD - Vs_p[p]) / 2;
352 break;
353 case _C_:
354 C_p += Cov * (VDD - Vs_p[p]) * (VDD - Vs_p[p])*
355 ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * taui_p[p] - ts_p[p] * (ts_p[p] - 2 * taui_p[p])) /
356 (2 * (t0_p[i] - taui_p[p]) * (t0_p[i] - taui_p[p]));
357 C_p += -Cg * (VDD - Vs_p[p]) * (VDD - Vs_p[p])*
358 ((tc * tc) - 2 * tc * taui_p[p] - ts_p[p] * (ts_p[p] - 2 * taui_p[p])) /
359 (2 * (t0_p[i] - taui_p[p]) * (t0_p[i] - taui_p[p]));
360 break;
361 case _D_:
362 C_p += Cov * (VDD - Vs_p[p]) * (VDD - Vs_p[p])*
363 ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * taui_p[p] - tc * (tc - 2 * taui_p[p])) /
364 (2 * (t0_p[i] - taui_p[p]) * (t0_p[i] - taui_p[p]));
365 break;
366 case _E_:
367 default:
368 break;
369 
370 
371 else if ( i == p )
372 
373 double Cov = TECH.Cgd0_p * ( W_p[ p ] + TECH.XW_p );
374 double Cg = Cov + 0.5 * TECH.Cox_p * W_p[ p ] * L_p[ p ];
375 int Op, SOp;
376 Op = Calct0tsnP( p, SOp );
377 if ( Op == _E_ )
378 
379 Op = SOp;
380 
381 switch ( Op )
382 
383 case _A_:
384 case _B_:
385 C_p += Cg * (VDD - Vd_p[i]) * (VDD - Vd_p[i]) * (ts_p[i] - tauo_p[i]) * (ts_p[i] - tauo_p[i]) /
386 (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
387 C_p += Cov * (VDD - Vd_p[i]) * (VDD - Vd_p[i])*
388 ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * tauo_p[i] - ts_p[i] * (ts_p[i] - 2 * tauo_p[i])) /
389 (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
390 break;
391 case _C_:
392 C_p += Cov * (VDD - Vd_p[i]) * (VDD - Vd_p[i]) * ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * tauo_p[i] - ts_p[i]*
393 (ts_p[i] - 2 * tauo_p[i])) / (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
394 C_p += -Cg * (VDD - Vd_p[i]) * (VDD - Vd_p[i])*
395 ((tc * tc) - 2 * tc * tauo_p[i] - ts_p[i] * (ts_p[i] - 2 * tauo_p[i])) /
396 (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
397 break;
398 case _D_:
399 C_p += Cov * (VDD - Vd_p[i]) * (VDD - Vd_p[i])*
400 ((t0_p[i] * t0_p[i]) - 2 * t0_p[i] * tauo_p[i] - tc * (tc - 2 * tauo_p[i])) /
401 (2 * (t0_p[i] - tauo_p[i]) * (t0_p[i] - tauo_p[i]));
402 break;
403 case _E_:
404 default:
405 break;
406 
407 
408 
409 if ( C_p < 0.0 )
410 C_p *= -1;
411 Ecc += C_p;
412 
413 return OK;
414 

Calcstart.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "fast.h"
7 
8 #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
9 
10  ///
11 double Fast::CalcStartTime( const Circuit& circuit, unsigned int NP, unsigned int NC, double start, double end, TransistorType type, const double* NewWidth, int& RetCode )
12 
13 int iter;
14 double a = start, b = end, c = end, d, e, min1, min2;
15 double fa, fb, fc, pp, q, r, s, tol1, xm, last;
16 double tol = TOL;
17 
18 if ( type == NMOS )
19 fb = t0N( circuit, NP, NC, b, NewWidth, RetCode );
20 else if ( type == PMOS )
21 fb = t0P( circuit, NP, NC, b, NewWidth, RetCode );
22 last = fb;
23 if ( type == NMOS )
24 fa = t0N( circuit, NP, NC, a, NewWidth, RetCode );
25 else if ( type == PMOS )
26 fa = t0P( circuit, NP, NC, a, NewWidth, RetCode );
27 if ( ( fa > 0.0 && fb > 0.0 ) || ( fa < 0.0 && fb < 0.0 ) )
28 
29 RetCode = NOT_FOUND;
30 return 0.0;
31 
32 fc = fb;
33 for ( iter = 1; iter <= ITERMAX; iter++ )
34 
35 if ( ( fb > 0.0 && fc > 0.0 ) || ( fb < 0.0 && fc < 0.0 ) )
36 
37 c = a;
38 fc = fa;
39 e = d = b - a;
40 
41 if ( fabs ( fc ) < fabs ( fb ) )
42 
43 a = b;
44 b = c;
45 c = a;
46 fa = fb;
47 fb = fc;
48 fc = fa;
49 
50 tol1 = 2.0 * EPS * fabs ( b ) + 0.5 * tol;
51 xm = 0.5 * ( c - b );
52 if ( fabs ( xm ) <= tol1 || fb == 0.0 )
53 return b;
54 if ( fabs ( e ) >= tol1 && fabs ( fa ) > fabs ( fb ) )
55 
56 s = fb / fa;
57 if ( a == c )
58 
59 pp = 2.0 * xm * s;
60 q = 1.0 - s;
61 
62 else
63 
64 q = fa / fc;
65 r = fb / fc;
66 pp = s * ( 2.0 * xm * q * ( q - r ) - ( b - a ) * ( r - 1.0 ) );
67 q = ( q - 1.0 ) * ( r - 1.0 ) * ( s - 1.0 );
68 
69 if ( pp > 0.0 )
70 q = -q;
71 pp = fabs ( pp );
72 min1 = 3.0 * xm * q - fabs ( tol1 * q );
73 min2 = fabs ( e * q );
74 if ( 2.0 * pp < ( min1 < min2 ? min1 : min2 ) )
75 
76 e = d;
77 d = pp / q;
78 
79 else
80 
81 d = xm;
82 e = d;
83 
84 
85 else
86 
87 d = xm;
88 e = d;
89 
90 a = b;
91 fa = fb;
92 if ( fabs ( d ) > tol1 )
93 b += d;
94 else
95 b += SIGN ( tol1, xm );
96 if ( type == NMOS )
97 fb = t0N( circuit, NP, NC, b, NewWidth, RetCode );
98 else if ( type == PMOS )
99 fb = t0P( circuit, NP, NC, b, NewWidth, RetCode );
100 
101 RetCode = NOT_FOUND;
102 return 0.0;
103 

Calctst0N.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "fast.h"

* t0: A=AA=F B=G C D * ts: A=F B=D=G AA=C * Calctst0N.cc
14 int Fast::Calct0ts1N( const Circuit& circuit, unsigned int NP, int& SaveOpCondition, const double* NewWidth )
15 
16 int OpCondition = _A_, LastOpCondition = 0;
17 double t0_bs, Vc, A_2_n, B_2_n, C_2_n, D_2_n, J_2_n, K_2_n, I_2_n, M_2_n;
18 double a, b, c, Cm1, Cm2, Cov, Cj, X, Y, alpha, beta, gamma, theta;
19 
20 t0_bs = TECH.Vtn0 * taui_n[ 1 ] / VDD;
21 if ( taui_n[ 1 ] <= tauo_n[ 1 ] )
22 
23 ts_n[ 1 ] = ( taui_n[ 1 ] - t0_n[ 1 ] ) * 0.5 + t0_n[ 1 ];  /* A */
23 
24 
25 else
26 
27 ts_n[ 1 ] = ( tauo_n[ 1 ] - t0_n[ 1 ] ) * 0.5 + t0_n[ 1 ];  /* F */
27 
28 
29 
30 Vc = TECH.Ec_n * L_n[ 1 ];
31 Cov = TECH.Cgd0_n * ( W_n[ 1 ] + TECH.XW_n );
32 Cm1 = Cov;
33 Cm2 = Cm1 + 0.5 * TECH.Cox_n * W_n[ 1 ] * L_n[ 1 ];
34 unsigned int pp = pathlist[ NP ].GetNumTranP();
35 const char* name = pathlist[ NP ].TransistorName( 0 );
36 int node;
37 double Wjn, Wgn, Wjp, Wgp;
38 int njn, ngn, njp, ngp, nc;
39 if ( circuit[ name ].Source() == 0 )
40 
41 node = circuit[ name ].Drain();
42 Wjn = circuit.JunctionNWidth( node, njn, NewWidth );
43 Wgn = circuit.GateNWidth( node, ngn, NewWidth );
44 Wjp = circuit.JunctionPWidth( node, njp, NewWidth );
45 Wgp = circuit.GatePWidth( node, ngp, NewWidth );
46 
47 else if ( circuit[ name ].Drain() == 0 )
48 
49 node = circuit[ name ].Source();
50 Wjn = circuit.JunctionNWidth( node, njn, NewWidth );
51 Wgn = circuit.GateNWidth( node, ngn, NewWidth );
52 Wjp = circuit.JunctionPWidth( node, njp, NewWidth );
53 Wgp = circuit.GatePWidth( node, ngp, NewWidth );
54 
55  // Nmos
56 Cj = TECH.C_nj * Wjn * TECH.Df * pow ( 1 + Vd_n[ 1 ] / TECH.PB_n, -TECH.mj_n ) +
57 TECH.C_np * 2 * ( Wjn + njn * TECH.Df ) * pow ( 1 + Vd_n[ 1 ] / TECH.PB_n, -TECH.mjsw_n );
58 Cj += TECH.Cgs0_n * ( Wjn + njn * TECH.XW_n );
59  // Pmos
60 if (pp > 0)
61 
62 Cj += TECH.C_pj * Wjp * TECH.Df * pow ( 1 + ( VDD - Vd_n[ 1 ] ) / TECH.PB_p, -TECH.mj_p ) +
63 TECH.C_pp * 2 * ( Wjp + njp * TECH.Df ) * pow ( 1 + ( VDD - Vd_n[ 1 ] ) / TECH.PB_p, -TECH.mjsw_p );
64 Cj += TECH.Cgd0_p * ( Wjp + njp * TECH.XW_p );
65 
66  // static
67 Cj += circuit.CapStaticGnd( node, nc );
68 Cj += circuit.CapStaticVdd( node, nc );
69 Cj += Wgn * TECH.Lmin * TECH.Cox_n;
70 Cj += Wgp * TECH.Lmin * TECH.Cox_p;
71 A_2_n = Vc * beta_n[ 1 ] * ( Vc - TECH.Vtn0 );
72 B_2_n = VDD * Vc * beta_n[ 1 ] / taui_n[ 1 ];
73 C_2_n = 2 * VDD / ( Vc * taui_n[ 1 ] );
74 D_2_n = ( Vc - 2 * TECH.Vtn0 ) / Vc;
75 J_2_n = Vc * Vd_n[ 1 ] * beta_n[ 1 ] * ( Vd_n[ 1 ] + 2 * TECH.Vtn0 ) / ( 2 * ( Vc + Vd_n[ 1 ] ) );
76 K_2_n = VDD * Vc * Vd_n[ 1 ] * beta_n[ 1 ] / ( taui_n[ 1 ] * ( Vc + Vd_n[ 1 ] ) );
77 I_2_n = ( Vc * Vc ) * beta_n[ 1 ] * ( sqrt ( ( 2 * VDD + Vc - 2 * TECH.Vtn0 ) / Vc ) - 1 ) *
78 ( sqrt ( ( 2 * VDD + Vc - 2 * TECH.Vtn0 ) / Vc ) - 1 ) / 2;
79 M_2_n = K_2_n * taui_n[ 1 ] - J_2_n;
80 X = Cj + Cm2;
81 Y = Cj + Cov;
82 while ( OpCondition != LastOpCondition )
83 
84 if ( LastOpCondition != 0 )
85 LastOpCondition = OpCondition;
86 else
87 LastOpCondition = _E_;
88 if ( ( t0_n[ 1 ] <= ts_n[ 1 ] ) &&
89 ( ts_n[ 1 ] <= taui_n[ 1 ] ) &&
90 ( taui_n[ 1 ] <= tauo_n[ 1 ] ) )
91 
92 OpCondition = SaveOpCondition = _A_;
93 if ( OpCondition != LastOpCondition )
94 
95 #ifdef SAT
96 b = ( 2 * ( Vd_n[ 1 ] * taui_n[ 1 ] *
97 ( Vc * ( t0_n[ 1 ] - tauo_n[ 1 ] ) - Vd_n[ 1 ] * tauo_n[ 1 ] ) -
98 VDD * Vc * ( t0_n[ 1 ] - tauo_n[ 1 ] ) * ( t0_n[ 1 ] - tauo_n[ 1 ] ) ) ) /
99 ( Vd_n[ 1 ] * Vd_n[ 1 ] * taui_n[ 1 ] );
100 c = ( 2 * Vc * ( t0_n[ 1 ] - tauo_n[ 1 ] ) * ( Vd_n[ 1 ] * tauo_n[ 1 ] +
101 TECH.Vtn0 * ( tauo_n[ 1 ] - t0_n[ 1 ] ) ) - Vd_n[ 1 ] * Vd_n[ 1 ] * tauo_n[ 1 ] * tauo_n[ 1 ] ) /
102 ( Vd_n[ 1 ] * Vd_n[ 1 ] );
103 if ( ( b * b + 4 * c ) >= 0 )
104 
105 ts_n[ 1 ] = -( sqrt ( b * b + 4 * c ) + b ) * 0.5;
106 if ( ts_n[ 1 ] < 0 )
107 ts_n[ 1 ] = ( sqrt ( b * b + 4 * c ) - b ) * 0.5;
108 
109 else
110 ts_n[ 1 ] = taui_n[ 1 ] * ( Vd_n[ 1 ] * tauo_n[ 1 ] + TECH.Vtn0 * ( tauo_n[ 1 ] - t0_n[ 1 ] ) ) /
111 ( Vd_n[ 1 ] * taui_n[ 1 ] - VDD * ( t0_n[ 1 ] - tauo_n[ 1 ] ) );
112 #else
113 ts_n[ 1 ] = taui_n[ 1 ] * ( Vd_n[ 1 ] * tauo_n[ 1 ] + TECH.Vtn0 * ( tauo_n[ 1 ] - t0_n[ 1 ] ) ) /
114 ( Vd_n[ 1 ] * taui_n[ 1 ] - VDD * ( t0_n[ 1 ] - tauo_n[ 1 ] ) );
115 
116 #endif
117 
118 
119 else if ( ( t0_n[ 1 ] <= taui_n[ 1 ] ) &&
120 ( taui_n[ 1 ] <= ts_n[ 1 ] ) &&
121 ( ts_n[ 1 ] <= tauo_n[ 1 ] ) )
122 
123 OpCondition = SaveOpCondition = _AA_;
124 if ( OpCondition != LastOpCondition )
125 
126 #ifdef SAT
127 ts_n[ 1 ] = ( sqrt ( Vc ) * ( t0_n[ 1 ] - tauo_n[ 1 ] ) *
128 sqrt ( 2 * VDD + Vc - 2 * TECH.Vtn0 ) + Vc * ( tauo_n[ 1 ] - t0_n[ 1 ] ) ) /
129 Vd_n[ 1 ] + tauo_n[ 1 ];
130 #else
131 ts_n[ 1 ] = ( VDD * ( t0_n[ 1 ] - tauo_n[ 1 ] ) + Vd_n[ 1 ] * tauo_n[ 1 ] +
132 TECH.Vtn0 * ( tauo_n[ 1 ] - t0_n[ 1 ] ) ) / Vd_n[ 1 ];
133 #endif
134 
135 
136 else if ( ( ts_n[ 1 ] <= t0_n[ 1 ] ) &&
137 ( t0_n[ 1 ] <= taui_n[ 1 ] ) &&
138 ( taui_n[ 1 ] <= tauo_n[ 1 ] ) )
139 
140 OpCondition = SaveOpCondition = _B_;
141 if ( OpCondition != LastOpCondition )
142 
143 #ifdef SAT
144 ts_n[ 1 ] = taui_n[ 1 ] *
145 ( 2 * Vc * ( Vd_n[ 1 ] + TECH.Vtn0 ) + ( Vd_n[ 1 ] * Vd_n[ 1 ] ) ) /
146 ( 2 * VDD * Vc );
147 #else
148 ts_n[ 1 ] = taui_n[ 1 ] * ( Vd_n[ 1 ] + TECH.Vtn0 ) / VDD;
149 #endif
150 a = 2 * ( Cm2 * VDD + J_2_n * taui_n[ 1 ] ) / ( K_2_n * taui_n[ 1 ]);
151 b = ( 6 * A_2_n * C_2_n * taui_n[1] * ( t0_bs - ts_n[ 1 ] ) +
152 3 * B_2_n * C_2_n * taui_n[1] * ( t0_bs * t0_bs - ts_n[ 1 ] * ts_n[ 1 ] ) -
153 4 * Vc * Vc * beta_n[ 1 ] * taui_n[1] * pow( C_2_n * t0_bs + D_2_n, 1.5 ) +
154 4 * Vc * Vc * beta_n[ 1 ] * pow( C_2_n * ts_n[ 1 ] + D_2_n, 1.5 ) -
155 3 * C_2_n * ts_n[ 1 ] * ( 2 * Cm2 * VDD - 2 * Cov * VDD +
156 taui_n[1] * (2 * J_2_n - K_2_n * ts_n[1] ) ) ) /
157 ( 3 * C_2_n * K_2_n * taui_n[ 1 ]);
158 if ( ( 4 * b + ( a * a ) ) >= 0 )
159 
160 t0_n[ 1 ] = ( a - sqrt ( 4 * b + ( a * a ) ) ) / 2;
161 if ( t0_n[ 1 ] < 0 )
162 t0_n[ 1 ] = ( sqrt ( 4 * b + ( a * a ) ) + a ) / 2;
163 
164 else
165 t0_n[ 1 ] = t0_bs;
166 
167 
168 else if ( ( taui_n[ 1 ] <= t0_n[ 1 ] ) &&
169 ( t0_n[ 1 ] <= ts_n[ 1 ] ) &&
170 ( ts_n[ 1 ] <= tauo_n[ 1 ] ) )
171 
172 OpCondition = SaveOpCondition = _C_;
173 if ( OpCondition != LastOpCondition )
174 
175 alpha = C_2_n * t0_bs + D_2_n;
176 beta = C_2_n * ts_n[ 1 ] + D_2_n;
177 theta = pow( alpha, 1.5 ) - pow( beta, 1.5 );
178 t0_n[ 1 ] = ( 6 * A_2_n * C_2_n * ( t0_bs - taui_n[ 1 ] ) +
179 3 * B_2_n * C_2_n * ( t0_bs * t0_bs - taui_n[ 1 ] * taui_n[ 1 ] ) -
180 2 * ( 2 * Vc * Vc * beta_n[ 1 ] * theta -
181 3 * C_2_n * (Cov * VDD + I_2_n * taui_n[1]))) /
182 ( 6 * C_2_n * I_2_n );
183 
184 #ifdef SAT
185 ts_n[ 1 ] = ( sqrt ( Vc ) * ( t0_n[ 1 ] - tauo_n[ 1 ] ) *
186 sqrt ( 2 * VDD + Vc - 2 * TECH.Vtn0 ) + Vc * ( tauo_n[ 1 ] - t0_n[ 1 ] ) ) /
187 Vd_n[ 1 ] + tauo_n[ 1 ];
188 #else
189 ts_n[ 1 ] = ( VDD * ( t0_n[ 1 ] - tauo_n[ 1 ] ) + Vd_n[ 1 ] * tauo_n[ 1 ] +
190 TECH.Vtn0 * ( tauo_n[ 1 ] - t0_n[ 1 ] ) ) / Vd_n[ 1 ];
191 #endif
192 
193 
194 else if ( ( ts_n[ 1 ] <= taui_n[ 1 ] ) &&
195 ( taui_n[ 1 ] <= t0_n[ 1 ] ) &&
196 ( t0_n[ 1 ] <= tauo_n[ 1 ] ) )
197 
198 OpCondition = SaveOpCondition = _D_;
199 if ( OpCondition != LastOpCondition )
200 
201 #ifdef SAT
202 ts_n[ 1 ] = taui_n[ 1 ] *
203 ( 2 * Vc * ( Vd_n[ 1 ] + TECH.Vtn0 ) + ( Vd_n[ 1 ] * Vd_n[ 1 ] ) ) /
204 ( 2 * VDD * Vc );
205 #else
206 ts_n[ 1 ] = taui_n[ 1 ] * ( Vd_n[ 1 ] + TECH.Vtn0 ) / VDD;
207 #endif
208 alpha = C_2_n * t0_bs + D_2_n;
209 beta = C_2_n * taui_n[ 1 ] + D_2_n;
210 gamma = C_2_n * ts_n[ 1 ] + D_2_n;
211 theta = -pow( alpha, 1.5 ) + pow( gamma, 1.5 );
212 t0_n[ 1 ] = ( 6 * A_2_n * C_2_n * taui_n[1] * ( t0_bs - ts_n[ 1 ] ) +
213 3 * B_2_n * C_2_n * taui_n[1] * ( ( t0_bs * t0_bs ) - ( ts_n[ 1 ] * ts_n[ 1 ] ) ) +
214 4 * Vc * Vc * beta_n[ 1 ] * taui_n[1] * theta -
215 3 * C_2_n * ( 2 * Cm2 * VDD * (ts_n[1] - taui_n[1]) -
216 2 * Cov * VDD * ts_n[1] + taui_n[1] *
217 (2 * J_2_n * (ts_n[1]-taui_n[1]) + K_2_n *
218 (taui_n[1] * taui_n[1] - ts_n[1] * ts_n[1]) -
219 2 * M_2_n * taui_n[1]))) /
220 ( 6 * C_2_n * M_2_n * taui_n[ 1 ] );
221 
222 
223 else if ( ( t0_n[ 1 ] <= ts_n[ 1 ] ) &&
224 ( ts_n[ 1 ] <= tauo_n[ 1 ] ) &&
225 ( tauo_n[ 1 ] <= taui_n[ 1 ] ) )
226 
227 OpCondition = SaveOpCondition = _F_;
228 if ( OpCondition != LastOpCondition )
229 
230 #ifdef SAT
231 b = ( 2 * ( Vd_n[ 1 ] * taui_n[ 1 ] *
232 ( Vc * ( t0_n[ 1 ] - tauo_n[ 1 ] ) - Vd_n[ 1 ] * tauo_n[ 1 ] ) -
233 VDD * Vc * ( t0_n[ 1 ] - tauo_n[ 1 ] ) * ( t0_n[ 1 ] - tauo_n[ 1 ] ) ) ) /
234 ( Vd_n[ 1 ] * Vd_n[ 1 ] * taui_n[ 1 ] );
235 c = ( 2 * Vc * ( t0_n[ 1 ] - tauo_n[ 1 ] ) * ( Vd_n[ 1 ] * tauo_n[ 1 ] +
236 TECH.Vtn0 * ( tauo_n[ 1 ] - t0_n[ 1 ] ) ) - Vd_n[ 1 ] * Vd_n[ 1 ] * tauo_n[ 1 ] * tauo_n[ 1 ] ) /
237 ( Vd_n[ 1 ] * Vd_n[ 1 ] );
238 if ( ( b * b + 4 * c ) >= 0 )
239 
240 ts_n[ 1 ] = -( sqrt ( b * b + 4 * c ) + b ) * 0.5;
241 if ( ts_n[ 1 ] < 0 )
242 ts_n[ 1 ] = ( sqrt ( b * b + 4 * c ) - b ) * 0.5;
243 
244 else
245 ts_n[ 1 ] = taui_n[ 1 ] * ( Vd_n[ 1 ] * tauo_n[ 1 ] + TECH.Vtn0 * ( tauo_n[ 1 ] - t0_n[ 1 ] ) ) /
246 ( Vd_n[ 1 ] * taui_n[ 1 ] - VDD * ( t0_n[ 1 ] - tauo_n[ 1 ] ) );
247 
248 #else
249 ts_n[ 1 ] = taui_n[ 1 ] * ( Vd_n[ 1 ] * tauo_n[ 1 ] + TECH.Vtn0 * ( tauo_n[ 1 ] - t0_n[ 1 ] ) ) /
250 ( Vd_n[ 1 ] * taui_n[ 1 ] - VDD * ( t0_n[ 1 ] - tauo_n[ 1 ] ) );
251 
252 #endif
253 
254 
255 else if ( ( ts_n[ 1 ] <= t0_n[ 1 ] ) &&
256 ( t0_n[ 1 ] <= tauo_n[ 1 ] ) &&
257 ( tauo_n[ 1 ] <= taui_n[ 1 ] ) )
258 
259 OpCondition = SaveOpCondition = _G_;
260 if ( OpCondition != LastOpCondition )
261 
262 #ifdef SAT
263 ts_n[ 1 ] = taui_n[ 1 ] *
264 ( 2 * Vc * ( Vd_n[ 1 ] + TECH.Vtn0 ) + ( Vd_n[ 1 ] * Vd_n[ 1 ] ) ) /
265 ( 2 * VDD * Vc );
266 #else
267 ts_n[ 1 ] = taui_n[ 1 ] * ( Vd_n[ 1 ] + TECH.Vtn0 ) / VDD;
268 #endif
269 a = 2 * ( Cm2 * VDD + J_2_n * taui_n[ 1 ] ) / ( K_2_n * taui_n[ 1 ]);
270 b = ( 6 * A_2_n * C_2_n * taui_n[1] * ( t0_bs - ts_n[ 1 ] ) +
271 3 * B_2_n * C_2_n * taui_n[1] * ( t0_bs * t0_bs - ts_n[ 1 ] * ts_n[ 1 ] ) -
272 4 * Vc * Vc * beta_n[ 1 ] * taui_n[1] * pow( C_2_n * t0_bs + D_2_n, 1.5 ) +
273 4 * Vc * Vc * beta_n[ 1 ] * pow( C_2_n * ts_n[ 1 ] + D_2_n, 1.5 ) -
274 3 * C_2_n * ts_n[ 1 ] * ( 2 * Cm2 * VDD - 2 * Cov * VDD +
275 taui_n[1] * (2 * J_2_n - K_2_n * ts_n[1] ) ) ) /
276 ( 3 * C_2_n * K_2_n * taui_n[ 1 ]);
277 if ( ( 4 * b + ( a * a ) ) >= 0 )
278 
279 t0_n[ 1 ] = ( a - sqrt ( 4 * b + ( a * a ) ) ) / 2;
280 if ( t0_n[ 1 ] < 0 )
281 t0_n[ 1 ] = ( sqrt ( 4 * b + ( a * a ) ) + a ) / 2;
282 
283 else
284 t0_n[ 1 ] = t0_bs;
285 
286 
287 else
288 
289 OpCondition = _E_;
290 
291 
292 return OpCondition;
293 
294 
295  ///
296 int Fast::Calct0tsnN( unsigned int n, int& SaveOpCondition )
297 
298 int OpCondition = _A_, LastOpCondition = 0;
299 double Vc, tc, X, Y, b, c;
300 
301 Vc = TECH.Ec_n * L_n[ n ];
302 ts_n[ n ] = ( A_1_n[ n ] * Vs_n[ n ] * taui_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
303 ( t0_n[ n ] - taui_n[ n ] ) * ( VDD * t0_n[ n ] + TECH.Vtn0 * ( tauo_n[ n ] - t0_n[ n ] ) ) ) /
304 ( A_1_n[ n ] * Vs_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
305 VDD * ( t0_n[ n ] - taui_n[ n ] ) );
306 if ( taui_n[ n ] < tauo_n[ n ] )
307 
308 SaveOpCondition = _A_;
309 
310 else
311 
312 tc = ( VDD * tauo_n[ n ] * ( t0_n[ n ] - taui_n[ n ] ) +
313 Vs_n[ n ] * taui_n[ n ] * ( tauo_n[ n ] - t0_n[ n ] ) ) /
314 ( VDD * ( t0_n[ n ] - taui_n[ n ] ) + Vs_n[ n ] * ( tauo_n[ n ] - t0_n[ n ] ) );
315 SaveOpCondition = _C_;
316 
317 while ( OpCondition != LastOpCondition )
318 
319 if ( LastOpCondition != 0 )
320 LastOpCondition = OpCondition;
321 else
322 LastOpCondition = _E_;
323 if ( ( taui_n[ n ] <= tauo_n[ n ] ) &&
324 ( ts_n[ n ] <= taui_n[ n ] ) &&
325 ( t0_n[ n ] <= ts_n[ n ] ) )
326 
327 OpCondition = SaveOpCondition = _A_;
328 if ( OpCondition != LastOpCondition )
329 
330 #ifdef SAT
331 X = t0_n[ n ] - taui_n[ n ];
332 Y = tauo_n[ n ] - t0_n[ n ];
333 b = -( 2 * ( VDD * X * X * ( Vc * Y + VDD * tauo_n[ n ] ) +
334 Vs_n[ n ] * X * Y * ( VDD * ( taui_n[ n ] + tauo_n[ n ] ) - A_1_n[ n ] * Vc * Y ) +
335 Vs_n[ n ] * Vs_n[ n ] * taui_n[ n ] * Y * Y ) ) /
336 ( ( VDD * X + Vs_n[ n ] * Y ) * ( VDD * X + Vs_n[ n ] * Y ) );
337 c = -( X * X * ( 2 * Y * Y * Vc * TECH.Vtn0 + 2 * Y * VDD * Vc * t0_n[ n ] + VDD * VDD * tauo_n[ n ] * tauo_n[ n ] ) +
338 2 * Vs_n[ n ] * taui_n[ n ] * X * Y * ( VDD * tauo_n[ n ] - A_1_n[ n ] * Vc * Y ) +
339 Vs_n[ n ] * Vs_n[ n ] * taui_n[ n ] * taui_n[ n ] * Y * Y ) /
340 ( ( VDD * X + Vs_n[ n ] * Y ) * ( VDD * X + Vs_n[ n ] * Y ) );
341 if ( ( b * b + 4 * c ) >= 0 )
342 
343 ts_n[ n ] = -( sqrt ( b * b + 4 * c ) + b ) * 0.5;
344 if ( ( ts_n[ n ] < 0 ) || ( ts_n[ n ] < t0_n[ n ] ) || ( ts_n[ n ] > tauo_n[ n ] ) )
345 ts_n[ n ] = ( sqrt ( b * b + 4 * c ) - b ) * 0.5;
346 if ( ( ts_n[ n ] < 0 ) || ( ts_n[ n ] < t0_n[ n ] ) || ( ts_n[ n ] > tauo_n[ n ] ) )
347 ts_n[ n ] = ( A_1_n[ n ] * Vs_n[ n ] * taui_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
348 ( t0_n[ n ] - taui_n[ n ] ) * ( VDD * t0_n[ n ] + TECH.Vtn0 * ( tauo_n[ n ] - t0_n[ n ] ) ) ) /
349 ( A_1_n[ n ] * Vs_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
350 VDD * ( t0_n[ n ] - taui_n[ n ] ) );
351 
352 else
353 ts_n[ n ] = ( A_1_n[ n ] * Vs_n[ n ] * taui_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
354 ( t0_n[ n ] - taui_n[ n ] ) * ( VDD * t0_n[ n ] + TECH.Vtn0 * ( tauo_n[ n ] - t0_n[ n ] ) ) ) /
355 ( A_1_n[ n ] * Vs_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
356 VDD * ( t0_n[ n ] - taui_n[ n ] ) );
357 #else
358 ts_n[ n ] = ( A_1_n[ n ] * Vs_n[ n ] * taui_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
359 ( t0_n[ n ] - taui_n[ n ] ) * ( VDD * t0_n[ n ] + TECH.Vtn0 * ( tauo_n[ n ] - t0_n[ n ] ) ) ) /
360 ( A_1_n[ n ] * Vs_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
361 VDD * ( t0_n[ n ] - taui_n[ n ] ) );
362 #endif
363 
364 
365 else if ( ( ts_n[ n ] <= tauo_n[ n ] ) &&
366 ( taui_n[ n ] <= ts_n[ n ] ) &&
367 ( t0_n[ n ] <= taui_n[ n ] ) )
368 
369 OpCondition = SaveOpCondition = _B_;
370 if ( OpCondition != LastOpCondition )
371 
372 #ifdef SAT
373 ts_n[ n ] = tauo_n[ n ] - ( tauo_n[ n ] - t0_n[ n ] ) *
374 ( sqrt ( Vc * ( 2 * VDD + Vc - 2 * TECH.Vtn0 ) ) - Vc ) / VDD;
375 #else
376 ts_n[ n ] = TECH.Vtn0 * ( tauo_n[ n ] - t0_n[ n ] ) / VDD + t0_n[ n ];
377 #endif
378 
379 
380 else if ( ( tauo_n[ n ] <= taui_n[ n ] ) &&
381 ( ts_n[ n ] < tc ) &&
382 ( t0_n[ n ] <= ts_n[ n ] ) )
383 

(ts
_n[n] < tc), not '<=' !!! Calctst0N.cc
385 OpCondition = SaveOpCondition = _C_;
386 if ( OpCondition != LastOpCondition )
387 
388 #ifdef SAT
389 X = t0_n[ n ] - taui_n[ n ];
390 Y = tauo_n[ n ] - t0_n[ n ];
391 b = -( 2 * ( VDD * X * X * ( Vc * Y + VDD * tauo_n[ n ] ) +
392 Vs_n[ n ] * X * Y * ( VDD * ( taui_n[ n ] + tauo_n[ n ] ) - A_1_n[ n ] * Vc * Y ) +
393 Vs_n[ n ] * Vs_n[ n ] * taui_n[ n ] * Y * Y ) ) /
394 ( ( VDD * X + Vs_n[ n ] * Y ) * ( VDD * X + Vs_n[ n ] * Y ) );
395 c = -( X * X * ( 2 * Y * Y * Vc * TECH.Vtn0 + 2 * Y * VDD * Vc * t0_n[ n ] + VDD * VDD * tauo_n[ n ] * tauo_n[ n ] ) +
396 2 * Vs_n[ n ] * taui_n[ n ] * X * Y * ( VDD * tauo_n[ n ] - A_1_n[ n ] * Vc * Y ) +
397 Vs_n[ n ] * Vs_n[ n ] * taui_n[ n ] * taui_n[ n ] * Y * Y ) /
398 ( ( VDD * X + Vs_n[ n ] * Y ) * ( VDD * X + Vs_n[ n ] * Y ) );
399 if ( ( b * b + 4 * c ) >= 0 )
400 
401 ts_n[ n ] = -( sqrt ( b * b + 4 * c ) + b ) * 0.5;
402 if ( ( ts_n[ n ] < 0 ) || ( ts_n[ n ] < t0_n[ n ] ) || ( ts_n[ n ] > tauo_n[ n ] ) )
403 ts_n[ n ] = ( sqrt ( b * b + 4 * c ) - b ) * 0.5;
404 if ( ( ts_n[ n ] < 0 ) || ( ts_n[ n ] < t0_n[ n ] ) || ( ts_n[ n ] > tauo_n[ n ] ) )
405 ts_n[ n ] = ( A_1_n[ n ] * Vs_n[ n ] * taui_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
406 ( t0_n[ n ] - taui_n[ n ] ) * ( VDD * t0_n[ n ] + TECH.Vtn0 * ( tauo_n[ n ] - t0_n[ n ] ) ) ) /
407 ( A_1_n[ n ] * Vs_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
408 VDD * ( t0_n[ n ] - taui_n[ n ] ) );
409 
410 else
411 
412 ts_n[ n ] = ( A_1_n[ n ] * Vs_n[ n ] * taui_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
413 ( t0_n[ n ] - taui_n[ n ] ) * ( VDD * t0_n[ n ] + TECH.Vtn0 * ( tauo_n[ n ] - t0_n[ n ] ) ) ) /
414 ( A_1_n[ n ] * Vs_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
415 VDD * ( t0_n[ n ] - taui_n[ n ] ) );
416 if ( ts_n[ n ] > tauo_n[ n ] )
417 ts_n[ n ] = tc;
418 
419 #else
420 ts_n[ n ] = ( A_1_n[ n ] * Vs_n[ n ] * taui_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
421 ( t0_n[ n ] - taui_n[ n ] ) * ( VDD * t0_n[ n ] + TECH.Vtn0 * ( tauo_n[ n ] - t0_n[ n ] ) ) ) /
422 ( A_1_n[ n ] * Vs_n[ n ] * ( t0_n[ n ] - tauo_n[ n ] ) +
423 VDD * ( t0_n[ n ] - taui_n[ n ] ) );
424 if ( ts_n[ n ] > tauo_n[ n ] )
425 ts_n[ n ] = tc;
426 #endif
427 
428 
429 else if ( ( tauo_n[ n ] <= taui_n[ n ] ) &&
430 ( tc <= ts_n[ n ] ) &&
431 ( t0_n[ n ] <= ts_n[ n ] ) )
432 
433 OpCondition = SaveOpCondition = _D_;
434 if ( OpCondition != LastOpCondition )
435 
436 ts_n[ n ] = tc;
437 
438 
439 else
440 
441 OpCondition = _E_;
442 
443 
444 return OpCondition;
445 

Calctst0P.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "fast.h"

* t0: A=AA=F B=G C D * ts: A=F B=D=G AA=C * Calctst0P.cc
15 int Fast::Calct0ts1P( const Circuit& circuit, unsigned int NP, int& SaveOpCondition, const double* NewWidth )
16 
17 int OpCondition = _A_, LastOpCondition = 0;
18 double t0_bs, Vc, A_2_p, B_2_p, C_2_p, D_2_p, G_2_p, J_2_p, K_2_p, M_2_p;
19 double b, c, Cm1, Cm2, Cov, Cj, X, XX, Y, alpha, gamma, theta;
20 
21 t0_bs = -TECH.Vtp0 * taui_p[ 1 ] / VDD;
22 if ( taui_p[ 1 ] <= tauo_p[ 1 ] )
23 
24 ts_p[ 1 ] = ( taui_p[ 1 ] - t0_p[ 1 ] ) * 0.5 + t0_p[ 1 ];  /* A */
24 
25 
26 else
27 
28 ts_p[ 1 ] = ( tauo_p[ 1 ] - t0_p[ 1 ] ) * 0.5 + t0_p[ 1 ];  /* F */
28 
29 
30 
31 Vc = TECH.Ec_p * L_p[ 1 ];
32 Cov = TECH.Cgd0_p * ( W_p[ 1 ] + TECH.XW_p );
33 Cm1 = Cov;
34 Cm2 = Cm1 + 0.5 * TECH.Cox_p * W_p[ 1 ] * L_p[ 1 ];
35 unsigned int nn = pathlist[ NP ].GetNumTranN();
36 double Wjn, Wgn, Wjp, Wgp;
37 int node;
38 int njn, ngn, njp, ngp, nc;
39 if (nn > 0)
40 
41 const char* name = pathlist[ NP ].TransistorName( nn - 1 );
42 if ( circuit[ name ].Source() == 0 )
43 
44 node = circuit[ name ].Drain();
45 Wjn = circuit.JunctionNWidth( node, njn, NewWidth );
46 Wgn = circuit.GateNWidth( node, ngn, NewWidth );
47 Wjp = circuit.JunctionPWidth( node, njp, NewWidth );
48 Wgp = circuit.GatePWidth( node, ngp, NewWidth );
49 
50 else if ( circuit[ name ].Drain() == 0 )
51 
52 node = circuit[ name ].Source();
53 Wjn = circuit.JunctionNWidth( node, njn, NewWidth );
54 Wgn = circuit.GateNWidth( node, ngn, NewWidth );
55 Wjp = circuit.JunctionPWidth( node, njp, NewWidth );
56 Wgp = circuit.GatePWidth( node, ngp, NewWidth );
57 
58  // Nmos
59 Cj = TECH.C_nj * Wjn * TECH.Df * pow ( 1 + Vd_p[ 1 ] / TECH.PB_n, -TECH.mj_n ) +
60 TECH.C_np * 2 * ( Wjn + njn * TECH.Df ) * pow ( 1 + Vd_p[ 1 ] / TECH.PB_n, -TECH.mjsw_n );
61 Cj += TECH.Cgs0_n * ( Wjn + njn * TECH.XW_n );
62 
63  // Pmos
64 Cj += TECH.C_pj * Wjp * TECH.Df * pow ( 1 + ( VDD - Vd_p[ 1 ] ) / TECH.PB_p, -TECH.mj_p ) +
65 TECH.C_pp * 2 * ( Wjp + njp * TECH.Df ) * pow ( 1 + ( VDD - Vd_p[ 1 ] ) / TECH.PB_p, -TECH.mjsw_p );
66 Cj += TECH.Cgd0_p * ( Wjp + njp * TECH.XW_p );
67  // static
68 Cj += circuit.CapStaticGnd( node, nc );
69 Cj += circuit.CapStaticVdd( node, nc );
70 Cj += Wgn * TECH.Lmin * TECH.Cox_p;
71 Cj += Wgp * TECH.Lmin * TECH.Cox_p;
72 A_2_p = Vc * beta_p[ 1 ] * ( Vc + TECH.Vtp0 );
73 B_2_p = VDD * Vc * beta_p[ 1 ] / taui_p[ 1 ];
74 C_2_p = ( Vc + 2 * TECH.Vtp0 ) / Vc;
75 D_2_p = 2 * VDD / ( Vc * taui_p[ 1 ] );
76 G_2_p = Vc * Vc * beta_p[ 1 ] * SQRT ( ( 2 * VDD + Vc + 2 * TECH.Vtp0 ) / Vc ) -
77 VDD * Vc * beta_p[ 1 ] - Vc * Vc * beta_p[ 1 ] - Vc * TECH.Vtp0 * beta_p[ 1 ];
78 K_2_p = VDD * Vc * beta_p[ 1 ] * ( Vd_p[ 1 ] - VDD ) / ( taui_p[ 1 ] * ( VDD + Vc - Vd_p[ 1 ] ) );
79 J_2_p = Vc * beta_p[ 1 ] * ( VDD - Vd_p[ 1 ] ) * ( VDD - Vd_p[ 1 ] - 2 * TECH.Vtp0 ) / ( 2 * ( VDD + Vc - Vd_p[ 1 ] ) );
80 M_2_p = Vc * beta_p[ 1 ] * ( VDD - Vd_p[ 1 ] ) * ( VDD + Vd_p[ 1 ] + 2 * TECH.Vtp0 ) / ( 2 * ( Vd_p[ 1 ] - Vc ) );
81 X = Cj + Cm2;
82 Y = Cj + Cov;
83 alpha = pow( ( D_2_p * t0_bs + C_2_p ), 1.5 );
84 gamma = pow( ( D_2_p * taui_p[ 1 ] + C_2_p ), 1.5 );
85 while ( OpCondition != LastOpCondition )
86 
87 if ( LastOpCondition != 0 )
88 LastOpCondition = OpCondition;
89 else
90 LastOpCondition = _E_;
91 if ( ( t0_p[ 1 ] <= ts_p[ 1 ] ) &&
92 ( ts_p[ 1 ] <= taui_p[ 1 ] ) &&
93 ( taui_p[ 1 ] <= tauo_p[ 1 ] ) )
94 
95 OpCondition = SaveOpCondition = _A_;
96 if ( OpCondition != LastOpCondition )
97 
98 XX = t0_p[ 1 ] - tauo_p[ 1 ];
99 #ifdef SAT
100 
101 b = ( 2 * ( VDD * VDD * taui_p[ 1 ] * tauo_p[ 1 ] + VDD * ( Vc * ( XX - taui_p[ 1 ] ) * XX -
102 2 * Vd_p[ 1 ] * taui_p[ 1 ] * tauo_p[ 1 ] ) +
103 Vd_p[ 1 ] * taui_p[ 1 ] * ( Vc * XX + Vd_p[ 1 ] * tauo_p[ 1 ] ) ) ) /
104 ( taui_p[ 1 ] * ( VDD - Vd_p[ 1 ] ) * ( VDD - Vd_p[ 1 ] ) );
105 c = ( VDD * VDD * tauo_p[ 1 ] * tauo_p[ 1 ] - 2 * VDD * tauo_p[ 1 ] * ( Vc * XX + Vd_p[ 1 ] * tauo_p[ 1 ] ) +
106 2 * Vc * XX * ( Vd_p[ 1 ] * tauo_p[ 1 ] - TECH.Vtp0 * XX ) + Vd_p[ 1 ] * tauo_p[ 1 ] * Vd_p[ 1 ] * tauo_p[ 1 ] ) /
107 ( ( VDD - Vd_p[ 1 ] ) * ( VDD - Vd_p[ 1 ] ) );
108 if ( ( b * b - 4 * c ) >= 0 )
109 
110 ts_p[ 1 ] = ( b - sqrt ( b * b - 4 * c ) ) * 0.5;
111 if ( ts_p[ 1 ] < 0 )
112 ts_p[ 1 ] = ( b + sqrt ( b * b - 4 * c ) ) * 0.5;
113 
114 else
115 ts_p[ 1 ] = -taui_p[ 1 ] * ( ( VDD - Vd_p[ 1 ] ) * tauo_p[ 1 ] +
116 TECH.Vtp0 * XX ) /
117 ( VDD * ( XX - taui_p[ 1 ] ) +
118 Vd_p[ 1 ] * taui_p[ 1 ] );
119 #else
120 ts_p[ 1 ] = -taui_p[ 1 ] * ( ( VDD - Vd_p[ 1 ] ) * tauo_p[ 1 ] +
121 TECH.Vtp0 * XX ) /
122 ( VDD * ( XX - taui_p[ 1 ] ) +
123 Vd_p[ 1 ] * taui_p[ 1 ] );
124 #endif
125 
126 
127 else if ( ( t0_p[ 1 ] <= taui_p[ 1 ] ) &&
128 ( taui_p[ 1 ] <= ts_p[ 1 ] ) &&
129 ( ts_p[ 1 ] <= tauo_p[ 1 ] ) )
130 
131 OpCondition = SaveOpCondition = _AA_;
132 if ( OpCondition != LastOpCondition )
133 
134 #ifdef SAT
135 ts_p[ 1 ] = tauo_p[ 1 ] - ( ( tauo_p[ 1 ] - t0_p[ 1 ] ) *
136 ( sqrt ( Vc * ( 2 * VDD + Vc + 2 * TECH.Vtp0 ) ) - Vc ) ) /
137 ( VDD - Vd_p[ 1 ] );
138 #else
139 ts_p[ 1 ] = ( VDD * t0_p[ 1 ] - Vd_p[ 1 ] * tauo_p[ 1 ] + TECH.Vtp0 * ( t0_p[ 1 ] - tauo_p[ 1 ] ) ) /
140 ( VDD - Vd_p[ 1 ] );
141 #endif
142 
143 
144 else if ( ( ts_p[ 1 ] <= t0_p[ 1 ] ) &&
145 ( t0_p[ 1 ] <= taui_p[ 1 ] ) &&
146 ( taui_p[ 1 ] <= tauo_p[ 1 ] ) )
147 
148 OpCondition = SaveOpCondition = _B_;
149 if ( OpCondition != LastOpCondition )
150 
151 #ifdef SAT
152 ts_p[ 1 ] = taui_p[ 1 ] * ( VDD * VDD + 2 * VDD * ( Vc - Vd_p[ 1 ] ) - 2 * Vc * ( Vd_p[ 1 ] + TECH.Vtp0 ) +
153 Vd_p[ 1 ] * Vd_p[ 1 ] ) / ( 2 * VDD * Vc );
154 #else
155 ts_p[ 1 ] = taui_p[ 1 ] * ( VDD - Vd_p[ 1 ] - TECH.Vtp0 ) / VDD;
156 #endif
157 theta = pow( ( D_2_p * ts_p[ 1 ] + C_2_p ), 1.5 );
158 b = 2 * ( Cm2 * VDD + J_2_p * taui_p[ 1 ] ) /
159 ( K_2_p * taui_p[ 1 ] );
160 c = ( 6 * A_2_p * D_2_p * taui_p[ 1 ] * ( t0_bs - ts_p[ 1 ] ) +
161 3 * B_2_p * D_2_p * taui_p[ 1 ] * ( t0_bs * t0_bs - ts_p[ 1 ] * ts_p[ 1 ] ) -
162 4 * Vc * Vc * beta_p[ 1 ] * taui_p[ 1 ] * alpha +
163 4 * Vc * Vc * beta_p[ 1 ] * taui_p[ 1 ] * theta -
164 3 * D_2_p * ts_p[ 1 ] *
165 ( 2 * Cm2 * VDD - 2 * Cov * VDD + taui_p[ 1 ] *
166 ( 2 * J_2_p + K_2_p * ts_p[ 1 ] ) ) ) /
167 ( 3 * D_2_p * K_2_p * taui_p[ 1 ] );
168 if ( ( b * b - 4 * c ) >= 0 )
169 
170 t0_p[ 1 ] = ( sqrt ( ( b * b ) - 4 * c ) - b ) * 0.5;
171 if ( t0_p[ 1 ] < 0 )
172 t0_p[ 1 ] = -( sqrt ( ( b * b ) - 4 * c ) + b ) * 0.5;
173 
174 else
175 t0_p[ 1 ] = t0_bs;
176 
177 
178 else if ( ( taui_p[ 1 ] <= t0_p[ 1 ] ) &&
179 ( t0_p[ 1 ] <= ts_p[ 1 ] ) &&
180 ( ts_p[ 1 ] <= tauo_p[ 1 ] ) )
181 
182 OpCondition = SaveOpCondition = _C_;
183 if ( OpCondition != LastOpCondition )
184 
185 
186 t0_p[ 1 ] = -( 6 * A_2_p * D_2_p * ( t0_bs - taui_p[ 1 ] ) +
187 3 * B_2_p * D_2_p * ( t0_bs * t0_bs - taui_p[ 1 ] * taui_p[ 1 ] ) -
188 2 * ( 2 * Vc * Vc * beta_p[ 1 ] * ( alpha - gamma ) -
189 3 * D_2_p * (Cov * VDD - G_2_p * taui_p[ 1 ]))) /
190 ( 6 * D_2_p * G_2_p );
191 #ifdef SAT
192 ts_p[ 1 ] = tauo_p[ 1 ] - ( ( tauo_p[ 1 ] - t0_p[ 1 ] ) *
193 ( sqrt ( Vc * ( 2 * VDD + Vc + 2 * TECH.Vtp0 ) ) - Vc ) ) /
194 ( VDD - Vd_p[ 1 ] );
195 #else
196 ts_p[ 1 ] = ( VDD * t0_p[ 1 ] - Vd_p[ 1 ] * tauo_p[ 1 ] + TECH.Vtp0 * ( t0_p[ 1 ] - tauo_p[ 1 ] ) ) /
197 ( VDD - Vd_p[ 1 ] );
198 #endif
199 
200 
201 else if ( ( ts_p[ 1 ] <= taui_p[ 1 ] ) &&
202 ( taui_p[ 1 ] <= t0_p[ 1 ] ) &&
203 ( t0_p[ 1 ] <= tauo_p[ 1 ] ) )
204 
205 OpCondition = SaveOpCondition = _D_;
206 if ( OpCondition != LastOpCondition )
207 
208 #ifdef SAT
209 ts_p[ 1 ] = taui_p[ 1 ] * ( VDD * VDD + 2 * VDD * ( Vc - Vd_p[ 1 ] ) - 2 * Vc * ( Vd_p[ 1 ] + TECH.Vtp0 ) +
210 ( Vd_p[ 1 ] * Vd_p[ 1 ] ) ) / ( 2 * VDD * Vc );
211 #else
212 ts_p[ 1 ] = taui_p[ 1 ] * ( VDD - Vd_p[ 1 ] + TECH.Vtp0 ) / VDD;
213 #endif
214 theta = pow( ( D_2_p * ts_p[ 1 ] + C_2_p ), 1.5 );
215 t0_p[ 1 ] = -( 6 * A_2_p * D_2_p * taui_p[ 1 ] * ( t0_bs - ts_p[ 1 ] ) +
216 3 * B_2_p * D_2_p * taui_p[ 1 ] * ( t0_bs * t0_bs - ts_p[ 1 ] * ts_p[1]) -
217 4 * Vc * Vc * beta_p[ 1 ] * ( alpha - theta ) -
218 3 * D_2_p * (2 * Cm2 * VDD * (ts_p[1] - taui_p[1]) -
219 2 * Cov * VDD * ts_p[1] +
220 taui_p[1] * (2 * J_2_p * (ts_p[1] - taui_p[1]) +
221 K_2_p * (ts_p[1] * ts_p[1] - taui_p[1] * taui_p[1]) +
222 2 * M_2_p * taui_p[1] ))) /
223 ( 6 * D_2_p * M_2_p * taui_p[ 1 ] );
224 
225 
226 else if ( ( t0_p[ 1 ] <= ts_p[ 1 ] ) &&
227 ( ts_p[ 1 ] <= tauo_p[ 1 ] ) &&
228 ( tauo_p[ 1 ] <= taui_p[ 1 ] ) )
229 
230 OpCondition = SaveOpCondition = _F_;
231 if ( OpCondition != LastOpCondition )
232 
233 X = t0_p[ 1 ] - tauo_p[ 1 ];
234 #ifdef SAT
235 
236 b = ( 2 * ( VDD * VDD * taui_p[ 1 ] * tauo_p[ 1 ] + VDD * ( Vc * ( X - taui_p[ 1 ] ) * X -
237 2 * Vd_p[ 1 ] * taui_p[ 1 ] * tauo_p[ 1 ] ) +
238 Vd_p[ 1 ] * taui_p[ 1 ] * ( Vc * X + Vd_p[ 1 ] * tauo_p[ 1 ] ) ) ) /
239 ( taui_p[ 1 ] * ( VDD - Vd_p[ 1 ] ) * ( VDD - Vd_p[ 1 ] ) );
240 c = ( VDD * VDD * tauo_p[ 1 ] * tauo_p[ 1 ] - 2 * VDD * tauo_p[ 1 ] * ( Vc * X + Vd_p[ 1 ] * tauo_p[ 1 ] ) +
241 2 * Vc * X * ( Vd_p[ 1 ] * tauo_p[ 1 ] - TECH.Vtp0 * X ) + Vd_p[ 1 ] * tauo_p[ 1 ] * Vd_p[ 1 ] * tauo_p[ 1 ] ) /
242 ( ( VDD - Vd_p[ 1 ] ) * ( VDD - Vd_p[ 1 ] ) );
243 if ( ( b * b - 4 * c ) >= 0 )
244 
245 ts_p[ 1 ] = ( b - sqrt ( b * b - 4 * c ) ) * 0.5;
246 if ( ts_p[ 1 ] < 0 )
247 ts_p[ 1 ] = ( b + sqrt ( b * b - 4 * c ) ) * 0.5;
248 
249 else
250 ts_p[ 1 ] = -taui_p[ 1 ] * ( ( VDD - Vd_p[ 1 ] ) * tauo_p[ 1 ] +
251 TECH.Vtp0 * X ) /
252 ( VDD * ( X - taui_p[ 1 ] ) +
253 Vd_p[ 1 ] * taui_p[ 1 ] );
254 #else
255 ts_p[ 1 ] = -taui_p[ 1 ] * ( ( VDD - Vd_p[ 1 ] ) * tauo_p[ 1 ] +
256 TECH.Vtp0 * X ) /
257 ( VDD * ( X - taui_p[ 1 ] ) +
258 Vd_p[ 1 ] * taui_p[ 1 ] );
259 #endif
260 
261 
262 
263 else if ( ( ts_p[ 1 ] <= t0_p[ 1 ] ) &&
264 ( t0_p[ 1 ] <= tauo_p[ 1 ] ) &&
265 ( tauo_p[ 1 ] <= taui_p[ 1 ] ) )
266 
267 OpCondition = SaveOpCondition = _G_;
268 if ( OpCondition != LastOpCondition )
269 
270 #ifdef SAT
271 ts_p[ 1 ] = taui_p[ 1 ] * ( VDD * VDD + 2 * VDD * ( Vc - Vd_p[ 1 ] ) - 2 * Vc * ( Vd_p[ 1 ] + TECH.Vtp0 ) +
272 Vd_p[ 1 ] * Vd_p[ 1 ] ) / ( 2 * VDD * Vc );
273 #else
274 ts_p[ 1 ] = taui_p[ 1 ] * ( VDD - Vd_p[ 1 ] - TECH.Vtp0 ) / VDD;
275 #endif
276 theta = pow( ( D_2_p * ts_p[ 1 ] + C_2_p ), 1.5 );
277 b = 2 * ( Cm2 * VDD + J_2_p * taui_p[ 1 ] ) /
278 ( K_2_p * taui_p[ 1 ] );
279 c = ( 6 * A_2_p * D_2_p * taui_p[ 1 ] * ( t0_bs - ts_p[ 1 ] ) +
280 3 * B_2_p * D_2_p * taui_p[ 1 ] * ( t0_bs * t0_bs - ts_p[ 1 ] * ts_p[ 1 ] ) -
281 4 * Vc * Vc * beta_p[ 1 ] * taui_p[ 1 ] * alpha +
282 4 * Vc * Vc * beta_p[ 1 ] * taui_p[ 1 ] * theta -
283 3 * D_2_p * ts_p[ 1 ] *
284 ( 2 * Cm2 * VDD - 2 * Cov * VDD + taui_p[ 1 ] *
285 ( 2 * J_2_p + K_2_p * ts_p[ 1 ] ) ) ) /
286 ( 3 * D_2_p * K_2_p * taui_p[ 1 ] );
287 if ( ( b * b - 4 * c ) >= 0 )
288 
289 t0_p[ 1 ] = ( sqrt ( ( b * b ) - 4 * c ) - b ) * 0.5;
290 if ( t0_p[ 1 ] < 0 )
291 t0_p[ 1 ] = -( sqrt ( ( b * b ) - 4 * c ) + b ) * 0.5;
292 
293 else
294 t0_p[ 1 ] = t0_bs;
295 
296 else
297 
298 OpCondition = _E_;
299 
300 
301 
302 return OpCondition;
303 
304 
305  ///
306 int Fast::Calct0tsnP( unsigned int p, int& SaveOpCondition )
307 
308 int OpCondition = _A_, LastOpCondition = 0;
309 double Vc, tc, X, Y, H, K, det, alpha, beta;
310 
311 Vc = TECH.Ec_p * L_p[ p ];
312 ts_p[ p ] = ( A_1_p[ p ] * ( t0_p[ p ] - tauo_p[ p ] ) * ( VDD * t0_p[ p ] - Vs_p[ p ] * taui_p[ p ] ) +
313 ( t0_p[ p ] - taui_p[ p ] ) * ( B_1_p[ p ] * ( t0_p[ p ] - tauo_p[ p ] ) +
314 VDD * t0_p[ p ] - Vd_p[ p ] * tauo_p[ p ] ) ) /
315 ( A_1_p[ p ] * ( VDD - Vs_p[ p ] ) * ( t0_p[ p ] - tauo_p[ p ] ) +
316 ( VDD - Vd_p[ p ] ) * ( t0_p[ p ] - taui_p[ p ] ) );
317 if ( taui_p[ p ] < tauo_p[ p ] )
318 
319 SaveOpCondition = _A_;
320 
321 else
322 
323 tc = ( VDD * tauo_p[ p ] * ( t0_p[ p ] - taui_p[ p ] ) +
324 Vs_p[ p ] * taui_p[ p ] * ( tauo_p[ p ] - t0_p[ p ] ) ) /
325 ( VDD * ( t0_p[ p ] - taui_p[ p ] ) + Vs_p[ p ] * ( tauo_p[ p ] - t0_p[ p ] ) );
326 SaveOpCondition = _C_;
327 
328 X = t0_p[ p ] - taui_p[ p ];
329 Y = tauo_p[ p ] - t0_p[ p ];
330 alpha = VDD - Vs_p[ p ];
331 beta = VDD - Vd_p[ p ];
332 while ( OpCondition != LastOpCondition )
333 
334 if ( LastOpCondition != 0 )
335 LastOpCondition = OpCondition;
336 else
337 LastOpCondition = _E_;
338 if ( ( taui_p[ p ] <= tauo_p[ p ] ) &&
339 ( ts_p[ p ] <= taui_p[ p ] ) &&
340 ( t0_p[ p ] <= ts_p[ p ] ) )
341 
342 OpCondition = SaveOpCondition = _A_;
343 if ( OpCondition != LastOpCondition )
344 
345 #ifdef SAT
346 double AAA, BBB;
347 AAA = ( X * beta + Y * alpha ) / ( X * Y );
348 BBB = -( VDD * t0_p[ p ] * ( X + Y ) - Vd_p[ p ] * X * tauo_p[ p ] - Vs_p[ p ] * Y * taui_p[ p ] ) / ( X * Y );
349 AAA /= Vc;
350 BBB /= Vc;
351 BBB -= 1.0;
352 H = 2 * ( A_1_p[ p ] + 1 ) * ( Vs_p[ p ] - VDD ) / ( Vc * X );
353 K = ( 2 * A_1_p[ p ] * ( VDD * t0_p[ p ] - Vs_p[ p ] * taui_p[ p ] ) +
354 2 * B_1_p[ p ] * X + 2 * VDD * t0_p[ p ] + Vc * X - 2 * Vs_p[ p ] * taui_p[ p ] ) /
355 ( Vc * X );
356 det = 4 * K * AAA * AAA - 4 * H * AAA * BBB + H * H;
357 if ( det >= 0 )
358 
359 ts_p[ p ] = ( SQRT ( det ) - 2 * AAA * BBB + H ) / ( 2 * AAA * AAA );
360 if ( ( ts_p[ p ] < 0 ) || ( ts_p[ p ] < t0_p[ p ] ) || ( ts_p[ p ] > tauo_p[ p ] ) )
361 ts_p[ p ] = -( SQRT ( det ) + 2 * AAA * BBB - H ) / ( 2 * AAA * AAA );
362 
363 else
364 ts_p[ p ] = ( A_1_p[ p ] * ( t0_p[ p ] - tauo_p[ p ] ) * ( VDD * t0_p[ p ] - Vs_p[ p ] * taui_p[ p ] ) +
365 ( t0_p[ p ] - taui_p[ p ] ) * ( B_1_p[ p ] * ( t0_p[ p ] - tauo_p[ p ] ) +
366 VDD * t0_p[ p ] - Vd_p[ p ] * tauo_p[ p ] ) ) /
367 ( A_1_p[ p ] * ( VDD - Vs_p[ p ] ) * ( t0_p[ p ] - tauo_p[ p ] ) +
368 ( VDD - Vd_p[ p ] ) * ( t0_p[ p ] - taui_p[ p ] ) );
369 #else
370 ts_p[ p ] = ( A_1_p[ p ] * ( t0_p[ p ] - tauo_p[ p ] ) * ( VDD * t0_p[ p ] - Vs_p[ p ] * taui_p[ p ] ) +
371 ( t0_p[ p ] - taui_p[ p ] ) * ( B_1_p[ p ] * ( t0_p[ p ] - tauo_p[ p ] ) +
372 VDD * t0_p[ p ] - Vd_p[ p ] * tauo_p[ p ] ) ) /
373 ( A_1_p[ p ] * ( VDD - Vs_p[ p ] ) * ( t0_p[ p ] - tauo_p[ p ] ) +
374 ( VDD - Vd_p[ p ] ) * ( t0_p[ p ] - taui_p[ p ] ) );
375 #endif
376 
377 
378 else if ( ( ts_p[ p ] <= tauo_p[ p ] ) &&
379 ( taui_p[ p ] <= ts_p[ p ] ) &&
380 ( t0_p[ p ] <= taui_p[ p ] ) )
381 
382 OpCondition = SaveOpCondition = _B_;
383 if ( OpCondition != LastOpCondition )
384 
385 #ifdef SAT
386 
387 ts_p[ p ] = tauo_p[ p ] + ( ( t0_p[ p ] - tauo_p[ p ] ) *
388 ( sqrt ( Vc * ( 2 * VDD + Vc + 2 * TECH.Vtp0 ) ) - Vc ) ) / ( VDD - Vd_p[ p ] );
389 #else
390 ts_p[ p ] = ( VDD * t0_p[ p ] - Vd_p[ p ] * tauo_p[ p ] +
391 TECH.Vtp0 * ( t0_p[ p ] - tauo_p[ p ] ) ) /
392 ( VDD - Vd_p[ p ] );
393 #endif
394 
395 
396 else if ( ( tauo_p[ p ] <= taui_p[ p ] ) &&
397 ( ts_p[ p ] < tc ) &&
398 ( t0_p[ p ] <= ts_p[ p ] ) )
399 

(ts_p[p] < tc), not '<=' !!! Calctst0P.cc
401 OpCondition = SaveOpCondition = _C_;
402 if ( OpCondition != LastOpCondition )
403 
404 #ifdef SAT
405 double AAA, BBB;
406 AAA = ( X * beta + Y * alpha ) / ( X * Y );
407 BBB = -( VDD * t0_p[ p ] * ( X + Y ) - Vd_p[ p ] * X * tauo_p[ p ] - Vs_p[ p ] * Y * taui_p[ p ] ) / ( X * Y );
408 AAA /= Vc;
409 BBB /= Vc;
410 BBB -= 1.0;
411 H = 2 * ( A_1_p[ p ] + 1 ) * ( Vs_p[ p ] - VDD ) / ( Vc * X );
412 K = ( 2 * A_1_p[ p ] * ( VDD * t0_p[ p ] - Vs_p[ p ] * taui_p[ p ] ) +
413 2 * B_1_p[ p ] * X + 2 * VDD * t0_p[ p ] + Vc * X - 2 * Vs_p[ p ] * taui_p[ p ] ) /
414 ( Vc * X );
415 det = 4 * K * AAA * AAA - 4 * H * AAA * BBB + H * H;
416 if ( det >= 0 )
417 
418 ts_p[ p ] = ( SQRT ( det ) - 2 * AAA * BBB + H ) / ( 2 * AAA * AAA );
419 if ( ( ts_p[ p ] < 0 ) || ( ts_p[ p ] < t0_p[ p ] ) || ( ts_p[ p ] > tauo_p[ p ] ) )
420 ts_p[ p ] = -( SQRT ( det ) + 2 * AAA * BBB - H ) / ( 2 * AAA * AAA );
421 
422 else
423 ts_p[ p ] = ( A_1_p[ p ] * ( t0_p[ p ] - tauo_p[ p ] ) * ( VDD * t0_p[ p ] - Vs_p[ p ] * taui_p[ p ] ) +
424 ( t0_p[ p ] - taui_p[ p ] ) * ( B_1_p[ p ] * ( t0_p[ p ] - tauo_p[ p ] ) +
425 VDD * t0_p[ p ] - Vd_p[ p ] * tauo_p[ p ] ) ) /
426 ( A_1_p[ p ] * ( VDD - Vs_p[ p ] ) * ( t0_p[ p ] - tauo_p[ p ] ) +
427 ( VDD - Vd_p[ p ] ) * ( t0_p[ p ] - taui_p[ p ] ) );
428 #else
429 
430 ts_p[ p ] = ( A_1_p[ p ] * ( t0_p[ p ] - tauo_p[ p ] ) * ( VDD * t0_p[ p ] - Vs_p[ p ] * taui_p[ p ] ) +
431 ( t0_p[ p ] - taui_p[ p ] ) * ( B_1_p[ p ] * ( t0_p[ p ] - tauo_p[ p ] ) +
432 VDD * t0_p[ p ] - Vd_p[ p ] * tauo_p[ p ] ) ) /
433 ( A_1_p[ p ] * ( VDD - Vs_p[ p ] ) * ( t0_p[ p ] - tauo_p[ p ] ) +
434 ( VDD - Vd_p[ p ] ) * ( t0_p[ p ] - taui_p[ p ] ) );
435 #endif
436 
437 
438 else if ( ( tauo_p[ p ] <= taui_p[ p ] ) &&
439 ( tc <= ts_p[ p ] ) &&
440 ( t0_p[ p ] <= ts_p[ p ] ) )
441 
442 OpCondition = SaveOpCondition = _D_;
443 if ( OpCondition != LastOpCondition )
444 
445 ts_p[ p ] = tc;
446 
447 
448 else
449 
450 OpCondition = _E_;
451 
452 
453 return OpCondition;
454 

Delay.cc
3 #include "mystdinclude.h"
4 #include "myenum.h"
5 #include "print.h"
6 #include "fast.h"
7 
8 
9  ///
10 double Fast::CalcDelay( const Circuit& circuit,
11 unsigned int NP,
12 unsigned int NC,
13 unsigned int n,
14 unsigned int p,
15 const double* NewWidth,
16 double tin,
17 TransitionType TOut,
18 int& RetCode )
19 
20 
21 
22 double t0_bs;
23 for ( unsigned int i = 1; i <= n; i++ )
24 
25 tauo_n[ i ] = tin;
26 
27 for ( unsigned int i = 1; i <= p; i++ )
28 
29 tauo_p[ i ] = tin;
30 
31 taui_n[ 1 ] = tin;
32 taui_p[ 1 ] = tin;
33 switch ( TOut )
34 
35 case FALL:  // n chain
36 t0_bs = TECH.Vtn0 * tin / VDD;
37 t0_n[ 1 ] = CalcStartTime( circuit, NP, NC, t0_bs, tauo_n[ 1 ], NMOS, NewWidth, RetCode );
38 if ( RetCode != OK )
39 t0_n