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 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 |