1/* Copyright (c) 2012 Massachusetts Institute of Technology 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to deal 5 * in the Software without restriction, including without limitation the rights 6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 * copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 * THE SOFTWARE. 20 */ 21 22#include "model/std_cells/ADDF.h" 23 24#include <cmath> 25 26#include "model/PortInfo.h" 27#include "model/EventInfo.h" 28#include "model/TransitionInfo.h" 29#include "model/std_cells/StdCellLib.h" 30#include "model/std_cells/CellMacros.h" 31#include "model/timing_graph/ElectricalNet.h" 32#include "model/timing_graph/ElectricalDriver.h" 33#include "model/timing_graph/ElectricalLoad.h" 34#include "model/timing_graph/ElectricalDelay.h" 35 36namespace DSENT 37{ 38 using std::ceil; 39 using std::max; 40 41 ADDF::ADDF(const String& instance_name_, const TechModel* tech_model_) 42 : StdCell(instance_name_, tech_model_) 43 { 44 initParameters(); 45 initProperties(); 46 } 47 48 ADDF::~ADDF() 49 {} 50 51 void ADDF::initProperties() 52 { 53 return; 54 } 55 56 void ADDF::constructModel() 57 { 58 // All constructModel should do is create Area/NDDPower/Energy Results as 59 // well as instantiate any sub-instances using only the hard parameters 60 61 createInputPort("A"); 62 createInputPort("B"); 63 createInputPort("CI"); 64 createOutputPort("S"); 65 createOutputPort("CO"); 66 67 createLoad("A_Cap"); 68 createLoad("B_Cap"); 69 createLoad("CI_Cap"); 70 createDelay("A_to_S_delay"); 71 createDelay("B_to_S_delay"); 72 createDelay("CI_to_S_delay"); 73 createDelay("A_to_CO_delay"); 74 createDelay("B_to_CO_delay"); 75 createDelay("CI_to_CO_delay"); 76 createDriver("S_Ron", true); 77 createDriver("CO_Ron", true); 78 79 ElectricalLoad* a_cap = getLoad("A_Cap"); 80 ElectricalLoad* b_cap = getLoad("B_Cap"); 81 ElectricalLoad* ci_cap = getLoad("CI_Cap"); 82 ElectricalDelay* a_to_s_delay = getDelay("A_to_S_delay"); 83 ElectricalDelay* b_to_s_delay = getDelay("B_to_S_delay"); 84 ElectricalDelay* ci_to_s_delay = getDelay("CI_to_S_delay"); 85 ElectricalDelay* a_to_co_delay = getDelay("A_to_CO_delay"); 86 ElectricalDelay* b_to_co_delay = getDelay("B_to_CO_delay"); 87 ElectricalDelay* ci_to_co_delay = getDelay("CI_to_CO_delay"); 88 ElectricalDriver* s_ron = getDriver("S_Ron"); 89 ElectricalDriver* co_ron = getDriver("CO_Ron"); 90 91 getNet("A")->addDownstreamNode(a_cap); 92 getNet("B")->addDownstreamNode(b_cap); 93 getNet("CI")->addDownstreamNode(ci_cap); 94 a_cap->addDownstreamNode(a_to_s_delay); 95 b_cap->addDownstreamNode(b_to_s_delay); 96 ci_cap->addDownstreamNode(ci_to_s_delay); 97 a_cap->addDownstreamNode(a_to_co_delay); 98 b_cap->addDownstreamNode(b_to_co_delay); 99 ci_cap->addDownstreamNode(ci_to_co_delay); 100 101 a_to_s_delay->addDownstreamNode(s_ron); 102 b_to_s_delay->addDownstreamNode(s_ron); 103 ci_to_s_delay->addDownstreamNode(s_ron); 104 a_to_co_delay->addDownstreamNode(co_ron); 105 b_to_co_delay->addDownstreamNode(co_ron); 106 ci_to_co_delay->addDownstreamNode(co_ron); 107 108 s_ron->addDownstreamNode(getNet("S")); 109 co_ron->addDownstreamNode(getNet("CO")); 110 111 // Create Area result 112 // Create NDD Power result 113 createElectricalAtomicResults(); 114 // Create ADDF Event Energy Result 115 createElectricalEventAtomicResult("ADDF"); 116 117 getEventInfo("Idle")->setStaticTransitionInfos(); 118 119 return; 120 } 121 122 void ADDF::updateModel() 123 { 124 // Get parameters 125 double drive_strength = getDrivingStrength(); 126 Map<double>* cache = getTechModel()->getStdCellLib()->getStdCellCache(); 127 128 // Standard cell cache string 129 String cell_name = "ADDF_X" + (String) drive_strength; 130 131 // Get timing parameters 132 getLoad("A_Cap")->setLoadCap(cache->get(cell_name + "->Cap->A")); 133 getLoad("B_Cap")->setLoadCap(cache->get(cell_name + "->Cap->B")); 134 getLoad("CI_Cap")->setLoadCap(cache->get(cell_name + "->Cap->CI")); 135 136 getDelay("A_to_S_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_S")); 137 getDelay("B_to_S_delay")->setDelay(cache->get(cell_name + "->Delay->B_to_S")); 138 getDelay("CI_to_S_delay")->setDelay(cache->get(cell_name + "->Delay->CI_to_S")); 139 getDelay("A_to_CO_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_CO")); 140 getDelay("B_to_CO_delay")->setDelay(cache->get(cell_name + "->Delay->B_to_CO")); 141 getDelay("CI_to_CO_delay")->setDelay(cache->get(cell_name + "->Delay->CI_to_CO")); 142 143 getDriver("S_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->S")); 144 getDriver("CO_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->CO")); 145 146 // Set the cell area 147 getAreaResult("Active")->setValue(cache->get(cell_name + "->Area->Active")); 148 getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->Area->Metal1Wire")); 149 150 return; 151 } 152 153 void ADDF::evaluateModel() 154 { 155 return; 156 } 157 158 void ADDF::useModel() 159 { 160 // Get parameters 161 double drive_strength = getDrivingStrength(); 162 Map<double>* cache = getTechModel()->getStdCellLib()->getStdCellCache(); 163 164 // Standard cell cache string 165 String cell_name = "ADDF_X" + (String) drive_strength; 166 167 // Propagate the transition info and get the 0->1 transition count 168 propagateTransitionInfo(); 169 double P_A = getInputPort("A")->getTransitionInfo().getProbability1(); 170 double P_B = getInputPort("B")->getTransitionInfo().getProbability1(); 171 double P_CI = getInputPort("CI")->getTransitionInfo().getProbability1(); 172 double A_num_trans_01 = getInputPort("A")->getTransitionInfo().getNumberTransitions01(); 173 double B_num_trans_01 = getInputPort("B")->getTransitionInfo().getNumberTransitions01(); 174 double CI_num_trans_01 = getInputPort("CI")->getTransitionInfo().getNumberTransitions01(); 175 double P_num_trans_01 = m_trans_P_.getNumberTransitions01(); 176 double G_num_trans_01 = m_trans_G_.getNumberTransitions01(); 177 double CP_num_trans_01 = m_trans_CP_.getNumberTransitions01(); 178 double S_num_trans_01 = getOutputPort("S")->getTransitionInfo().getNumberTransitions01(); 179 double CO_num_trans_01 = getOutputPort("CO")->getTransitionInfo().getNumberTransitions01(); 180 181 // Calculate leakage 182 double leakage = 0; 183 leakage += cache->get(cell_name + "->Leakage->!A!B!CI") * (1 - P_A) * (1 - P_B) * (1 - P_CI); 184 leakage += cache->get(cell_name + "->Leakage->!A!BCI") * (1 - P_A) * (1 - P_B) * P_CI; 185 leakage += cache->get(cell_name + "->Leakage->!AB!CI") * (1 - P_A) * P_B * (1 - P_CI); 186 leakage += cache->get(cell_name + "->Leakage->!ABCI") * (1 - P_A) * P_B * P_CI; 187 leakage += cache->get(cell_name + "->Leakage->A!B!CI") * P_A * (1 - P_B) * (1 - P_CI); 188 leakage += cache->get(cell_name + "->Leakage->A!BCI") * P_A * (1 - P_B) * P_CI; 189 leakage += cache->get(cell_name + "->Leakage->AB!CI") * P_A * P_B * (1 - P_CI); 190 leakage += cache->get(cell_name + "->Leakage->ABCI") * P_A * P_B * P_CI; 191 getNddPowerResult("Leakage")->setValue(leakage); 192 193 // Get VDD 194 double vdd = getTechModel()->get("Vdd"); 195 196 // Get capacitances 197 double a_b_cap = cache->get(cell_name + "->Cap->A_b"); 198 double b_b_cap = cache->get(cell_name + "->Cap->B_b"); 199 double ci_b_cap = cache->get(cell_name + "->Cap->CI_b"); 200 double p_cap = cache->get(cell_name + "->Cap->P"); 201 double p_b_cap = cache->get(cell_name + "->Cap->P_b"); 202 double s_cap = cache->get(cell_name + "->Cap->S"); 203 double cp_cap = cache->get(cell_name + "->Cap->CP"); 204 double g_cap = cache->get(cell_name + "->Cap->G"); 205 double co_cap = cache->get(cell_name + "->Cap->CO"); 206 double s_load_cap = getNet("S")->getTotalDownstreamCap(); 207 double co_load_cap = getNet("CO")->getTotalDownstreamCap(); 208 209 // Calculate ADDF Event energy 210 double addf_event_energy = 0.0; 211 addf_event_energy += a_b_cap * A_num_trans_01; 212 addf_event_energy += b_b_cap * B_num_trans_01; 213 addf_event_energy += ci_b_cap * CI_num_trans_01; 214 addf_event_energy += (p_cap + p_b_cap) * P_num_trans_01; 215 addf_event_energy += (s_cap + s_load_cap) * S_num_trans_01; 216 addf_event_energy += cp_cap * CP_num_trans_01; 217 addf_event_energy += g_cap * G_num_trans_01; 218 addf_event_energy += (co_cap + co_load_cap) * CO_num_trans_01; 219 addf_event_energy *= vdd * vdd; 220 getEventResult("ADDF")->setValue(addf_event_energy); 221 222 return; 223 } 224 225 void ADDF::propagateTransitionInfo() 226 { 227 const TransitionInfo& trans_A = getInputPort("A")->getTransitionInfo(); 228 const TransitionInfo& trans_B = getInputPort("B")->getTransitionInfo(); 229 const TransitionInfo& trans_CI = getInputPort("CI")->getTransitionInfo(); 230 231 double max_freq_mult = max(max(trans_A.getFrequencyMultiplier(), trans_B.getFrequencyMultiplier()), trans_CI.getFrequencyMultiplier()); 232 const TransitionInfo& scaled_trans_A = trans_A.scaleFrequencyMultiplier(max_freq_mult); 233 const TransitionInfo& scaled_trans_B = trans_B.scaleFrequencyMultiplier(max_freq_mult); 234 const TransitionInfo& scaled_trans_CI = trans_CI.scaleFrequencyMultiplier(max_freq_mult); 235 236 double A_prob_00 = scaled_trans_A.getNumberTransitions00() / max_freq_mult; 237 double A_prob_01 = scaled_trans_A.getNumberTransitions01() / max_freq_mult; 238 double A_prob_10 = A_prob_01; 239 double A_prob_11 = scaled_trans_A.getNumberTransitions11() / max_freq_mult; 240 double B_prob_00 = scaled_trans_B.getNumberTransitions00() / max_freq_mult; 241 double B_prob_01 = scaled_trans_B.getNumberTransitions01() / max_freq_mult; 242 double B_prob_10 = B_prob_01; 243 double B_prob_11 = scaled_trans_B.getNumberTransitions11() / max_freq_mult; 244 double CI_prob_00 = scaled_trans_CI.getNumberTransitions00() / max_freq_mult; 245 double CI_prob_01 = scaled_trans_CI.getNumberTransitions01() / max_freq_mult; 246 double CI_prob_10 = CI_prob_01; 247 double CI_prob_11 = scaled_trans_CI.getNumberTransitions11() / max_freq_mult; 248 249 // Set P transition info 250 double P_prob_00 = A_prob_00 * B_prob_00 + 251 A_prob_01 * B_prob_01 + 252 A_prob_10 * B_prob_10 + 253 A_prob_11 * B_prob_11; 254 double P_prob_01 = A_prob_00 * B_prob_01 + 255 A_prob_01 * B_prob_00 + 256 A_prob_10 * B_prob_11 + 257 A_prob_11 * B_prob_10; 258 double P_prob_10 = P_prob_01; 259 double P_prob_11 = A_prob_00 * B_prob_11 + 260 A_prob_01 * B_prob_10 + 261 A_prob_10 * B_prob_01 + 262 A_prob_11 * B_prob_00; 263 264 // Set G transition info 265 double G_prob_00 = A_prob_11 * B_prob_11; 266 double G_prob_01 = A_prob_11 * B_prob_10 + 267 A_prob_10 * (B_prob_11 + B_prob_10); 268 double G_prob_10 = G_prob_01; 269 double G_prob_11 = A_prob_00 + 270 A_prob_01 * (B_prob_00 + B_prob_10) + 271 A_prob_10 * (B_prob_00 + B_prob_01) + 272 A_prob_11 * B_prob_00; 273 274 // Set CP transition info 275 double CP_prob_00 = P_prob_11 * CI_prob_11; 276 double CP_prob_01 = P_prob_11 * CI_prob_10 + 277 P_prob_10 * (CI_prob_11 + CI_prob_10); 278 double CP_prob_10 = CP_prob_01; 279 double CP_prob_11 = P_prob_00 + 280 P_prob_01 * (CI_prob_00 + CI_prob_10) + 281 P_prob_10 * (CI_prob_00 + CI_prob_01) + 282 P_prob_11 * CI_prob_00; 283 284 // Set S transition info 285 double S_prob_00 = P_prob_00 * CI_prob_00 + 286 P_prob_01 * CI_prob_01 + 287 P_prob_10 * CI_prob_10 + 288 P_prob_11 * CI_prob_11; 289 double S_prob_01 = P_prob_00 * CI_prob_01 + 290 P_prob_01 * CI_prob_00 + 291 P_prob_10 * CI_prob_11 + 292 P_prob_11 * CI_prob_10; 293 double S_prob_11 = P_prob_00 * CI_prob_11 + 294 P_prob_01 * CI_prob_10 + 295 P_prob_10 * CI_prob_01 + 296 P_prob_11 * CI_prob_00; 297 298 // Set CO transition info 299 double CO_prob_00 = G_prob_11 * CP_prob_11; 300 double CO_prob_01 = G_prob_11 * CP_prob_10 + 301 G_prob_10 * (CP_prob_11 + CP_prob_10); 302 double CO_prob_11 = G_prob_00 + 303 G_prob_01 * (CP_prob_00 + CP_prob_10) + 304 G_prob_10 * (CP_prob_00 + CP_prob_01) + 305 G_prob_11 * CP_prob_00; 306 307 m_trans_P_ = TransitionInfo(P_prob_00 * max_freq_mult, P_prob_01 * max_freq_mult, P_prob_11 * max_freq_mult); 308 m_trans_G_ = TransitionInfo(G_prob_00 * max_freq_mult, G_prob_01 * max_freq_mult, G_prob_11 * max_freq_mult); 309 m_trans_CP_ = TransitionInfo(CP_prob_00 * max_freq_mult, CP_prob_01 * max_freq_mult, CP_prob_11 * max_freq_mult); 310 311 // Check that probabilities add up to 1.0 with some finite tolerance 312 ASSERT(LibUtil::Math::isEqual((S_prob_00 + S_prob_01 + S_prob_01 + S_prob_11), 1.0), 313 "[Error] " + getInstanceName() + "Output S transition probabilities must add up to 1 (" + 314 (String) S_prob_00 + ", " + (String) S_prob_01 + ", " + (String) S_prob_11 + ")!"); 315 316 // Check that probabilities add up to 1.0 with some finite tolerance 317 ASSERT(LibUtil::Math::isEqual((CO_prob_00 + CO_prob_01 + CO_prob_01 + CO_prob_11), 1.0), 318 "[Error] " + getInstanceName() + "Output S transition probabilities must add up to 1 (" + 319 (String) CO_prob_00 + ", " + (String) CO_prob_01 + ", " + (String) CO_prob_11 + ")!"); 320 321 // Turn probability of transitions per cycle into number of transitions per time unit 322 TransitionInfo trans_S(S_prob_00 * max_freq_mult, S_prob_01 * max_freq_mult, S_prob_11 * max_freq_mult); 323 getOutputPort("S")->setTransitionInfo(trans_S); 324 TransitionInfo trans_CO(CO_prob_00 * max_freq_mult, CO_prob_01 * max_freq_mult, CO_prob_11 * max_freq_mult); 325 getOutputPort("CO")->setTransitionInfo(trans_CO); 326 return; 327 } 328 329 // Creates the standard cell, characterizes and abstracts away the details 330 void ADDF::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) 331 { 332 // Get parameters 333 double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); 334 Map<double>* cache = cell_lib_->getStdCellCache(); 335 336 // Standard cell cache string 337 String cell_name = "ADDF_X" + (String) drive_strength_; 338 339 Log::printLine("=== " + cell_name + " ==="); 340 341 // Now actually build the full standard cell model 342 createInputPort("A"); 343 createInputPort("B"); 344 createInputPort("CI"); 345 createOutputPort("S"); 346 createOutputPort("CO"); 347 348 createNet("A_b"); 349 createNet("B_b"); 350 createNet("CI_b"); 351 createNet("P"); 352 createNet("P_b"); 353 createNet("G"); //actually G_b since it is NAND'ed 354 createNet("CP"); //actually (CP)_b since it is NAND'ed 355 356 // Adds macros 357 CellMacros::addInverter(this, "INV1", false, true, "A", "A_b"); 358 CellMacros::addInverter(this, "INV2", false, true, "B", "B_b"); 359 CellMacros::addInverter(this, "INV3", false, true, "CI", "CI_b"); 360 CellMacros::addInverter(this, "INV4", false, true, "P", "P_b"); 361 CellMacros::addTristate(this, "INVZ1", false, true, true, true, "B", "A", "A_b", "P"); 362 CellMacros::addTristate(this, "INVZ2", false, true, true, true, "B_b", "A_b", "A", "P"); 363 CellMacros::addTristate(this, "INVZ3", true, true, true, true, "P", "CI", "CI_b", "S"); 364 CellMacros::addTristate(this, "INVZ4", true, true, true, true, "P_b", "CI_b", "CI", "S"); 365 CellMacros::addNand2(this, "NAND1", false, true, true, "CI", "P", "CP"); 366 CellMacros::addNand2(this, "NAND2", false, true, true, "A", "B", "G"); 367 CellMacros::addNand2(this, "NAND3", true, true, true, "CP", "G", "CO"); 368 369 // I have no idea how to size each of the parts haha 370 CellMacros::updateInverter(this, "INV1", drive_strength_ * 0.250); 371 CellMacros::updateInverter(this, "INV2", drive_strength_ * 0.250); 372 CellMacros::updateInverter(this, "INV3", drive_strength_ * 0.250); 373 CellMacros::updateInverter(this, "INV4", drive_strength_ * 0.500); 374 CellMacros::updateTristate(this, "INVZ1", drive_strength_ * 0.250); 375 CellMacros::updateTristate(this, "INVZ2", drive_strength_ * 0.250); 376 CellMacros::updateTristate(this, "INVZ3", drive_strength_ * 0.500); 377 CellMacros::updateTristate(this, "INVZ4", drive_strength_ * 0.500); 378 CellMacros::updateNand2(this, "NAND1", drive_strength_ * 0.500); 379 CellMacros::updateNand2(this, "NAND2", drive_strength_ * 0.500); 380 CellMacros::updateNand2(this, "NAND3", drive_strength_ * 1.000); 381 382 // Cache area result 383 double area = 0.0; 384 area += gate_pitch * getTotalHeight() * 1; 385 area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV1_GatePitches").toDouble(); 386 area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV2_GatePitches").toDouble(); 387 area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV3_GatePitches").toDouble(); 388 area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV4_GatePitches").toDouble(); 389 area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ1_GatePitches").toDouble(); 390 area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ2_GatePitches").toDouble(); 391 area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ3_GatePitches").toDouble(); 392 area += gate_pitch * getTotalHeight() * getGenProperties()->get("INVZ4_GatePitches").toDouble(); 393 area += gate_pitch * getTotalHeight() * getGenProperties()->get("NAND1_GatePitches").toDouble(); 394 area += gate_pitch * getTotalHeight() * getGenProperties()->get("NAND2_GatePitches").toDouble(); 395 area += gate_pitch * getTotalHeight() * getGenProperties()->get("NAND3_GatePitches").toDouble(); 396 cache->set(cell_name + "->Area->Active", area); 397 cache->set(cell_name + "->Area->Metal1Wire", area); 398 Log::printLine(cell_name + "->Area->Active=" + (String) area); 399 Log::printLine(cell_name + "->Area->Metal1Wire=" + (String) area); 400 401 // -------------------------------------------------------------------- 402 // Leakage Model Calculation 403 // -------------------------------------------------------------------- 404 // Cache leakage power results (for every single signal combination) 405 double leakage_000 = 0; //!A, !B, !CI 406 double leakage_001 = 0; //!A, !B, CI 407 double leakage_010 = 0; //!A, B, !CI 408 double leakage_011 = 0; //!A, B, CI 409 double leakage_100 = 0; //A, !B, !CI 410 double leakage_101 = 0; //A, !B, CI 411 double leakage_110 = 0; //A, B, !CI 412 double leakage_111 = 0; //A, B, CI 413 414 //This is so painful... 415 leakage_000 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); 416 leakage_000 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); 417 leakage_000 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); 418 leakage_000 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); 419 leakage_000 += getGenProperties()->get("INVZ1_LeakagePower_010_0").toDouble(); 420 leakage_000 += getGenProperties()->get("INVZ2_LeakagePower_101_0").toDouble(); 421 leakage_000 += getGenProperties()->get("INVZ3_LeakagePower_010_0").toDouble(); 422 leakage_000 += getGenProperties()->get("INVZ4_LeakagePower_101_0").toDouble(); 423 leakage_000 += getGenProperties()->get("NAND1_LeakagePower_00").toDouble(); 424 leakage_000 += getGenProperties()->get("NAND2_LeakagePower_00").toDouble(); 425 leakage_000 += getGenProperties()->get("NAND3_LeakagePower_11").toDouble(); 426 427 leakage_001 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); 428 leakage_001 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); 429 leakage_001 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); 430 leakage_001 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); 431 leakage_001 += getGenProperties()->get("INVZ1_LeakagePower_010_0").toDouble(); 432 leakage_001 += getGenProperties()->get("INVZ2_LeakagePower_101_0").toDouble(); 433 leakage_001 += getGenProperties()->get("INVZ3_LeakagePower_100_1").toDouble(); 434 leakage_001 += getGenProperties()->get("INVZ4_LeakagePower_011_1").toDouble(); 435 leakage_001 += getGenProperties()->get("NAND1_LeakagePower_10").toDouble(); 436 leakage_001 += getGenProperties()->get("NAND2_LeakagePower_00").toDouble(); 437 leakage_001 += getGenProperties()->get("NAND3_LeakagePower_11").toDouble(); 438 439 leakage_010 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); 440 leakage_010 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); 441 leakage_010 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); 442 leakage_010 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); 443 leakage_010 += getGenProperties()->get("INVZ1_LeakagePower_011_1").toDouble(); 444 leakage_010 += getGenProperties()->get("INVZ2_LeakagePower_100_1").toDouble(); 445 leakage_010 += getGenProperties()->get("INVZ3_LeakagePower_011_1").toDouble(); 446 leakage_010 += getGenProperties()->get("INVZ4_LeakagePower_100_1").toDouble(); 447 leakage_010 += getGenProperties()->get("NAND1_LeakagePower_01").toDouble(); 448 leakage_010 += getGenProperties()->get("NAND2_LeakagePower_01").toDouble(); 449 leakage_010 += getGenProperties()->get("NAND3_LeakagePower_11").toDouble(); 450 451 leakage_011 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); 452 leakage_011 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); 453 leakage_011 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); 454 leakage_011 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); 455 leakage_011 += getGenProperties()->get("INVZ1_LeakagePower_011_1").toDouble(); 456 leakage_011 += getGenProperties()->get("INVZ2_LeakagePower_100_1").toDouble(); 457 leakage_011 += getGenProperties()->get("INVZ3_LeakagePower_101_0").toDouble(); 458 leakage_011 += getGenProperties()->get("INVZ4_LeakagePower_010_0").toDouble(); 459 leakage_011 += getGenProperties()->get("NAND1_LeakagePower_11").toDouble(); 460 leakage_011 += getGenProperties()->get("NAND2_LeakagePower_01").toDouble(); 461 leakage_011 += getGenProperties()->get("NAND3_LeakagePower_01").toDouble(); 462 463 leakage_100 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); 464 leakage_100 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); 465 leakage_100 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); 466 leakage_100 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); 467 leakage_100 += getGenProperties()->get("INVZ1_LeakagePower_100_1").toDouble(); 468 leakage_100 += getGenProperties()->get("INVZ2_LeakagePower_011_1").toDouble(); 469 leakage_100 += getGenProperties()->get("INVZ3_LeakagePower_011_1").toDouble(); 470 leakage_100 += getGenProperties()->get("INVZ4_LeakagePower_100_1").toDouble(); 471 leakage_100 += getGenProperties()->get("NAND1_LeakagePower_01").toDouble(); 472 leakage_100 += getGenProperties()->get("NAND2_LeakagePower_10").toDouble(); 473 leakage_100 += getGenProperties()->get("NAND3_LeakagePower_11").toDouble(); 474 475 leakage_101 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); 476 leakage_101 += getGenProperties()->get("INV2_LeakagePower_0").toDouble(); 477 leakage_101 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); 478 leakage_101 += getGenProperties()->get("INV4_LeakagePower_1").toDouble(); 479 leakage_101 += getGenProperties()->get("INVZ1_LeakagePower_100_1").toDouble(); 480 leakage_101 += getGenProperties()->get("INVZ2_LeakagePower_011_1").toDouble(); 481 leakage_101 += getGenProperties()->get("INVZ3_LeakagePower_101_0").toDouble(); 482 leakage_101 += getGenProperties()->get("INVZ4_LeakagePower_010_0").toDouble(); 483 leakage_101 += getGenProperties()->get("NAND1_LeakagePower_11").toDouble(); 484 leakage_101 += getGenProperties()->get("NAND2_LeakagePower_10").toDouble(); 485 leakage_101 += getGenProperties()->get("NAND3_LeakagePower_01").toDouble(); 486 487 leakage_110 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); 488 leakage_110 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); 489 leakage_110 += getGenProperties()->get("INV3_LeakagePower_0").toDouble(); 490 leakage_110 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); 491 leakage_110 += getGenProperties()->get("INVZ1_LeakagePower_101_0").toDouble(); 492 leakage_110 += getGenProperties()->get("INVZ2_LeakagePower_010_0").toDouble(); 493 leakage_110 += getGenProperties()->get("INVZ3_LeakagePower_010_0").toDouble(); 494 leakage_110 += getGenProperties()->get("INVZ4_LeakagePower_101_0").toDouble(); 495 leakage_110 += getGenProperties()->get("NAND1_LeakagePower_00").toDouble(); 496 leakage_110 += getGenProperties()->get("NAND2_LeakagePower_11").toDouble(); 497 leakage_110 += getGenProperties()->get("NAND3_LeakagePower_10").toDouble(); 498 499 leakage_111 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); 500 leakage_111 += getGenProperties()->get("INV2_LeakagePower_1").toDouble(); 501 leakage_111 += getGenProperties()->get("INV3_LeakagePower_1").toDouble(); 502 leakage_111 += getGenProperties()->get("INV4_LeakagePower_0").toDouble(); 503 leakage_111 += getGenProperties()->get("INVZ1_LeakagePower_101_0").toDouble(); 504 leakage_111 += getGenProperties()->get("INVZ2_LeakagePower_010_0").toDouble(); 505 leakage_111 += getGenProperties()->get("INVZ3_LeakagePower_100_1").toDouble(); 506 leakage_111 += getGenProperties()->get("INVZ4_LeakagePower_011_1").toDouble(); 507 leakage_111 += getGenProperties()->get("NAND1_LeakagePower_10").toDouble(); 508 leakage_111 += getGenProperties()->get("NAND2_LeakagePower_11").toDouble(); 509 leakage_111 += getGenProperties()->get("NAND3_LeakagePower_10").toDouble(); 510 511 cache->set(cell_name + "->Leakage->!A!B!CI", leakage_000); 512 cache->set(cell_name + "->Leakage->!A!BCI", leakage_001); 513 cache->set(cell_name + "->Leakage->!AB!CI", leakage_010); 514 cache->set(cell_name + "->Leakage->!ABCI", leakage_011); 515 cache->set(cell_name + "->Leakage->A!B!CI", leakage_100); 516 cache->set(cell_name + "->Leakage->A!BCI", leakage_101); 517 cache->set(cell_name + "->Leakage->AB!CI", leakage_110); 518 cache->set(cell_name + "->Leakage->ABCI", leakage_111); 519 Log::printLine(cell_name + "->Leakage->!A!B!CI=" + (String) leakage_000); 520 Log::printLine(cell_name + "->Leakage->!A!BCI=" + (String) leakage_001); 521 Log::printLine(cell_name + "->Leakage->!AB!CI=" + (String) leakage_010); 522 Log::printLine(cell_name + "->Leakage->!ABCI=" + (String) leakage_011); 523 Log::printLine(cell_name + "->Leakage->A!B!CI=" + (String) leakage_100); 524 Log::printLine(cell_name + "->Leakage->A!BCI=" + (String) leakage_101); 525 Log::printLine(cell_name + "->Leakage->AB!CI=" + (String) leakage_110); 526 Log::printLine(cell_name + "->Leakage->ABCI=" + (String) leakage_111); 527 // -------------------------------------------------------------------- 528 529 /* 530 // Cache event energy results 531 double event_a_flip = 0.0; 532 event_a_flip += getGenProperties()->get("INV1_A_Flip").toDouble() + getGenProperties()->get("INV1_ZN_Flip").toDouble(); 533 event_a_flip += getGenProperties()->get("INVZ1_OE_Flip").toDouble() + getGenProperties()->get("INVZ1_OEN_Flip").toDouble(); 534 event_a_flip += getGenProperties()->get("INVZ2_OE_Flip").toDouble() + getGenProperties()->get("INVZ2_OEN_Flip").toDouble(); 535 event_a_flip += getGenProperties()->get("NAND2_A1_Flip").toDouble(); 536 cache->set(cell_name + "->Event_A_Flip", event_a_flip); 537 Log::printLine(cell_name + "->Event_A_Flip=" + (String) event_a_flip); 538 539 double event_b_flip = 0.0; 540 event_b_flip += getGenProperties()->get("INV2_A_Flip").toDouble() + getGenProperties()->get("INV2_ZN_Flip").toDouble(); 541 event_b_flip += getGenProperties()->get("INVZ1_A_Flip").toDouble(); 542 event_b_flip += getGenProperties()->get("INVZ2_A_Flip").toDouble(); 543 event_b_flip += getGenProperties()->get("NAND2_A1_Flip").toDouble(); 544 cache->set(cell_name + "->Event_B_Flip", event_b_flip); 545 Log::printLine(cell_name + "->Event_B_Flip=" + (String) event_b_flip); 546 547 double event_ci_flip = 0.0; 548 event_ci_flip += getGenProperties()->get("INV3_A_Flip").toDouble() + getGenProperties()->get("INV3_ZN_Flip").toDouble(); 549 event_ci_flip += getGenProperties()->get("INVZ3_OE_Flip").toDouble() + getGenProperties()->get("INVZ3_OEN_Flip").toDouble(); 550 event_ci_flip += getGenProperties()->get("INVZ4_OE_Flip").toDouble() + getGenProperties()->get("INVZ4_OEN_Flip").toDouble(); 551 event_ci_flip += getGenProperties()->get("NAND1_A1_Flip").toDouble(); 552 cache->set(cell_name + "->Event_CI_Flip", event_ci_flip); 553 Log::printLine(cell_name + "->Event_CI_Flip=" + (String) event_ci_flip); 554 555 double event_p_flip = 0.0; 556 event_p_flip += getGenProperties()->get("INV4_A_Flip").toDouble() + getGenProperties()->get("INV4_ZN_Flip").toDouble(); 557 event_p_flip += getGenProperties()->get("INVZ1_ZN_Flip").toDouble(); 558 event_p_flip += getGenProperties()->get("INVZ2_ZN_Flip").toDouble(); 559 event_p_flip += getGenProperties()->get("NAND1_A2_Flip").toDouble(); 560 cache->set(cell_name + "->Event_P_Flip", event_p_flip); 561 Log::printLine(cell_name + "->Event_P_Flip=" + (String) event_p_flip); 562 563 double event_s_flip = 0.0; 564 event_s_flip += getGenProperties()->get("INVZ3_ZN_Flip").toDouble(); 565 event_s_flip += getGenProperties()->get("INVZ4_ZN_Flip").toDouble(); 566 cache->set(cell_name + "->Event_S_Flip", event_s_flip); 567 Log::printLine(cell_name + "->Event_S_Flip=" + (String) event_s_flip); 568 569 double event_cp_flip = 0.0; 570 event_cp_flip += getGenProperties()->get("NAND1_ZN_Flip").toDouble(); 571 event_cp_flip += getGenProperties()->get("NAND3_A2_Flip").toDouble(); 572 cache->set(cell_name + "->Event_CP_Flip", event_cp_flip); 573 Log::printLine(cell_name + "->Event_CP_Flip=" + (String) event_cp_flip); 574 575 double event_g_flip = 0.0; 576 event_g_flip += getGenProperties()->get("NAND2_ZN_Flip").toDouble(); 577 event_g_flip += getGenProperties()->get("NAND3_A2_Flip").toDouble(); 578 cache->set(cell_name + "->Event_G_Flip", event_g_flip); 579 Log::printLine(cell_name + "->Event_G_Flip=" + (String) event_g_flip); 580 581 double event_co_flip = 0.0; 582 event_co_flip += getGenProperties()->get("NAND3_ZN_Flip").toDouble(); 583 cache->set(cell_name + "->Event_CO_Flip", event_co_flip); 584 Log::printLine(cell_name + "->Event_CO_Flip=" + (String) event_co_flip); 585 */ 586 // -------------------------------------------------------------------- 587 // Get Node Capacitances 588 // -------------------------------------------------------------------- 589 double a_cap = getNet("A")->getTotalDownstreamCap(); 590 double b_cap = getNet("B")->getTotalDownstreamCap(); 591 double ci_cap = getNet("CI")->getTotalDownstreamCap(); 592 double a_b_cap = getNet("A_b")->getTotalDownstreamCap(); 593 double b_b_cap = getNet("B_b")->getTotalDownstreamCap(); 594 double ci_b_cap = getNet("CI_b")->getTotalDownstreamCap(); 595 double p_cap = getNet("P")->getTotalDownstreamCap(); 596 double p_b_cap = getNet("P_b")->getTotalDownstreamCap(); 597 double s_cap = getNet("S")->getTotalDownstreamCap(); 598 double cp_cap = getNet("CP")->getTotalDownstreamCap(); 599 double g_cap = getNet("G")->getTotalDownstreamCap(); 600 double co_cap = getNet("CO")->getTotalDownstreamCap(); 601 602 cache->set(cell_name + "->Cap->A", a_cap); 603 cache->set(cell_name + "->Cap->B", b_cap); 604 cache->set(cell_name + "->Cap->CI", ci_cap); 605 cache->set(cell_name + "->Cap->A_b", a_b_cap); 606 cache->set(cell_name + "->Cap->B_b", b_b_cap); 607 cache->set(cell_name + "->Cap->CI_b", ci_b_cap); 608 cache->set(cell_name + "->Cap->P", p_cap); 609 cache->set(cell_name + "->Cap->P_b", p_b_cap); 610 cache->set(cell_name + "->Cap->S", s_cap); 611 cache->set(cell_name + "->Cap->CP", cp_cap); 612 cache->set(cell_name + "->Cap->G", g_cap); 613 cache->set(cell_name + "->Cap->CO", co_cap); 614 615 Log::printLine(cell_name + "->Cap->A=" + (String) a_cap); 616 Log::printLine(cell_name + "->Cap->B=" + (String) b_cap); 617 Log::printLine(cell_name + "->Cap->CI=" + (String) ci_cap); 618 Log::printLine(cell_name + "->Cap->A_b=" + (String) a_b_cap); 619 Log::printLine(cell_name + "->Cap->B_b=" + (String) b_b_cap); 620 Log::printLine(cell_name + "->Cap->CI_b=" + (String) ci_b_cap); 621 Log::printLine(cell_name + "->Cap->P=" + (String) p_cap); 622 Log::printLine(cell_name + "->Cap->P_b=" + (String) p_b_cap); 623 Log::printLine(cell_name + "->Cap->S=" + (String) s_cap); 624 Log::printLine(cell_name + "->Cap->CP=" + (String) cp_cap); 625 Log::printLine(cell_name + "->Cap->G=" + (String) g_cap); 626 Log::printLine(cell_name + "->Cap->CO=" + (String) co_cap); 627 // -------------------------------------------------------------------- 628 629 // -------------------------------------------------------------------- 630 // Build Internal Delay Model 631 // -------------------------------------------------------------------- 632 // Build abstracted timing model 633 double s_ron = (getDriver("INVZ3_RonZN")->getOutputRes() + getDriver("INVZ4_RonZN")->getOutputRes()) / 2; 634 double co_ron = getDriver("NAND3_RonZN")->getOutputRes(); 635 636 double a_to_s_delay = 0.0; 637 a_to_s_delay += getDriver("INV1_RonZN")->calculateDelay(); 638 a_to_s_delay += max(getDriver("INVZ1_RonZN")->calculateDelay(), getDriver("INVZ2_RonZN")->calculateDelay()); 639 a_to_s_delay += max(getDriver("INVZ3_RonZN")->calculateDelay(), getDriver("INV4_RonZN")->calculateDelay() + getDriver("INVZ4_RonZN")->calculateDelay()); 640 641 double b_to_s_delay = 0.0; 642 b_to_s_delay += max(getDriver("INVZ1_RonZN")->calculateDelay(), getDriver("INV2_RonZN")->calculateDelay() + getDriver("INVZ2_RonZN")->calculateDelay()); 643 b_to_s_delay += max(getDriver("INVZ3_RonZN")->calculateDelay(), getDriver("INV4_RonZN")->calculateDelay() + getDriver("INVZ4_RonZN")->calculateDelay()); 644 645 double ci_to_s_delay = 0.0; 646 ci_to_s_delay += getDriver("INV3_RonZN")->calculateDelay(); 647 ci_to_s_delay += max(getDriver("INVZ3_RonZN")->calculateDelay(), getDriver("INVZ4_RonZN")->calculateDelay()); 648 649 double a_to_co_delay = 0.0; 650 a_to_co_delay += max(getDriver("NAND2_RonZN")->calculateDelay(), //Generate path 651 getDriver("INV1_RonZN")->calculateDelay() + //Carry propagate path 652 max(getDriver("INVZ1_RonZN")->calculateDelay(), getDriver("INVZ2_RonZN")->calculateDelay()) + 653 getDriver("NAND1_RonZN")->calculateDelay()); 654 a_to_co_delay += getDriver("NAND3_RonZN")->calculateDelay(); 655 656 double b_to_co_delay = 0.0; 657 b_to_co_delay += max(getDriver("NAND2_RonZN")->calculateDelay(), //Generate path 658 max(getDriver("INVZ1_RonZN")->calculateDelay(), //Carry propagate path 659 getDriver("INV2_RonZN")->calculateDelay() + getDriver("INVZ2_RonZN")->calculateDelay()) + 660 getDriver("NAND1_RonZN")->calculateDelay()); 661 b_to_co_delay += getDriver("NAND3_RonZN")->calculateDelay(); 662 663 double ci_to_co_delay = 0.0; 664 ci_to_co_delay += getDriver("NAND1_RonZN")->calculateDelay(); 665 ci_to_co_delay += getDriver("NAND3_RonZN")->calculateDelay(); 666 667 cache->set(cell_name + "->DriveRes->S", s_ron); 668 cache->set(cell_name + "->DriveRes->CO", co_ron); 669 670 cache->set(cell_name + "->Delay->A_to_S", a_to_s_delay); 671 cache->set(cell_name + "->Delay->B_to_S", b_to_s_delay); 672 cache->set(cell_name + "->Delay->CI_to_S", ci_to_s_delay); 673 cache->set(cell_name + "->Delay->A_to_CO", a_to_co_delay); 674 cache->set(cell_name + "->Delay->B_to_CO", b_to_co_delay); 675 cache->set(cell_name + "->Delay->CI_to_CO", ci_to_co_delay); 676 677 Log::printLine(cell_name + "->DriveRes->S=" + (String) s_ron); 678 Log::printLine(cell_name + "->DriveRes->CO=" + (String) co_ron); 679 Log::printLine(cell_name + "->Delay->A_to_S=" + (String) a_to_s_delay); 680 Log::printLine(cell_name + "->Delay->B_to_S=" + (String) b_to_s_delay); 681 Log::printLine(cell_name + "->Delay->CI_to_S=" + (String) ci_to_s_delay); 682 Log::printLine(cell_name + "->Delay->A_to_CO=" + (String) a_to_co_delay); 683 Log::printLine(cell_name + "->Delay->B_to_CO=" + (String) b_to_co_delay); 684 Log::printLine(cell_name + "->Delay->CI_to_CO=" + (String) ci_to_co_delay); 685 // -------------------------------------------------------------------- 686 687 return; 688 689 } 690 691} // namespace DSENT 692 693