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