basic_circuit.cc (10152:52c552138ba1) basic_circuit.cc (10234:5cb711fa6176)
1/*****************************************************************************
2 * McPAT/CACTI
3 * SOFTWARE LICENSE AGREEMENT
4 * Copyright 2012 Hewlett-Packard Development Company, L.P.
1/*****************************************************************************
2 * McPAT/CACTI
3 * SOFTWARE LICENSE AGREEMENT
4 * Copyright 2012 Hewlett-Packard Development Company, L.P.
5 * Copyright (c) 2010-2013 Advanced Micro Devices, Inc.
5 * All Rights Reserved
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met: redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer;
11 * redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the

--- 7 unchanged lines hidden (view full) ---

20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
6 * All Rights Reserved
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met: redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer;
12 * redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the

--- 7 unchanged lines hidden (view full) ---

21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 ***************************************************************************/
31
32
33
34
35#include <cassert>
36#include <cmath>
37#include <iostream>
38
39#include "basic_circuit.h"
40#include "parameter.h"
41
30 *
31 ***************************************************************************/
32
33
34
35
36#include <cassert>
37#include <cmath>
38#include <iostream>
39
40#include "basic_circuit.h"
41#include "parameter.h"
42
42uint32_t _log2(uint64_t num)
43{
44 uint32_t log2 = 0;
43uint32_t _log2(uint64_t num) {
44 uint32_t log2 = 0;
45
45
46 if (num == 0)
47 {
48 std::cerr << "log0?" << std::endl;
49 exit(1);
50 }
46 if (num == 0) {
47 std::cerr << "log0?" << std::endl;
48 exit(1);
49 }
51
50
52 while (num > 1)
53 {
54 num = (num >> 1);
55 log2++;
56 }
51 while (num > 1) {
52 num = (num >> 1);
53 log2++;
54 }
57
55
58 return log2;
56 return log2;
59}
60
61
57}
58
59
62bool is_pow2(int64_t val)
63{
64 if (val <= 0)
65 {
66 return false;
67 }
68 else if (val == 1)
69 {
70 return true;
71 }
72 else
73 {
74 return (_log2(val) != _log2(val-1));
75 }
60bool is_pow2(int64_t val) {
61 if (val <= 0) {
62 return false;
63 } else if (val == 1) {
64 return true;
65 } else {
66 return (_log2(val) != _log2(val - 1));
67 }
76}
77
78
68}
69
70
79int powers (int base, int n)
80{
81 int i, p;
71int powers (int base, int n) {
72 int i, p;
82
73
83 p = 1;
84 for (i = 1; i <= n; ++i)
85 p *= base;
86 return p;
74 p = 1;
75 for (i = 1; i <= n; ++i)
76 p *= base;
77 return p;
87}
88
89/*----------------------------------------------------------------------*/
90
78}
79
80/*----------------------------------------------------------------------*/
81
91double logtwo (double x)
92{
93 assert(x > 0);
94 return ((double) (log (x) / log (2.0)));
82double logtwo (double x) {
83 assert(x > 0);
84 return ((double) (log (x) / log (2.0)));
95}
96
97/*----------------------------------------------------------------------*/
98
99
100double gate_C(
101 double width,
102 double wirelength,
103 bool _is_dram,
104 bool _is_cell,
85}
86
87/*----------------------------------------------------------------------*/
88
89
90double gate_C(
91 double width,
92 double wirelength,
93 bool _is_dram,
94 bool _is_cell,
105 bool _is_wl_tr)
106{
107 const TechnologyParameter::DeviceType * dt;
95 bool _is_wl_tr) {
96 const TechnologyParameter::DeviceType * dt;
108
97
109 if (_is_dram && _is_cell)
110 {
111 dt = &g_tp.dram_acc; //DRAM cell access transistor
112 }
113 else if (_is_dram && _is_wl_tr)
114 {
115 dt = &g_tp.dram_wl; //DRAM wordline transistor
116 }
117 else if (!_is_dram && _is_cell)
118 {
119 dt = &g_tp.sram_cell; // SRAM cell access transistor
120 }
121 else
122 {
123 dt = &g_tp.peri_global;
124 }
98 if (_is_dram && _is_cell) {
99 dt = &g_tp.dram_acc; //DRAM cell access transistor
100 } else if (_is_dram && _is_wl_tr) {
101 dt = &g_tp.dram_wl; //DRAM wordline transistor
102 } else if (!_is_dram && _is_cell) {
103 dt = &g_tp.sram_cell; // SRAM cell access transistor
104 } else {
105 dt = &g_tp.peri_global;
106 }
125
107
126 return (dt->C_g_ideal + dt->C_overlap + 3*dt->C_fringe)*width + dt->l_phy*Cpolywire;
108 return (dt->C_g_ideal + dt->C_overlap + 3*dt->C_fringe)*width + dt->l_phy*Cpolywire;
127}
128
129
130// returns gate capacitance in Farads
131// actually this function is the same as gate_C() now
132double gate_C_pass(
133 double width, // gate width in um (length is Lphy_periph_global)
134 double wirelength, // poly wire length going to gate in lambda
135 bool _is_dram,
136 bool _is_cell,
109}
110
111
112// returns gate capacitance in Farads
113// actually this function is the same as gate_C() now
114double gate_C_pass(
115 double width, // gate width in um (length is Lphy_periph_global)
116 double wirelength, // poly wire length going to gate in lambda
117 bool _is_dram,
118 bool _is_cell,
137 bool _is_wl_tr)
138{
139 // v5.0
140 const TechnologyParameter::DeviceType * dt;
119 bool _is_wl_tr) {
120 // v5.0
121 const TechnologyParameter::DeviceType * dt;
141
122
142 if ((_is_dram) && (_is_cell))
143 {
144 dt = &g_tp.dram_acc; //DRAM cell access transistor
145 }
146 else if ((_is_dram) && (_is_wl_tr))
147 {
148 dt = &g_tp.dram_wl; //DRAM wordline transistor
149 }
150 else if ((!_is_dram) && _is_cell)
151 {
152 dt = &g_tp.sram_cell; // SRAM cell access transistor
153 }
154 else
155 {
156 dt = &g_tp.peri_global;
157 }
123 if ((_is_dram) && (_is_cell)) {
124 dt = &g_tp.dram_acc; //DRAM cell access transistor
125 } else if ((_is_dram) && (_is_wl_tr)) {
126 dt = &g_tp.dram_wl; //DRAM wordline transistor
127 } else if ((!_is_dram) && _is_cell) {
128 dt = &g_tp.sram_cell; // SRAM cell access transistor
129 } else {
130 dt = &g_tp.peri_global;
131 }
158
132
159 return (dt->C_g_ideal + dt->C_overlap + 3*dt->C_fringe)*width + dt->l_phy*Cpolywire;
133 return (dt->C_g_ideal + dt->C_overlap + 3*dt->C_fringe)*width + dt->l_phy*Cpolywire;
160}
161
162
163
164double drain_C_(
165 double width,
166 int nchannel,
167 int stack,
168 int next_arg_thresh_folding_width_or_height_cell,
169 double fold_dimension,
170 bool _is_dram,
171 bool _is_cell,
134}
135
136
137
138double drain_C_(
139 double width,
140 int nchannel,
141 int stack,
142 int next_arg_thresh_folding_width_or_height_cell,
143 double fold_dimension,
144 bool _is_dram,
145 bool _is_cell,
172 bool _is_wl_tr)
173{
174 double w_folded_tr;
175 const TechnologyParameter::DeviceType * dt;
146 bool _is_wl_tr) {
147 double w_folded_tr;
148 const TechnologyParameter::DeviceType * dt;
176
149
177 if ((_is_dram) && (_is_cell))
178 {
179 dt = &g_tp.dram_acc; // DRAM cell access transistor
180 }
181 else if ((_is_dram) && (_is_wl_tr))
182 {
183 dt = &g_tp.dram_wl; // DRAM wordline transistor
184 }
185 else if ((!_is_dram) && _is_cell)
186 {
187 dt = &g_tp.sram_cell; // SRAM cell access transistor
188 }
189 else
190 {
191 dt = &g_tp.peri_global;
192 }
150 if ((_is_dram) && (_is_cell)) {
151 dt = &g_tp.dram_acc; // DRAM cell access transistor
152 } else if ((_is_dram) && (_is_wl_tr)) {
153 dt = &g_tp.dram_wl; // DRAM wordline transistor
154 } else if ((!_is_dram) && _is_cell) {
155 dt = &g_tp.sram_cell; // SRAM cell access transistor
156 } else {
157 dt = &g_tp.peri_global;
158 }
193
159
194 double c_junc_area = dt->C_junc;
195 double c_junc_sidewall = dt->C_junc_sidewall;
196 double c_fringe = 2*dt->C_fringe;
197 double c_overlap = 2*dt->C_overlap;
198 double drain_C_metal_connecting_folded_tr = 0;
160 double c_junc_area = dt->C_junc;
161 double c_junc_sidewall = dt->C_junc_sidewall;
162 double c_fringe = 2 * dt->C_fringe;
163 double c_overlap = 2 * dt->C_overlap;
164 double drain_C_metal_connecting_folded_tr = 0;
199
165
200 // determine the width of the transistor after folding (if it is getting folded)
201 if (next_arg_thresh_folding_width_or_height_cell == 0)
202 { // interpret fold_dimension as the the folding width threshold
203 // i.e. the value of transistor width above which the transistor gets folded
204 w_folded_tr = fold_dimension;
205 }
206 else
207 { // interpret fold_dimension as the height of the cell that this transistor is part of.
208 double h_tr_region = fold_dimension - 2 * g_tp.HPOWERRAIL;
209 // TODO : w_folded_tr must come from Component::compute_gate_area()
210 double ratio_p_to_n = 2.0 / (2.0 + 1.0);
211 if (nchannel)
212 {
213 w_folded_tr = (1 - ratio_p_to_n) * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS);
166 // determine the width of the transistor after folding (if it is getting folded)
167 if (next_arg_thresh_folding_width_or_height_cell == 0) {
168 // interpret fold_dimension as the the folding width threshold
169 // i.e. the value of transistor width above which the transistor gets folded
170 w_folded_tr = fold_dimension;
171 } else { // interpret fold_dimension as the height of the cell that this transistor is part of.
172 double h_tr_region = fold_dimension - 2 * g_tp.HPOWERRAIL;
173 // TODO : w_folded_tr must come from Component::compute_gate_area()
174 double ratio_p_to_n = 2.0 / (2.0 + 1.0);
175 if (nchannel) {
176 w_folded_tr = (1 - ratio_p_to_n) * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS);
177 } else {
178 w_folded_tr = ratio_p_to_n * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS);
179 }
214 }
180 }
215 else
216 {
217 w_folded_tr = ratio_p_to_n * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS);
181 int num_folded_tr = (int) (ceil(width / w_folded_tr));
182
183 if (num_folded_tr < 2) {
184 w_folded_tr = width;
218 }
185 }
219 }
220 int num_folded_tr = (int) (ceil(width / w_folded_tr));
221
186
222 if (num_folded_tr < 2)
223 {
224 w_folded_tr = width;
225 }
187 double total_drain_w = (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) + // only for drain
188 (stack - 1) * g_tp.spacing_poly_to_poly;
189 double drain_h_for_sidewall = w_folded_tr;
190 double total_drain_height_for_cap_wrt_gate = w_folded_tr + 2 * w_folded_tr * (stack - 1);
191 if (num_folded_tr > 1) {
192 total_drain_w += (num_folded_tr - 2) * (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) +
193 (num_folded_tr - 1) * ((stack - 1) * g_tp.spacing_poly_to_poly);
226
194
227 double total_drain_w = (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) + // only for drain
228 (stack - 1) * g_tp.spacing_poly_to_poly;
229 double drain_h_for_sidewall = w_folded_tr;
230 double total_drain_height_for_cap_wrt_gate = w_folded_tr + 2 * w_folded_tr * (stack - 1);
231 if (num_folded_tr > 1)
232 {
233 total_drain_w += (num_folded_tr - 2) * (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) +
234 (num_folded_tr - 1) * ((stack - 1) * g_tp.spacing_poly_to_poly);
235
236 if (num_folded_tr%2 == 0)
237 {
238 drain_h_for_sidewall = 0;
195 if (num_folded_tr % 2 == 0) {
196 drain_h_for_sidewall = 0;
197 }
198 total_drain_height_for_cap_wrt_gate *= num_folded_tr;
199 drain_C_metal_connecting_folded_tr = g_tp.wire_local.C_per_um * total_drain_w;
239 }
200 }
240 total_drain_height_for_cap_wrt_gate *= num_folded_tr;
241 drain_C_metal_connecting_folded_tr = g_tp.wire_local.C_per_um * total_drain_w;
242 }
243
201
244 double drain_C_area = c_junc_area * total_drain_w * w_folded_tr;
245 double drain_C_sidewall = c_junc_sidewall * (drain_h_for_sidewall + 2 * total_drain_w);
246 double drain_C_wrt_gate = (c_fringe + c_overlap) * total_drain_height_for_cap_wrt_gate;
202 double drain_C_area = c_junc_area * total_drain_w * w_folded_tr;
203 double drain_C_sidewall = c_junc_sidewall * (drain_h_for_sidewall + 2 * total_drain_w);
204 double drain_C_wrt_gate = (c_fringe + c_overlap) * total_drain_height_for_cap_wrt_gate;
247
205
248 return (drain_C_area + drain_C_sidewall + drain_C_wrt_gate + drain_C_metal_connecting_folded_tr);
206 return (drain_C_area + drain_C_sidewall + drain_C_wrt_gate + drain_C_metal_connecting_folded_tr);
249}
250
251
252double tr_R_on(
253 double width,
254 int nchannel,
255 int stack,
256 bool _is_dram,
257 bool _is_cell,
207}
208
209
210double tr_R_on(
211 double width,
212 int nchannel,
213 int stack,
214 bool _is_dram,
215 bool _is_cell,
258 bool _is_wl_tr)
259{
260 const TechnologyParameter::DeviceType * dt;
216 bool _is_wl_tr) {
217 const TechnologyParameter::DeviceType * dt;
261
218
262 if ((_is_dram) && (_is_cell))
263 {
264 dt = &g_tp.dram_acc; //DRAM cell access transistor
265 }
266 else if ((_is_dram) && (_is_wl_tr))
267 {
268 dt = &g_tp.dram_wl; //DRAM wordline transistor
269 }
270 else if ((!_is_dram) && _is_cell)
271 {
272 dt = &g_tp.sram_cell; // SRAM cell access transistor
273 }
274 else
275 {
276 dt = &g_tp.peri_global;
277 }
219 if ((_is_dram) && (_is_cell)) {
220 dt = &g_tp.dram_acc; //DRAM cell access transistor
221 } else if ((_is_dram) && (_is_wl_tr)) {
222 dt = &g_tp.dram_wl; //DRAM wordline transistor
223 } else if ((!_is_dram) && _is_cell) {
224 dt = &g_tp.sram_cell; // SRAM cell access transistor
225 } else {
226 dt = &g_tp.peri_global;
227 }
278
228
279 double restrans = (nchannel) ? dt->R_nch_on : dt->R_pch_on;
280 return (stack * restrans / width);
229 double restrans = (nchannel) ? dt->R_nch_on : dt->R_pch_on;
230 return (stack * restrans / width);
281}
282
283
284/* This routine operates in reverse: given a resistance, it finds
285 * the transistor width that would have this R. It is used in the
286 * data wordline to estimate the wordline driver size. */
287
288// returns width in um
289double R_to_w(
290 double res,
291 int nchannel,
292 bool _is_dram,
293 bool _is_cell,
231}
232
233
234/* This routine operates in reverse: given a resistance, it finds
235 * the transistor width that would have this R. It is used in the
236 * data wordline to estimate the wordline driver size. */
237
238// returns width in um
239double R_to_w(
240 double res,
241 int nchannel,
242 bool _is_dram,
243 bool _is_cell,
294 bool _is_wl_tr)
295{
296 const TechnologyParameter::DeviceType * dt;
244 bool _is_wl_tr) {
245 const TechnologyParameter::DeviceType * dt;
297
246
298 if ((_is_dram) && (_is_cell))
299 {
300 dt = &g_tp.dram_acc; //DRAM cell access transistor
301 }
302 else if ((_is_dram) && (_is_wl_tr))
303 {
304 dt = &g_tp.dram_wl; //DRAM wordline transistor
305 }
306 else if ((!_is_dram) && (_is_cell))
307 {
308 dt = &g_tp.sram_cell; // SRAM cell access transistor
309 }
310 else
311 {
312 dt = &g_tp.peri_global;
313 }
247 if ((_is_dram) && (_is_cell)) {
248 dt = &g_tp.dram_acc; //DRAM cell access transistor
249 } else if ((_is_dram) && (_is_wl_tr)) {
250 dt = &g_tp.dram_wl; //DRAM wordline transistor
251 } else if ((!_is_dram) && (_is_cell)) {
252 dt = &g_tp.sram_cell; // SRAM cell access transistor
253 } else {
254 dt = &g_tp.peri_global;
255 }
314
256
315 double restrans = (nchannel) ? dt->R_nch_on : dt->R_pch_on;
316 return (restrans / res);
257 double restrans = (nchannel) ? dt->R_nch_on : dt->R_pch_on;
258 return (restrans / res);
317}
318
319
320double pmos_to_nmos_sz_ratio(
321 bool _is_dram,
259}
260
261
262double pmos_to_nmos_sz_ratio(
263 bool _is_dram,
322 bool _is_wl_tr)
323{
324 double p_to_n_sizing_ratio;
325 if ((_is_dram) && (_is_wl_tr))
326 { //DRAM wordline transistor
327 p_to_n_sizing_ratio = g_tp.dram_wl.n_to_p_eff_curr_drv_ratio;
328 }
329 else
330 { //DRAM or SRAM all other transistors
331 p_to_n_sizing_ratio = g_tp.peri_global.n_to_p_eff_curr_drv_ratio;
332 }
333 return p_to_n_sizing_ratio;
264 bool _is_wl_tr) {
265 double p_to_n_sizing_ratio;
266 if ((_is_dram) && (_is_wl_tr)) { //DRAM wordline transistor
267 p_to_n_sizing_ratio = g_tp.dram_wl.n_to_p_eff_curr_drv_ratio;
268 } else { //DRAM or SRAM all other transistors
269 p_to_n_sizing_ratio = g_tp.peri_global.n_to_p_eff_curr_drv_ratio;
270 }
271 return p_to_n_sizing_ratio;
334}
335
336
337// "Timing Models for MOS Circuits" by Mark Horowitz, 1984
338double horowitz(
339 double inputramptime, // input rise time
340 double tf, // time constant of gate
341 double vs1, // threshold voltage
342 double vs2, // threshold voltage
272}
273
274
275// "Timing Models for MOS Circuits" by Mark Horowitz, 1984
276double horowitz(
277 double inputramptime, // input rise time
278 double tf, // time constant of gate
279 double vs1, // threshold voltage
280 double vs2, // threshold voltage
343 int rise) // whether input rises or fall
344{
345 if (inputramptime == 0 && vs1 == vs2)
346 {
347 return tf * (vs1 < 1 ? -log(vs1) : log(vs1));
348 }
349 double a, b, td;
281 int rise) { // whether input rises or fall
282 if (inputramptime == 0 && vs1 == vs2) {
283 return tf * (vs1 < 1 ? -log(vs1) : log(vs1));
284 }
285 double a, b, td;
350
286
351 a = inputramptime / tf;
352 if (rise == RISE)
353 {
354 b = 0.5;
355 td = tf * sqrt(log(vs1)*log(vs1) + 2*a*b*(1.0 - vs1)) + tf*(log(vs1) - log(vs2));
356 }
357 else
358 {
359 b = 0.4;
360 td = tf * sqrt(log(1.0 - vs1)*log(1.0 - vs1) + 2*a*b*(vs1)) + tf*(log(1.0 - vs1) - log(1.0 - vs2));
361 }
362 return (td);
287 a = inputramptime / tf;
288 if (rise == RISE) {
289 b = 0.5;
290 td = tf * sqrt(log(vs1) * log(vs1) + 2 * a * b * (1.0 - vs1)) +
291 tf * (log(vs1) - log(vs2));
292 } else {
293 b = 0.4;
294 td = tf * sqrt(log(1.0 - vs1) * log(1.0 - vs1) + 2 * a * b * (vs1)) +
295 tf * (log(1.0 - vs1) - log(1.0 - vs2));
296 }
297 return (td);
363}
364
365double cmos_Ileak(
366 double nWidth,
367 double pWidth,
368 bool _is_dram,
369 bool _is_cell,
298}
299
300double cmos_Ileak(
301 double nWidth,
302 double pWidth,
303 bool _is_dram,
304 bool _is_cell,
370 bool _is_wl_tr)
371{
372 TechnologyParameter::DeviceType * dt;
305 bool _is_wl_tr) {
306 TechnologyParameter::DeviceType * dt;
373
307
374 if ((!_is_dram)&&(_is_cell))
375 { //SRAM cell access transistor
376 dt = &(g_tp.sram_cell);
377 }
378 else if ((_is_dram)&&(_is_wl_tr))
379 { //DRAM wordline transistor
380 dt = &(g_tp.dram_wl);
381 }
382 else
383 { //DRAM or SRAM all other transistors
384 dt = &(g_tp.peri_global);
385 }
386 return nWidth*dt->I_off_n + pWidth*dt->I_off_p;
308 if ((!_is_dram) && (_is_cell)) { //SRAM cell access transistor
309 dt = &(g_tp.sram_cell);
310 } else if ((_is_dram) && (_is_wl_tr)) { //DRAM wordline transistor
311 dt = &(g_tp.dram_wl);
312 } else { //DRAM or SRAM all other transistors
313 dt = &(g_tp.peri_global);
314 }
315 return nWidth*dt->I_off_n + pWidth*dt->I_off_p;
387}
388
389
390double simplified_nmos_leakage(
391 double nwidth,
392 bool _is_dram,
393 bool _is_cell,
316}
317
318
319double simplified_nmos_leakage(
320 double nwidth,
321 bool _is_dram,
322 bool _is_cell,
394 bool _is_wl_tr)
395{
396 TechnologyParameter::DeviceType * dt;
323 bool _is_wl_tr) {
324 TechnologyParameter::DeviceType * dt;
397
325
398 if ((!_is_dram)&&(_is_cell))
399 { //SRAM cell access transistor
400 dt = &(g_tp.sram_cell);
401 }
402 else if ((_is_dram)&&(_is_wl_tr))
403 { //DRAM wordline transistor
404 dt = &(g_tp.dram_wl);
405 }
406 else
407 { //DRAM or SRAM all other transistors
408 dt = &(g_tp.peri_global);
409 }
410 return nwidth * dt->I_off_n;
326 if ((!_is_dram) && (_is_cell)) { //SRAM cell access transistor
327 dt = &(g_tp.sram_cell);
328 } else if ((_is_dram) && (_is_wl_tr)) { //DRAM wordline transistor
329 dt = &(g_tp.dram_wl);
330 } else { //DRAM or SRAM all other transistors
331 dt = &(g_tp.peri_global);
332 }
333 return nwidth * dt->I_off_n;
411}
412
334}
335
413int factorial(int n, int m)
414{
415 int fa = m, i;
416 for (i=m+1; i<=n; i++)
417 fa *=i;
418 return fa;
336int factorial(int n, int m) {
337 int fa = m, i;
338 for (i = m + 1; i <= n; i++)
339 fa *= i;
340 return fa;
419}
420
341}
342
421int combination(int n, int m)
422{
423 int ret;
424 ret = factorial(n, m+1) / factorial(n - m);
425 return ret;
343int combination(int n, int m) {
344 int ret;
345 ret = factorial(n, m + 1) / factorial(n - m);
346 return ret;
426}
427
428double simplified_pmos_leakage(
429 double pwidth,
430 bool _is_dram,
431 bool _is_cell,
347}
348
349double simplified_pmos_leakage(
350 double pwidth,
351 bool _is_dram,
352 bool _is_cell,
432 bool _is_wl_tr)
433{
434 TechnologyParameter::DeviceType * dt;
353 bool _is_wl_tr) {
354 TechnologyParameter::DeviceType * dt;
435
355
436 if ((!_is_dram)&&(_is_cell))
437 { //SRAM cell access transistor
438 dt = &(g_tp.sram_cell);
439 }
440 else if ((_is_dram)&&(_is_wl_tr))
441 { //DRAM wordline transistor
442 dt = &(g_tp.dram_wl);
443 }
444 else
445 { //DRAM or SRAM all other transistors
446 dt = &(g_tp.peri_global);
447 }
448 return pwidth * dt->I_off_p;
356 if ((!_is_dram) && (_is_cell)) { //SRAM cell access transistor
357 dt = &(g_tp.sram_cell);
358 } else if ((_is_dram) && (_is_wl_tr)) { //DRAM wordline transistor
359 dt = &(g_tp.dram_wl);
360 } else { //DRAM or SRAM all other transistors
361 dt = &(g_tp.peri_global);
362 }
363 return pwidth * dt->I_off_p;
449}
450
451double cmos_Ig_n(
452 double nWidth,
453 bool _is_dram,
454 bool _is_cell,
364}
365
366double cmos_Ig_n(
367 double nWidth,
368 bool _is_dram,
369 bool _is_cell,
455 bool _is_wl_tr)
456{
457 TechnologyParameter::DeviceType * dt;
370 bool _is_wl_tr) {
371 TechnologyParameter::DeviceType * dt;
458
372
459 if ((!_is_dram)&&(_is_cell))
460 { //SRAM cell access transistor
461 dt = &(g_tp.sram_cell);
462 }
463 else if ((_is_dram)&&(_is_wl_tr))
464 { //DRAM wordline transistor
465 dt = &(g_tp.dram_wl);
466 }
467 else
468 { //DRAM or SRAM all other transistors
469 dt = &(g_tp.peri_global);
470 }
471 return nWidth*dt->I_g_on_n;
373 if ((!_is_dram) && (_is_cell)) { //SRAM cell access transistor
374 dt = &(g_tp.sram_cell);
375 } else if ((_is_dram) && (_is_wl_tr)) { //DRAM wordline transistor
376 dt = &(g_tp.dram_wl);
377 } else { //DRAM or SRAM all other transistors
378 dt = &(g_tp.peri_global);
379 }
380 return nWidth*dt->I_g_on_n;
472}
473
474double cmos_Ig_p(
475 double pWidth,
476 bool _is_dram,
477 bool _is_cell,
381}
382
383double cmos_Ig_p(
384 double pWidth,
385 bool _is_dram,
386 bool _is_cell,
478 bool _is_wl_tr)
479{
480 TechnologyParameter::DeviceType * dt;
387 bool _is_wl_tr) {
388 TechnologyParameter::DeviceType * dt;
481
389
482 if ((!_is_dram)&&(_is_cell))
483 { //SRAM cell access transistor
484 dt = &(g_tp.sram_cell);
485 }
486 else if ((_is_dram)&&(_is_wl_tr))
487 { //DRAM wordline transistor
488 dt = &(g_tp.dram_wl);
489 }
490 else
491 { //DRAM or SRAM all other transistors
492 dt = &(g_tp.peri_global);
493 }
494 return pWidth*dt->I_g_on_p;
390 if ((!_is_dram) && (_is_cell)) { //SRAM cell access transistor
391 dt = &(g_tp.sram_cell);
392 } else if ((_is_dram) && (_is_wl_tr)) { //DRAM wordline transistor
393 dt = &(g_tp.dram_wl);
394 } else { //DRAM or SRAM all other transistors
395 dt = &(g_tp.peri_global);
396 }
397 return pWidth*dt->I_g_on_p;
495}
496
497double cmos_Isub_leakage(
498 double nWidth,
499 double pWidth,
500 int fanin,
501 enum Gate_type g_type,
502 bool _is_dram,
503 bool _is_cell,
504 bool _is_wl_tr,
398}
399
400double cmos_Isub_leakage(
401 double nWidth,
402 double pWidth,
403 int fanin,
404 enum Gate_type g_type,
405 bool _is_dram,
406 bool _is_cell,
407 bool _is_wl_tr,
505 enum Half_net_topology topo)
506{
507 assert (fanin>=1);
508 double nmos_leak = simplified_nmos_leakage(nWidth, _is_dram, _is_cell, _is_wl_tr);
509 double pmos_leak = simplified_pmos_leakage(pWidth, _is_dram, _is_cell, _is_wl_tr);
510 double Isub=0;
408 enum Half_net_topology topo) {
409 assert (fanin >= 1);
410 double nmos_leak = simplified_nmos_leakage(nWidth, _is_dram, _is_cell, _is_wl_tr);
411 double pmos_leak = simplified_pmos_leakage(pWidth, _is_dram, _is_cell, _is_wl_tr);
412 double Isub = 0;
511 int num_states;
512 int num_off_tx;
513
514 num_states = int(pow(2.0, fanin));
515
413 int num_states;
414 int num_off_tx;
415
416 num_states = int(pow(2.0, fanin));
417
516 switch (g_type)
517 {
418 switch (g_type) {
518 case nmos:
419 case nmos:
519 if (fanin==1)
520 {
521 Isub = nmos_leak/num_states;
522 }
523 else
524 {
525 if (topo==parallel)
526 {
527 Isub=nmos_leak*fanin/num_states; //only when all tx are off, leakage power is non-zero. The possibility of this state is 1/num_states
420 if (fanin == 1) {
421 Isub = nmos_leak / num_states;
422 } else {
423 if (topo == parallel) {
424 //only when all tx are off, leakage power is non-zero.
425 //The possibility of this state is 1/num_states
426 Isub = nmos_leak * fanin / num_states;
427 } else {
428 for (num_off_tx = 1; num_off_tx <= fanin; num_off_tx++) {
429 //when num_off_tx ==0 there is no leakage power
430 Isub += nmos_leak * pow(UNI_LEAK_STACK_FACTOR,
431 (num_off_tx - 1)) *
432 combination(fanin, num_off_tx);
528 }
433 }
529 else
530 {
531 for (num_off_tx=1; num_off_tx<=fanin; num_off_tx++) //when num_off_tx ==0 there is no leakage power
532 {
533 //Isub += nmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*(factorial(fanin)/(factorial(fanin, num_off_tx)*factorial(num_off_tx)));
534 Isub += nmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*combination(fanin, num_off_tx);
535 }
536 Isub /=num_states;
537 }
434 Isub /= num_states;
435 }
538
539 }
540 break;
541 case pmos:
436
437 }
438 break;
439 case pmos:
542 if (fanin==1)
543 {
544 Isub = pmos_leak/num_states;
545 }
546 else
547 {
548 if (topo==parallel)
549 {
550 Isub=pmos_leak*fanin/num_states; //only when all tx are off, leakage power is non-zero. The possibility of this state is 1/num_states
440 if (fanin == 1) {
441 Isub = pmos_leak / num_states;
442 } else {
443 if (topo == parallel) {
444 //only when all tx are off, leakage power is non-zero.
445 //The possibility of this state is 1/num_states
446 Isub = pmos_leak * fanin / num_states;
447 } else {
448 for (num_off_tx = 1; num_off_tx <= fanin; num_off_tx++) {
449 //when num_off_tx ==0 there is no leakage power
450 Isub += pmos_leak * pow(UNI_LEAK_STACK_FACTOR,
451 (num_off_tx - 1)) *
452 combination(fanin, num_off_tx);
551 }
453 }
552 else
553 {
554 for (num_off_tx=1; num_off_tx<=fanin; num_off_tx++) //when num_off_tx ==0 there is no leakage power
555 {
556 //Isub += pmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*(factorial(fanin)/(factorial(fanin, num_off_tx)*factorial(num_off_tx)));
557 Isub += pmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*combination(fanin, num_off_tx);
558 }
559 Isub /=num_states;
560 }
454 Isub /= num_states;
455 }
561
562 }
563 break;
564 case inv:
456
457 }
458 break;
459 case inv:
565 Isub = (nmos_leak + pmos_leak)/2;
460 Isub = (nmos_leak + pmos_leak) / 2;
566 break;
567 case nand:
461 break;
462 case nand:
568 Isub += fanin*pmos_leak;//the pullup network
569 for (num_off_tx=1; num_off_tx<=fanin; num_off_tx++) // the pulldown network
570 {
571 //Isub += nmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*(factorial(fanin)/(factorial(fanin, num_off_tx)*factorial(num_off_tx)));
572 Isub += nmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*combination(fanin, num_off_tx);
463 Isub += fanin * pmos_leak;//the pullup network
464 for (num_off_tx = 1; num_off_tx <= fanin; num_off_tx++) {
465 // the pulldown network
466 Isub += nmos_leak * pow(UNI_LEAK_STACK_FACTOR,
467 (num_off_tx - 1)) *
468 combination(fanin, num_off_tx);
573 }
469 }
574 Isub /=num_states;
470 Isub /= num_states;
575 break;
576 case nor:
471 break;
472 case nor:
577 for (num_off_tx=1; num_off_tx<=fanin; num_off_tx++) // the pullup network
578 {
579 //Isub += pmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*(factorial(fanin)/(factorial(fanin, num_off_tx)*factorial(num_off_tx)));
580 Isub += pmos_leak*pow(UNI_LEAK_STACK_FACTOR,(num_off_tx-1))*combination(fanin, num_off_tx);
473 for (num_off_tx = 1; num_off_tx <= fanin; num_off_tx++) {
474 // the pullup network
475 Isub += pmos_leak * pow(UNI_LEAK_STACK_FACTOR,
476 (num_off_tx - 1)) *
477 combination(fanin, num_off_tx);
581 }
478 }
582 Isub += fanin*nmos_leak;//the pulldown network
583 Isub /=num_states;
479 Isub += fanin * nmos_leak;//the pulldown network
480 Isub /= num_states;
584 break;
585 case tri:
481 break;
482 case tri:
586 Isub += (nmos_leak + pmos_leak)/2;//enabled
587 Isub += nmos_leak*UNI_LEAK_STACK_FACTOR; //disabled upper bound of leakage power
588 Isub /=2;
483 Isub += (nmos_leak + pmos_leak) / 2;//enabled
484 //disabled upper bound of leakage power
485 Isub += nmos_leak * UNI_LEAK_STACK_FACTOR;
486 Isub /= 2;
589 break;
590 case tg:
487 break;
488 case tg:
591 Isub = (nmos_leak + pmos_leak)/2;
489 Isub = (nmos_leak + pmos_leak) / 2;
592 break;
593 default:
594 assert(0);
595 break;
490 break;
491 default:
492 assert(0);
493 break;
596 }
494 }
597
598 return Isub;
599}
600
601
602double cmos_Ig_leakage(
603 double nWidth,
604 double pWidth,
605 int fanin,
606 enum Gate_type g_type,
607 bool _is_dram,
608 bool _is_cell,
609 bool _is_wl_tr,
495
496 return Isub;
497}
498
499
500double cmos_Ig_leakage(
501 double nWidth,
502 double pWidth,
503 int fanin,
504 enum Gate_type g_type,
505 bool _is_dram,
506 bool _is_cell,
507 bool _is_wl_tr,
610 enum Half_net_topology topo)
611{
612 assert (fanin>=1);
613 double nmos_leak = cmos_Ig_n(nWidth, _is_dram, _is_cell, _is_wl_tr);
614 double pmos_leak = cmos_Ig_p(pWidth, _is_dram, _is_cell, _is_wl_tr);
615 double Ig_on=0;
616 int num_states;
617 int num_on_tx;
508 enum Half_net_topology topo) {
509 assert (fanin >= 1);
510 double nmos_leak = cmos_Ig_n(nWidth, _is_dram, _is_cell, _is_wl_tr);
511 double pmos_leak = cmos_Ig_p(pWidth, _is_dram, _is_cell, _is_wl_tr);
512 double Ig_on = 0;
513 int num_states;
514 int num_on_tx;
618
515
619 num_states = int(pow(2.0, fanin));
516 num_states = int(pow(2.0, fanin));
620
517
621 switch (g_type)
622 {
623 case nmos:
624 if (fanin==1)
625 {
626 Ig_on = nmos_leak/num_states;
518 switch (g_type) {
519 case nmos:
520 if (fanin == 1) {
521 Ig_on = nmos_leak / num_states;
522 } else {
523 if (topo == parallel) {
524 for (num_on_tx = 1; num_on_tx <= fanin; num_on_tx++) {
525 Ig_on += nmos_leak * combination(fanin, num_on_tx) *
526 num_on_tx;
627 }
527 }
628 else
629 {
630 if (topo==parallel)
631 {
632 for (num_on_tx=1; num_on_tx<=fanin; num_on_tx++)
633 {
634 Ig_on += nmos_leak*combination(fanin, num_on_tx)*num_on_tx;
635 }
636 }
637 else
638 {
639 Ig_on += nmos_leak * fanin;//pull down network when all TXs are on.
640 //num_on_tx is the number of on tx
641 for (num_on_tx=1; num_on_tx<fanin; num_on_tx++)//when num_on_tx=[1,n-1]
642 {
643 Ig_on += nmos_leak*combination(fanin, num_on_tx)*num_on_tx/2;//TODO: this is a approximation now, a precise computation will be very complicated.
644 }
645 Ig_on /=num_states;
646 }
528 } else {
529 //pull down network when all TXs are on.
530 Ig_on += nmos_leak * fanin;
531 //num_on_tx is the number of on tx
532 for (num_on_tx = 1; num_on_tx < fanin; num_on_tx++) {
533 //when num_on_tx=[1,n-1]
534 //TODO: this is a approximation now, a precise computation
535 //will be very complicated.
536 Ig_on += nmos_leak * combination(fanin, num_on_tx) *
537 num_on_tx / 2;
647 }
538 }
648 break;
649 case pmos:
650 if (fanin==1)
651 {
652 Ig_on = pmos_leak/num_states;
539 Ig_on /= num_states;
540 }
541 }
542 break;
543 case pmos:
544 if (fanin == 1) {
545 Ig_on = pmos_leak / num_states;
546 } else {
547 if (topo == parallel) {
548 for (num_on_tx = 1; num_on_tx <= fanin; num_on_tx++) {
549 Ig_on += pmos_leak * combination(fanin, num_on_tx) *
550 num_on_tx;
653 }
551 }
654 else
655 {
656 if (topo==parallel)
657 {
658 for (num_on_tx=1; num_on_tx<=fanin; num_on_tx++)
659 {
660 Ig_on += pmos_leak*combination(fanin, num_on_tx)*num_on_tx;
661 }
662 }
663 else
664 {
665 Ig_on += pmos_leak * fanin;//pull down network when all TXs are on.
666 //num_on_tx is the number of on tx
667 for (num_on_tx=1; num_on_tx<fanin; num_on_tx++)//when num_on_tx=[1,n-1]
668 {
669 Ig_on += pmos_leak*combination(fanin, num_on_tx)*num_on_tx/2;//TODO: this is a approximation now, a precise computation will be very complicated.
670 }
671 Ig_on /=num_states;
672 }
552 } else {
553 //pull down network when all TXs are on.
554 Ig_on += pmos_leak * fanin;
555 //num_on_tx is the number of on tx
556 for (num_on_tx = 1; num_on_tx < fanin; num_on_tx++) {
557 //when num_on_tx=[1,n-1]
558 //TODO: this is a approximation now, a precise computation
559 //will be very complicated.
560 Ig_on += pmos_leak * combination(fanin, num_on_tx) *
561 num_on_tx / 2;
673 }
562 }
674 break;
563 Ig_on /= num_states;
564 }
565 }
566 break;
675
567
676 case inv:
677 Ig_on = (nmos_leak + pmos_leak)/2;
678 break;
679 case nand:
680 //pull up network
681 for (num_on_tx=1; num_on_tx<=fanin; num_on_tx++)//when num_on_tx=[1,n]
682 {
683 Ig_on += pmos_leak*combination(fanin, num_on_tx)*num_on_tx;
684 }
568 case inv:
569 Ig_on = (nmos_leak + pmos_leak) / 2;
570 break;
571 case nand:
572 //pull up network
573 //when num_on_tx=[1,n]
574 for (num_on_tx = 1; num_on_tx <= fanin; num_on_tx++) {
575 Ig_on += pmos_leak * combination(fanin, num_on_tx) * num_on_tx;
576 }
685
577
686 //pull down network
687 Ig_on += nmos_leak * fanin;//pull down network when all TXs are on.
688 //num_on_tx is the number of on tx
689 for (num_on_tx=1; num_on_tx<fanin; num_on_tx++)//when num_on_tx=[1,n-1]
690 {
691 Ig_on += nmos_leak*combination(fanin, num_on_tx)*num_on_tx/2;//TODO: this is a approximation now, a precise computation will be very complicated.
692 }
693 Ig_on /=num_states;
694 break;
695 case nor:
696 // num_on_tx is the number of on tx in pull up network
697 Ig_on += pmos_leak * fanin;//pull up network when all TXs are on.
698 for (num_on_tx=1; num_on_tx<fanin; num_on_tx++)
699 {
700 Ig_on += pmos_leak*combination(fanin, num_on_tx)*num_on_tx/2;
578 //pull down network
579 Ig_on += nmos_leak * fanin;//pull down network when all TXs are on.
580 //num_on_tx is the number of on tx
581 for (num_on_tx = 1; num_on_tx < fanin; num_on_tx++) {
582 //when num_on_tx=[1,n-1]
583 //TODO: this is a approximation now, a precise computation will be
584 //very complicated.
585 Ig_on += nmos_leak * combination(fanin, num_on_tx) * num_on_tx / 2;
586 }
587 Ig_on /= num_states;
588 break;
589 case nor:
590 // num_on_tx is the number of on tx in pull up network
591 Ig_on += pmos_leak * fanin;//pull up network when all TXs are on.
592 for (num_on_tx = 1; num_on_tx < fanin; num_on_tx++) {
593 Ig_on += pmos_leak * combination(fanin, num_on_tx) * num_on_tx / 2;
701
594
702 }
703 //pull down network
704 for (num_on_tx=1; num_on_tx<=fanin; num_on_tx++)//when num_on_tx=[1,n]
705 {
706 Ig_on += nmos_leak*combination(fanin, num_on_tx)*num_on_tx;
707 }
708 Ig_on /=num_states;
709 break;
710 case tri:
711 Ig_on += (2*nmos_leak + 2*pmos_leak)/2;//enabled
712 Ig_on += (nmos_leak + pmos_leak)/2; //disabled upper bound of leakage power
713 Ig_on /=2;
714 break;
715 case tg:
716 Ig_on = (nmos_leak + pmos_leak)/2;
717 break;
718 default:
719 assert(0);
720 break;
721 }
595 }
596 //pull down network
597 for (num_on_tx = 1; num_on_tx <= fanin; num_on_tx++) {
598 //when num_on_tx=[1,n]
599 Ig_on += nmos_leak * combination(fanin, num_on_tx) * num_on_tx;
600 }
601 Ig_on /= num_states;
602 break;
603 case tri:
604 Ig_on += (2 * nmos_leak + 2 * pmos_leak) / 2;//enabled
605 //disabled upper bound of leakage power
606 Ig_on += (nmos_leak + pmos_leak) / 2;
607 Ig_on /= 2;
608 break;
609 case tg:
610 Ig_on = (nmos_leak + pmos_leak) / 2;
611 break;
612 default:
613 assert(0);
614 break;
615 }
722
616
723 return Ig_on;
617 return Ig_on;
724}
725
726double shortcircuit_simple(
727 double vt,
728 double velocity_index,
729 double c_in,
730 double c_out,
731 double w_nmos,
732 double w_pmos,
733 double i_on_n,
734 double i_on_p,
735 double i_on_n_in,
736 double i_on_p_in,
618}
619
620double shortcircuit_simple(
621 double vt,
622 double velocity_index,
623 double c_in,
624 double c_out,
625 double w_nmos,
626 double w_pmos,
627 double i_on_n,
628 double i_on_p,
629 double i_on_n_in,
630 double i_on_p_in,
737 double vdd)
738{
631 double vdd) {
739
632
740 double p_short_circuit, p_short_circuit_discharge, p_short_circuit_charge, p_short_circuit_discharge_low, p_short_circuit_discharge_high, p_short_circuit_charge_low, p_short_circuit_charge_high; //this is actually energy
741 double fo_n, fo_p, fanout, beta_ratio, vt_to_vdd_ratio;
633 double p_short_circuit, p_short_circuit_discharge, p_short_circuit_charge, p_short_circuit_discharge_low, p_short_circuit_discharge_high, p_short_circuit_charge_low, p_short_circuit_charge_high; //this is actually energy
634 double fo_n, fo_p, fanout, beta_ratio, vt_to_vdd_ratio;
742
635
743 fo_n = i_on_n/i_on_n_in;
744 fo_p = i_on_p/i_on_p_in;
745 fanout = c_out/c_in;
746 beta_ratio = i_on_p/i_on_n;
747 vt_to_vdd_ratio = vt/vdd;
636 fo_n = i_on_n / i_on_n_in;
637 fo_p = i_on_p / i_on_p_in;
638 fanout = c_out / c_in;
639 beta_ratio = i_on_p / i_on_n;
640 vt_to_vdd_ratio = vt / vdd;
748
641
749 //p_short_circuit_discharge_low = 10/3*(pow(0.5-vt_to_vdd_ratio,3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_p*fo_p/fanout/beta_ratio;
750 p_short_circuit_discharge_low = 10/3*(pow(((vdd-vt)-vt_to_vdd_ratio),3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_p*fo_p/fanout/beta_ratio;
751 p_short_circuit_charge_low = 10/3*(pow(((vdd-vt)-vt_to_vdd_ratio),3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_n*fo_n/fanout*beta_ratio;
642 //p_short_circuit_discharge_low = 10/3*(pow(0.5-vt_to_vdd_ratio,3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_p*fo_p/fanout/beta_ratio;
643 p_short_circuit_discharge_low =
644 10 / 3 * (pow(((vdd - vt) - vt_to_vdd_ratio), 3.0) /
645 pow(velocity_index, 2.0) / pow(2.0, 3 * vt_to_vdd_ratio *
646 vt_to_vdd_ratio)) * c_in *
647 vdd * vdd * fo_p * fo_p / fanout / beta_ratio;
648 p_short_circuit_charge_low =
649 10 / 3 * (pow(((vdd - vt) - vt_to_vdd_ratio), 3.0) /
650 pow(velocity_index, 2.0) / pow(2.0, 3 * vt_to_vdd_ratio *
651 vt_to_vdd_ratio)) * c_in *
652 vdd * vdd * fo_n * fo_n / fanout * beta_ratio;
752// double t1, t2, t3, t4, t5;
753// t1=pow(((vdd-vt)-vt_to_vdd_ratio),3);
754// t2=pow(velocity_index,2.0);
755// t3=pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio);
756// t4=t1/t2/t3;
757// cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl;
758
653// double t1, t2, t3, t4, t5;
654// t1=pow(((vdd-vt)-vt_to_vdd_ratio),3);
655// t2=pow(velocity_index,2.0);
656// t3=pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio);
657// t4=t1/t2/t3;
658// cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl;
659
759 p_short_circuit_discharge_high = pow(((vdd-vt)-vt_to_vdd_ratio),1.5)*c_in*vdd*vdd*fo_p/10/pow(2, 3*vt_to_vdd_ratio+2*velocity_index);
760 p_short_circuit_charge_high = pow(((vdd-vt)-vt_to_vdd_ratio),1.5)*c_in*vdd*vdd*fo_n/10/pow(2, 3*vt_to_vdd_ratio+2*velocity_index);
660 p_short_circuit_discharge_high =
661 pow(((vdd - vt) - vt_to_vdd_ratio), 1.5) * c_in * vdd * vdd *
662 fo_p / 10 / pow(2, 3 * vt_to_vdd_ratio + 2 * velocity_index);
663 p_short_circuit_charge_high = pow(((vdd - vt) - vt_to_vdd_ratio), 1.5) *
664 c_in * vdd * vdd * fo_n / 10 / pow(2, 3 * vt_to_vdd_ratio + 2 *
665 velocity_index);
761
762// t1=pow(((vdd-vt)-vt_to_vdd_ratio),1.5);
763// t2=pow(2, 3*vt_to_vdd_ratio+2*velocity_index);
764// t3=t1/t2;
765// cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl;
766// p_short_circuit_discharge = 1.0/(1.0/p_short_circuit_discharge_low + 1.0/p_short_circuit_discharge_high);
767// p_short_circuit_charge = 1/(1/p_short_circuit_charge_low + 1/p_short_circuit_charge_high); //harmmoic mean cannot be applied simple formulas.
768
666
667// t1=pow(((vdd-vt)-vt_to_vdd_ratio),1.5);
668// t2=pow(2, 3*vt_to_vdd_ratio+2*velocity_index);
669// t3=t1/t2;
670// cout <<t1<<"t1\n"<<t2<<"t2\n"<<t3<<"t3\n"<<t4<<"t4\n"<<fanout<<endl;
671// p_short_circuit_discharge = 1.0/(1.0/p_short_circuit_discharge_low + 1.0/p_short_circuit_discharge_high);
672// p_short_circuit_charge = 1/(1/p_short_circuit_charge_low + 1/p_short_circuit_charge_high); //harmmoic mean cannot be applied simple formulas.
673
769 p_short_circuit_discharge = p_short_circuit_discharge_low;
770 p_short_circuit_charge = p_short_circuit_charge_low;
771 p_short_circuit = (p_short_circuit_discharge + p_short_circuit_charge)/2;
674 p_short_circuit_discharge = p_short_circuit_discharge_low;
675 p_short_circuit_charge = p_short_circuit_charge_low;
676 p_short_circuit = (p_short_circuit_discharge + p_short_circuit_charge) / 2;
772
677
773 return (p_short_circuit);
678 return (p_short_circuit);
774}
775
776double shortcircuit(
777 double vt,
778 double velocity_index,
779 double c_in,
780 double c_out,
781 double w_nmos,
782 double w_pmos,
783 double i_on_n,
784 double i_on_p,
785 double i_on_n_in,
786 double i_on_p_in,
679}
680
681double shortcircuit(
682 double vt,
683 double velocity_index,
684 double c_in,
685 double c_out,
686 double w_nmos,
687 double w_pmos,
688 double i_on_n,
689 double i_on_p,
690 double i_on_n_in,
691 double i_on_p_in,
787 double vdd)
788{
692 double vdd) {
789
693
790 double p_short_circuit=0, p_short_circuit_discharge;//, p_short_circuit_charge, p_short_circuit_discharge_low, p_short_circuit_discharge_high, p_short_circuit_charge_low, p_short_circuit_charge_high; //this is actually energy
791 double fo_n, fo_p, fanout, beta_ratio, vt_to_vdd_ratio;
792 double f_alpha, k_v, e, g_v_alpha, h_v_alpha;
694 //this is actually energy
695 double p_short_circuit = 0, p_short_circuit_discharge;
696 double fo_n, fo_p, fanout, beta_ratio, vt_to_vdd_ratio;
697 double f_alpha, k_v, e, g_v_alpha, h_v_alpha;
793
698
794 fo_n = i_on_n/i_on_n_in;
795 fo_p = i_on_p/i_on_p_in;
796 fanout = 1;
797 beta_ratio = i_on_p/i_on_n;
798 vt_to_vdd_ratio = vt/vdd;
799 e = 2.71828;
800 f_alpha = 1/(velocity_index+2) -velocity_index/(2*(velocity_index+3)) +velocity_index/(velocity_index+4)*(velocity_index/2-1);
801 k_v = 0.9/0.8+(vdd-vt)/0.8*log(10*(vdd-vt)/e);
802 g_v_alpha = (velocity_index + 1)*pow((1-velocity_index),velocity_index)*pow((1-velocity_index),velocity_index/2)/f_alpha/pow((1-velocity_index-velocity_index),(velocity_index/2+velocity_index+2));
803 h_v_alpha = pow(2, velocity_index)*(velocity_index+1)*pow((1-velocity_index),velocity_index)/pow((1-velocity_index-velocity_index),(velocity_index+1));
699 fo_n = i_on_n / i_on_n_in;
700 fo_p = i_on_p / i_on_p_in;
701 fanout = 1;
702 beta_ratio = i_on_p / i_on_n;
703 vt_to_vdd_ratio = vt / vdd;
704 e = 2.71828;
705 f_alpha = 1 / (velocity_index + 2) - velocity_index /
706 (2 * (velocity_index + 3)) + velocity_index / (velocity_index + 4) *
707 (velocity_index / 2 - 1);
708 k_v = 0.9 / 0.8 + (vdd - vt) / 0.8 * log(10 * (vdd - vt) / e);
709 g_v_alpha = (velocity_index + 1) *
710 pow((1 - velocity_index), velocity_index) *
711 pow((1 - velocity_index), velocity_index / 2) / f_alpha /
712 pow((1 - velocity_index - velocity_index),
713 (velocity_index / 2 + velocity_index + 2));
714 h_v_alpha = pow(2, velocity_index) * (velocity_index + 1) *
715 pow((1 - velocity_index), velocity_index) /
716 pow((1 - velocity_index - velocity_index), (velocity_index + 1));
804
717
805 //p_short_circuit_discharge_low = 10/3*(pow(0.5-vt_to_vdd_ratio,3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_p*fo_p/fanout/beta_ratio;
718 //p_short_circuit_discharge_low = 10/3*(pow(0.5-vt_to_vdd_ratio,3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_p*fo_p/fanout/beta_ratio;
806// p_short_circuit_discharge_low = 10/3*(pow(((vdd-vt)-vt_to_vdd_ratio),3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_p*fo_p/fanout/beta_ratio;
807// p_short_circuit_charge_low = 10/3*(pow(((vdd-vt)-vt_to_vdd_ratio),3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_n*fo_n/fanout*beta_ratio;
808// double t1, t2, t3, t4, t5;
809// t1=pow(((vdd-vt)-vt_to_vdd_ratio),3);
810// t2=pow(velocity_index,2.0);
811// t3=pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio);
812// t4=t1/t2/t3;
813//

--- 5 unchanged lines hidden (view full) ---

819//
820// p_short_circuit_discharge = 1.0/(1.0/p_short_circuit_discharge_low + 1.0/p_short_circuit_discharge_high);
821// p_short_circuit_charge = 1/(1/p_short_circuit_charge_low + 1/p_short_circuit_charge_high);
822//
823// p_short_circuit = (p_short_circuit_discharge + p_short_circuit_charge)/2;
824//
825// p_short_circuit = p_short_circuit_discharge;
826
719// p_short_circuit_discharge_low = 10/3*(pow(((vdd-vt)-vt_to_vdd_ratio),3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_p*fo_p/fanout/beta_ratio;
720// p_short_circuit_charge_low = 10/3*(pow(((vdd-vt)-vt_to_vdd_ratio),3.0)/pow(velocity_index,2.0)/pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio))*c_in*vdd*vdd*fo_n*fo_n/fanout*beta_ratio;
721// double t1, t2, t3, t4, t5;
722// t1=pow(((vdd-vt)-vt_to_vdd_ratio),3);
723// t2=pow(velocity_index,2.0);
724// t3=pow(2.0,3*vt_to_vdd_ratio*vt_to_vdd_ratio);
725// t4=t1/t2/t3;
726//

--- 5 unchanged lines hidden (view full) ---

732//
733// p_short_circuit_discharge = 1.0/(1.0/p_short_circuit_discharge_low + 1.0/p_short_circuit_discharge_high);
734// p_short_circuit_charge = 1/(1/p_short_circuit_charge_low + 1/p_short_circuit_charge_high);
735//
736// p_short_circuit = (p_short_circuit_discharge + p_short_circuit_charge)/2;
737//
738// p_short_circuit = p_short_circuit_discharge;
739
827 p_short_circuit_discharge = k_v*vdd*vdd*c_in*fo_p*fo_p/((vdd-vt)*g_v_alpha*fanout*beta_ratio/2/k_v + h_v_alpha*fo_p);
828 return (p_short_circuit);
740 p_short_circuit_discharge = k_v * vdd * vdd * c_in * fo_p * fo_p /
741 ((vdd - vt) * g_v_alpha * fanout * beta_ratio / 2 / k_v + h_v_alpha *
742 fo_p);
743 return (p_short_circuit);
829}
744}