OR.cc revision 10447:a465576671d4
1#include "model/electrical/OR.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/StdCell.h" 10#include "model/timing_graph/ElectricalNet.h" 11 12namespace DSENT 13{ 14 using std::ceil; 15 using std::floor; 16 17 OR::OR(const String& instance_name_, const TechModel* tech_model_) 18 : ElectricalModel(instance_name_, tech_model_) 19 { 20 initParameters(); 21 initProperties(); 22 } 23 24 OR::~OR() 25 {} 26 27 void OR::initParameters() 28 { 29 addParameterName("NumberInputs"); 30 addParameterName("NumberBits"); 31 addParameterName("BitDuplicate", "TRUE"); 32 return; 33 } 34 35 void OR::initProperties() 36 { 37 return; 38 } 39 40 OR* OR::clone() const 41 { 42 // TODO 43 return NULL; 44 } 45 46 void OR::constructModel() 47 { 48 // Get parameter 49 unsigned int number_inputs = getParameter("NumberInputs").toUInt(); 50 unsigned int number_bits = getParameter("NumberBits").toUInt(); 51 bool bit_duplicate = getParameter("BitDuplicate").toBool(); 52 53 ASSERT(number_inputs > 0, "[Error] " + getInstanceName() + 54 " -> Number of inputs must be > 0!"); 55 ASSERT(number_bits > 0, "[Error] " + getInstanceName() + 56 " -> Number of bits must be > 0!"); 57 58 59 // Init ports 60 for(unsigned int i = 0; i < number_inputs; ++i) 61 { 62 createInputPort("In" + (String)i, makeNetIndex(0, number_bits-1)); 63 } 64 createOutputPort("Out", makeNetIndex(0, number_bits-1)); 65 66 // Number of inputs on the 0 side 67 unsigned int or0_number_inputs = (unsigned int)ceil((double)number_inputs / 2.0); 68 // Number of inputs on the 1 side 69 unsigned int or1_number_inputs = (unsigned int)floor((double)number_inputs / 2.0); 70 71 // Create area, power, and event results 72 createElectricalResults(); 73 createElectricalEventResult("OR"); 74 75 getEventInfo("Idle")->setStaticTransitionInfos(); 76 77 //Depending on whether we want to create a 1-bit instance and have it multiplied 78 //up by number of bits or actually instantiate number_bits of 1-bit instances. 79 //Recursively instantiates smaller ors 80 if(bit_duplicate || number_bits == 1) 81 { 82 // If it is just a 1-input or, just connect output to input 83 if(number_inputs == 1) 84 { 85 assign("Out", "In0"); 86 } 87 else 88 { 89 // If it is more than 1 input, instantiate two sub ors (OR_way0 and OR_way1) 90 // and create a final OR2 to OR them 91 const String& or0_name = "OR_way0"; 92 const String& or1_name = "OR_way1"; 93 const String& orf_name = "OR2_i" + (String)number_inputs; 94 95 OR* or0 = new OR(or0_name, getTechModel()); 96 or0->setParameter("NumberInputs", or0_number_inputs); 97 or0->setParameter("NumberBits", 1); 98 or0->setParameter("BitDuplicate", "TRUE"); 99 or0->construct(); 100 101 OR* or1 = new OR(or1_name, getTechModel()); 102 or1->setParameter("NumberInputs", or1_number_inputs); 103 or1->setParameter("NumberBits", 1); 104 or1->setParameter("BitDuplicate", "TRUE"); 105 or1->construct(); 106 107 StdCell* orf = getTechModel()->getStdCellLib()->createStdCell("OR2", orf_name); 108 orf->construct(); 109 110 // Create outputs of way0 and way1 ors with final or 111 createNet("way0_Out"); 112 createNet("way1_Out"); 113 portConnect(or0, "Out", "way0_Out"); 114 portConnect(or1, "Out", "way1_Out"); 115 portConnect(orf, "A", "way0_Out"); 116 portConnect(orf, "B", "way1_Out"); 117 118 // Connect inputs to the sub ors. 119 for(unsigned int i = 0; i < or0_number_inputs; ++i) 120 { 121 createNet("way0_In" + (String)i); 122 portConnect(or0, "In" + (String)i, "way0_In" + (String)i); 123 assignVirtualFanin("way0_In" + (String)i, "In" + (String)i); 124 } 125 for(unsigned int i = 0; i < or1_number_inputs; ++i) 126 { 127 createNet("way1_In" + (String)i); 128 portConnect(or1, "In" + (String)i, "way1_In" + (String)i); 129 assignVirtualFanin("way1_In" + (String)i, "In" + (String)(i + or0_number_inputs)); 130 } 131 132 // Connect outputs 133 createNet("OR2_Out"); 134 portConnect(orf, "Y", "OR2_Out"); 135 assignVirtualFanout("Out", "OR2_Out"); 136 137 addSubInstances(or0, number_bits); 138 addElectricalSubResults(or0, number_bits); 139 addSubInstances(or1, number_bits); 140 addElectricalSubResults(or1, number_bits); 141 addSubInstances(orf, number_bits); 142 addElectricalSubResults(orf, number_bits); 143 144 Result* or_event = getEventResult("OR"); 145 or_event->addSubResult(or0->getEventResult("OR"), or0_name, number_bits); 146 or_event->addSubResult(or1->getEventResult("OR"), or1_name, number_bits); 147 or_event->addSubResult(orf->getEventResult("OR2"), orf_name, number_bits); 148 149 } 150 } 151 else 152 { 153 // Init a bunch of 1-bit ors 154 Result* or_event = getEventResult("OR"); 155 for(unsigned int n = 0; n < number_bits; ++n) 156 { 157 const String& or_name = "OR_bit" + (String)n; 158 159 OR* ors = new OR(or_name, getTechModel()); 160 ors->setParameter("NumberInputs", number_inputs); 161 ors->setParameter("NumberBits", 1); 162 ors->setParameter("BitDuplicate", "TRUE"); 163 ors->construct(); 164 165 for(unsigned int i = 0; i < number_inputs; ++i) 166 { 167 portConnect(ors, "In" + (String)i, "In" + (String)i, makeNetIndex(n)); 168 } 169 portConnect(ors, "Out", "Out", makeNetIndex(n)); 170 171 addSubInstances(ors, 1.0); 172 addElectricalSubResults(ors, 1.0); 173 or_event->addSubResult(ors->getEventResult("OR"), or_name, 1.0); 174 } 175 } 176 return; 177 } 178 179 void OR::propagateTransitionInfo() 180 { 181 // Get parameters 182 unsigned int number_inputs = getParameter("NumberInputs").toUInt(); 183 unsigned int number_bits = getParameter("NumberBits").toUInt(); 184 bool bit_duplicate = getParameter("BitDuplicate").toBool(); 185 186 // Number of inputs on 0 side 187 unsigned int or0_number_inputs = (unsigned int)ceil((double)number_inputs / 2.0); 188 unsigned int or1_number_inputs = (unsigned int)floor((double)number_inputs / 2.0); 189 190 if(bit_duplicate || number_bits == 1) 191 { 192 if(number_inputs == 1) 193 { 194 propagatePortTransitionInfo("Out", "In0"); 195 } 196 else 197 { 198 ElectricalModel* or0 = (ElectricalModel*)getSubInstance("OR_way0"); 199 for(unsigned int i = 0; i < or0_number_inputs; ++i) 200 { 201 propagatePortTransitionInfo(or0, "In" + (String)i, "In" + (String)i); 202 } 203 or0->use(); 204 205 ElectricalModel* or1 = (ElectricalModel*)getSubInstance("OR_way1"); 206 for(unsigned int i = 0; i < or1_number_inputs; ++i) 207 { 208 propagatePortTransitionInfo(or1, "In" + (String)i, "In" + (String)i); 209 } 210 or1->use(); 211 212 ElectricalModel* orf = (ElectricalModel*)getSubInstance("OR2_i" + (String)number_inputs); 213 propagatePortTransitionInfo(orf, "A", or0, "Out"); 214 propagatePortTransitionInfo(orf, "B", or1, "Out"); 215 orf->use(); 216 217 // Set output probability 218 propagatePortTransitionInfo("Out", orf, "Y"); 219 } 220 } 221 else 222 { 223 for(unsigned int n = 0; n < number_bits; ++n) 224 { 225 ElectricalModel* or_bit = (ElectricalModel*)getSubInstance("OR_bit" + (String)n); 226 for(unsigned int i = 0; i < number_inputs; ++i) 227 { 228 propagatePortTransitionInfo(or_bit, "In" + (String)i, "In" + (String)i); 229 } 230 or_bit->use(); 231 } 232 233 ElectricalModel* or_bit = (ElectricalModel*)getSubInstance("OR_bit0"); 234 propagatePortTransitionInfo("Out", or_bit, "Out"); 235 } 236 return; 237 } 238} // namespace DSENT 239 240