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

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

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

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

21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 ***************************************************************************/
31
32#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
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);
65}
66
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;
75
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;
79
80
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;
91
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 }
98
104
99 wire_spacing = wire_width;
105 wire_spacing = wire_width;
100
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) */;
103
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;
108
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);
112}
113
114
115
118}
119
120
121
116Wire::~Wire()
117{
122Wire::~Wire() {
118}
119
120
121
122void
123}
124
125
126
127void
123Wire::calculate_wire_stats()
124{
128Wire::calculate_wire_stats() {
125
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 }
135
137
136 wire_spacing = wire_width;
138 wire_spacing = wire_width;
137
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) */;
140
141
142
143
142 if (wt != Low_swing) {
144 if (wt != Low_swing) {
143
145
144 // delay_optimal_wire();
146 // delay_optimal_wire();
145
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 }
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 */
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
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
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;
242}
243
244
245
245}
246
247
248
246double Wire::signal_rise_time ()
247{
249double Wire::signal_rise_time () {
248
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;
254
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
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
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;
291
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 }
322
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 */
333
334// capacitance between wires in the same level
335// sidewall = 2*miller_value * horiz_dielectric_constant * (wire_height/wire_spacing)
336// * epsilon0;
337
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;
340
341
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;
345
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
348
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
351
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)
358}
359
360
362}
363
364
361 double
362Wire::wire_res (double len /*(in m)*/)
363{
365double
366Wire::wire_res (double len /*(in m)*/) {
364
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!
368
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)));
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 */
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();
403
404
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;
406
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);
420
421#define RES_ADJ (8.6) // Increase in resistance due to low driving vol.
422
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);
425
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_);
428
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 }
433
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);
443
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);
450
454
451 double timeconst = res_eq * cap_eq;
455 double timeconst = res_eq * cap_eq;
452
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;
456
460
457 inputrise = delay / (deviceType->Vdd - deviceType->Vth); /* for the next stage */
461 inputrise = delay / (deviceType->Vdd - deviceType->Vth); /* for the next stage */
458
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;
469
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;
473
474
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));
480
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));
484
489
485 inputrise = delay / deviceType->Vth;
490 inputrise = delay / deviceType->Vth;
486
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();
501
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);
508#define VOL_SWING .1
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 */
511
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));
516
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));
519
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;
522
528
523 delay += g_tp.sense_delay;
529 delay += g_tp.sense_delay;
524
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;
530
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;
538}
539
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);
547}
548
549
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);
560
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
569
573
570 // wire cap /m
571 double wc = wire_cap(len);
574 // wire cap /m
575 double wc = wire_cap(len);
572
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));
575
580
576 // calc the optimum spacing between the repeaters (m)
581 // calc the optimum spacing between the repeaters (m)
577
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;
581
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;
584
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;
589
595
590 delay = 0.693 * tc * len/repeater_spacing;
596 delay = 0.693 * tc * len / repeater_spacing;
591
592#define Ishort_ckt 65e-6 /* across all tech Ref:Banerjee et al. {IEEE TED} */
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;
595
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));
606}
607
608
609
610// calculate power/delay values for wires with suboptimal repeater sizing/spacing
611void
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();
615 double sp, si;
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
620
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 }
632// cout << "Repeater size - "<< i <<
633// " Repeater spacing - " << j <<
634// " Delay - " << del <<
635// " PowerD - " << pow.readOp.dynamic <<
636// " PowerL - " << pow.readOp.leakage <<endl;
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());
642
655
656 }
643 }
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;
651}
652
653
654
664}
665
666
667
655void Wire::update_fullswing()
656{
668void Wire::update_fullswing() {
657
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 }
703 }
713 }
704 }
714 i--;
705 }
715 }
706 i--;
707 }
708}
709
710
711
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);
727
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
736
743
737 // wire cap /m
738 double wc = wire_cap(len);
744 // wire cap /m
745 double wc = wire_cap(len);
739
746
740 repeater_spacing = space;
741 repeater_size = size;
747 repeater_spacing = space;
748 repeater_size = size;
742
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;
745
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;
750
758
751 *delay = 0.693 * tc * len/repeater_spacing;
759 *delay = 0.693 * tc * len / repeater_spacing;
752
753#define Ishort_ckt 65e-6 /* across all tech Ref:Banerjee et al. {IEEE TED} */
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;
756
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));
761
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));
765
779
766 return ptemp;
780 return ptemp;
767}
768
769void
781}
782
783void
770Wire::print_wire()
771{
784Wire::print_wire() {
772
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;
783
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;
830
831}
832
852
853}
854