ElectricalModel.cc revision 10447:a465576671d4
1754SN/A#include "model/ElectricalModel.h" 21762SN/A 3754SN/A#include "model/PortInfo.h" 4754SN/A#include "model/EventInfo.h" 5754SN/A#include "model/timing_graph/ElectricalDriver.h" 6754SN/A#include "model/timing_graph/ElectricalDriverMultiplier.h" 7754SN/A#include "model/timing_graph/ElectricalNet.h" 8754SN/A#include "model/timing_graph/ElectricalLoad.h" 9754SN/A#include "model/timing_graph/ElectricalDelay.h" 10754SN/A 11754SN/Anamespace DSENT 12754SN/A{ 13754SN/A ElectricalModel::ElectricalModel(const String& instance_name_, const TechModel* tech_model_) 14754SN/A : Model(instance_name_, tech_model_) 15754SN/A { 16754SN/A m_curr_driving_strengths_idx_ = -1; 17754SN/A m_input_ports_ = new Map<PortInfo*>; 18754SN/A m_output_ports_ = new Map<PortInfo*>; 19754SN/A m_net_references_ = new Map<NetIndex>; 20754SN/A m_drivers_ = new Map<ElectricalDriver*>; 21754SN/A m_driver_multipliers_ = new Map<ElectricalDriverMultiplier*>; 22754SN/A m_nets_ = new Map<ElectricalNet*>; 23754SN/A m_loads_ = new Map<ElectricalLoad*>; 24754SN/A m_delays_ = new Map<ElectricalDelay*>; 25754SN/A m_event_infos_ = new Map<EventInfo*>; 26754SN/A } 272665Ssaidi@eecs.umich.edu 282665Ssaidi@eecs.umich.edu ElectricalModel::~ElectricalModel() 292665Ssaidi@eecs.umich.edu { 30754SN/A deletePtrMap<PortInfo>(m_input_ports_); 31754SN/A deletePtrMap<PortInfo>(m_output_ports_); 32754SN/A delete m_net_references_; 33754SN/A deletePtrMap<ElectricalDriver>(m_drivers_); 34754SN/A deletePtrMap<ElectricalDriverMultiplier>(m_driver_multipliers_); 351070SN/A deletePtrMap<ElectricalNet>(m_nets_); 361070SN/A deletePtrMap<ElectricalLoad>(m_loads_); 37754SN/A deletePtrMap<ElectricalDelay>(m_delays_); 381070SN/A deletePtrMap<EventInfo>(m_event_infos_); 39754SN/A m_input_ports_ = NULL; 401917SN/A m_output_ports_ = NULL; 411917SN/A m_net_references_ = NULL; 421070SN/A m_drivers_ = NULL; 43754SN/A m_driver_multipliers_ = NULL; 441070SN/A m_nets_ = NULL; 451681SN/A m_loads_ = NULL; 461681SN/A m_net_references_ = NULL; 47754SN/A m_event_infos_ = NULL; 481070SN/A } 491070SN/A 501082SN/A void ElectricalModel::checkProperties() const 511070SN/A { 521070SN/A // Check if the specified driving strength exists in the available driving strengths 531070SN/A if(getProperties()->keyExist("DrivingStrength")) 54754SN/A { 55754SN/A const double driving_strength = getProperty("DrivingStrength"); 561070SN/A bool is_found = false; 571070SN/A for(int i = 0; i < (int)m_driving_strengths_.size(); ++i) 581070SN/A { 591070SN/A if(driving_strength == m_driving_strengths_[i]) 601070SN/A { 611070SN/A is_found = true; 621070SN/A break; 631070SN/A } 641070SN/A } 651070SN/A ASSERT(is_found, "[Error] " + getInstanceName() + 661070SN/A " -> Driving strength (" + String(driving_strength) + ")" 671070SN/A " not found in available driving strengths (" + 681070SN/A getParameter("AvailableDrivingStrengths")); 691070SN/A } 701070SN/A 711070SN/A // Do normal check on the properties 721070SN/A Model::checkProperties(); 731070SN/A return; 741070SN/A } 751070SN/A 761070SN/A double ElectricalModel::getDrivingStrength() const 771070SN/A { 781070SN/A if(m_curr_driving_strengths_idx_ == -1) 791070SN/A { 801070SN/A return 0; 811070SN/A } 821070SN/A else 831070SN/A { 841070SN/A return m_driving_strengths_[m_curr_driving_strengths_idx_]; 851070SN/A } 861070SN/A } 871070SN/A 881070SN/A int ElectricalModel::getDrivingStrengthIdx() const 891070SN/A { 901070SN/A return m_curr_driving_strengths_idx_; 911070SN/A } 921070SN/A 931070SN/A void ElectricalModel::setDrivingStrengthIdx(int idx_) 941070SN/A { 951070SN/A ASSERT(((idx_ >= 0) && (idx_ < (int)m_driving_strengths_.size())), 961070SN/A "[Error] " + getInstanceName() + 971070SN/A " -> Driving strength index out of range (" + String(idx_) + ")"); 981070SN/A 991070SN/A m_curr_driving_strengths_idx_ = idx_; 1001070SN/A setProperty("DrivingStrength", m_driving_strengths_[m_curr_driving_strengths_idx_]); 1011070SN/A 1021070SN/A Log::printLine(getInstanceName() + " -> Changing drive strength to " + (String) m_driving_strengths_[m_curr_driving_strengths_idx_]); 1031082SN/A update(); 104754SN/A return; 105754SN/A } 1061070SN/A 1071070SN/A void ElectricalModel::setMinDrivingStrength() 108754SN/A { 1091070SN/A setDrivingStrengthIdx(0); 1101070SN/A return; 1112107SN/A } 1121070SN/A 1131070SN/A bool ElectricalModel::hasMinDrivingStrength() const 1141070SN/A { 1151070SN/A return (m_curr_driving_strengths_idx_ == 0); 1161070SN/A } 1171070SN/A 1181070SN/A bool ElectricalModel::hasMaxDrivingStrength() const 1191070SN/A { 120754SN/A return (m_curr_driving_strengths_idx_ == ((int)m_driving_strengths_.size() - 1)); 121754SN/A } 1221070SN/A 1231070SN/A void ElectricalModel::increaseDrivingStrength() 1241070SN/A { 125754SN/A if(!hasMaxDrivingStrength()) 126754SN/A { 1271070SN/A setDrivingStrengthIdx(m_curr_driving_strengths_idx_ + 1); 1281070SN/A } 1292107SN/A return; 1301070SN/A } 1311070SN/A 1321070SN/A void ElectricalModel::decreaseDrivingStrength() 1331070SN/A { 1341070SN/A if(!hasMinDrivingStrength()) 1351070SN/A { 1361070SN/A setDrivingStrengthIdx(m_curr_driving_strengths_idx_ - 1); 1371070SN/A } 1381082SN/A return; 1391070SN/A } 1402190SN/A 1411070SN/A void ElectricalModel::setAvailableDrivingStrengths(const String& driving_strengths_) 1421070SN/A { 1431070SN/A setParameter("AvailableDrivingStrengths", driving_strengths_); 1441070SN/A const vector<String>& split_str = driving_strengths_.split("[,"); 1451070SN/A 1461070SN/A // Check if there is at least one driving strength specified 1471070SN/A ASSERT(!split_str.empty(), "[Error] " + getInstanceName() + 1481070SN/A " -> Specified driving strength string does not contain any driving strengths (" + 1491070SN/A driving_strengths_ + ")"); 1501070SN/A 1511070SN/A // TODO - check if the driving strengths is sorted 1521070SN/A 1531070SN/A // Overwrite the available driving strengths 1541070SN/A m_driving_strengths_.clear(); 1551070SN/A for(int i = 0; i < (int)split_str.size(); ++i) 1562147SN/A { 1571070SN/A m_driving_strengths_.push_back(split_str[i].toDouble()); 1581070SN/A } 1591070SN/A 1601070SN/A // Set the driving strength to minimum 1611070SN/A m_curr_driving_strengths_idx_ = 0; 1621070SN/A setProperty("DrivingStrength", m_driving_strengths_[m_curr_driving_strengths_idx_]); 1631070SN/A return; 1641070SN/A } 1651070SN/A 1661070SN/A // Connect a port (input or output) to some ElectricalNet 1671070SN/A void ElectricalModel::portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_) 1681070SN/A { 1691070SN/A ASSERT(m_net_references_->keyExist(connect_net_name_), "[Error] " + getInstanceName() + 1702190SN/A " -> Net '" + connect_net_name_ + "' does not exist!"); 1711070SN/A 1721070SN/A portConnect(connect_model_, connect_port_name_, connect_net_name_, m_net_references_->get(connect_net_name_)); 1731070SN/A } 1741070SN/A 1751070SN/A void ElectricalModel::portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_, const NetIndex& connect_net_indices_) 1761070SN/A { 1771070SN/A ASSERT(m_net_references_->keyExist(connect_net_name_), "[Error] " + getInstanceName() + 1781070SN/A " -> Net '" + connect_net_name_ + "' does not exist!"); 1791070SN/A 1801070SN/A // Check whether the port name is an input or output, ASSERTion error if neither 1811070SN/A bool is_input = connect_model_->getInputs()->keyExist(connect_port_name_); 1822190SN/A bool is_output = connect_model_->getOutputs()->keyExist(connect_port_name_); 1832190SN/A 1842190SN/A ASSERT(is_input || is_output, "[Error] " + getInstanceName() + " -> Model '" + connect_model_->getInstanceName() + 1851070SN/A "' does not have a port named '" + connect_port_name_ + "'!"); 1862190SN/A 1871070SN/A int connect_net_width = connect_net_indices_.second - connect_net_indices_.first + 1; 1881070SN/A const NetIndex& port_indices = connect_model_->getNetReference(connect_port_name_); 1891070SN/A int port_width = port_indices.second - port_indices.first + 1; 1901070SN/A 1911070SN/A ASSERT(connect_net_width == port_width, "[Error] " + getInstanceName() + " -> Port width mismatch for Model '" + 1921070SN/A connect_model_->getInstanceName() + "." + connect_port_name_ + toString(port_indices) + 1931070SN/A "' and net '" + connect_net_name_ + toString(connect_net_indices_) + "'!"); 1941070SN/A 195754SN/A int port_index = port_indices.first; 196 int connect_net_index = connect_net_indices_.first; 197 198 if(is_input) 199 { 200 while(port_index <= port_indices.second) 201 { 202 getNet(connect_net_name_, makeNetIndex(connect_net_index))->addDownstreamNode( 203 connect_model_->getNet(connect_port_name_, makeNetIndex(port_index))); 204 ++port_index; 205 ++connect_net_index; 206 } 207 } 208 else if(is_output) 209 { 210 while (port_index <= port_indices.second) 211 { 212 connect_model_->getNet(connect_port_name_, makeNetIndex(port_index))->addDownstreamNode( 213 getNet(connect_net_name_, makeNetIndex(connect_net_index))); 214 ++port_index; 215 ++connect_net_index; 216 } 217 } 218 } 219 220 //Get Drivers 221 const Map<ElectricalDriver*>* ElectricalModel::getDrivers() const 222 { 223 return m_drivers_; 224 } 225 226 ElectricalDriver* ElectricalModel::getDriver(const String& name_) 227 { 228 return m_drivers_->get(name_); 229 } 230 231 //Get Driver Multipliers 232 const Map<ElectricalDriverMultiplier*>* ElectricalModel::getDriverMultipliers() const 233 { 234 return m_driver_multipliers_; 235 } 236 237 ElectricalDriverMultiplier* ElectricalModel::getDriverMultiplier(const String& name_) 238 { 239 return m_driver_multipliers_->get(name_); 240 } 241 242 //Get Nets 243 const Map<ElectricalNet*>* ElectricalModel::getNets() const 244 { 245 return m_nets_; 246 } 247 248 ElectricalNet* ElectricalModel::getNet(const String& name_) 249 { 250 return getNet(name_, m_net_references_->get(name_)); 251 } 252 253 ElectricalNet* ElectricalModel::getNet(const String& name_, const NetIndex& index_) 254 { 255 ASSERT(index_.first == index_.second, "[Error] " + getInstanceName() + 256 " -> Ambiguous get net since (" + name_ + ") is a bus consisting of several nets!"); 257 return m_nets_->get(name_ + "[" + (String) index_.first + "]"); 258 } 259 260 //Get Loads 261 const Map<ElectricalLoad*>* ElectricalModel::getLoads() const 262 { 263 return m_loads_; 264 } 265 266 ElectricalLoad* ElectricalModel::getLoad(const String& name_) 267 { 268 return m_loads_->get(name_); 269 } 270 271 //Get Delays 272 const Map<ElectricalDelay*>* ElectricalModel::getDelays() const 273 { 274 return m_delays_; 275 } 276 277 ElectricalDelay* ElectricalModel::getDelay(const String& name_) 278 { 279 return m_delays_->get(name_); 280 } 281 282 //Get Inputs 283 const Map<PortInfo*>* ElectricalModel::getInputs() const 284 { 285 return m_input_ports_; 286 } 287 288 PortInfo* ElectricalModel::getInputPort(const String& name_) 289 { 290 ASSERT(m_input_ports_->keyExist(name_), "[Error] " + getInstanceName() + 291 " -> Input port (" + name_ + ") does not exist"); 292 293 return m_input_ports_->get(name_); 294 } 295 296 const PortInfo* ElectricalModel::getInputPort(const String& name_) const 297 { 298 ASSERT(m_input_ports_->keyExist(name_), "[Error] " + getInstanceName() + 299 " -> Input port (" + name_ + ") does not exist"); 300 301 return m_input_ports_->get(name_); 302 } 303 304 //Get Outputs 305 const Map<PortInfo*>* ElectricalModel::getOutputs() const 306 { 307 return m_output_ports_; 308 } 309 310 PortInfo* ElectricalModel::getOutputPort(const String& name_) 311 { 312 ASSERT(m_output_ports_->keyExist(name_), "[Error] " + getInstanceName() + 313 " -> Output port (" + name_ + ") does not exist"); 314 315 return m_output_ports_->get(name_); 316 } 317 318 const PortInfo* ElectricalModel::getOutputPort(const String& name_) const 319 { 320 ASSERT(m_output_ports_->keyExist(name_), "[Error] " + getInstanceName() + 321 " -> Output port (" + name_ + ") does not exist"); 322 323 return m_output_ports_->get(name_); 324 } 325 326 const Map<NetIndex>* ElectricalModel::getNetReferences() const 327 { 328 return m_net_references_; 329 } 330 331 const NetIndex ElectricalModel::getNetReference(const String& name_) const 332 { 333 return m_net_references_->get(name_); 334 } 335 336 //------------------------------------------------------------------------- 337 // Electrical Connectivity and Timing Element Creation Functions 338 //------------------------------------------------------------------------- 339 340 // Input Port creation 341 void ElectricalModel::createInputPort(const String& name_, const NetIndex& net_indices_) 342 { 343 // Create the new nets (including its net reference) 344 // This should already check that it has not been previously declared 345 createNet(name_, net_indices_); 346 // Add the net name to list of input ports 347 m_input_ports_->set(name_, new PortInfo(name_, net_indices_)); 348 return; 349 } 350 351 // Output Port creation 352 void ElectricalModel::createOutputPort(const String& name_, const NetIndex& net_indices_) 353 { 354 // Create the new nets (including its net reference) 355 // This should already check that it has not been previously declared 356 createNet(name_, net_indices_); 357 // Add the net name to list of output ports 358 m_output_ports_->set(name_, new PortInfo(name_, net_indices_)); 359 return; 360 } 361 362 // Net creation 363 void ElectricalModel::createNet(const String& name_) 364 { 365 // Creating a net with specifying an index range means that the net is just 366 // a 1-bit wire indexed at [0] 367 createNet(name_, makeNetIndex(0, 0)); 368 return; 369 } 370 371 void ElectricalModel::createNet(const String& name_, const NetIndex& net_indices_) 372 { 373 // Check that it hasn't been previously declared 374 ASSERT( !m_nets_->keyExist(name_) && !m_net_references_->keyExist(name_), 375 "[Error] " + getInstanceName() + " -> Redeclaration of net " + name_); 376 377 int start = net_indices_.first; 378 int end = net_indices_.second; 379 380 for (int index = start; index <= end; ++index) 381 { 382 String indexed_name = name_ + "[" + (String) index + "]"; 383 // Create the new net 384 ElectricalNet* net = new ElectricalNet(indexed_name, this); 385 // Add the net to net map 386 m_nets_->set(indexed_name, net); 387 } 388 // Add net to net references 389 m_net_references_->set(name_, net_indices_); 390 return; 391 } 392 393 // Driver creation 394 void ElectricalModel::createDriver(const String& name_, bool sizable_) 395 { 396 // Check that it hasn't been previously declared 397 ASSERT( !m_drivers_->keyExist(name_), 398 "[Error] " + getInstanceName() + " -> Redeclaration of driver " + name_); 399 400 ElectricalDriver* driver = new ElectricalDriver(name_, this, sizable_); 401 m_drivers_->set(name_, driver); 402 return; 403 } 404 405 /* 406 void ElectricalModel::createDriver(const String& name_, bool sizable_, int start_index_, int end_index_) 407 { 408 for (int index = start_index_; index <= end_index_; ++index) 409 { 410 createDriver(name_ + "[" + (String) index + "]", sizable_); 411 } 412 return; 413 } 414 */ 415 416 // Driver Multiplier creation 417 void ElectricalModel::createDriverMultiplier(const String& name_) 418 { 419 // Check that it hasn't been previously declared 420 ASSERT( !m_driver_multipliers_->keyExist(name_), 421 "[Error] " + getInstanceName() + " -> Redeclaration of driver_multiplier " + name_); 422 423 ElectricalDriverMultiplier* driver_multiplier = new ElectricalDriverMultiplier(name_, this); 424 m_driver_multipliers_->set(name_, driver_multiplier); 425 return; 426 } 427 428 // Load creation 429 430 void ElectricalModel::createLoad(const String& name_) 431 { 432 // Check that it hasn't been previously declared 433 ASSERT( !m_loads_->keyExist(name_), 434 "[Error] " + getInstanceName() + " -> Redeclaration of load " + name_); 435 436 ElectricalLoad* load = new ElectricalLoad(name_, this); 437 m_loads_->set(name_, load); 438 return; 439 } 440 441 /* 442 void ElectricalModel::createLoad(const String& name_, int start_index_, int end_index_) 443 { 444 for (int index = start_index_; index <= end_index_; ++index) 445 { 446 createLoad(name_ + "[" + (String) index + "]"); 447 } 448 return; 449 } 450 */ 451 452 // Delay creation 453 void ElectricalModel::createDelay(const String& name_) 454 { 455 // Check that it hasn't been previously declared 456 ASSERT( !m_delays_->keyExist(name_), 457 "[Error] " + getInstanceName() + " -> Redeclaration of delay " + name_); 458 459 ElectricalDelay* delay = new ElectricalDelay(name_, this); 460 m_delays_->set(name_, delay); 461 return; 462 } 463 464 /* 465 void ElectricalModel::createDelay(const String& name_, int start_index_, int end_index_) 466 { 467 for (int index = start_index_; index <= end_index_; ++index) 468 { 469 createDelay(name_ + "[" + (String) index + "]"); 470 } 471 return; 472 } 473 */ 474 //------------------------------------------------------------------------- 475 476 // Assign a net to be downstream from another net 477 // case 1: 'assign downstream_net_name_ = upstream_net_name_' 478 void ElectricalModel::assign(const String& downstream_net_name_, const String& upstream_net_name_) 479 { 480 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 481 downstream_net_name_ + "' does not exist!"); 482 483 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 484 upstream_net_name_ + "' does not exist!"); 485 486 assign(downstream_net_name_, getNetReference(downstream_net_name_), 487 upstream_net_name_, getNetReference(upstream_net_name_)); 488 489 return; 490 } 491 492 // case 2: 'assign downstream_net_name_[begin:end] = upstream_net_name_' 493 void ElectricalModel::assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_) 494 { 495 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 496 downstream_net_name_ + "' does not exist!"); 497 498 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 499 upstream_net_name_ + "' does not exist!"); 500 501 assign(downstream_net_name_, downstream_net_indices_, 502 upstream_net_name_, getNetReference(upstream_net_name_)); 503 504 return; 505 } 506 507 // case 3: 'assign downstream_net_name_ = upstream_net_name_[begin:end]' 508 void ElectricalModel::assign(const String& downstream_net_name_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) 509 { 510 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 511 downstream_net_name_ + "' does not exist!"); 512 513 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 514 upstream_net_name_ + "' does not exist!"); 515 516 assign(downstream_net_name_, getNetReference(downstream_net_name_), 517 upstream_net_name_, upstream_net_indices_); 518 519 return; 520 } 521 // case 4: 'assign downstream_net_name_[begin:end] = upstream_net_name_[begin:end]' 522 void ElectricalModel::assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) 523 { 524 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 525 downstream_net_name_ + "' does not exist!"); 526 527 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 528 upstream_net_name_ + "' does not exist!"); 529 530 // Check that the assignment widths are the same 531 int downstream_width = downstream_net_indices_.second - downstream_net_indices_.first + 1; 532 int upstream_width = upstream_net_indices_.second - upstream_net_indices_.first + 1; 533 534 ASSERT(downstream_width == upstream_width, "[Error] " + getInstanceName() + " -> Assignment width mismatch: " + 535 downstream_net_name_ + " (" + (String) downstream_width + ") and " + 536 upstream_net_name_ + " (" + (String) upstream_width + ")"); 537 538 // Loop through indices and connect them together 539 int down_index = downstream_net_indices_.first; 540 int up_index = upstream_net_indices_.first; 541 while (down_index <= downstream_net_indices_.second) 542 { 543 getNet(upstream_net_name_, makeNetIndex(up_index))->addDownstreamNode( 544 getNet(downstream_net_name_, makeNetIndex(down_index))); 545 546 ++up_index; 547 ++down_index; 548 } 549 550 return; 551 } 552 553 // Assign a net to another net through a driver multiplier 554 void ElectricalModel::assignVirtualFanout(const String& downstream_net_name_, const String& upstream_net_name_) 555 { 556 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + 557 " -> Net '" + upstream_net_name_ + "' does not exist!"); 558 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + 559 " -> Net '" + downstream_net_name_ + "' does not exist!"); 560 561 assignVirtualFanout(downstream_net_name_, getNetReference(downstream_net_name_), upstream_net_name_, getNetReference(upstream_net_name_)); 562 return; 563 } 564 565 // Assign a net to another net through a driver multiplier 566 void ElectricalModel::assignVirtualFanout(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) 567 { 568 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + 569 " -> Net '" + upstream_net_name_ + "' does not exist!"); 570 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + 571 " -> Net '" + downstream_net_name_ + "' does not exist!"); 572 573 const String& drive_mult_name = upstream_net_name_ + "_" + (String) upstream_net_indices_.first + "_DriverMultiplier"; 574 bool is_drive_mult_exist = getDriverMultipliers()->keyExist(drive_mult_name); 575 576 // Create a driver multiplier and assign it to upstream_net since it doesn't exist 577 if(!is_drive_mult_exist) 578 { 579 createDriverMultiplier(drive_mult_name); 580 getNet(upstream_net_name_, upstream_net_indices_)->addDownstreamNode(getDriverMultiplier(drive_mult_name)); 581 } 582 583 // Assign downstream_net_name_[end:begin] = driver_multiplier_name_ 584 ElectricalDriverMultiplier* drive_mult = getDriverMultiplier(drive_mult_name); 585 int begin_index = downstream_net_indices_.first; 586 int end_index = downstream_net_indices_.second; 587 for(int i = begin_index; i <= end_index; ++i) 588 { 589 drive_mult->addDownstreamNode(getNet(downstream_net_name_, makeNetIndex(i))); 590 } 591 return; 592 } 593 594 void ElectricalModel::assignVirtualFanin(const String& downstream_net_name_, const String& upstream_net_name_) 595 { 596 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + 597 " -> Net '" + upstream_net_name_ + "' does not exist!"); 598 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + 599 " -> Net '" + downstream_net_name_ + "' does not exist!"); 600 601 assignVirtualFanin(downstream_net_name_, getNetReference(downstream_net_name_), upstream_net_name_, getNetReference(upstream_net_name_)); 602 return; 603 } 604 605 void ElectricalModel::assignVirtualFanin(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) 606 { 607 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + 608 " -> Net '" + upstream_net_name_ + "' does not exist!"); 609 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + 610 " -> Net '" + downstream_net_name_ + "' does not exist!"); 611 612 int begin_index = upstream_net_indices_.first; 613 int end_index = upstream_net_indices_.second; 614 615 for(int i = begin_index; i <= end_index; ++i) 616 { 617 getNet(upstream_net_name_, makeNetIndex(i))->addDownstreamNode(getNet(downstream_net_name_, downstream_net_indices_)); 618 } 619 return; 620 } 621 622 void ElectricalModel::createElectricalResults() 623 { 624 // Add active area result 625 addAreaResult(new Result("Active")); 626 627 // Add wire area result 628 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 629 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 630 TechModel::ConstWireLayerIterator it; 631 for(it = it_begin; it != it_end; ++it) 632 { 633 const String& layer_name = (*it); 634 addAreaResult(new Result(layer_name + "Wire")); 635 } 636 637 // Add leakage result 638 addNddPowerResult(new Result("Leakage")); 639 640 // Add idle event result 641 createElectricalEventResult("Idle"); 642 return; 643 } 644 645 void ElectricalModel::addElectricalSubResults(const ElectricalModel* model_, double number_models_) 646 { 647 // Add active area sub result 648 getAreaResult("Active")->addSubResult(model_->getAreaResult("Active"), model_->getInstanceName(), number_models_); 649 650 // Add wire area sub result 651 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 652 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 653 TechModel::ConstWireLayerIterator it; 654 for(it = it_begin; it != it_end; ++it) 655 { 656 const String& layer_name = (*it); 657 const String& result_name = layer_name + "Wire"; 658 getAreaResult(result_name)->addSubResult(model_->getAreaResult(result_name), model_->getInstanceName(), number_models_); 659 } 660 661 // Add leakage sub result 662 getNddPowerResult("Leakage")->addSubResult(model_->getNddPowerResult("Leakage"), model_->getInstanceName(), number_models_); 663 664 // Add idle event sub result 665 getEventResult("Idle")->addSubResult(model_->getEventResult("Idle"), model_->getInstanceName(), number_models_); 666 return; 667 } 668 669 void ElectricalModel::addElectricalWireSubResult(const String& wire_layer_, const Result* result_, const String& producer_, double number_results_) 670 { 671 getAreaResult(wire_layer_ + "Wire")->addSubResult(result_, producer_, number_results_); 672 return; 673 } 674 675 void ElectricalModel::createElectricalAtomicResults() 676 { 677 // Add active area result 678 addAreaResult(new AtomicResult("Active")); 679 680 // Add wire area result 681 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 682 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 683 TechModel::ConstWireLayerIterator it; 684 for(it = it_begin; it != it_end; ++it) 685 { 686 const String& layer_name = (*it); 687 addAreaResult(new AtomicResult(layer_name + "Wire")); 688 } 689 690 // Add leakage result 691 addNddPowerResult(new AtomicResult("Leakage")); 692 693 // Add idle event result 694 createElectricalEventAtomicResult("Idle"); 695 return; 696 } 697 698 void ElectricalModel::addElecticalAtomicResultValues(const ElectricalModel* model_, double number_models_) 699 { 700 getAreaResult("Active")->addValue(model_->getAreaResult("Active")->calculateSum() * number_models_); 701 702 // Add wire area sub result 703 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 704 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 705 TechModel::ConstWireLayerIterator it; 706 for(it = it_begin; it != it_end; ++it) 707 { 708 const String& layer_name = (*it); 709 const String& result_name = layer_name + "Wire"; 710 getAreaResult(result_name)->addValue(model_->getAreaResult(result_name)->calculateSum() * number_models_); 711 } 712 713 // Add leakage sub result 714 getNddPowerResult("Leakage")->addValue(model_->getNddPowerResult("Leakage")->calculateSum() * number_models_); 715 716 // Add idle event sub result 717 getEventResult("Idle")->addValue(model_->getEventResult("Idle")->calculateSum() * number_models_); 718 return; 719 } 720 721 void ElectricalModel::addElecticalWireAtomicResultValue(const String& wire_layer_, double value_) 722 { 723 getAreaResult(wire_layer_ + "Wire")->addValue(value_); 724 return; 725 } 726 727 void ElectricalModel::resetElectricalAtomicResults() 728 { 729 getAreaResult("Active")->setValue(0.0); 730 731 // Reset wire area sub result 732 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 733 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 734 TechModel::ConstWireLayerIterator it; 735 for(it = it_begin; it != it_end; ++it) 736 { 737 const String& layer_name = (*it); 738 const String& result_name = layer_name + "Wire"; 739 getAreaResult(result_name)->setValue(0.0); 740 } 741 742 // Reset leakage sub result 743 getNddPowerResult("Leakage")->setValue(0.0); 744 745 // Reset idle event sub result 746 getEventResult("Idle")->setValue(0.0); 747 748 return; 749 } 750 751 void ElectricalModel::createElectricalEventResult(const String& name_) 752 { 753 // Add the event result 754 addEventResult(new Result(name_)); 755 // Add event info 756 m_event_infos_->set(name_, new EventInfo(name_, getInputs())); 757 return; 758 } 759 760 void ElectricalModel::createElectricalEventAtomicResult(const String& name_) 761 { 762 // Add the event result 763 addEventResult(new AtomicResult(name_)); 764 // Add event info 765 m_event_infos_->set(name_, new EventInfo(name_, getInputs())); 766 return; 767 } 768 769 void ElectricalModel::assignPortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const TransitionInfo& trans_info_) 770 { 771 ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() + 772 " -> Downstream model does not exist"); 773 774 downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info_); 775 return; 776 } 777 778 void ElectricalModel::propagatePortTransitionInfo(const String& downstream_port_name_, const String& upstream_port_name_) 779 { 780 const TransitionInfo& trans_info = getInputPort(upstream_port_name_)->getTransitionInfo(); 781 getOutputPort(downstream_port_name_)->setTransitionInfo(trans_info); 782 return; 783 } 784 785 void ElectricalModel::propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const String& upstream_port_name_) 786 { 787 ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() + 788 " -> Downstream model does not exist"); 789 790 const TransitionInfo& trans_info = getInputPort(upstream_port_name_)->getTransitionInfo(); 791 downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info); 792 return; 793 } 794 795 void ElectricalModel::propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_) 796 { 797 ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() + 798 " -> Downstream model does not exist"); 799 ASSERT(upstream_model_ != NULL, "[Error] " + getInstanceName() + 800 " -> Upstream model does not exist"); 801 802 const TransitionInfo& trans_info = upstream_model_->getOutputPort(upstream_port_name_)->getTransitionInfo(); 803 804 downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info); 805 return; 806 } 807 808 void ElectricalModel::propagatePortTransitionInfo(const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_) 809 { 810 ASSERT(upstream_model_ != NULL, "[Error] " + getInstanceName() + 811 " -> Upstream model does not exist"); 812 813 const TransitionInfo& trans_info = upstream_model_->getOutputPort(upstream_port_name_)->getTransitionInfo(); 814 getOutputPort(downstream_port_name_)->setTransitionInfo(trans_info); 815 return; 816 } 817 818 void ElectricalModel::propagateTransitionInfo() 819 { 820 // by default do nothing. 821 } 822 823 void ElectricalModel::useModel(const String& event_name_) 824 { 825 getGenProperties()->set("UseModelEvent", event_name_); 826 applyTransitionInfo(event_name_); 827 useModel(); 828 return; 829 } 830 831 void ElectricalModel::useModel() 832 { 833 propagateTransitionInfo(); 834 return; 835 } 836 837 void ElectricalModel::applyTransitionInfo(const String& event_name_) 838 { 839 // Check if the event actually exists 840 ASSERT(hasEventResult(event_name_), "[Error] " + getInstanceName() + 841 " -> Event (" + event_name_ + ") does not exist in the result map"); 842 ASSERT(m_event_infos_->keyExist(event_name_), "[Error] " + getInstanceName() + 843 " -> Event (" + event_name_ + ") does not exist in the event info map"); 844 845 const EventInfo* event_info = m_event_infos_->get(event_name_); 846 847 // Set the input ports' transition information for the event 848 Map<PortInfo*>::ConstIterator it_begin = m_input_ports_->begin(); 849 Map<PortInfo*>::ConstIterator it_end = m_input_ports_->end(); 850 Map<PortInfo*>::ConstIterator it; 851 for(it = it_begin; it != it_end; ++it) 852 { 853 const String& port_name = it->first; 854 PortInfo* port_info = it->second; 855 const TransitionInfo& trans_info = event_info->getTransitionInfo(port_name); 856 port_info->setTransitionInfo(trans_info); 857 } 858 859 return; 860 } 861 862 EventInfo* ElectricalModel::getEventInfo(const String& event_name_) 863 { 864 ASSERT(m_event_infos_->keyExist(event_name_), "[Error] " + getInstanceName() + 865 " -> Event (" + event_name_ + ") does not exist"); 866 867 return m_event_infos_->get(event_name_); 868 } 869 870} // namespace DSENT 871 872