BUF.cc revision 10447
1#include "model/std_cells/BUF.h" 2 3#include <cmath> 4 5#include "model/PortInfo.h" 6#include "model/TransitionInfo.h" 7#include "model/EventInfo.h" 8#include "model/std_cells/StdCellLib.h" 9#include "model/std_cells/CellMacros.h" 10#include "model/timing_graph/ElectricalNet.h" 11#include "model/timing_graph/ElectricalDriver.h" 12#include "model/timing_graph/ElectricalLoad.h" 13#include "model/timing_graph/ElectricalDelay.h" 14 15namespace DSENT 16{ 17 using std::max; 18 19 BUF::BUF(const String& instance_name_, const TechModel* tech_model_) 20 : StdCell(instance_name_, tech_model_) 21 { 22 initProperties(); 23 } 24 25 BUF::~BUF() 26 {} 27 28 void BUF::initProperties() 29 { 30 return; 31 } 32 33 void BUF::constructModel() 34 { 35 createInputPort("A"); 36 createOutputPort("Y"); 37 38 createLoad("A_Cap"); 39 createDelay("A_to_Y_delay"); 40 createDriver("Y_Ron", true); 41 42 ElectricalLoad* a_cap = getLoad("A_Cap"); 43 ElectricalDelay* a_to_y_delay = getDelay("A_to_Y_delay"); 44 ElectricalDriver* y_ron = getDriver("Y_Ron"); 45 46 getNet("A")->addDownstreamNode(a_cap); 47 a_cap->addDownstreamNode(a_to_y_delay); 48 a_to_y_delay->addDownstreamNode(y_ron); 49 y_ron->addDownstreamNode(getNet("Y")); 50 51 // Create Area result 52 // Create NDD Power result 53 createElectricalAtomicResults(); 54 // Create OR Event Energy Result 55 createElectricalEventAtomicResult("BUF"); 56 57 getEventInfo("Idle")->setStaticTransitionInfos(); 58 59 return; 60 } 61 62 void BUF::updateModel() 63 { 64 // Get parameters 65 double drive_strength = getDrivingStrength(); 66 Map<double>* cache = getTechModel()->getStdCellLib()->getStdCellCache(); 67 68 // Standard cell cache string 69 const String& cell_name = "BUF_X" + (String) drive_strength; 70 71 // Get timing parameters 72 getLoad("A_Cap")->setLoadCap(cache->get(cell_name + "->Cap->A")); 73 getDelay("A_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_Y")); 74 getDriver("Y_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->Y")); 75 76 // Set the cell area 77 getAreaResult("Active")->setValue(cache->get(cell_name + "->ActiveArea")); 78 getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->ActiveArea")); 79 80 return; 81 } 82 83 void BUF::evaluateModel() 84 { 85 return; 86 } 87 88 void BUF::useModel() 89 { 90 // Get parameters 91 double drive_strength = getDrivingStrength(); 92 Map<double>* cache = getTechModel()->getStdCellLib()->getStdCellCache(); 93 94 // Stadard cell cache string 95 const String& cell_name = "BUF_X" + (String) drive_strength; 96 97 // Propagate the transition info and get the 0->1 transtion count 98 propagateTransitionInfo(); 99 double P_A = getInputPort("A")->getTransitionInfo().getProbability1(); 100 double Y_num_trans_01 = getOutputPort("Y")->getTransitionInfo().getNumberTransitions01(); 101 102 // Calculate leakage 103 double leakage = 0; 104 leakage += cache->get(cell_name + "->Leakage->!A") * (1 - P_A); 105 leakage += cache->get(cell_name + "->Leakage->A") * P_A; 106 getNddPowerResult("Leakage")->setValue(leakage); 107 108 // Get VDD 109 double vdd = getTechModel()->get("Vdd"); 110 111 // Get capacitances 112 double y_b_cap = cache->get(cell_name + "->Cap->Y_b"); 113 double y_cap = cache->get(cell_name + "->Cap->Y"); 114 double y_load_cap = getNet("Y")->getTotalDownstreamCap(); 115 116 // Calculate BUFEvent energy 117 double energy_per_trans_01 = (y_b_cap + y_cap + y_load_cap) * vdd * vdd; 118 getEventResult("BUF")->setValue(energy_per_trans_01 * Y_num_trans_01); 119 120 return; 121 } 122 123 void BUF::propagateTransitionInfo() 124 { 125 // Get input signal transition info 126 const TransitionInfo& trans_A = getInputPort("A")->getTransitionInfo(); 127 128 getOutputPort("Y")->setTransitionInfo(trans_A); 129 return; 130 } 131 132 // Creates the standard cell, characterizes and abstracts away the details 133 void BUF::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) 134 { 135 // Get parameters 136 double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); 137 Map<double>* cache = cell_lib_->getStdCellCache(); 138 139 // Stadard cell cache string 140 const String& cell_name = "BUF_X" + (String) drive_strength_; 141 142 Log::printLine("=== " + cell_name + " ==="); 143 144 // Now actually build the full standard cell model 145 createInputPort("A"); 146 createOutputPort("Y"); 147 148 createNet("Y_b"); 149 150 // Adds macros 151 CellMacros::addInverter(this, "INV0", false, true, "A", "Y_b"); 152 CellMacros::addInverter(this, "INV1", false, true, "Y_b", "Y"); 153 154 // Update macros 155 CellMacros::updateInverter(this, "INV0", drive_strength_ * 0.367); 156 CellMacros::updateInverter(this, "INV1", drive_strength_ * 1.0); 157 158 // Cache area result 159 double area = 0.0; 160 area += gate_pitch * getTotalHeight() * 1; 161 area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV0_GatePitches").toDouble(); 162 area += gate_pitch * getTotalHeight() * getGenProperties()->get("INV1_GatePitches").toDouble(); 163 cache->set(cell_name + "->ActiveArea", area); 164 Log::printLine(cell_name + "->ActiveArea=" + (String)area); 165 166 // -------------------------------------------------------------------- 167 // Leakage Model Calculation 168 // -------------------------------------------------------------------- 169 // Cache leakage power results (for every single signal combination) 170 double leakage_0 = 0.0; // !A 171 double leakage_1 = 0.0; // A 172 173 leakage_0 += getGenProperties()->get("INV0_LeakagePower_0").toDouble(); 174 leakage_0 += getGenProperties()->get("INV1_LeakagePower_1").toDouble(); 175 176 leakage_1 += getGenProperties()->get("INV0_LeakagePower_1").toDouble(); 177 leakage_1 += getGenProperties()->get("INV1_LeakagePower_0").toDouble(); 178 179 cache->set(cell_name + "->Leakage->!A", leakage_0); 180 cache->set(cell_name + "->Leakage->A", leakage_1); 181 Log::printLine(cell_name + "->Leakage->!A=" + (String) leakage_0); 182 Log::printLine(cell_name + "->Leakage->A=" + (String) leakage_1); 183 // -------------------------------------------------------------------- 184 185 // -------------------------------------------------------------------- 186 // Get Node Capacitances 187 // -------------------------------------------------------------------- 188 double a_cap = getNet("A")->getTotalDownstreamCap(); 189 double y_b_cap = getNet("Y_b")->getTotalDownstreamCap(); 190 double y_cap = getNet("Y")->getTotalDownstreamCap(); 191 192 cache->set(cell_name + "->Cap->A", a_cap); 193 cache->set(cell_name + "->Cap->Y_b", y_b_cap); 194 cache->set(cell_name + "->Cap->Y", y_cap); 195 Log::printLine(cell_name + "->Cap->A_Cap=" + (String) a_cap); 196 Log::printLine(cell_name + "->Cap->Y_b_Cap=" + (String) y_b_cap); 197 Log::printLine(cell_name + "->Cap->Y_Cap=" + (String) y_cap); 198 // -------------------------------------------------------------------- 199 200 // -------------------------------------------------------------------- 201 // Build Internal Delay Model 202 // -------------------------------------------------------------------- 203 double y_ron = getDriver("INV1_RonZN")->getOutputRes(); 204 double a_to_y_delay = getDriver("INV0_RonZN")->calculateDelay() + 205 getDriver("INV1_RonZN")->calculateDelay(); 206 207 cache->set(cell_name + "->DriveRes->Y", y_ron); 208 cache->set(cell_name + "->Delay->A_to_Y", a_to_y_delay); 209 Log::printLine(cell_name + "->DriveRes->Y=" + (String) y_ron); 210 Log::printLine(cell_name + "->Delay->A_to_Y=" + (String) a_to_y_delay); 211 // -------------------------------------------------------------------- 212 213 return; 214 } 215} // namespace DSENT 216 217