1 /* Copyright (c) 2012 Massachusetts Institute of Technology
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:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
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
22 #include "model/std_cells/INV.h"
26 #include "model/PortInfo.h"
27 #include "model/TransitionInfo.h"
28 #include "model/EventInfo.h"
29 #include "model/std_cells/CellMacros.h"
30 #include "model/std_cells/StdCellLib.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"
41 INV::INV(const String
& instance_name_
, const TechModel
* tech_model_
)
42 : StdCell(instance_name_
, tech_model_
)
50 void INV::initProperties()
55 void INV::constructModel()
57 // All constructModel should do is create Area/NDDPower/Energy Results as
58 // well as instantiate any sub-instances using only the hard parameters
60 // Build Electrical Connectivity
62 createOutputPort("Y");
65 createDelay("A_to_Y_delay");
66 createDriver("Y_Ron", true);
68 ElectricalLoad
* a_cap
= getLoad("A_Cap");
69 ElectricalDelay
* a_to_y_delay
= getDelay("A_to_Y_delay");
70 ElectricalDriver
* y_ron
= getDriver("Y_Ron");
72 getNet("A")->addDownstreamNode(a_cap
);
73 a_cap
->addDownstreamNode(a_to_y_delay
);
74 a_to_y_delay
->addDownstreamNode(y_ron
);
75 y_ron
->addDownstreamNode(getNet("Y"));
78 // Create NDD Power result
79 createElectricalAtomicResults();
80 // Create INV Event Energy Result
81 createElectricalEventAtomicResult("INV");
83 getEventInfo("Idle")->setStaticTransitionInfos();
88 void INV::updateModel()
90 // All updateModel should do is calculate numbers for the Area/NDDPower/Energy
91 // Results as anything else that needs to be done using either soft or hard parameters
94 double drive_strength
= getDrivingStrength();
95 Map
<double>* cache
= getTechModel()->getStdCellLib()->getStdCellCache();
97 // Standard cell cache string
98 String cell_name
= "INV_X" + (String
) drive_strength
;
100 // Get timing parameters
101 getLoad("A_Cap")->setLoadCap(cache
->get(cell_name
+ "->Cap->A"));
102 getDriver("Y_Ron")->setOutputRes(cache
->get(cell_name
+ "->DriveRes->Y"));
103 getDelay("A_to_Y_delay")->setDelay(cache
->get(cell_name
+ "->Delay->A_to_Y"));
106 getAreaResult("Active")->setValue(cache
->get(cell_name
+ "->Area->Active"));
107 getAreaResult("Metal1Wire")->setValue(cache
->get(cell_name
+ "->Area->Metal1Wire"));
112 void INV::evaluateModel()
120 double drive_strength
= getDrivingStrength();
121 Map
<double>* cache
= getTechModel()->getStdCellLib()->getStdCellCache();
123 // Standard cell cache string
124 String cell_name
= "INV_X" + (String
) drive_strength
;
126 // Propagate the transition info and get the 0->1 transtion count
127 propagateTransitionInfo();
128 double P_A
= getInputPort("A")->getTransitionInfo().getProbability1();
129 double Y_num_trans_01
= getOutputPort("Y")->getTransitionInfo().getNumberTransitions01();
133 leakage
+= cache
->get(cell_name
+ "->Leakage->!A") * (1 - P_A
);
134 leakage
+= cache
->get(cell_name
+ "->Leakage->A") * P_A
;
135 getNddPowerResult("Leakage")->setValue(leakage
);
138 double vdd
= getTechModel()->get("Vdd");
141 //double a_cap = cache->get(cell_name + "->Cap->A");
142 double y_cap
= cache
->get(cell_name
+ "->Cap->Y");
143 double y_load_cap
= getNet("Y")->getTotalDownstreamCap();
145 // Calculate INV Event energy
146 double energy_per_trans_01
= (y_cap
+ y_load_cap
) * vdd
* vdd
;
147 getEventResult("INV")->setValue(energy_per_trans_01
* Y_num_trans_01
);
151 void INV::propagateTransitionInfo()
153 // Get input transition info
154 const TransitionInfo
& trans_A
= getInputPort("A")->getTransitionInfo();
156 // Set output transition info
157 double Y_num_trans_00
= trans_A
.getNumberTransitions11();
158 double Y_num_trans_01
= trans_A
.getNumberTransitions01();
159 double Y_num_trans_11
= trans_A
.getNumberTransitions00();
161 TransitionInfo
trans_Y(Y_num_trans_00
, Y_num_trans_01
, Y_num_trans_11
);
162 getOutputPort("Y")->setTransitionInfo(trans_Y
);
166 // Creates the standard cell, characterizes and abstracts away the details
167 void INV::cacheStdCell(StdCellLib
* cell_lib_
, double drive_strength_
)
169 // Standard cell cache string
170 String cell_name
= "INV_X" + (String
) drive_strength_
;
172 Log::printLine("=== " + cell_name
+ " ===");
175 double gate_pitch
= cell_lib_
->getTechModel()->get("Gate->PitchContacted");
176 Map
<double>* cache
= cell_lib_
->getStdCellCache();
178 // Now actually build the full standard cell model
179 // Create the two input ports
180 createInputPort("A");
181 createOutputPort("Y");
184 CellMacros::addInverter(this, "INV", true, true, "A", "Y");
185 CellMacros::updateInverter(this, "INV", drive_strength_
);
188 double area
= gate_pitch
* getTotalHeight() * (1 + getGenProperties()->get("INV_GatePitches").toDouble());
189 cache
->set(cell_name
+ "->Area->Active", area
);
190 cache
->set(cell_name
+ "->Area->Metal1Wire", area
);
191 Log::printLine(cell_name
+ "->Area->Active=" + (String
) area
);
192 Log::printLine(cell_name
+ "->Area->Metal1Wire=" + (String
) area
);
194 // --------------------------------------------------------------------
195 // Leakage Model Calculation
196 // --------------------------------------------------------------------
197 double leakage_a0
= getGenProperties()->get("INV_LeakagePower_0").toDouble();
198 double leakage_a1
= getGenProperties()->get("INV_LeakagePower_1").toDouble();
199 cache
->set(cell_name
+ "->Leakage->!A", leakage_a0
);
200 cache
->set(cell_name
+ "->Leakage->A", leakage_a1
);
201 Log::printLine(cell_name
+ "->Leakage->!A=" + (String
) leakage_a0
);
202 Log::printLine(cell_name
+ "->Leakage->A=" + (String
) leakage_a1
);
203 // --------------------------------------------------------------------
206 // Cache event energy results
207 double event_a_flip = getGenProperties()->get("INV_A_Flip").toDouble() + getGenProperties()->get("INV_ZN_Flip").toDouble();
208 cache->set(cell_name + "->Event_A_Flip", event_a_flip);
209 Log::printLine(cell_name + "->Event_A_Flip=" + (String) event_a_flip);
212 // --------------------------------------------------------------------
213 // Get Node Capacitances
214 // --------------------------------------------------------------------
215 double a_cap
= getNet("A")->getTotalDownstreamCap();
216 double y_cap
= getNet("Y")->getTotalDownstreamCap();
218 cache
->set(cell_name
+ "->Cap->A", a_cap
);
219 cache
->set(cell_name
+ "->Cap->Y", y_cap
);
220 Log::printLine(cell_name
+ "->Cap->A=" + (String
) a_cap
);
221 Log::printLine(cell_name
+ "->Cap->Y=" + (String
) y_cap
);
222 // --------------------------------------------------------------------
224 // --------------------------------------------------------------------
225 // Build Internal Delay Model
226 // --------------------------------------------------------------------
227 double y_ron
= getDriver("INV_RonZN")->getOutputRes();
228 double a_to_y_delay
= getDriver("INV_RonZN")->calculateDelay();
229 cache
->set(cell_name
+ "->DriveRes->Y", y_ron
);
230 cache
->set(cell_name
+ "->Delay->A_to_Y", a_to_y_delay
);
231 Log::printLine(cell_name
+ "->DriveRes->Y=" + (String
) y_ron
);
232 Log::printLine(cell_name
+ "->Delay->A_to_Y=" + (String
) a_to_y_delay
);
233 // --------------------------------------------------------------------