component.cc (10152:52c552138ba1) | component.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 33 34 35#include <cassert> 36#include <cmath> 37#include <iostream> 38 39#include "bank.h" 40#include "component.h" 41#include "decoder.h" 42 43using namespace std; 44 45 46 47Component::Component() | 30 * 31 ***************************************************************************/ 32 33 34 35 36#include <cassert> 37#include <cmath> 38#include <iostream> 39 40#include "bank.h" 41#include "component.h" 42#include "decoder.h" 43 44using namespace std; 45 46 47 48Component::Component() |
48 :area(), power(), rt_power(),delay(0) 49{ | 49 : area(), power(), rt_power(), delay(0) { |
50} 51 52 53 | 50} 51 52 53 |
54Component::~Component() 55{ | 54Component::~Component() { |
56} 57 58 59 | 55} 56 57 58 |
60double Component::compute_diffusion_width(int num_stacked_in, int num_folded_tr) 61{ 62 double w_poly = g_ip->F_sz_um; 63 double spacing_poly_to_poly = g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact; 64 double total_diff_w = 2 * spacing_poly_to_poly + // for both source and drain 65 num_stacked_in * w_poly + 66 (num_stacked_in - 1) * g_tp.spacing_poly_to_poly; | 59double Component::compute_diffusion_width(int num_stacked_in, int num_folded_tr) { 60 double w_poly = g_ip->F_sz_um; 61 double spacing_poly_to_poly = g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact; 62 double total_diff_w = 2 * spacing_poly_to_poly + // for both source and drain 63 num_stacked_in * w_poly + 64 (num_stacked_in - 1) * g_tp.spacing_poly_to_poly; |
67 | 65 |
68 if (num_folded_tr > 1) 69 { 70 total_diff_w += (num_folded_tr - 2) * 2 * spacing_poly_to_poly + 71 (num_folded_tr - 1) * num_stacked_in * w_poly + 72 (num_folded_tr - 1) * (num_stacked_in - 1) * g_tp.spacing_poly_to_poly; 73 } | 66 if (num_folded_tr > 1) { 67 total_diff_w += (num_folded_tr - 2) * 2 * spacing_poly_to_poly + 68 (num_folded_tr - 1) * num_stacked_in * w_poly + 69 (num_folded_tr - 1) * (num_stacked_in - 1) * g_tp.spacing_poly_to_poly; 70 } |
74 | 71 |
75 return total_diff_w; | 72 return total_diff_w; |
76} 77 78 79 80double Component::compute_gate_area( 81 int gate_type, 82 int num_inputs, 83 double w_pmos, 84 double w_nmos, | 73} 74 75 76 77double Component::compute_gate_area( 78 int gate_type, 79 int num_inputs, 80 double w_pmos, 81 double w_nmos, |
85 double h_gate) 86{ 87 if (w_pmos <= 0.0 || w_nmos <= 0.0) 88 { 89 return 0.0; 90 } | 82 double h_gate) { 83 if (w_pmos <= 0.0 || w_nmos <= 0.0) { 84 return 0.0; 85 } |
91 | 86 |
92 double w_folded_pmos, w_folded_nmos; 93 int num_folded_pmos, num_folded_nmos; 94 double total_ndiff_w, total_pdiff_w; 95 Area gate; | 87 double w_folded_pmos, w_folded_nmos; 88 int num_folded_pmos, num_folded_nmos; 89 double total_ndiff_w, total_pdiff_w; 90 Area gate; |
96 | 91 |
97 double h_tr_region = h_gate - 2 * g_tp.HPOWERRAIL; 98 double ratio_p_to_n = w_pmos / (w_pmos + w_nmos); | 92 double h_tr_region = h_gate - 2 * g_tp.HPOWERRAIL; 93 double ratio_p_to_n = w_pmos / (w_pmos + w_nmos); |
99 | 94 |
100 if (ratio_p_to_n >= 1 || ratio_p_to_n <= 0) 101 { 102 return 0.0; 103 } | 95 if (ratio_p_to_n >= 1 || ratio_p_to_n <= 0) { 96 return 0.0; 97 } |
104 | 98 |
105 w_folded_pmos = (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) * ratio_p_to_n; 106 w_folded_nmos = (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) * (1 - ratio_p_to_n); 107 assert(w_folded_pmos > 0); | 99 w_folded_pmos = (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) * ratio_p_to_n; 100 w_folded_nmos = (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) * (1 - ratio_p_to_n); 101 assert(w_folded_pmos > 0); |
108 | 102 |
109 num_folded_pmos = (int) (ceil(w_pmos / w_folded_pmos)); 110 num_folded_nmos = (int) (ceil(w_nmos / w_folded_nmos)); | 103 num_folded_pmos = (int) (ceil(w_pmos / w_folded_pmos)); 104 num_folded_nmos = (int) (ceil(w_nmos / w_folded_nmos)); |
111 | 105 |
112 switch (gate_type) 113 { | 106 switch (gate_type) { |
114 case INV: | 107 case INV: |
115 total_ndiff_w = compute_diffusion_width(1, num_folded_nmos); 116 total_pdiff_w = compute_diffusion_width(1, num_folded_pmos); 117 break; | 108 total_ndiff_w = compute_diffusion_width(1, num_folded_nmos); 109 total_pdiff_w = compute_diffusion_width(1, num_folded_pmos); 110 break; |
118 119 case NOR: | 111 112 case NOR: |
120 total_ndiff_w = compute_diffusion_width(1, num_inputs * num_folded_nmos); 121 total_pdiff_w = compute_diffusion_width(num_inputs, num_folded_pmos); 122 break; | 113 total_ndiff_w = compute_diffusion_width(1, num_inputs * num_folded_nmos); 114 total_pdiff_w = compute_diffusion_width(num_inputs, num_folded_pmos); 115 break; |
123 124 case NAND: | 116 117 case NAND: |
125 total_ndiff_w = compute_diffusion_width(num_inputs, num_folded_nmos); 126 total_pdiff_w = compute_diffusion_width(1, num_inputs * num_folded_pmos); 127 break; | 118 total_ndiff_w = compute_diffusion_width(num_inputs, num_folded_nmos); 119 total_pdiff_w = compute_diffusion_width(1, num_inputs * num_folded_pmos); 120 break; |
128 default: | 121 default: |
129 cout << "Unknown gate type: " << gate_type << endl; 130 exit(1); 131 } | 122 cout << "Unknown gate type: " << gate_type << endl; 123 exit(1); 124 } |
132 | 125 |
133 gate.w = MAX(total_ndiff_w, total_pdiff_w); | 126 gate.w = MAX(total_ndiff_w, total_pdiff_w); |
134 | 127 |
135 if (w_folded_nmos > w_nmos) 136 { 137 //means that the height of the gate can 138 //be made smaller than the input height specified, so calculate the height of the gate. 139 gate.h = w_nmos + w_pmos + g_tp.MIN_GAP_BET_P_AND_N_DIFFS + 2 * g_tp.HPOWERRAIL; 140 } 141 else 142 { 143 gate.h = h_gate; 144 } 145 return gate.get_area(); | 128 if (w_folded_nmos > w_nmos) { 129 //means that the height of the gate can 130 //be made smaller than the input height specified, so calculate the height of the gate. 131 gate.h = w_nmos + w_pmos + g_tp.MIN_GAP_BET_P_AND_N_DIFFS + 2 * g_tp.HPOWERRAIL; 132 } else { 133 gate.h = h_gate; 134 } 135 return gate.get_area(); |
146} 147 148 149 150double Component::compute_tr_width_after_folding( 151 double input_width, | 136} 137 138 139 140double Component::compute_tr_width_after_folding( 141 double input_width, |
152 double threshold_folding_width) 153{//This is actually the width of the cell not the width of a device. 154//The width of a cell and the width of a device is orthogonal. 155 if (input_width <= 0) 156 { 157 return 0; 158 } | 142 double threshold_folding_width) { 143 //This is actually the width of the cell not the width of a device. 144 //The width of a cell and the width of a device is orthogonal. 145 if (input_width <= 0) { 146 return 0; 147 } |
159 | 148 |
160 int num_folded_tr = (int) (ceil(input_width / threshold_folding_width)); 161 double spacing_poly_to_poly = g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact; 162 double width_poly = g_ip->F_sz_um; 163 double total_diff_width = num_folded_tr * width_poly + (num_folded_tr + 1) * spacing_poly_to_poly; | 149 int num_folded_tr = (int) (ceil(input_width / threshold_folding_width)); 150 double spacing_poly_to_poly = g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact; 151 double width_poly = g_ip->F_sz_um; 152 double total_diff_width = num_folded_tr * width_poly + (num_folded_tr + 1) * spacing_poly_to_poly; |
164 | 153 |
165 return total_diff_width; | 154 return total_diff_width; |
166} 167 168 169 | 155} 156 157 158 |
170double Component::height_sense_amplifier(double pitch_sense_amp) 171{ 172 // compute the height occupied by all PMOS transistors 173 double h_pmos_tr = compute_tr_width_after_folding(g_tp.w_sense_p, pitch_sense_amp) * 2 + 174 compute_tr_width_after_folding(g_tp.w_iso, pitch_sense_amp) + 175 2 * g_tp.MIN_GAP_BET_SAME_TYPE_DIFFS; | 159double Component::height_sense_amplifier(double pitch_sense_amp) { 160 // compute the height occupied by all PMOS transistors 161 double h_pmos_tr = compute_tr_width_after_folding(g_tp.w_sense_p, pitch_sense_amp) * 2 + 162 compute_tr_width_after_folding(g_tp.w_iso, pitch_sense_amp) + 163 2 * g_tp.MIN_GAP_BET_SAME_TYPE_DIFFS; |
176 | 164 |
177 // compute the height occupied by all NMOS transistors 178 double h_nmos_tr = compute_tr_width_after_folding(g_tp.w_sense_n, pitch_sense_amp) * 2 + 179 compute_tr_width_after_folding(g_tp.w_sense_en, pitch_sense_amp) + 180 2 * g_tp.MIN_GAP_BET_SAME_TYPE_DIFFS; | 165 // compute the height occupied by all NMOS transistors 166 double h_nmos_tr = compute_tr_width_after_folding(g_tp.w_sense_n, pitch_sense_amp) * 2 + 167 compute_tr_width_after_folding(g_tp.w_sense_en, pitch_sense_amp) + 168 2 * g_tp.MIN_GAP_BET_SAME_TYPE_DIFFS; |
181 | 169 |
182 // compute total height by considering gap between the p and n diffusion areas 183 return h_pmos_tr + h_nmos_tr + g_tp.MIN_GAP_BET_P_AND_N_DIFFS; | 170 // compute total height by considering gap between the p and n diffusion areas 171 return h_pmos_tr + h_nmos_tr + g_tp.MIN_GAP_BET_P_AND_N_DIFFS; |
184} 185 186 187 188int Component::logical_effort( 189 int num_gates_min, 190 double g, 191 double F, 192 double * w_n, 193 double * w_p, 194 double C_load, 195 double p_to_n_sz_ratio, 196 bool is_dram_, 197 bool is_wl_tr_, | 172} 173 174 175 176int Component::logical_effort( 177 int num_gates_min, 178 double g, 179 double F, 180 double * w_n, 181 double * w_p, 182 double C_load, 183 double p_to_n_sz_ratio, 184 bool is_dram_, 185 bool is_wl_tr_, |
198 double max_w_nmos) 199{ 200 int num_gates = (int) (log(F) / log(fopt)); | 186 double max_w_nmos) { 187 int num_gates = (int) (log(F) / log(fopt)); |
201 | 188 |
202 // check if num_gates is odd. if so, add 1 to make it even 203 num_gates+= (num_gates % 2) ? 1 : 0; 204 num_gates = MAX(num_gates, num_gates_min); 205 206 // recalculate the effective fanout of each stage 207 double f = pow(F, 1.0 / num_gates); 208 int i = num_gates - 1; 209 double C_in = C_load / f; 210 w_n[i] = (1.0 / (1.0 + p_to_n_sz_ratio)) * C_in / gate_C(1, 0, is_dram_, false, is_wl_tr_); 211 w_n[i] = MAX(w_n[i], g_tp.min_w_nmos_); 212 w_p[i] = p_to_n_sz_ratio * w_n[i]; 213 214 if (w_n[i] > max_w_nmos) 215 { 216 double C_ld = gate_C((1 + p_to_n_sz_ratio) * max_w_nmos, 0, is_dram_, false, is_wl_tr_); 217 F = g * C_ld / gate_C(w_n[0] + w_p[0], 0, is_dram_, false, is_wl_tr_); 218 num_gates = (int) (log(F) / log(fopt)) + 1; 219 num_gates+= (num_gates % 2) ? 1 : 0; | 189 // check if num_gates is odd. if so, add 1 to make it even 190 num_gates += (num_gates % 2) ? 1 : 0; |
220 num_gates = MAX(num_gates, num_gates_min); | 191 num_gates = MAX(num_gates, num_gates_min); |
221 f = pow(F, 1.0 / (num_gates - 1)); 222 i = num_gates - 1; 223 w_n[i] = max_w_nmos; | 192 193 // recalculate the effective fanout of each stage 194 double f = pow(F, 1.0 / num_gates); 195 int i = num_gates - 1; 196 double C_in = C_load / f; 197 w_n[i] = (1.0 / (1.0 + p_to_n_sz_ratio)) * C_in / gate_C(1, 0, is_dram_, false, is_wl_tr_); 198 w_n[i] = MAX(w_n[i], g_tp.min_w_nmos_); |
224 w_p[i] = p_to_n_sz_ratio * w_n[i]; | 199 w_p[i] = p_to_n_sz_ratio * w_n[i]; |
225 } | |
226 | 200 |
227 for (i = num_gates - 2; i >= 1; i--) 228 { 229 w_n[i] = MAX(w_n[i+1] / f, g_tp.min_w_nmos_); 230 w_p[i] = p_to_n_sz_ratio * w_n[i]; 231 } | 201 if (w_n[i] > max_w_nmos) { 202 double C_ld = gate_C((1 + p_to_n_sz_ratio) * max_w_nmos, 0, is_dram_, false, is_wl_tr_); 203 F = g * C_ld / gate_C(w_n[0] + w_p[0], 0, is_dram_, false, is_wl_tr_); 204 num_gates = (int) (log(F) / log(fopt)) + 1; 205 num_gates += (num_gates % 2) ? 1 : 0; 206 num_gates = MAX(num_gates, num_gates_min); 207 f = pow(F, 1.0 / (num_gates - 1)); 208 i = num_gates - 1; 209 w_n[i] = max_w_nmos; 210 w_p[i] = p_to_n_sz_ratio * w_n[i]; 211 } |
232 | 212 |
233 assert(num_gates <= MAX_NUMBER_GATES_STAGE); 234 return num_gates; | 213 for (i = num_gates - 2; i >= 1; i--) { 214 w_n[i] = MAX(w_n[i+1] / f, g_tp.min_w_nmos_); 215 w_p[i] = p_to_n_sz_ratio * w_n[i]; 216 } 217 218 assert(num_gates <= MAX_NUMBER_GATES_STAGE); 219 return num_gates; |
235} 236 | 220} 221 |