INV.cc revision 10447
1#include "model/std_cells/INV.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/CellMacros.h" 9#include "model/std_cells/StdCellLib.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::ceil; 18 using std::max; 19 20 INV::INV(const String& instance_name_, const TechModel* tech_model_) 21 : StdCell(instance_name_, tech_model_) 22 { 23 initProperties(); 24 } 25 26 INV::~INV() 27 {} 28 29 void INV::initProperties() 30 { 31 return; 32 } 33 34 void INV::constructModel() 35 { 36 // All constructModel should do is create Area/NDDPower/Energy Results as 37 // well as instantiate any sub-instances using only the hard parameters 38 39 // Build Electrical Connectivity 40 createInputPort("A"); 41 createOutputPort("Y"); 42 43 createLoad("A_Cap"); 44 createDelay("A_to_Y_delay"); 45 createDriver("Y_Ron", true); 46 47 ElectricalLoad* a_cap = getLoad("A_Cap"); 48 ElectricalDelay* a_to_y_delay = getDelay("A_to_Y_delay"); 49 ElectricalDriver* y_ron = getDriver("Y_Ron"); 50 51 getNet("A")->addDownstreamNode(a_cap); 52 a_cap->addDownstreamNode(a_to_y_delay); 53 a_to_y_delay->addDownstreamNode(y_ron); 54 y_ron->addDownstreamNode(getNet("Y")); 55 56 // Create Area result 57 // Create NDD Power result 58 createElectricalAtomicResults(); 59 // Create INV Event Energy Result 60 createElectricalEventAtomicResult("INV"); 61 62 getEventInfo("Idle")->setStaticTransitionInfos(); 63 64 return; 65 } 66 67 void INV::updateModel() 68 { 69 // All updateModel should do is calculate numbers for the Area/NDDPower/Energy 70 // Results as anything else that needs to be done using either soft or hard parameters 71 72 // Get parameters 73 double drive_strength = getDrivingStrength(); 74 Map<double>* cache = getTechModel()->getStdCellLib()->getStdCellCache(); 75 76 // Standard cell cache string 77 String cell_name = "INV_X" + (String) drive_strength; 78 79 // Get timing parameters 80 getLoad("A_Cap")->setLoadCap(cache->get(cell_name + "->Cap->A")); 81 getDriver("Y_Ron")->setOutputRes(cache->get(cell_name + "->DriveRes->Y")); 82 getDelay("A_to_Y_delay")->setDelay(cache->get(cell_name + "->Delay->A_to_Y")); 83 84 // Set the cell area 85 getAreaResult("Active")->setValue(cache->get(cell_name + "->Area->Active")); 86 getAreaResult("Metal1Wire")->setValue(cache->get(cell_name + "->Area->Metal1Wire")); 87 88 return; 89 } 90 91 void INV::evaluateModel() 92 { 93 return; 94 } 95 96 void INV::useModel() 97 { 98 // Get parameters 99 double drive_strength = getDrivingStrength(); 100 Map<double>* cache = getTechModel()->getStdCellLib()->getStdCellCache(); 101 102 // Standard cell cache string 103 String cell_name = "INV_X" + (String) drive_strength; 104 105 // Propagate the transition info and get the 0->1 transtion count 106 propagateTransitionInfo(); 107 double P_A = getInputPort("A")->getTransitionInfo().getProbability1(); 108 double Y_num_trans_01 = getOutputPort("Y")->getTransitionInfo().getNumberTransitions01(); 109 110 // Calculate leakage 111 double leakage = 0; 112 leakage += cache->get(cell_name + "->Leakage->!A") * (1 - P_A); 113 leakage += cache->get(cell_name + "->Leakage->A") * P_A; 114 getNddPowerResult("Leakage")->setValue(leakage); 115 116 // Get VDD 117 double vdd = getTechModel()->get("Vdd"); 118 119 // Get capacitances 120 //double a_cap = cache->get(cell_name + "->Cap->A"); 121 double y_cap = cache->get(cell_name + "->Cap->Y"); 122 double y_load_cap = getNet("Y")->getTotalDownstreamCap(); 123 124 // Calculate INV Event energy 125 double energy_per_trans_01 = (y_cap + y_load_cap) * vdd * vdd; 126 getEventResult("INV")->setValue(energy_per_trans_01 * Y_num_trans_01); 127 return; 128 } 129 130 void INV::propagateTransitionInfo() 131 { 132 // Get input transition info 133 const TransitionInfo& trans_A = getInputPort("A")->getTransitionInfo(); 134 135 // Set output transition info 136 double Y_num_trans_00 = trans_A.getNumberTransitions11(); 137 double Y_num_trans_01 = trans_A.getNumberTransitions01(); 138 double Y_num_trans_11 = trans_A.getNumberTransitions00(); 139 140 TransitionInfo trans_Y(Y_num_trans_00, Y_num_trans_01, Y_num_trans_11); 141 getOutputPort("Y")->setTransitionInfo(trans_Y); 142 return; 143 } 144 145 // Creates the standard cell, characterizes and abstracts away the details 146 void INV::cacheStdCell(StdCellLib* cell_lib_, double drive_strength_) 147 { 148 // Standard cell cache string 149 String cell_name = "INV_X" + (String) drive_strength_; 150 151 Log::printLine("=== " + cell_name + " ==="); 152 153 // Get parameters 154 double gate_pitch = cell_lib_->getTechModel()->get("Gate->PitchContacted"); 155 Map<double>* cache = cell_lib_->getStdCellCache(); 156 157 // Now actually build the full standard cell model 158 // Create the two input ports 159 createInputPort("A"); 160 createOutputPort("Y"); 161 162 // Adds macros 163 CellMacros::addInverter(this, "INV", true, true, "A", "Y"); 164 CellMacros::updateInverter(this, "INV", drive_strength_); 165 166 // Cache area result 167 double area = gate_pitch * getTotalHeight() * (1 + getGenProperties()->get("INV_GatePitches").toDouble()); 168 cache->set(cell_name + "->Area->Active", area); 169 cache->set(cell_name + "->Area->Metal1Wire", area); 170 Log::printLine(cell_name + "->Area->Active=" + (String) area); 171 Log::printLine(cell_name + "->Area->Metal1Wire=" + (String) area); 172 173 // -------------------------------------------------------------------- 174 // Leakage Model Calculation 175 // -------------------------------------------------------------------- 176 double leakage_a0 = getGenProperties()->get("INV_LeakagePower_0").toDouble(); 177 double leakage_a1 = getGenProperties()->get("INV_LeakagePower_1").toDouble(); 178 cache->set(cell_name + "->Leakage->!A", leakage_a0); 179 cache->set(cell_name + "->Leakage->A", leakage_a1); 180 Log::printLine(cell_name + "->Leakage->!A=" + (String) leakage_a0); 181 Log::printLine(cell_name + "->Leakage->A=" + (String) leakage_a1); 182 // -------------------------------------------------------------------- 183 184 /* 185 // Cache event energy results 186 double event_a_flip = getGenProperties()->get("INV_A_Flip").toDouble() + getGenProperties()->get("INV_ZN_Flip").toDouble(); 187 cache->set(cell_name + "->Event_A_Flip", event_a_flip); 188 Log::printLine(cell_name + "->Event_A_Flip=" + (String) event_a_flip); 189 */ 190 191 // -------------------------------------------------------------------- 192 // Get Node Capacitances 193 // -------------------------------------------------------------------- 194 double a_cap = getNet("A")->getTotalDownstreamCap(); 195 double y_cap = getNet("Y")->getTotalDownstreamCap(); 196 197 cache->set(cell_name + "->Cap->A", a_cap); 198 cache->set(cell_name + "->Cap->Y", y_cap); 199 Log::printLine(cell_name + "->Cap->A=" + (String) a_cap); 200 Log::printLine(cell_name + "->Cap->Y=" + (String) y_cap); 201 // -------------------------------------------------------------------- 202 203 // -------------------------------------------------------------------- 204 // Build Internal Delay Model 205 // -------------------------------------------------------------------- 206 double y_ron = getDriver("INV_RonZN")->getOutputRes(); 207 double a_to_y_delay = getDriver("INV_RonZN")->calculateDelay(); 208 cache->set(cell_name + "->DriveRes->Y", y_ron); 209 cache->set(cell_name + "->Delay->A_to_Y", a_to_y_delay); 210 Log::printLine(cell_name + "->DriveRes->Y=" + (String) y_ron); 211 Log::printLine(cell_name + "->Delay->A_to_Y=" + (String) a_to_y_delay); 212 // -------------------------------------------------------------------- 213 214 return; 215 216 } 217 218} // namespace DSENT 219 220