wire.cc revision 10152
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
13 * documentation and/or other materials provided with the distribution;
14 * neither the name of the copyright holders nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
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<Component>::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
833