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/ElectricalModel.h" 23 24#include "model/PortInfo.h" 25#include "model/EventInfo.h" 26#include "model/timing_graph/ElectricalDriver.h" 27#include "model/timing_graph/ElectricalDriverMultiplier.h" 28#include "model/timing_graph/ElectricalNet.h" 29#include "model/timing_graph/ElectricalLoad.h" 30#include "model/timing_graph/ElectricalDelay.h" 31 32namespace DSENT 33{ 34 ElectricalModel::ElectricalModel(const String& instance_name_, const TechModel* tech_model_) 35 : Model(instance_name_, tech_model_) 36 { 37 m_curr_driving_strengths_idx_ = -1; 38 m_input_ports_ = new Map<PortInfo*>; 39 m_output_ports_ = new Map<PortInfo*>; 40 m_net_references_ = new Map<NetIndex>; 41 m_drivers_ = new Map<ElectricalDriver*>; 42 m_driver_multipliers_ = new Map<ElectricalDriverMultiplier*>; 43 m_nets_ = new Map<ElectricalNet*>; 44 m_loads_ = new Map<ElectricalLoad*>; 45 m_delays_ = new Map<ElectricalDelay*>; 46 m_event_infos_ = new Map<EventInfo*>; 47 } 48 49 ElectricalModel::~ElectricalModel() 50 { 51 deletePtrMap<PortInfo>(m_input_ports_); 52 deletePtrMap<PortInfo>(m_output_ports_); 53 delete m_net_references_; 54 deletePtrMap<ElectricalDriver>(m_drivers_); 55 deletePtrMap<ElectricalDriverMultiplier>(m_driver_multipliers_); 56 deletePtrMap<ElectricalNet>(m_nets_); 57 deletePtrMap<ElectricalLoad>(m_loads_); 58 deletePtrMap<ElectricalDelay>(m_delays_); 59 deletePtrMap<EventInfo>(m_event_infos_); 60 m_input_ports_ = NULL; 61 m_output_ports_ = NULL; 62 m_net_references_ = NULL; 63 m_drivers_ = NULL; 64 m_driver_multipliers_ = NULL; 65 m_nets_ = NULL; 66 m_loads_ = NULL; 67 m_net_references_ = NULL; 68 m_event_infos_ = NULL; 69 } 70 71 void ElectricalModel::checkProperties() const 72 { 73 // Check if the specified driving strength exists in the available driving strengths 74 if(getProperties()->keyExist("DrivingStrength")) 75 { 76 const double driving_strength = getProperty("DrivingStrength"); 77 bool is_found = false; 78 for(int i = 0; i < (int)m_driving_strengths_.size(); ++i) 79 { 80 if(driving_strength == m_driving_strengths_[i]) 81 { 82 is_found = true; 83 break; 84 } 85 } 86 ASSERT(is_found, "[Error] " + getInstanceName() + 87 " -> Driving strength (" + String(driving_strength) + ")" 88 " not found in available driving strengths (" + 89 getParameter("AvailableDrivingStrengths")); 90 } 91 92 // Do normal check on the properties 93 Model::checkProperties(); 94 return; 95 } 96 97 double ElectricalModel::getDrivingStrength() const 98 { 99 if(m_curr_driving_strengths_idx_ == -1) 100 { 101 return 0; 102 } 103 else 104 { 105 return m_driving_strengths_[m_curr_driving_strengths_idx_]; 106 } 107 } 108 109 int ElectricalModel::getDrivingStrengthIdx() const 110 { 111 return m_curr_driving_strengths_idx_; 112 } 113 114 void ElectricalModel::setDrivingStrengthIdx(int idx_) 115 { 116 ASSERT(((idx_ >= 0) && (idx_ < (int)m_driving_strengths_.size())), 117 "[Error] " + getInstanceName() + 118 " -> Driving strength index out of range (" + String(idx_) + ")"); 119 120 m_curr_driving_strengths_idx_ = idx_; 121 setProperty("DrivingStrength", m_driving_strengths_[m_curr_driving_strengths_idx_]); 122 123 Log::printLine(getInstanceName() + " -> Changing drive strength to " + (String) m_driving_strengths_[m_curr_driving_strengths_idx_]); 124 update(); 125 return; 126 } 127 128 void ElectricalModel::setMinDrivingStrength() 129 { 130 setDrivingStrengthIdx(0); 131 return; 132 } 133 134 bool ElectricalModel::hasMinDrivingStrength() const 135 { 136 return (m_curr_driving_strengths_idx_ == 0); 137 } 138 139 bool ElectricalModel::hasMaxDrivingStrength() const 140 { 141 return (m_curr_driving_strengths_idx_ == ((int)m_driving_strengths_.size() - 1)); 142 } 143 144 void ElectricalModel::increaseDrivingStrength() 145 { 146 if(!hasMaxDrivingStrength()) 147 { 148 setDrivingStrengthIdx(m_curr_driving_strengths_idx_ + 1); 149 } 150 return; 151 } 152 153 void ElectricalModel::decreaseDrivingStrength() 154 { 155 if(!hasMinDrivingStrength()) 156 { 157 setDrivingStrengthIdx(m_curr_driving_strengths_idx_ - 1); 158 } 159 return; 160 } 161 162 void ElectricalModel::setAvailableDrivingStrengths(const String& driving_strengths_) 163 { 164 setParameter("AvailableDrivingStrengths", driving_strengths_); 165 const vector<String>& split_str = driving_strengths_.split("[,"); 166 167 // Check if there is at least one driving strength specified 168 ASSERT(!split_str.empty(), "[Error] " + getInstanceName() + 169 " -> Specified driving strength string does not contain any driving strengths (" + 170 driving_strengths_ + ")"); 171 172 // TODO - check if the driving strengths is sorted 173 174 // Overwrite the available driving strengths 175 m_driving_strengths_.clear(); 176 for(int i = 0; i < (int)split_str.size(); ++i) 177 { 178 m_driving_strengths_.push_back(split_str[i].toDouble()); 179 } 180 181 // Set the driving strength to minimum 182 m_curr_driving_strengths_idx_ = 0; 183 setProperty("DrivingStrength", m_driving_strengths_[m_curr_driving_strengths_idx_]); 184 return; 185 } 186 187 // Connect a port (input or output) to some ElectricalNet 188 void ElectricalModel::portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_) 189 { 190 ASSERT(m_net_references_->keyExist(connect_net_name_), "[Error] " + getInstanceName() + 191 " -> Net '" + connect_net_name_ + "' does not exist!"); 192 193 portConnect(connect_model_, connect_port_name_, connect_net_name_, m_net_references_->get(connect_net_name_)); 194 } 195 196 void ElectricalModel::portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_, const NetIndex& connect_net_indices_) 197 { 198 ASSERT(m_net_references_->keyExist(connect_net_name_), "[Error] " + getInstanceName() + 199 " -> Net '" + connect_net_name_ + "' does not exist!"); 200 201 // Check whether the port name is an input or output, ASSERTion error if neither 202 bool is_input = connect_model_->getInputs()->keyExist(connect_port_name_); 203 bool is_output = connect_model_->getOutputs()->keyExist(connect_port_name_); 204 205 ASSERT(is_input || is_output, "[Error] " + getInstanceName() + " -> Model '" + connect_model_->getInstanceName() + 206 "' does not have a port named '" + connect_port_name_ + "'!"); 207 208 int connect_net_width = connect_net_indices_.second - connect_net_indices_.first + 1; 209 const NetIndex& port_indices = connect_model_->getNetReference(connect_port_name_); 210 int port_width = port_indices.second - port_indices.first + 1; 211 212 ASSERT(connect_net_width == port_width, "[Error] " + getInstanceName() + " -> Port width mismatch for Model '" + 213 connect_model_->getInstanceName() + "." + connect_port_name_ + toString(port_indices) + 214 "' and net '" + connect_net_name_ + toString(connect_net_indices_) + "'!"); 215 216 int port_index = port_indices.first; 217 int connect_net_index = connect_net_indices_.first; 218 219 if(is_input) 220 { 221 while(port_index <= port_indices.second) 222 { 223 getNet(connect_net_name_, makeNetIndex(connect_net_index))->addDownstreamNode( 224 connect_model_->getNet(connect_port_name_, makeNetIndex(port_index))); 225 ++port_index; 226 ++connect_net_index; 227 } 228 } 229 else if(is_output) 230 { 231 while (port_index <= port_indices.second) 232 { 233 connect_model_->getNet(connect_port_name_, makeNetIndex(port_index))->addDownstreamNode( 234 getNet(connect_net_name_, makeNetIndex(connect_net_index))); 235 ++port_index; 236 ++connect_net_index; 237 } 238 } 239 } 240 241 //Get Drivers 242 const Map<ElectricalDriver*>* ElectricalModel::getDrivers() const 243 { 244 return m_drivers_; 245 } 246 247 ElectricalDriver* ElectricalModel::getDriver(const String& name_) 248 { 249 return m_drivers_->get(name_); 250 } 251 252 //Get Driver Multipliers 253 const Map<ElectricalDriverMultiplier*>* ElectricalModel::getDriverMultipliers() const 254 { 255 return m_driver_multipliers_; 256 } 257 258 ElectricalDriverMultiplier* ElectricalModel::getDriverMultiplier(const String& name_) 259 { 260 return m_driver_multipliers_->get(name_); 261 } 262 263 //Get Nets 264 const Map<ElectricalNet*>* ElectricalModel::getNets() const 265 { 266 return m_nets_; 267 } 268 269 ElectricalNet* ElectricalModel::getNet(const String& name_) 270 { 271 return getNet(name_, m_net_references_->get(name_)); 272 } 273 274 ElectricalNet* ElectricalModel::getNet(const String& name_, const NetIndex& index_) 275 { 276 ASSERT(index_.first == index_.second, "[Error] " + getInstanceName() + 277 " -> Ambiguous get net since (" + name_ + ") is a bus consisting of several nets!"); 278 return m_nets_->get(name_ + "[" + (String) index_.first + "]"); 279 } 280 281 //Get Loads 282 const Map<ElectricalLoad*>* ElectricalModel::getLoads() const 283 { 284 return m_loads_; 285 } 286 287 ElectricalLoad* ElectricalModel::getLoad(const String& name_) 288 { 289 return m_loads_->get(name_); 290 } 291 292 //Get Delays 293 const Map<ElectricalDelay*>* ElectricalModel::getDelays() const 294 { 295 return m_delays_; 296 } 297 298 ElectricalDelay* ElectricalModel::getDelay(const String& name_) 299 { 300 return m_delays_->get(name_); 301 } 302 303 //Get Inputs 304 const Map<PortInfo*>* ElectricalModel::getInputs() const 305 { 306 return m_input_ports_; 307 } 308 309 PortInfo* ElectricalModel::getInputPort(const String& name_) 310 { 311 ASSERT(m_input_ports_->keyExist(name_), "[Error] " + getInstanceName() + 312 " -> Input port (" + name_ + ") does not exist"); 313 314 return m_input_ports_->get(name_); 315 } 316 317 const PortInfo* ElectricalModel::getInputPort(const String& name_) const 318 { 319 ASSERT(m_input_ports_->keyExist(name_), "[Error] " + getInstanceName() + 320 " -> Input port (" + name_ + ") does not exist"); 321 322 return m_input_ports_->get(name_); 323 } 324 325 //Get Outputs 326 const Map<PortInfo*>* ElectricalModel::getOutputs() const 327 { 328 return m_output_ports_; 329 } 330 331 PortInfo* ElectricalModel::getOutputPort(const String& name_) 332 { 333 ASSERT(m_output_ports_->keyExist(name_), "[Error] " + getInstanceName() + 334 " -> Output port (" + name_ + ") does not exist"); 335 336 return m_output_ports_->get(name_); 337 } 338 339 const PortInfo* ElectricalModel::getOutputPort(const String& name_) const 340 { 341 ASSERT(m_output_ports_->keyExist(name_), "[Error] " + getInstanceName() + 342 " -> Output port (" + name_ + ") does not exist"); 343 344 return m_output_ports_->get(name_); 345 } 346 347 const Map<NetIndex>* ElectricalModel::getNetReferences() const 348 { 349 return m_net_references_; 350 } 351 352 const NetIndex ElectricalModel::getNetReference(const String& name_) const 353 { 354 return m_net_references_->get(name_); 355 } 356 357 //------------------------------------------------------------------------- 358 // Electrical Connectivity and Timing Element Creation Functions 359 //------------------------------------------------------------------------- 360 361 // Input Port creation 362 void ElectricalModel::createInputPort(const String& name_, const NetIndex& net_indices_) 363 { 364 // Create the new nets (including its net reference) 365 // This should already check that it has not been previously declared 366 createNet(name_, net_indices_); 367 // Add the net name to list of input ports 368 m_input_ports_->set(name_, new PortInfo(name_, net_indices_)); 369 return; 370 } 371 372 // Output Port creation 373 void ElectricalModel::createOutputPort(const String& name_, const NetIndex& net_indices_) 374 { 375 // Create the new nets (including its net reference) 376 // This should already check that it has not been previously declared 377 createNet(name_, net_indices_); 378 // Add the net name to list of output ports 379 m_output_ports_->set(name_, new PortInfo(name_, net_indices_)); 380 return; 381 } 382 383 // Net creation 384 void ElectricalModel::createNet(const String& name_) 385 { 386 // Creating a net with specifying an index range means that the net is just 387 // a 1-bit wire indexed at [0] 388 createNet(name_, makeNetIndex(0, 0)); 389 return; 390 } 391 392 void ElectricalModel::createNet(const String& name_, const NetIndex& net_indices_) 393 { 394 // Check that it hasn't been previously declared 395 ASSERT( !m_nets_->keyExist(name_) && !m_net_references_->keyExist(name_), 396 "[Error] " + getInstanceName() + " -> Redeclaration of net " + name_); 397 398 int start = net_indices_.first; 399 int end = net_indices_.second; 400 401 for (int index = start; index <= end; ++index) 402 { 403 String indexed_name = name_ + "[" + (String) index + "]"; 404 // Create the new net 405 ElectricalNet* net = new ElectricalNet(indexed_name, this); 406 // Add the net to net map 407 m_nets_->set(indexed_name, net); 408 } 409 // Add net to net references 410 m_net_references_->set(name_, net_indices_); 411 return; 412 } 413 414 // Driver creation 415 void ElectricalModel::createDriver(const String& name_, bool sizable_) 416 { 417 // Check that it hasn't been previously declared 418 ASSERT( !m_drivers_->keyExist(name_), 419 "[Error] " + getInstanceName() + " -> Redeclaration of driver " + name_); 420 421 ElectricalDriver* driver = new ElectricalDriver(name_, this, sizable_); 422 m_drivers_->set(name_, driver); 423 return; 424 } 425 426 /* 427 void ElectricalModel::createDriver(const String& name_, bool sizable_, int start_index_, int end_index_) 428 { 429 for (int index = start_index_; index <= end_index_; ++index) 430 { 431 createDriver(name_ + "[" + (String) index + "]", sizable_); 432 } 433 return; 434 } 435 */ 436 437 // Driver Multiplier creation 438 void ElectricalModel::createDriverMultiplier(const String& name_) 439 { 440 // Check that it hasn't been previously declared 441 ASSERT( !m_driver_multipliers_->keyExist(name_), 442 "[Error] " + getInstanceName() + " -> Redeclaration of driver_multiplier " + name_); 443 444 ElectricalDriverMultiplier* driver_multiplier = new ElectricalDriverMultiplier(name_, this); 445 m_driver_multipliers_->set(name_, driver_multiplier); 446 return; 447 } 448 449 // Load creation 450 451 void ElectricalModel::createLoad(const String& name_) 452 { 453 // Check that it hasn't been previously declared 454 ASSERT( !m_loads_->keyExist(name_), 455 "[Error] " + getInstanceName() + " -> Redeclaration of load " + name_); 456 457 ElectricalLoad* load = new ElectricalLoad(name_, this); 458 m_loads_->set(name_, load); 459 return; 460 } 461 462 /* 463 void ElectricalModel::createLoad(const String& name_, int start_index_, int end_index_) 464 { 465 for (int index = start_index_; index <= end_index_; ++index) 466 { 467 createLoad(name_ + "[" + (String) index + "]"); 468 } 469 return; 470 } 471 */ 472 473 // Delay creation 474 void ElectricalModel::createDelay(const String& name_) 475 { 476 // Check that it hasn't been previously declared 477 ASSERT( !m_delays_->keyExist(name_), 478 "[Error] " + getInstanceName() + " -> Redeclaration of delay " + name_); 479 480 ElectricalDelay* delay = new ElectricalDelay(name_, this); 481 m_delays_->set(name_, delay); 482 return; 483 } 484 485 /* 486 void ElectricalModel::createDelay(const String& name_, int start_index_, int end_index_) 487 { 488 for (int index = start_index_; index <= end_index_; ++index) 489 { 490 createDelay(name_ + "[" + (String) index + "]"); 491 } 492 return; 493 } 494 */ 495 //------------------------------------------------------------------------- 496 497 // Assign a net to be downstream from another net 498 // case 1: 'assign downstream_net_name_ = upstream_net_name_' 499 void ElectricalModel::assign(const String& downstream_net_name_, const String& upstream_net_name_) 500 { 501 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 502 downstream_net_name_ + "' does not exist!"); 503 504 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 505 upstream_net_name_ + "' does not exist!"); 506 507 assign(downstream_net_name_, getNetReference(downstream_net_name_), 508 upstream_net_name_, getNetReference(upstream_net_name_)); 509 510 return; 511 } 512 513 // case 2: 'assign downstream_net_name_[begin:end] = upstream_net_name_' 514 void ElectricalModel::assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_) 515 { 516 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 517 downstream_net_name_ + "' does not exist!"); 518 519 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 520 upstream_net_name_ + "' does not exist!"); 521 522 assign(downstream_net_name_, downstream_net_indices_, 523 upstream_net_name_, getNetReference(upstream_net_name_)); 524 525 return; 526 } 527 528 // case 3: 'assign downstream_net_name_ = upstream_net_name_[begin:end]' 529 void ElectricalModel::assign(const String& downstream_net_name_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) 530 { 531 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 532 downstream_net_name_ + "' does not exist!"); 533 534 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 535 upstream_net_name_ + "' does not exist!"); 536 537 assign(downstream_net_name_, getNetReference(downstream_net_name_), 538 upstream_net_name_, upstream_net_indices_); 539 540 return; 541 } 542 // case 4: 'assign downstream_net_name_[begin:end] = upstream_net_name_[begin:end]' 543 void ElectricalModel::assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) 544 { 545 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 546 downstream_net_name_ + "' does not exist!"); 547 548 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 549 upstream_net_name_ + "' does not exist!"); 550 551 // Check that the assignment widths are the same 552 int downstream_width = downstream_net_indices_.second - downstream_net_indices_.first + 1; 553 int upstream_width = upstream_net_indices_.second - upstream_net_indices_.first + 1; 554 555 ASSERT(downstream_width == upstream_width, "[Error] " + getInstanceName() + " -> Assignment width mismatch: " + 556 downstream_net_name_ + " (" + (String) downstream_width + ") and " + 557 upstream_net_name_ + " (" + (String) upstream_width + ")"); 558 559 // Loop through indices and connect them together 560 int down_index = downstream_net_indices_.first; 561 int up_index = upstream_net_indices_.first; 562 while (down_index <= downstream_net_indices_.second) 563 { 564 getNet(upstream_net_name_, makeNetIndex(up_index))->addDownstreamNode( 565 getNet(downstream_net_name_, makeNetIndex(down_index))); 566 567 ++up_index; 568 ++down_index; 569 } 570 571 return; 572 } 573 574 // Assign a net to another net through a driver multiplier 575 void ElectricalModel::assignVirtualFanout(const String& downstream_net_name_, const String& upstream_net_name_) 576 { 577 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + 578 " -> Net '" + upstream_net_name_ + "' does not exist!"); 579 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + 580 " -> Net '" + downstream_net_name_ + "' does not exist!"); 581 582 assignVirtualFanout(downstream_net_name_, getNetReference(downstream_net_name_), upstream_net_name_, getNetReference(upstream_net_name_)); 583 return; 584 } 585 586 // Assign a net to another net through a driver multiplier 587 void ElectricalModel::assignVirtualFanout(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) 588 { 589 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + 590 " -> Net '" + upstream_net_name_ + "' does not exist!"); 591 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + 592 " -> Net '" + downstream_net_name_ + "' does not exist!"); 593 594 const String& drive_mult_name = upstream_net_name_ + "_" + (String) upstream_net_indices_.first + "_DriverMultiplier"; 595 bool is_drive_mult_exist = getDriverMultipliers()->keyExist(drive_mult_name); 596 597 // Create a driver multiplier and assign it to upstream_net since it doesn't exist 598 if(!is_drive_mult_exist) 599 { 600 createDriverMultiplier(drive_mult_name); 601 getNet(upstream_net_name_, upstream_net_indices_)->addDownstreamNode(getDriverMultiplier(drive_mult_name)); 602 } 603 604 // Assign downstream_net_name_[end:begin] = driver_multiplier_name_ 605 ElectricalDriverMultiplier* drive_mult = getDriverMultiplier(drive_mult_name); 606 int begin_index = downstream_net_indices_.first; 607 int end_index = downstream_net_indices_.second; 608 for(int i = begin_index; i <= end_index; ++i) 609 { 610 drive_mult->addDownstreamNode(getNet(downstream_net_name_, makeNetIndex(i))); 611 } 612 return; 613 } 614 615 void ElectricalModel::assignVirtualFanin(const String& downstream_net_name_, const String& upstream_net_name_) 616 { 617 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + 618 " -> Net '" + upstream_net_name_ + "' does not exist!"); 619 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + 620 " -> Net '" + downstream_net_name_ + "' does not exist!"); 621 622 assignVirtualFanin(downstream_net_name_, getNetReference(downstream_net_name_), upstream_net_name_, getNetReference(upstream_net_name_)); 623 return; 624 } 625 626 void ElectricalModel::assignVirtualFanin(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) 627 { 628 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + 629 " -> Net '" + upstream_net_name_ + "' does not exist!"); 630 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + 631 " -> Net '" + downstream_net_name_ + "' does not exist!"); 632 633 int begin_index = upstream_net_indices_.first; 634 int end_index = upstream_net_indices_.second; 635 636 for(int i = begin_index; i <= end_index; ++i) 637 { 638 getNet(upstream_net_name_, makeNetIndex(i))->addDownstreamNode(getNet(downstream_net_name_, downstream_net_indices_)); 639 } 640 return; 641 } 642 643 void ElectricalModel::createElectricalResults() 644 { 645 // Add active area result 646 addAreaResult(new Result("Active")); 647 648 // Add wire area result 649 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 650 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 651 TechModel::ConstWireLayerIterator it; 652 for(it = it_begin; it != it_end; ++it) 653 { 654 const String& layer_name = (*it); 655 addAreaResult(new Result(layer_name + "Wire")); 656 } 657 658 // Add leakage result 659 addNddPowerResult(new Result("Leakage")); 660 661 // Add idle event result 662 createElectricalEventResult("Idle"); 663 return; 664 } 665 666 void ElectricalModel::addElectricalSubResults(const ElectricalModel* model_, double number_models_) 667 { 668 // Add active area sub result 669 getAreaResult("Active")->addSubResult(model_->getAreaResult("Active"), model_->getInstanceName(), number_models_); 670 671 // Add wire area sub result 672 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 673 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 674 TechModel::ConstWireLayerIterator it; 675 for(it = it_begin; it != it_end; ++it) 676 { 677 const String& layer_name = (*it); 678 const String& result_name = layer_name + "Wire"; 679 getAreaResult(result_name)->addSubResult(model_->getAreaResult(result_name), model_->getInstanceName(), number_models_); 680 } 681 682 // Add leakage sub result 683 getNddPowerResult("Leakage")->addSubResult(model_->getNddPowerResult("Leakage"), model_->getInstanceName(), number_models_); 684 685 // Add idle event sub result 686 getEventResult("Idle")->addSubResult(model_->getEventResult("Idle"), model_->getInstanceName(), number_models_); 687 return; 688 } 689 690 void ElectricalModel::addElectricalWireSubResult(const String& wire_layer_, const Result* result_, const String& producer_, double number_results_) 691 { 692 getAreaResult(wire_layer_ + "Wire")->addSubResult(result_, producer_, number_results_); 693 return; 694 } 695 696 void ElectricalModel::createElectricalAtomicResults() 697 { 698 // Add active area result 699 addAreaResult(new AtomicResult("Active")); 700 701 // Add wire area result 702 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 703 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 704 TechModel::ConstWireLayerIterator it; 705 for(it = it_begin; it != it_end; ++it) 706 { 707 const String& layer_name = (*it); 708 addAreaResult(new AtomicResult(layer_name + "Wire")); 709 } 710 711 // Add leakage result 712 addNddPowerResult(new AtomicResult("Leakage")); 713 714 // Add idle event result 715 createElectricalEventAtomicResult("Idle"); 716 return; 717 } 718 719 void ElectricalModel::addElecticalAtomicResultValues(const ElectricalModel* model_, double number_models_) 720 { 721 getAreaResult("Active")->addValue(model_->getAreaResult("Active")->calculateSum() * number_models_); 722 723 // Add wire area sub result 724 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 725 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 726 TechModel::ConstWireLayerIterator it; 727 for(it = it_begin; it != it_end; ++it) 728 { 729 const String& layer_name = (*it); 730 const String& result_name = layer_name + "Wire"; 731 getAreaResult(result_name)->addValue(model_->getAreaResult(result_name)->calculateSum() * number_models_); 732 } 733 734 // Add leakage sub result 735 getNddPowerResult("Leakage")->addValue(model_->getNddPowerResult("Leakage")->calculateSum() * number_models_); 736 737 // Add idle event sub result 738 getEventResult("Idle")->addValue(model_->getEventResult("Idle")->calculateSum() * number_models_); 739 return; 740 } 741 742 void ElectricalModel::addElecticalWireAtomicResultValue(const String& wire_layer_, double value_) 743 { 744 getAreaResult(wire_layer_ + "Wire")->addValue(value_); 745 return; 746 } 747 748 void ElectricalModel::resetElectricalAtomicResults() 749 { 750 getAreaResult("Active")->setValue(0.0); 751 752 // Reset wire area sub result 753 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 754 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 755 TechModel::ConstWireLayerIterator it; 756 for(it = it_begin; it != it_end; ++it) 757 { 758 const String& layer_name = (*it); 759 const String& result_name = layer_name + "Wire"; 760 getAreaResult(result_name)->setValue(0.0); 761 } 762 763 // Reset leakage sub result 764 getNddPowerResult("Leakage")->setValue(0.0); 765 766 // Reset idle event sub result 767 getEventResult("Idle")->setValue(0.0); 768 769 return; 770 } 771 772 void ElectricalModel::createElectricalEventResult(const String& name_) 773 { 774 // Add the event result 775 addEventResult(new Result(name_)); 776 // Add event info 777 m_event_infos_->set(name_, new EventInfo(name_, getInputs())); 778 return; 779 } 780 781 void ElectricalModel::createElectricalEventAtomicResult(const String& name_) 782 { 783 // Add the event result 784 addEventResult(new AtomicResult(name_)); 785 // Add event info 786 m_event_infos_->set(name_, new EventInfo(name_, getInputs())); 787 return; 788 } 789 790 void ElectricalModel::assignPortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const TransitionInfo& trans_info_) 791 { 792 ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() + 793 " -> Downstream model does not exist"); 794 795 downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info_); 796 return; 797 } 798 799 void ElectricalModel::propagatePortTransitionInfo(const String& downstream_port_name_, const String& upstream_port_name_) 800 { 801 const TransitionInfo& trans_info = getInputPort(upstream_port_name_)->getTransitionInfo(); 802 getOutputPort(downstream_port_name_)->setTransitionInfo(trans_info); 803 return; 804 } 805 806 void ElectricalModel::propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const String& upstream_port_name_) 807 { 808 ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() + 809 " -> Downstream model does not exist"); 810 811 const TransitionInfo& trans_info = getInputPort(upstream_port_name_)->getTransitionInfo(); 812 downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info); 813 return; 814 } 815 816 void ElectricalModel::propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_) 817 { 818 ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() + 819 " -> Downstream model does not exist"); 820 ASSERT(upstream_model_ != NULL, "[Error] " + getInstanceName() + 821 " -> Upstream model does not exist"); 822 823 const TransitionInfo& trans_info = upstream_model_->getOutputPort(upstream_port_name_)->getTransitionInfo(); 824 825 downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info); 826 return; 827 } 828 829 void ElectricalModel::propagatePortTransitionInfo(const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_) 830 { 831 ASSERT(upstream_model_ != NULL, "[Error] " + getInstanceName() + 832 " -> Upstream model does not exist"); 833 834 const TransitionInfo& trans_info = upstream_model_->getOutputPort(upstream_port_name_)->getTransitionInfo(); 835 getOutputPort(downstream_port_name_)->setTransitionInfo(trans_info); 836 return; 837 } 838 839 void ElectricalModel::propagateTransitionInfo() 840 { 841 // by default do nothing. 842 } 843 844 void ElectricalModel::useModel(const String& event_name_) 845 { 846 getGenProperties()->set("UseModelEvent", event_name_); 847 applyTransitionInfo(event_name_); 848 useModel(); 849 return; 850 } 851 852 void ElectricalModel::useModel() 853 { 854 propagateTransitionInfo(); 855 return; 856 } 857 858 void ElectricalModel::applyTransitionInfo(const String& event_name_) 859 { 860 // Check if the event actually exists 861 ASSERT(hasEventResult(event_name_), "[Error] " + getInstanceName() + 862 " -> Event (" + event_name_ + ") does not exist in the result map"); 863 ASSERT(m_event_infos_->keyExist(event_name_), "[Error] " + getInstanceName() + 864 " -> Event (" + event_name_ + ") does not exist in the event info map"); 865 866 const EventInfo* event_info = m_event_infos_->get(event_name_); 867 868 // Set the input ports' transition information for the event 869 Map<PortInfo*>::ConstIterator it_begin = m_input_ports_->begin(); 870 Map<PortInfo*>::ConstIterator it_end = m_input_ports_->end(); 871 Map<PortInfo*>::ConstIterator it; 872 for(it = it_begin; it != it_end; ++it) 873 { 874 const String& port_name = it->first; 875 PortInfo* port_info = it->second; 876 const TransitionInfo& trans_info = event_info->getTransitionInfo(port_name); 877 port_info->setTransitionInfo(trans_info); 878 } 879 880 return; 881 } 882 883 EventInfo* ElectricalModel::getEventInfo(const String& event_name_) 884 { 885 ASSERT(m_event_infos_->keyExist(event_name_), "[Error] " + getInstanceName() + 886 " -> Event (" + event_name_ + ") does not exist"); 887 888 return m_event_infos_->get(event_name_); 889 } 890 891} // namespace DSENT 892 893