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 13 * documentation and/or other materials provided with the distribution; 14 * neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
| 6 * All Rights Reserved 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are 10 * met: redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer; 12 * redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution; 15 * neither the name of the copyright holders nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.”
| 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
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
|