Deleted Added
sdiff udiff text old ( 10152:52c552138ba1 ) new ( 10234:5cb711fa6176 )
full compact
1/*****************************************************************************
2 * McPAT/CACTI
3 * SOFTWARE LICENSE AGREEMENT
4 * Copyright 2012 Hewlett-Packard Development Company, L.P.
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
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 ***************************************************************************/
31
32#include "wire.h"
33#include "cmath"
34// use this constructor to calculate wire stats
35Wire::Wire(
36 enum Wire_type wire_model,
37 double wl,
38 int n,
39 double w_s,
40 double s_s,
41 enum Wire_placement wp,
42 double resistivity,
43 TechnologyParameter::DeviceType *dt
44 ):wt(wire_model), wire_length(wl*1e-6), nsense(n), w_scale(w_s), s_scale(s_s),
45 resistivity(resistivity), deviceType(dt)
46{
47 wire_placement = wp;
48 min_w_pmos = deviceType->n_to_p_eff_curr_drv_ratio*g_tp.min_w_nmos_;
49 in_rise_time = 0;
50 out_rise_time = 0;
51 if (initialized != 1) {
52 cout << "Wire not initialized. Initializing it with default values\n";
53 Wire winit;
54 }
55 calculate_wire_stats();
56 // change everything back to seconds, microns, and Joules
57 repeater_spacing *= 1e6;
58 wire_length *= 1e6;
59 wire_width *= 1e6;
60 wire_spacing *= 1e6;
61 assert(wire_length > 0);
62 assert(power.readOp.dynamic > 0);
63 assert(power.readOp.leakage > 0);
64 assert(power.readOp.gate_leakage > 0);
65}
66
67 // the following values are for peripheral global technology
68 // specified in the input config file
69 Component Wire::global;
70 Component Wire::global_5;
71 Component Wire::global_10;
72 Component Wire::global_20;
73 Component Wire::global_30;
74 Component Wire::low_swing;
75
76 int Wire::initialized;
77 double Wire::wire_width_init;
78 double Wire::wire_spacing_init;
79
80
81Wire::Wire(double w_s, double s_s, enum Wire_placement wp, double resis, TechnologyParameter::DeviceType *dt)
82{
83 w_scale = w_s;
84 s_scale = s_s;
85 deviceType = dt;
86 wire_placement = wp;
87 resistivity = resis;
88 min_w_pmos = deviceType->n_to_p_eff_curr_drv_ratio * g_tp.min_w_nmos_;
89 in_rise_time = 0;
90 out_rise_time = 0;
91
92 switch (wire_placement)
93 {
94 case outside_mat: wire_width = g_tp.wire_outside_mat.pitch; break;
95 case inside_mat : wire_width = g_tp.wire_inside_mat.pitch; break;
96 default: wire_width = g_tp.wire_local.pitch; break;
97 }
98
99 wire_spacing = wire_width;
100
101 wire_width *= (w_scale * 1e-6/2) /* (m) */;
102 wire_spacing *= (s_scale * 1e-6/2) /* (m) */;
103
104 initialized = 1;
105 init_wire();
106 wire_width_init = wire_width;
107 wire_spacing_init = wire_spacing;
108
109 assert(power.readOp.dynamic > 0);
110 assert(power.readOp.leakage > 0);
111 assert(power.readOp.gate_leakage > 0);
112}
113
114
115
116Wire::~Wire()
117{
118}
119
120
121
122void
123Wire::calculate_wire_stats()
124{
125
126 if (wire_placement == outside_mat) {
127 wire_width = g_tp.wire_outside_mat.pitch;
128 }
129 else if (wire_placement == inside_mat) {
130 wire_width = g_tp.wire_inside_mat.pitch;
131 }
132 else {
133 wire_width = g_tp.wire_local.pitch;
134 }
135
136 wire_spacing = wire_width;
137
138 wire_width *= (w_scale * 1e-6/2) /* (m) */;
139 wire_spacing *= (s_scale * 1e-6/2) /* (m) */;
140
141
142 if (wt != Low_swing) {
143
144 // delay_optimal_wire();
145
146 if (wt == Global) {
147 delay = global.delay * wire_length;
148 power.readOp.dynamic = global.power.readOp.dynamic * wire_length;
149 power.readOp.leakage = global.power.readOp.leakage * wire_length;
150 power.readOp.gate_leakage = global.power.readOp.gate_leakage * wire_length;
151 repeater_spacing = global.area.w;
152 repeater_size = global.area.h;
153 area.set_area((wire_length/repeater_spacing) *
154 compute_gate_area(INV, 1, min_w_pmos * repeater_size,
155 g_tp.min_w_nmos_ * repeater_size, g_tp.cell_h_def));
156 }
157 else if (wt == Global_5) {
158 delay = global_5.delay * wire_length;
159 power.readOp.dynamic = global_5.power.readOp.dynamic * wire_length;
160 power.readOp.leakage = global_5.power.readOp.leakage * wire_length;
161 power.readOp.gate_leakage = global_5.power.readOp.gate_leakage * wire_length;
162 repeater_spacing = global_5.area.w;
163 repeater_size = global_5.area.h;
164 area.set_area((wire_length/repeater_spacing) *
165 compute_gate_area(INV, 1, min_w_pmos * repeater_size,
166 g_tp.min_w_nmos_ * repeater_size, g_tp.cell_h_def));
167 }
168 else if (wt == Global_10) {
169 delay = global_10.delay * wire_length;
170 power.readOp.dynamic = global_10.power.readOp.dynamic * wire_length;
171 power.readOp.leakage = global_10.power.readOp.leakage * wire_length;
172 power.readOp.gate_leakage = global_10.power.readOp.gate_leakage * wire_length;
173 repeater_spacing = global_10.area.w;
174 repeater_size = global_10.area.h;
175 area.set_area((wire_length/repeater_spacing) *
176 compute_gate_area(INV, 1, min_w_pmos * repeater_size,
177 g_tp.min_w_nmos_ * repeater_size, g_tp.cell_h_def));
178 }
179 else if (wt == Global_20) {
180 delay = global_20.delay * wire_length;
181 power.readOp.dynamic = global_20.power.readOp.dynamic * wire_length;
182 power.readOp.leakage = global_20.power.readOp.leakage * wire_length;
183 power.readOp.gate_leakage = global_20.power.readOp.gate_leakage * wire_length;
184 repeater_spacing = global_20.area.w;
185 repeater_size = global_20.area.h;
186 area.set_area((wire_length/repeater_spacing) *
187 compute_gate_area(INV, 1, min_w_pmos * repeater_size,
188 g_tp.min_w_nmos_ * repeater_size, g_tp.cell_h_def));
189 }
190 else if (wt == Global_30) {
191 delay = global_30.delay * wire_length;
192 power.readOp.dynamic = global_30.power.readOp.dynamic * wire_length;
193 power.readOp.leakage = global_30.power.readOp.leakage * wire_length;
194 power.readOp.gate_leakage = global_30.power.readOp.gate_leakage * wire_length;
195 repeater_spacing = global_30.area.w;
196 repeater_size = global_30.area.h;
197 area.set_area((wire_length/repeater_spacing) *
198 compute_gate_area(INV, 1, min_w_pmos * repeater_size,
199 g_tp.min_w_nmos_ * repeater_size, g_tp.cell_h_def));
200 }
201 out_rise_time = delay*repeater_spacing/deviceType->Vth;
202 }
203 else if (wt == Low_swing) {
204 low_swing_model ();
205 repeater_spacing = wire_length;
206 repeater_size = 1;
207 }
208 else {
209 assert(0);
210 }
211}
212
213
214
215/*
216 * The fall time of an input signal to the first stage of a circuit is
217 * assumed to be same as the fall time of the output signal of two
218 * inverters connected in series (refer: CACTI 1 Technical report,
219 * section 6.1.3)
220 */
221 double
222Wire::signal_fall_time ()
223{
224
225 /* rise time of inverter 1's output */
226 double rt;
227 /* fall time of inverter 2's output */
228 double ft;
229 double timeconst;
230
231 timeconst = (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) +
232 drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
233 gate_C(min_w_pmos + g_tp.min_w_nmos_, 0)) *
234 tr_R_on(min_w_pmos, PCH, 1);
235 rt = horowitz (0, timeconst, deviceType->Vth/deviceType->Vdd, deviceType->Vth/deviceType->Vdd, FALL) / (deviceType->Vdd - deviceType->Vth);
236 timeconst = (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) +
237 drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
238 gate_C(min_w_pmos + g_tp.min_w_nmos_, 0)) *
239 tr_R_on(g_tp.min_w_nmos_, NCH, 1);
240 ft = horowitz (rt, timeconst, deviceType->Vth/deviceType->Vdd, deviceType->Vth/deviceType->Vdd, RISE) / deviceType->Vth;
241 return ft;
242}
243
244
245
246double Wire::signal_rise_time ()
247{
248
249 /* rise time of inverter 1's output */
250 double ft;
251 /* fall time of inverter 2's output */
252 double rt;
253 double timeconst;
254
255 timeconst = (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) +
256 drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
257 gate_C(min_w_pmos + g_tp.min_w_nmos_, 0)) *
258 tr_R_on(g_tp.min_w_nmos_, NCH, 1);
259 rt = horowitz (0, timeconst, deviceType->Vth/deviceType->Vdd, deviceType->Vth/deviceType->Vdd, RISE) / deviceType->Vth;
260 timeconst = (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) +
261 drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
262 gate_C(min_w_pmos + g_tp.min_w_nmos_, 0)) *
263 tr_R_on(min_w_pmos, PCH, 1);
264 ft = horowitz (rt, timeconst, deviceType->Vth/deviceType->Vdd, deviceType->Vth/deviceType->Vdd, FALL) / (deviceType->Vdd - deviceType->Vth);
265 return ft; //sec
266}
267
268
269
270/* Wire resistance and capacitance calculations
271 * wire width
272 *
273 * /__/
274 * | |
275 * | | height = ASPECT_RATIO*wire width (ASPECT_RATIO = 2.2, ref: ITRS)
276 * |__|/
277 *
278 * spacing between wires in same level = wire width
279 * spacing between wires in adjacent levels = wire width---this is incorrect,
280 * according to R.Ho's paper and thesis. ILD != wire width
281 *
282 */
283
284double Wire::wire_cap (double len /* in m */, bool call_from_outside)
285{
286 //TODO: this should be consistent with the wire_res in technology file
287 double sidewall, adj, tot_cap;
288 double wire_height;
289 double epsilon0 = 8.8542e-12;
290 double aspect_ratio, horiz_dielectric_constant, vert_dielectric_constant, miller_value,ild_thickness;
291
292 switch (wire_placement)
293 {
294 case outside_mat:
295 {
296 aspect_ratio = g_tp.wire_outside_mat.aspect_ratio;
297 horiz_dielectric_constant = g_tp.wire_outside_mat.horiz_dielectric_constant;
298 vert_dielectric_constant = g_tp.wire_outside_mat.vert_dielectric_constant;
299 miller_value = g_tp.wire_outside_mat.miller_value;
300 ild_thickness = g_tp.wire_outside_mat.ild_thickness;
301 break;
302 }
303 case inside_mat :
304 {
305 aspect_ratio = g_tp.wire_inside_mat.aspect_ratio;
306 horiz_dielectric_constant = g_tp.wire_inside_mat.horiz_dielectric_constant;
307 vert_dielectric_constant = g_tp.wire_inside_mat.vert_dielectric_constant;
308 miller_value = g_tp.wire_inside_mat.miller_value;
309 ild_thickness = g_tp.wire_inside_mat.ild_thickness;
310 break;
311 }
312 default:
313 {
314 aspect_ratio = g_tp.wire_local.aspect_ratio;
315 horiz_dielectric_constant = g_tp.wire_local.horiz_dielectric_constant;
316 vert_dielectric_constant = g_tp.wire_local.vert_dielectric_constant;
317 miller_value = g_tp.wire_local.miller_value;
318 ild_thickness = g_tp.wire_local.ild_thickness;
319 break;
320 }
321 }
322
323 if (call_from_outside)
324 {
325 wire_width *= 1e-6;
326 wire_spacing *= 1e-6;
327 }
328 wire_height = wire_width/w_scale*aspect_ratio;
329 /*
330 * assuming height does not change. wire_width = width_original*w_scale
331 * So wire_height does not change as wire width increases
332 */
333
334// capacitance between wires in the same level
335// sidewall = 2*miller_value * horiz_dielectric_constant * (wire_height/wire_spacing)
336// * epsilon0;
337
338 sidewall = miller_value * horiz_dielectric_constant * (wire_height/wire_spacing)
339 * epsilon0;
340
341
342 // capacitance between wires in adjacent levels
343 //adj = miller_value * vert_dielectric_constant *w_scale * epsilon0;
344 //adj = 2*vert_dielectric_constant *wire_width/(ild_thickness*1e-6) * epsilon0;
345
346 adj = miller_value *vert_dielectric_constant *wire_width/(ild_thickness*1e-6) * epsilon0;
347 //Change ild_thickness from micron to M
348
349 //tot_cap = (sidewall + adj + (deviceType->C_fringe * 1e6)); //F/m
350 tot_cap = (sidewall + adj + (g_tp.fringe_cap * 1e6)); //F/m
351
352 if (call_from_outside)
353 {
354 wire_width *= 1e6;
355 wire_spacing *= 1e6;
356 }
357 return (tot_cap*len); // (F)
358}
359
360
361 double
362Wire::wire_res (double len /*(in m)*/)
363{
364
365 double aspect_ratio,alpha_scatter =1.05, dishing_thickness=0, barrier_thickness=0;
366 //TODO: this should be consistent with the wire_res in technology file
367 //The whole computation should be consistent with the wire_res in technology.cc too!
368
369 switch (wire_placement)
370 {
371 case outside_mat:
372 {
373 aspect_ratio = g_tp.wire_outside_mat.aspect_ratio;
374 break;
375 }
376 case inside_mat :
377 {
378 aspect_ratio = g_tp.wire_inside_mat.aspect_ratio;
379 break;
380 }
381 default:
382 {
383 aspect_ratio = g_tp.wire_local.aspect_ratio;
384 break;
385 }
386 }
387 return (alpha_scatter * resistivity * 1e-6 * len/((aspect_ratio*wire_width/w_scale-dishing_thickness - barrier_thickness)*
388 (wire_width-2*barrier_thickness)));
389}
390
391/*
392 * Calculates the delay, power and area of the transmitter circuit.
393 *
394 * The transmitter delay is the sum of nand gate delay, inverter delay
395 * low swing nmos delay, and the wire delay
396 * (ref: Technical report 6)
397 */
398 void
399Wire::low_swing_model()
400{
401 double len = wire_length;
402 double beta = pmos_to_nmos_sz_ratio();
403
404
405 double inputrise = (in_rise_time == 0) ? signal_rise_time() : in_rise_time;
406
407 /* Final nmos low swing driver size calculation:
408 * Try to size the driver such that the delay
409 * is less than 8FO4.
410 * If the driver size is greater than
411 * the max allowable size, assume max size for the driver.
412 * In either case, recalculate the delay using
413 * the final driver size assuming slow input with
414 * finite rise time instead of ideal step input
415 *
416 * (ref: Technical report 6)
417 */
418 double cwire = wire_cap(len); /* load capacitance */
419 double rwire = wire_res(len);
420
421#define RES_ADJ (8.6) // Increase in resistance due to low driving vol.
422
423 double driver_res = (-8*g_tp.FO4/(log(0.5) * cwire))/RES_ADJ;
424 double nsize = R_to_w(driver_res, NCH);
425
426 nsize = MIN(nsize, g_tp.max_w_nmos_);
427 nsize = MAX(nsize, g_tp.min_w_nmos_);
428
429 if(rwire*cwire > 8*g_tp.FO4)
430 {
431 nsize = g_tp.max_w_nmos_;
432 }
433
434 // size the inverter appropriately to minimize the transmitter delay
435 // Note - In order to minimize leakage, we are not adding a set of inverters to
436 // bring down delay. Instead, we are sizing the single gate
437 // based on the logical effort.
438 double st_eff = sqrt((2+beta/1+beta)*gate_C(nsize, 0)/(gate_C(2*g_tp.min_w_nmos_, 0)
439 + gate_C(2*min_w_pmos, 0)));
440 double req_cin = ((2+beta/1+beta)*gate_C(nsize, 0))/st_eff;
441 double inv_size = req_cin/(gate_C(min_w_pmos, 0) + gate_C(g_tp.min_w_nmos_, 0));
442 inv_size = MAX(inv_size, 1);
443
444 /* nand gate delay */
445 double res_eq = (2 * tr_R_on(g_tp.min_w_nmos_, NCH, 1));
446 double cap_eq = 2 * drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
447 drain_C_(2*g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) +
448 gate_C(inv_size*g_tp.min_w_nmos_, 0) +
449 gate_C(inv_size*min_w_pmos, 0);
450
451 double timeconst = res_eq * cap_eq;
452
453 delay = horowitz(inputrise, timeconst, deviceType->Vth/deviceType->Vdd,
454 deviceType->Vth/deviceType->Vdd, RISE);
455 double temp_power = cap_eq*deviceType->Vdd*deviceType->Vdd;
456
457 inputrise = delay / (deviceType->Vdd - deviceType->Vth); /* for the next stage */
458
459 /* Inverter delay:
460 * The load capacitance of this inv depends on
461 * the gate capacitance of the final stage nmos
462 * transistor which in turn depends on nsize
463 */
464 res_eq = tr_R_on(inv_size*min_w_pmos, PCH, 1);
465 cap_eq = drain_C_(inv_size*min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
466 drain_C_(inv_size*g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) +
467 gate_C(nsize, 0);
468 timeconst = res_eq * cap_eq;
469
470 delay += horowitz(inputrise, timeconst, deviceType->Vth/deviceType->Vdd,
471 deviceType->Vth/deviceType->Vdd, FALL);
472 temp_power += cap_eq*deviceType->Vdd*deviceType->Vdd;
473
474
475 transmitter.delay = delay;
476 transmitter.power.readOp.dynamic = temp_power*2; /* since it is a diff. model*/
477 transmitter.power.readOp.leakage = deviceType->Vdd *
478 (4 * cmos_Isub_leakage(g_tp.min_w_nmos_, min_w_pmos, 2, nand) +
479 4 * cmos_Isub_leakage(g_tp.min_w_nmos_, min_w_pmos, 1, inv));
480
481 transmitter.power.readOp.gate_leakage = deviceType->Vdd *
482 (4 * cmos_Ig_leakage(g_tp.min_w_nmos_, min_w_pmos, 2, nand) +
483 4 * cmos_Ig_leakage(g_tp.min_w_nmos_, min_w_pmos, 1, inv));
484
485 inputrise = delay / deviceType->Vth;
486
487 /* nmos delay + wire delay */
488 cap_eq = cwire + drain_C_(nsize, NCH, 1, 1, g_tp.cell_h_def)*2 +
489 nsense * sense_amp_input_cap(); //+receiver cap
490 /*
491 * NOTE: nmos is used as both pull up and pull down transistor
492 * in the transmitter. This is because for low voltage swing, drive
493 * resistance of nmos is less than pmos
494 * (for a detailed graph ref: On-Chip Wires: Scaling and Efficiency)
495 */
496 timeconst = (tr_R_on(nsize, NCH, 1)*RES_ADJ) * (cwire +
497 drain_C_(nsize, NCH, 1, 1, g_tp.cell_h_def)*2) +
498 rwire*cwire/2 +
499 (tr_R_on(nsize, NCH, 1)*RES_ADJ + rwire) *
500 nsense * sense_amp_input_cap();
501
502 /*
503 * since we are pre-equalizing and overdriving the low
504 * swing wires, the net time constant is less
505 * than the actual value
506 */
507 delay += horowitz(inputrise, timeconst, deviceType->Vth/deviceType->Vdd, .25, 0);
508#define VOL_SWING .1
509 temp_power += cap_eq*VOL_SWING*.400; /* .4v is the over drive voltage */
510 temp_power *= 2; /* differential wire */
511
512 l_wire.delay = delay - transmitter.delay;
513 l_wire.power.readOp.dynamic = temp_power - transmitter.power.readOp.dynamic;
514 l_wire.power.readOp.leakage = deviceType->Vdd*
515 (4* cmos_Isub_leakage(nsize, 0, 1, nmos));
516
517 l_wire.power.readOp.gate_leakage = deviceType->Vdd*
518 (4* cmos_Ig_leakage(nsize, 0, 1, nmos));
519
520 //double rt = horowitz(inputrise, timeconst, deviceType->Vth/deviceType->Vdd,
521 // deviceType->Vth/deviceType->Vdd, RISE)/deviceType->Vth;
522
523 delay += g_tp.sense_delay;
524
525 sense_amp.delay = g_tp.sense_delay;
526 out_rise_time = g_tp.sense_delay/(deviceType->Vth);
527 sense_amp.power.readOp.dynamic = g_tp.sense_dy_power;
528 sense_amp.power.readOp.leakage = 0; //FIXME
529 sense_amp.power.readOp.gate_leakage = 0;
530
531 power.readOp.dynamic = temp_power + sense_amp.power.readOp.dynamic;
532 power.readOp.leakage = transmitter.power.readOp.leakage +
533 l_wire.power.readOp.leakage +
534 sense_amp.power.readOp.leakage;
535 power.readOp.gate_leakage = transmitter.power.readOp.gate_leakage +
536 l_wire.power.readOp.gate_leakage +
537 sense_amp.power.readOp.gate_leakage;
538}
539
540 double
541Wire::sense_amp_input_cap()
542{
543 return drain_C_(g_tp.w_iso, PCH, 1, 1, g_tp.cell_h_def) +
544 gate_C(g_tp.w_sense_en + g_tp.w_sense_n, 0) +
545 drain_C_(g_tp.w_sense_n, NCH, 1, 1, g_tp.cell_h_def) +
546 drain_C_(g_tp.w_sense_p, PCH, 1, 1, g_tp.cell_h_def);
547}
548
549
550void Wire::delay_optimal_wire ()
551{
552 double len = wire_length;
553 //double min_wire_width = wire_width; //m
554 double beta = pmos_to_nmos_sz_ratio();
555 double switching = 0; // switching energy
556 double short_ckt = 0; // short-circuit energy
557 double tc = 0; // time constant
558 // input cap of min sized driver
559 double input_cap = gate_C(g_tp.min_w_nmos_ + min_w_pmos, 0);
560
561 // output parasitic capacitance of
562 // the min. sized driver
563 double out_cap = drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
564 drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def);
565 // drive resistance
566 double out_res = (tr_R_on(g_tp.min_w_nmos_, NCH, 1) +
567 tr_R_on(min_w_pmos, PCH, 1))/2;
568 double wr = wire_res(len); //ohm
569
570 // wire cap /m
571 double wc = wire_cap(len);
572
573 // size the repeater such that the delay of the wire is minimum
574 double repeater_scaling = sqrt(out_res*wc/(wr*input_cap)); // len will cancel
575
576 // calc the optimum spacing between the repeaters (m)
577
578 repeater_spacing = sqrt(2 * out_res * (out_cap + input_cap)/
579 ((wr/len)*(wc/len)));
580 repeater_size = repeater_scaling;
581
582 switching = (repeater_scaling * (input_cap + out_cap) +
583 repeater_spacing * (wc/len)) * deviceType->Vdd * deviceType->Vdd;
584
585 tc = out_res * (input_cap + out_cap) +
586 out_res * wc/len * repeater_spacing/repeater_scaling +
587 wr/len * repeater_spacing * input_cap * repeater_scaling +
588 0.5 * (wr/len) * (wc/len)* repeater_spacing * repeater_spacing;
589
590 delay = 0.693 * tc * len/repeater_spacing;
591
592#define Ishort_ckt 65e-6 /* across all tech Ref:Banerjee et al. {IEEE TED} */
593 short_ckt = deviceType->Vdd * g_tp.min_w_nmos_ * Ishort_ckt * 1.0986 *
594 repeater_scaling * tc;
595
596 area.set_area((len/repeater_spacing) *
597 compute_gate_area(INV, 1, min_w_pmos * repeater_scaling,
598 g_tp.min_w_nmos_ * repeater_scaling, g_tp.cell_h_def));
599 power.readOp.dynamic = ((len/repeater_spacing)*(switching + short_ckt));
600 power.readOp.leakage = ((len/repeater_spacing)*
601 deviceType->Vdd*
602 cmos_Isub_leakage(g_tp.min_w_nmos_*repeater_scaling, beta*g_tp.min_w_nmos_*repeater_scaling, 1, inv));
603 power.readOp.gate_leakage = ((len/repeater_spacing)*
604 deviceType->Vdd*
605 cmos_Ig_leakage(g_tp.min_w_nmos_*repeater_scaling, beta*g_tp.min_w_nmos_*repeater_scaling, 1, inv));
606}
607
608
609
610// calculate power/delay values for wires with suboptimal repeater sizing/spacing
611void
612Wire::init_wire(){
613 wire_length = 1;
614 delay_optimal_wire();
615 double sp, si;
616 powerDef pow;
617 si = repeater_size;
618 sp = repeater_spacing;
619 sp *= 1e6; // in microns
620
621 double i, j, del;
622 repeated_wire.push_back(Component());
623 for (j=sp; j < 4*sp; j+=100) {
624 for (i = si; i > 1; i--) {
625 pow = wire_model(j*1e-6, i, &del);
626 if (j == sp && i == si) {
627 global.delay = del;
628 global.power = pow;
629 global.area.h = si;
630 global.area.w = sp*1e-6; // m
631 }
632// cout << "Repeater size - "<< i <<
633// " Repeater spacing - " << j <<
634// " Delay - " << del <<
635// " PowerD - " << pow.readOp.dynamic <<
636// " PowerL - " << pow.readOp.leakage <<endl;
637 repeated_wire.back().delay = del;
638 repeated_wire.back().power.readOp = pow.readOp;
639 repeated_wire.back().area.w = j*1e-6; //m
640 repeated_wire.back().area.h = i;
641 repeated_wire.push_back(Component());
642
643 }
644 }
645 repeated_wire.pop_back();
646 update_fullswing();
647 Wire *l_wire = new Wire(Low_swing, 0.001/* 1 mm*/, 1);
648 low_swing.delay = l_wire->delay;
649 low_swing.power = l_wire->power;
650 delete l_wire;
651}
652
653
654
655void Wire::update_fullswing()
656{
657
658 list::iterator citer;
659 double del[4];
660 del[3] = this->global.delay + this->global.delay*.3;
661 del[2] = global.delay + global.delay*.2;
662 del[1] = global.delay + global.delay*.1;
663 del[0] = global.delay + global.delay*.05;
664 double threshold;
665 double ncost;
666 double cost;
667 int i = 4;
668 while (i>0) {
669 threshold = del[i-1];
670 cost = BIGNUM;
671 for (citer = repeated_wire.begin(); citer != repeated_wire.end(); citer++)
672 {
673 if (citer->delay > threshold) {
674 citer = repeated_wire.erase(citer);
675 citer --;
676 }
677 else {
678 ncost = citer->power.readOp.dynamic/global.power.readOp.dynamic +
679 citer->power.readOp.leakage/global.power.readOp.leakage;
680 if(ncost < cost)
681 {
682 cost = ncost;
683 if (i == 4) {
684 global_30.delay = citer->delay;
685 global_30.power = citer->power;
686 global_30.area = citer->area;
687 }
688 else if (i==3) {
689 global_20.delay = citer->delay;
690 global_20.power = citer->power;
691 global_20.area = citer->area;
692 }
693 else if(i==2) {
694 global_10.delay = citer->delay;
695 global_10.power = citer->power;
696 global_10.area = citer->area;
697 }
698 else if(i==1) {
699 global_5.delay = citer->delay;
700 global_5.power = citer->power;
701 global_5.area = citer->area;
702 }
703 }
704 }
705 }
706 i--;
707 }
708}
709
710
711
712powerDef Wire::wire_model (double space, double size, double *delay)
713{
714 powerDef ptemp;
715 double len = 1;
716 //double min_wire_width = wire_width; //m
717 double beta = pmos_to_nmos_sz_ratio();
718 // switching energy
719 double switching = 0;
720 // short-circuit energy
721 double short_ckt = 0;
722 // time constant
723 double tc = 0;
724 // input cap of min sized driver
725 double input_cap = gate_C (g_tp.min_w_nmos_ +
726 min_w_pmos, 0);
727
728 // output parasitic capacitance of
729 // the min. sized driver
730 double out_cap = drain_C_(min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) +
731 drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def);
732 // drive resistance
733 double out_res = (tr_R_on(g_tp.min_w_nmos_, NCH, 1) +
734 tr_R_on(min_w_pmos, PCH, 1))/2;
735 double wr = wire_res(len); //ohm
736
737 // wire cap /m
738 double wc = wire_cap(len);
739
740 repeater_spacing = space;
741 repeater_size = size;
742
743 switching = (repeater_size * (input_cap + out_cap) +
744 repeater_spacing * (wc/len)) * deviceType->Vdd * deviceType->Vdd;
745
746 tc = out_res * (input_cap + out_cap) +
747 out_res * wc/len * repeater_spacing/repeater_size +
748 wr/len * repeater_spacing * out_cap * repeater_size +
749 0.5 * (wr/len) * (wc/len)* repeater_spacing * repeater_spacing;
750
751 *delay = 0.693 * tc * len/repeater_spacing;
752
753#define Ishort_ckt 65e-6 /* across all tech Ref:Banerjee et al. {IEEE TED} */
754 short_ckt = deviceType->Vdd * g_tp.min_w_nmos_ * Ishort_ckt * 1.0986 *
755 repeater_size * tc;
756
757 ptemp.readOp.dynamic = ((len/repeater_spacing)*(switching + short_ckt));
758 ptemp.readOp.leakage = ((len/repeater_spacing)*
759 deviceType->Vdd*
760 cmos_Isub_leakage(g_tp.min_w_nmos_*repeater_size, beta*g_tp.min_w_nmos_*repeater_size, 1, inv));
761
762 ptemp.readOp.gate_leakage = ((len/repeater_spacing)*
763 deviceType->Vdd*
764 cmos_Ig_leakage(g_tp.min_w_nmos_*repeater_size, beta*g_tp.min_w_nmos_*repeater_size, 1, inv));
765
766 return ptemp;
767}
768
769void
770Wire::print_wire()
771{
772
773 cout << "\nWire Properties:\n\n";
774 cout << " Delay Optimal\n\tRepeater size - "<< global.area.h <<
775 " \n\tRepeater spacing - " << global.area.w*1e3 << " (mm)"
776 " \n\tDelay - " << global.delay*1e6 << " (ns/mm)"
777 " \n\tPowerD - " << global.power.readOp.dynamic *1e6<< " (nJ/mm)"
778 " \n\tPowerL - " << global.power.readOp.leakage << " (mW/mm)"
779 " \n\tPowerLgate - " << global.power.readOp.gate_leakage << " (mW/mm)\n";
780 cout << "\tWire width - " <<wire_width_init*1e6 << " microns\n";
781 cout << "\tWire spacing - " <<wire_spacing_init*1e6 << " microns\n";
782 cout <<endl;
783
784 cout << " 5% Overhead\n\tRepeater size - "<< global_5.area.h <<
785 " \n\tRepeater spacing - " << global_5.area.w*1e3 << " (mm)"
786 " \n\tDelay - " << global_5.delay *1e6<< " (ns/mm)"
787 " \n\tPowerD - " << global_5.power.readOp.dynamic *1e6<< " (nJ/mm)"
788 " \n\tPowerL - " << global_5.power.readOp.leakage << " (mW/mm)"
789 " \n\tPowerLgate - " << global_5.power.readOp.gate_leakage << " (mW/mm)\n";
790 cout << "\tWire width - " <<wire_width_init*1e6 << " microns\n";
791 cout << "\tWire spacing - " <<wire_spacing_init*1e6 << " microns\n";
792 cout <<endl;
793 cout << " 10% Overhead\n\tRepeater size - "<< global_10.area.h <<
794 " \n\tRepeater spacing - " << global_10.area.w*1e3 << " (mm)"
795 " \n\tDelay - " << global_10.delay *1e6<< " (ns/mm)"
796 " \n\tPowerD - " << global_10.power.readOp.dynamic *1e6<< " (nJ/mm)"
797 " \n\tPowerL - " << global_10.power.readOp.leakage << " (mW/mm)"
798 " \n\tPowerLgate - " << global_10.power.readOp.gate_leakage << " (mW/mm)\n";
799 cout << "\tWire width - " <<wire_width_init*1e6 << " microns\n";
800 cout << "\tWire spacing - " <<wire_spacing_init*1e6 << " microns\n";
801 cout <<endl;
802 cout << " 20% Overhead\n\tRepeater size - "<< global_20.area.h <<
803 " \n\tRepeater spacing - " << global_20.area.w*1e3 << " (mm)"
804 " \n\tDelay - " << global_20.delay *1e6<< " (ns/mm)"
805 " \n\tPowerD - " << global_20.power.readOp.dynamic *1e6<< " (nJ/mm)"
806 " \n\tPowerL - " << global_20.power.readOp.leakage << " (mW/mm)"
807 " \n\tPowerLgate - " << global_20.power.readOp.gate_leakage << " (mW/mm)\n";
808 cout << "\tWire width - " <<wire_width_init*1e6 << " microns\n";
809 cout << "\tWire spacing - " <<wire_spacing_init*1e6 << " microns\n";
810 cout <<endl;
811 cout << " 30% Overhead\n\tRepeater size - "<< global_30.area.h <<
812 " \n\tRepeater spacing - " << global_30.area.w*1e3 << " (mm)"
813 " \n\tDelay - " << global_30.delay *1e6<< " (ns/mm)"
814 " \n\tPowerD - " << global_30.power.readOp.dynamic *1e6<< " (nJ/mm)"
815 " \n\tPowerL - " << global_30.power.readOp.leakage << " (mW/mm)"
816 " \n\tPowerLgate - " << global_30.power.readOp.gate_leakage << " (mW/mm)\n";
817 cout << "\tWire width - " <<wire_width_init*1e6 << " microns\n";
818 cout << "\tWire spacing - " <<wire_spacing_init*1e6 << " microns\n";
819 cout <<endl;
820 cout << " Low-swing wire (1 mm) - Note: Unlike repeated wires, \n\tdelay and power "
821 "values of low-swing wires do not\n\thave a linear relationship with length." <<
822 " \n\tdelay - " << low_swing.delay *1e9<< " (ns)"
823 " \n\tpowerD - " << low_swing.power.readOp.dynamic *1e9<< " (nJ)"
824 " \n\tPowerL - " << low_swing.power.readOp.leakage << " (mW)"
825 " \n\tPowerLgate - " << low_swing.power.readOp.gate_leakage << " (mW)\n";
826 cout << "\tWire width - " <<wire_width_init * 2 /* differential */<< " microns\n";
827 cout << "\tWire spacing - " <<wire_spacing_init * 2 /* differential */<< " microns\n";
828 cout <<endl;
829 cout <<endl;
830
831}
832