ElectricalModel.cc revision 10448
110448Snilay@cs.wisc.edu/* Copyright (c) 2012 Massachusetts Institute of Technology 210448Snilay@cs.wisc.edu * 310448Snilay@cs.wisc.edu * Permission is hereby granted, free of charge, to any person obtaining a copy 410448Snilay@cs.wisc.edu * of this software and associated documentation files (the "Software"), to deal 510448Snilay@cs.wisc.edu * in the Software without restriction, including without limitation the rights 610448Snilay@cs.wisc.edu * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 710448Snilay@cs.wisc.edu * copies of the Software, and to permit persons to whom the Software is 810448Snilay@cs.wisc.edu * furnished to do so, subject to the following conditions: 910448Snilay@cs.wisc.edu * 1010448Snilay@cs.wisc.edu * The above copyright notice and this permission notice shall be included in 1110448Snilay@cs.wisc.edu * all copies or substantial portions of the Software. 1210448Snilay@cs.wisc.edu * 1310448Snilay@cs.wisc.edu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1410448Snilay@cs.wisc.edu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1510448Snilay@cs.wisc.edu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1610448Snilay@cs.wisc.edu * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1710448Snilay@cs.wisc.edu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1810448Snilay@cs.wisc.edu * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 1910448Snilay@cs.wisc.edu * THE SOFTWARE. 2010448Snilay@cs.wisc.edu */ 2110448Snilay@cs.wisc.edu 2210447Snilay@cs.wisc.edu#include "model/ElectricalModel.h" 2310447Snilay@cs.wisc.edu 2410447Snilay@cs.wisc.edu#include "model/PortInfo.h" 2510447Snilay@cs.wisc.edu#include "model/EventInfo.h" 2610447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalDriver.h" 2710447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalDriverMultiplier.h" 2810447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalNet.h" 2910447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalLoad.h" 3010447Snilay@cs.wisc.edu#include "model/timing_graph/ElectricalDelay.h" 3110447Snilay@cs.wisc.edu 3210447Snilay@cs.wisc.edunamespace DSENT 3310447Snilay@cs.wisc.edu{ 3410447Snilay@cs.wisc.edu ElectricalModel::ElectricalModel(const String& instance_name_, const TechModel* tech_model_) 3510447Snilay@cs.wisc.edu : Model(instance_name_, tech_model_) 3610447Snilay@cs.wisc.edu { 3710447Snilay@cs.wisc.edu m_curr_driving_strengths_idx_ = -1; 3810447Snilay@cs.wisc.edu m_input_ports_ = new Map<PortInfo*>; 3910447Snilay@cs.wisc.edu m_output_ports_ = new Map<PortInfo*>; 4010447Snilay@cs.wisc.edu m_net_references_ = new Map<NetIndex>; 4110447Snilay@cs.wisc.edu m_drivers_ = new Map<ElectricalDriver*>; 4210447Snilay@cs.wisc.edu m_driver_multipliers_ = new Map<ElectricalDriverMultiplier*>; 4310447Snilay@cs.wisc.edu m_nets_ = new Map<ElectricalNet*>; 4410447Snilay@cs.wisc.edu m_loads_ = new Map<ElectricalLoad*>; 4510447Snilay@cs.wisc.edu m_delays_ = new Map<ElectricalDelay*>; 4610447Snilay@cs.wisc.edu m_event_infos_ = new Map<EventInfo*>; 4710447Snilay@cs.wisc.edu } 4810447Snilay@cs.wisc.edu 4910447Snilay@cs.wisc.edu ElectricalModel::~ElectricalModel() 5010447Snilay@cs.wisc.edu { 5110447Snilay@cs.wisc.edu deletePtrMap<PortInfo>(m_input_ports_); 5210447Snilay@cs.wisc.edu deletePtrMap<PortInfo>(m_output_ports_); 5310447Snilay@cs.wisc.edu delete m_net_references_; 5410447Snilay@cs.wisc.edu deletePtrMap<ElectricalDriver>(m_drivers_); 5510447Snilay@cs.wisc.edu deletePtrMap<ElectricalDriverMultiplier>(m_driver_multipliers_); 5610447Snilay@cs.wisc.edu deletePtrMap<ElectricalNet>(m_nets_); 5710447Snilay@cs.wisc.edu deletePtrMap<ElectricalLoad>(m_loads_); 5810447Snilay@cs.wisc.edu deletePtrMap<ElectricalDelay>(m_delays_); 5910447Snilay@cs.wisc.edu deletePtrMap<EventInfo>(m_event_infos_); 6010447Snilay@cs.wisc.edu m_input_ports_ = NULL; 6110447Snilay@cs.wisc.edu m_output_ports_ = NULL; 6210447Snilay@cs.wisc.edu m_net_references_ = NULL; 6310447Snilay@cs.wisc.edu m_drivers_ = NULL; 6410447Snilay@cs.wisc.edu m_driver_multipliers_ = NULL; 6510447Snilay@cs.wisc.edu m_nets_ = NULL; 6610447Snilay@cs.wisc.edu m_loads_ = NULL; 6710447Snilay@cs.wisc.edu m_net_references_ = NULL; 6810447Snilay@cs.wisc.edu m_event_infos_ = NULL; 6910447Snilay@cs.wisc.edu } 7010447Snilay@cs.wisc.edu 7110447Snilay@cs.wisc.edu void ElectricalModel::checkProperties() const 7210447Snilay@cs.wisc.edu { 7310447Snilay@cs.wisc.edu // Check if the specified driving strength exists in the available driving strengths 7410447Snilay@cs.wisc.edu if(getProperties()->keyExist("DrivingStrength")) 7510447Snilay@cs.wisc.edu { 7610447Snilay@cs.wisc.edu const double driving_strength = getProperty("DrivingStrength"); 7710447Snilay@cs.wisc.edu bool is_found = false; 7810447Snilay@cs.wisc.edu for(int i = 0; i < (int)m_driving_strengths_.size(); ++i) 7910447Snilay@cs.wisc.edu { 8010447Snilay@cs.wisc.edu if(driving_strength == m_driving_strengths_[i]) 8110447Snilay@cs.wisc.edu { 8210447Snilay@cs.wisc.edu is_found = true; 8310447Snilay@cs.wisc.edu break; 8410447Snilay@cs.wisc.edu } 8510447Snilay@cs.wisc.edu } 8610447Snilay@cs.wisc.edu ASSERT(is_found, "[Error] " + getInstanceName() + 8710447Snilay@cs.wisc.edu " -> Driving strength (" + String(driving_strength) + ")" 8810447Snilay@cs.wisc.edu " not found in available driving strengths (" + 8910447Snilay@cs.wisc.edu getParameter("AvailableDrivingStrengths")); 9010447Snilay@cs.wisc.edu } 9110447Snilay@cs.wisc.edu 9210447Snilay@cs.wisc.edu // Do normal check on the properties 9310447Snilay@cs.wisc.edu Model::checkProperties(); 9410447Snilay@cs.wisc.edu return; 9510447Snilay@cs.wisc.edu } 9610447Snilay@cs.wisc.edu 9710447Snilay@cs.wisc.edu double ElectricalModel::getDrivingStrength() const 9810447Snilay@cs.wisc.edu { 9910447Snilay@cs.wisc.edu if(m_curr_driving_strengths_idx_ == -1) 10010447Snilay@cs.wisc.edu { 10110447Snilay@cs.wisc.edu return 0; 10210447Snilay@cs.wisc.edu } 10310447Snilay@cs.wisc.edu else 10410447Snilay@cs.wisc.edu { 10510447Snilay@cs.wisc.edu return m_driving_strengths_[m_curr_driving_strengths_idx_]; 10610447Snilay@cs.wisc.edu } 10710447Snilay@cs.wisc.edu } 10810447Snilay@cs.wisc.edu 10910447Snilay@cs.wisc.edu int ElectricalModel::getDrivingStrengthIdx() const 11010447Snilay@cs.wisc.edu { 11110447Snilay@cs.wisc.edu return m_curr_driving_strengths_idx_; 11210447Snilay@cs.wisc.edu } 11310447Snilay@cs.wisc.edu 11410447Snilay@cs.wisc.edu void ElectricalModel::setDrivingStrengthIdx(int idx_) 11510447Snilay@cs.wisc.edu { 11610447Snilay@cs.wisc.edu ASSERT(((idx_ >= 0) && (idx_ < (int)m_driving_strengths_.size())), 11710447Snilay@cs.wisc.edu "[Error] " + getInstanceName() + 11810447Snilay@cs.wisc.edu " -> Driving strength index out of range (" + String(idx_) + ")"); 11910447Snilay@cs.wisc.edu 12010447Snilay@cs.wisc.edu m_curr_driving_strengths_idx_ = idx_; 12110447Snilay@cs.wisc.edu setProperty("DrivingStrength", m_driving_strengths_[m_curr_driving_strengths_idx_]); 12210447Snilay@cs.wisc.edu 12310447Snilay@cs.wisc.edu Log::printLine(getInstanceName() + " -> Changing drive strength to " + (String) m_driving_strengths_[m_curr_driving_strengths_idx_]); 12410447Snilay@cs.wisc.edu update(); 12510447Snilay@cs.wisc.edu return; 12610447Snilay@cs.wisc.edu } 12710447Snilay@cs.wisc.edu 12810447Snilay@cs.wisc.edu void ElectricalModel::setMinDrivingStrength() 12910447Snilay@cs.wisc.edu { 13010447Snilay@cs.wisc.edu setDrivingStrengthIdx(0); 13110447Snilay@cs.wisc.edu return; 13210447Snilay@cs.wisc.edu } 13310447Snilay@cs.wisc.edu 13410447Snilay@cs.wisc.edu bool ElectricalModel::hasMinDrivingStrength() const 13510447Snilay@cs.wisc.edu { 13610447Snilay@cs.wisc.edu return (m_curr_driving_strengths_idx_ == 0); 13710447Snilay@cs.wisc.edu } 13810447Snilay@cs.wisc.edu 13910447Snilay@cs.wisc.edu bool ElectricalModel::hasMaxDrivingStrength() const 14010447Snilay@cs.wisc.edu { 14110447Snilay@cs.wisc.edu return (m_curr_driving_strengths_idx_ == ((int)m_driving_strengths_.size() - 1)); 14210447Snilay@cs.wisc.edu } 14310447Snilay@cs.wisc.edu 14410447Snilay@cs.wisc.edu void ElectricalModel::increaseDrivingStrength() 14510447Snilay@cs.wisc.edu { 14610447Snilay@cs.wisc.edu if(!hasMaxDrivingStrength()) 14710447Snilay@cs.wisc.edu { 14810447Snilay@cs.wisc.edu setDrivingStrengthIdx(m_curr_driving_strengths_idx_ + 1); 14910447Snilay@cs.wisc.edu } 15010447Snilay@cs.wisc.edu return; 15110447Snilay@cs.wisc.edu } 15210447Snilay@cs.wisc.edu 15310447Snilay@cs.wisc.edu void ElectricalModel::decreaseDrivingStrength() 15410447Snilay@cs.wisc.edu { 15510447Snilay@cs.wisc.edu if(!hasMinDrivingStrength()) 15610447Snilay@cs.wisc.edu { 15710447Snilay@cs.wisc.edu setDrivingStrengthIdx(m_curr_driving_strengths_idx_ - 1); 15810447Snilay@cs.wisc.edu } 15910447Snilay@cs.wisc.edu return; 16010447Snilay@cs.wisc.edu } 16110447Snilay@cs.wisc.edu 16210447Snilay@cs.wisc.edu void ElectricalModel::setAvailableDrivingStrengths(const String& driving_strengths_) 16310447Snilay@cs.wisc.edu { 16410447Snilay@cs.wisc.edu setParameter("AvailableDrivingStrengths", driving_strengths_); 16510447Snilay@cs.wisc.edu const vector<String>& split_str = driving_strengths_.split("[,"); 16610447Snilay@cs.wisc.edu 16710447Snilay@cs.wisc.edu // Check if there is at least one driving strength specified 16810447Snilay@cs.wisc.edu ASSERT(!split_str.empty(), "[Error] " + getInstanceName() + 16910447Snilay@cs.wisc.edu " -> Specified driving strength string does not contain any driving strengths (" + 17010447Snilay@cs.wisc.edu driving_strengths_ + ")"); 17110447Snilay@cs.wisc.edu 17210447Snilay@cs.wisc.edu // TODO - check if the driving strengths is sorted 17310447Snilay@cs.wisc.edu 17410447Snilay@cs.wisc.edu // Overwrite the available driving strengths 17510447Snilay@cs.wisc.edu m_driving_strengths_.clear(); 17610447Snilay@cs.wisc.edu for(int i = 0; i < (int)split_str.size(); ++i) 17710447Snilay@cs.wisc.edu { 17810447Snilay@cs.wisc.edu m_driving_strengths_.push_back(split_str[i].toDouble()); 17910447Snilay@cs.wisc.edu } 18010447Snilay@cs.wisc.edu 18110447Snilay@cs.wisc.edu // Set the driving strength to minimum 18210447Snilay@cs.wisc.edu m_curr_driving_strengths_idx_ = 0; 18310447Snilay@cs.wisc.edu setProperty("DrivingStrength", m_driving_strengths_[m_curr_driving_strengths_idx_]); 18410447Snilay@cs.wisc.edu return; 18510447Snilay@cs.wisc.edu } 18610447Snilay@cs.wisc.edu 18710447Snilay@cs.wisc.edu // Connect a port (input or output) to some ElectricalNet 18810447Snilay@cs.wisc.edu void ElectricalModel::portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_) 18910447Snilay@cs.wisc.edu { 19010447Snilay@cs.wisc.edu ASSERT(m_net_references_->keyExist(connect_net_name_), "[Error] " + getInstanceName() + 19110447Snilay@cs.wisc.edu " -> Net '" + connect_net_name_ + "' does not exist!"); 19210447Snilay@cs.wisc.edu 19310447Snilay@cs.wisc.edu portConnect(connect_model_, connect_port_name_, connect_net_name_, m_net_references_->get(connect_net_name_)); 19410447Snilay@cs.wisc.edu } 19510447Snilay@cs.wisc.edu 19610447Snilay@cs.wisc.edu void ElectricalModel::portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_, const NetIndex& connect_net_indices_) 19710447Snilay@cs.wisc.edu { 19810447Snilay@cs.wisc.edu ASSERT(m_net_references_->keyExist(connect_net_name_), "[Error] " + getInstanceName() + 19910447Snilay@cs.wisc.edu " -> Net '" + connect_net_name_ + "' does not exist!"); 20010447Snilay@cs.wisc.edu 20110447Snilay@cs.wisc.edu // Check whether the port name is an input or output, ASSERTion error if neither 20210447Snilay@cs.wisc.edu bool is_input = connect_model_->getInputs()->keyExist(connect_port_name_); 20310447Snilay@cs.wisc.edu bool is_output = connect_model_->getOutputs()->keyExist(connect_port_name_); 20410447Snilay@cs.wisc.edu 20510447Snilay@cs.wisc.edu ASSERT(is_input || is_output, "[Error] " + getInstanceName() + " -> Model '" + connect_model_->getInstanceName() + 20610447Snilay@cs.wisc.edu "' does not have a port named '" + connect_port_name_ + "'!"); 20710447Snilay@cs.wisc.edu 20810447Snilay@cs.wisc.edu int connect_net_width = connect_net_indices_.second - connect_net_indices_.first + 1; 20910447Snilay@cs.wisc.edu const NetIndex& port_indices = connect_model_->getNetReference(connect_port_name_); 21010447Snilay@cs.wisc.edu int port_width = port_indices.second - port_indices.first + 1; 21110447Snilay@cs.wisc.edu 21210447Snilay@cs.wisc.edu ASSERT(connect_net_width == port_width, "[Error] " + getInstanceName() + " -> Port width mismatch for Model '" + 21310447Snilay@cs.wisc.edu connect_model_->getInstanceName() + "." + connect_port_name_ + toString(port_indices) + 21410447Snilay@cs.wisc.edu "' and net '" + connect_net_name_ + toString(connect_net_indices_) + "'!"); 21510447Snilay@cs.wisc.edu 21610447Snilay@cs.wisc.edu int port_index = port_indices.first; 21710447Snilay@cs.wisc.edu int connect_net_index = connect_net_indices_.first; 21810447Snilay@cs.wisc.edu 21910447Snilay@cs.wisc.edu if(is_input) 22010447Snilay@cs.wisc.edu { 22110447Snilay@cs.wisc.edu while(port_index <= port_indices.second) 22210447Snilay@cs.wisc.edu { 22310447Snilay@cs.wisc.edu getNet(connect_net_name_, makeNetIndex(connect_net_index))->addDownstreamNode( 22410447Snilay@cs.wisc.edu connect_model_->getNet(connect_port_name_, makeNetIndex(port_index))); 22510447Snilay@cs.wisc.edu ++port_index; 22610447Snilay@cs.wisc.edu ++connect_net_index; 22710447Snilay@cs.wisc.edu } 22810447Snilay@cs.wisc.edu } 22910447Snilay@cs.wisc.edu else if(is_output) 23010447Snilay@cs.wisc.edu { 23110447Snilay@cs.wisc.edu while (port_index <= port_indices.second) 23210447Snilay@cs.wisc.edu { 23310447Snilay@cs.wisc.edu connect_model_->getNet(connect_port_name_, makeNetIndex(port_index))->addDownstreamNode( 23410447Snilay@cs.wisc.edu getNet(connect_net_name_, makeNetIndex(connect_net_index))); 23510447Snilay@cs.wisc.edu ++port_index; 23610447Snilay@cs.wisc.edu ++connect_net_index; 23710447Snilay@cs.wisc.edu } 23810447Snilay@cs.wisc.edu } 23910447Snilay@cs.wisc.edu } 24010447Snilay@cs.wisc.edu 24110447Snilay@cs.wisc.edu //Get Drivers 24210447Snilay@cs.wisc.edu const Map<ElectricalDriver*>* ElectricalModel::getDrivers() const 24310447Snilay@cs.wisc.edu { 24410447Snilay@cs.wisc.edu return m_drivers_; 24510447Snilay@cs.wisc.edu } 24610447Snilay@cs.wisc.edu 24710447Snilay@cs.wisc.edu ElectricalDriver* ElectricalModel::getDriver(const String& name_) 24810447Snilay@cs.wisc.edu { 24910447Snilay@cs.wisc.edu return m_drivers_->get(name_); 25010447Snilay@cs.wisc.edu } 25110447Snilay@cs.wisc.edu 25210447Snilay@cs.wisc.edu //Get Driver Multipliers 25310447Snilay@cs.wisc.edu const Map<ElectricalDriverMultiplier*>* ElectricalModel::getDriverMultipliers() const 25410447Snilay@cs.wisc.edu { 25510447Snilay@cs.wisc.edu return m_driver_multipliers_; 25610447Snilay@cs.wisc.edu } 25710447Snilay@cs.wisc.edu 25810447Snilay@cs.wisc.edu ElectricalDriverMultiplier* ElectricalModel::getDriverMultiplier(const String& name_) 25910447Snilay@cs.wisc.edu { 26010447Snilay@cs.wisc.edu return m_driver_multipliers_->get(name_); 26110447Snilay@cs.wisc.edu } 26210447Snilay@cs.wisc.edu 26310447Snilay@cs.wisc.edu //Get Nets 26410447Snilay@cs.wisc.edu const Map<ElectricalNet*>* ElectricalModel::getNets() const 26510447Snilay@cs.wisc.edu { 26610447Snilay@cs.wisc.edu return m_nets_; 26710447Snilay@cs.wisc.edu } 26810447Snilay@cs.wisc.edu 26910447Snilay@cs.wisc.edu ElectricalNet* ElectricalModel::getNet(const String& name_) 27010447Snilay@cs.wisc.edu { 27110447Snilay@cs.wisc.edu return getNet(name_, m_net_references_->get(name_)); 27210447Snilay@cs.wisc.edu } 27310447Snilay@cs.wisc.edu 27410447Snilay@cs.wisc.edu ElectricalNet* ElectricalModel::getNet(const String& name_, const NetIndex& index_) 27510447Snilay@cs.wisc.edu { 27610447Snilay@cs.wisc.edu ASSERT(index_.first == index_.second, "[Error] " + getInstanceName() + 27710447Snilay@cs.wisc.edu " -> Ambiguous get net since (" + name_ + ") is a bus consisting of several nets!"); 27810447Snilay@cs.wisc.edu return m_nets_->get(name_ + "[" + (String) index_.first + "]"); 27910447Snilay@cs.wisc.edu } 28010447Snilay@cs.wisc.edu 28110447Snilay@cs.wisc.edu //Get Loads 28210447Snilay@cs.wisc.edu const Map<ElectricalLoad*>* ElectricalModel::getLoads() const 28310447Snilay@cs.wisc.edu { 28410447Snilay@cs.wisc.edu return m_loads_; 28510447Snilay@cs.wisc.edu } 28610447Snilay@cs.wisc.edu 28710447Snilay@cs.wisc.edu ElectricalLoad* ElectricalModel::getLoad(const String& name_) 28810447Snilay@cs.wisc.edu { 28910447Snilay@cs.wisc.edu return m_loads_->get(name_); 29010447Snilay@cs.wisc.edu } 29110447Snilay@cs.wisc.edu 29210447Snilay@cs.wisc.edu //Get Delays 29310447Snilay@cs.wisc.edu const Map<ElectricalDelay*>* ElectricalModel::getDelays() const 29410447Snilay@cs.wisc.edu { 29510447Snilay@cs.wisc.edu return m_delays_; 29610447Snilay@cs.wisc.edu } 29710447Snilay@cs.wisc.edu 29810447Snilay@cs.wisc.edu ElectricalDelay* ElectricalModel::getDelay(const String& name_) 29910447Snilay@cs.wisc.edu { 30010447Snilay@cs.wisc.edu return m_delays_->get(name_); 30110447Snilay@cs.wisc.edu } 30210447Snilay@cs.wisc.edu 30310447Snilay@cs.wisc.edu //Get Inputs 30410447Snilay@cs.wisc.edu const Map<PortInfo*>* ElectricalModel::getInputs() const 30510447Snilay@cs.wisc.edu { 30610447Snilay@cs.wisc.edu return m_input_ports_; 30710447Snilay@cs.wisc.edu } 30810447Snilay@cs.wisc.edu 30910447Snilay@cs.wisc.edu PortInfo* ElectricalModel::getInputPort(const String& name_) 31010447Snilay@cs.wisc.edu { 31110447Snilay@cs.wisc.edu ASSERT(m_input_ports_->keyExist(name_), "[Error] " + getInstanceName() + 31210447Snilay@cs.wisc.edu " -> Input port (" + name_ + ") does not exist"); 31310447Snilay@cs.wisc.edu 31410447Snilay@cs.wisc.edu return m_input_ports_->get(name_); 31510447Snilay@cs.wisc.edu } 31610447Snilay@cs.wisc.edu 31710447Snilay@cs.wisc.edu const PortInfo* ElectricalModel::getInputPort(const String& name_) const 31810447Snilay@cs.wisc.edu { 31910447Snilay@cs.wisc.edu ASSERT(m_input_ports_->keyExist(name_), "[Error] " + getInstanceName() + 32010447Snilay@cs.wisc.edu " -> Input port (" + name_ + ") does not exist"); 32110447Snilay@cs.wisc.edu 32210447Snilay@cs.wisc.edu return m_input_ports_->get(name_); 32310447Snilay@cs.wisc.edu } 32410447Snilay@cs.wisc.edu 32510447Snilay@cs.wisc.edu //Get Outputs 32610447Snilay@cs.wisc.edu const Map<PortInfo*>* ElectricalModel::getOutputs() const 32710447Snilay@cs.wisc.edu { 32810447Snilay@cs.wisc.edu return m_output_ports_; 32910447Snilay@cs.wisc.edu } 33010447Snilay@cs.wisc.edu 33110447Snilay@cs.wisc.edu PortInfo* ElectricalModel::getOutputPort(const String& name_) 33210447Snilay@cs.wisc.edu { 33310447Snilay@cs.wisc.edu ASSERT(m_output_ports_->keyExist(name_), "[Error] " + getInstanceName() + 33410447Snilay@cs.wisc.edu " -> Output port (" + name_ + ") does not exist"); 33510447Snilay@cs.wisc.edu 33610447Snilay@cs.wisc.edu return m_output_ports_->get(name_); 33710447Snilay@cs.wisc.edu } 33810447Snilay@cs.wisc.edu 33910447Snilay@cs.wisc.edu const PortInfo* ElectricalModel::getOutputPort(const String& name_) const 34010447Snilay@cs.wisc.edu { 34110447Snilay@cs.wisc.edu ASSERT(m_output_ports_->keyExist(name_), "[Error] " + getInstanceName() + 34210447Snilay@cs.wisc.edu " -> Output port (" + name_ + ") does not exist"); 34310447Snilay@cs.wisc.edu 34410447Snilay@cs.wisc.edu return m_output_ports_->get(name_); 34510447Snilay@cs.wisc.edu } 34610447Snilay@cs.wisc.edu 34710447Snilay@cs.wisc.edu const Map<NetIndex>* ElectricalModel::getNetReferences() const 34810447Snilay@cs.wisc.edu { 34910447Snilay@cs.wisc.edu return m_net_references_; 35010447Snilay@cs.wisc.edu } 35110447Snilay@cs.wisc.edu 35210447Snilay@cs.wisc.edu const NetIndex ElectricalModel::getNetReference(const String& name_) const 35310447Snilay@cs.wisc.edu { 35410447Snilay@cs.wisc.edu return m_net_references_->get(name_); 35510447Snilay@cs.wisc.edu } 35610447Snilay@cs.wisc.edu 35710447Snilay@cs.wisc.edu //------------------------------------------------------------------------- 35810447Snilay@cs.wisc.edu // Electrical Connectivity and Timing Element Creation Functions 35910447Snilay@cs.wisc.edu //------------------------------------------------------------------------- 36010447Snilay@cs.wisc.edu 36110447Snilay@cs.wisc.edu // Input Port creation 36210447Snilay@cs.wisc.edu void ElectricalModel::createInputPort(const String& name_, const NetIndex& net_indices_) 36310447Snilay@cs.wisc.edu { 36410447Snilay@cs.wisc.edu // Create the new nets (including its net reference) 36510447Snilay@cs.wisc.edu // This should already check that it has not been previously declared 36610447Snilay@cs.wisc.edu createNet(name_, net_indices_); 36710447Snilay@cs.wisc.edu // Add the net name to list of input ports 36810447Snilay@cs.wisc.edu m_input_ports_->set(name_, new PortInfo(name_, net_indices_)); 36910447Snilay@cs.wisc.edu return; 37010447Snilay@cs.wisc.edu } 37110447Snilay@cs.wisc.edu 37210447Snilay@cs.wisc.edu // Output Port creation 37310447Snilay@cs.wisc.edu void ElectricalModel::createOutputPort(const String& name_, const NetIndex& net_indices_) 37410447Snilay@cs.wisc.edu { 37510447Snilay@cs.wisc.edu // Create the new nets (including its net reference) 37610447Snilay@cs.wisc.edu // This should already check that it has not been previously declared 37710447Snilay@cs.wisc.edu createNet(name_, net_indices_); 37810447Snilay@cs.wisc.edu // Add the net name to list of output ports 37910447Snilay@cs.wisc.edu m_output_ports_->set(name_, new PortInfo(name_, net_indices_)); 38010447Snilay@cs.wisc.edu return; 38110447Snilay@cs.wisc.edu } 38210447Snilay@cs.wisc.edu 38310447Snilay@cs.wisc.edu // Net creation 38410447Snilay@cs.wisc.edu void ElectricalModel::createNet(const String& name_) 38510447Snilay@cs.wisc.edu { 38610447Snilay@cs.wisc.edu // Creating a net with specifying an index range means that the net is just 38710447Snilay@cs.wisc.edu // a 1-bit wire indexed at [0] 38810447Snilay@cs.wisc.edu createNet(name_, makeNetIndex(0, 0)); 38910447Snilay@cs.wisc.edu return; 39010447Snilay@cs.wisc.edu } 39110447Snilay@cs.wisc.edu 39210447Snilay@cs.wisc.edu void ElectricalModel::createNet(const String& name_, const NetIndex& net_indices_) 39310447Snilay@cs.wisc.edu { 39410447Snilay@cs.wisc.edu // Check that it hasn't been previously declared 39510447Snilay@cs.wisc.edu ASSERT( !m_nets_->keyExist(name_) && !m_net_references_->keyExist(name_), 39610447Snilay@cs.wisc.edu "[Error] " + getInstanceName() + " -> Redeclaration of net " + name_); 39710447Snilay@cs.wisc.edu 39810447Snilay@cs.wisc.edu int start = net_indices_.first; 39910447Snilay@cs.wisc.edu int end = net_indices_.second; 40010447Snilay@cs.wisc.edu 40110447Snilay@cs.wisc.edu for (int index = start; index <= end; ++index) 40210447Snilay@cs.wisc.edu { 40310447Snilay@cs.wisc.edu String indexed_name = name_ + "[" + (String) index + "]"; 40410447Snilay@cs.wisc.edu // Create the new net 40510447Snilay@cs.wisc.edu ElectricalNet* net = new ElectricalNet(indexed_name, this); 40610447Snilay@cs.wisc.edu // Add the net to net map 40710447Snilay@cs.wisc.edu m_nets_->set(indexed_name, net); 40810447Snilay@cs.wisc.edu } 40910447Snilay@cs.wisc.edu // Add net to net references 41010447Snilay@cs.wisc.edu m_net_references_->set(name_, net_indices_); 41110447Snilay@cs.wisc.edu return; 41210447Snilay@cs.wisc.edu } 41310447Snilay@cs.wisc.edu 41410447Snilay@cs.wisc.edu // Driver creation 41510447Snilay@cs.wisc.edu void ElectricalModel::createDriver(const String& name_, bool sizable_) 41610447Snilay@cs.wisc.edu { 41710447Snilay@cs.wisc.edu // Check that it hasn't been previously declared 41810447Snilay@cs.wisc.edu ASSERT( !m_drivers_->keyExist(name_), 41910447Snilay@cs.wisc.edu "[Error] " + getInstanceName() + " -> Redeclaration of driver " + name_); 42010447Snilay@cs.wisc.edu 42110447Snilay@cs.wisc.edu ElectricalDriver* driver = new ElectricalDriver(name_, this, sizable_); 42210447Snilay@cs.wisc.edu m_drivers_->set(name_, driver); 42310447Snilay@cs.wisc.edu return; 42410447Snilay@cs.wisc.edu } 42510447Snilay@cs.wisc.edu 42610447Snilay@cs.wisc.edu /* 42710447Snilay@cs.wisc.edu void ElectricalModel::createDriver(const String& name_, bool sizable_, int start_index_, int end_index_) 42810447Snilay@cs.wisc.edu { 42910447Snilay@cs.wisc.edu for (int index = start_index_; index <= end_index_; ++index) 43010447Snilay@cs.wisc.edu { 43110447Snilay@cs.wisc.edu createDriver(name_ + "[" + (String) index + "]", sizable_); 43210447Snilay@cs.wisc.edu } 43310447Snilay@cs.wisc.edu return; 43410447Snilay@cs.wisc.edu } 43510447Snilay@cs.wisc.edu */ 43610447Snilay@cs.wisc.edu 43710447Snilay@cs.wisc.edu // Driver Multiplier creation 43810447Snilay@cs.wisc.edu void ElectricalModel::createDriverMultiplier(const String& name_) 43910447Snilay@cs.wisc.edu { 44010447Snilay@cs.wisc.edu // Check that it hasn't been previously declared 44110447Snilay@cs.wisc.edu ASSERT( !m_driver_multipliers_->keyExist(name_), 44210447Snilay@cs.wisc.edu "[Error] " + getInstanceName() + " -> Redeclaration of driver_multiplier " + name_); 44310447Snilay@cs.wisc.edu 44410447Snilay@cs.wisc.edu ElectricalDriverMultiplier* driver_multiplier = new ElectricalDriverMultiplier(name_, this); 44510447Snilay@cs.wisc.edu m_driver_multipliers_->set(name_, driver_multiplier); 44610447Snilay@cs.wisc.edu return; 44710447Snilay@cs.wisc.edu } 44810447Snilay@cs.wisc.edu 44910447Snilay@cs.wisc.edu // Load creation 45010447Snilay@cs.wisc.edu 45110447Snilay@cs.wisc.edu void ElectricalModel::createLoad(const String& name_) 45210447Snilay@cs.wisc.edu { 45310447Snilay@cs.wisc.edu // Check that it hasn't been previously declared 45410447Snilay@cs.wisc.edu ASSERT( !m_loads_->keyExist(name_), 45510447Snilay@cs.wisc.edu "[Error] " + getInstanceName() + " -> Redeclaration of load " + name_); 45610447Snilay@cs.wisc.edu 45710447Snilay@cs.wisc.edu ElectricalLoad* load = new ElectricalLoad(name_, this); 45810447Snilay@cs.wisc.edu m_loads_->set(name_, load); 45910447Snilay@cs.wisc.edu return; 46010447Snilay@cs.wisc.edu } 46110447Snilay@cs.wisc.edu 46210447Snilay@cs.wisc.edu /* 46310447Snilay@cs.wisc.edu void ElectricalModel::createLoad(const String& name_, int start_index_, int end_index_) 46410447Snilay@cs.wisc.edu { 46510447Snilay@cs.wisc.edu for (int index = start_index_; index <= end_index_; ++index) 46610447Snilay@cs.wisc.edu { 46710447Snilay@cs.wisc.edu createLoad(name_ + "[" + (String) index + "]"); 46810447Snilay@cs.wisc.edu } 46910447Snilay@cs.wisc.edu return; 47010447Snilay@cs.wisc.edu } 47110447Snilay@cs.wisc.edu */ 47210447Snilay@cs.wisc.edu 47310447Snilay@cs.wisc.edu // Delay creation 47410447Snilay@cs.wisc.edu void ElectricalModel::createDelay(const String& name_) 47510447Snilay@cs.wisc.edu { 47610447Snilay@cs.wisc.edu // Check that it hasn't been previously declared 47710447Snilay@cs.wisc.edu ASSERT( !m_delays_->keyExist(name_), 47810447Snilay@cs.wisc.edu "[Error] " + getInstanceName() + " -> Redeclaration of delay " + name_); 47910447Snilay@cs.wisc.edu 48010447Snilay@cs.wisc.edu ElectricalDelay* delay = new ElectricalDelay(name_, this); 48110447Snilay@cs.wisc.edu m_delays_->set(name_, delay); 48210447Snilay@cs.wisc.edu return; 48310447Snilay@cs.wisc.edu } 48410447Snilay@cs.wisc.edu 48510447Snilay@cs.wisc.edu /* 48610447Snilay@cs.wisc.edu void ElectricalModel::createDelay(const String& name_, int start_index_, int end_index_) 48710447Snilay@cs.wisc.edu { 48810447Snilay@cs.wisc.edu for (int index = start_index_; index <= end_index_; ++index) 48910447Snilay@cs.wisc.edu { 49010447Snilay@cs.wisc.edu createDelay(name_ + "[" + (String) index + "]"); 49110447Snilay@cs.wisc.edu } 49210447Snilay@cs.wisc.edu return; 49310447Snilay@cs.wisc.edu } 49410447Snilay@cs.wisc.edu */ 49510447Snilay@cs.wisc.edu //------------------------------------------------------------------------- 49610447Snilay@cs.wisc.edu 49710447Snilay@cs.wisc.edu // Assign a net to be downstream from another net 49810447Snilay@cs.wisc.edu // case 1: 'assign downstream_net_name_ = upstream_net_name_' 49910447Snilay@cs.wisc.edu void ElectricalModel::assign(const String& downstream_net_name_, const String& upstream_net_name_) 50010447Snilay@cs.wisc.edu { 50110447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 50210447Snilay@cs.wisc.edu downstream_net_name_ + "' does not exist!"); 50310447Snilay@cs.wisc.edu 50410447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 50510447Snilay@cs.wisc.edu upstream_net_name_ + "' does not exist!"); 50610447Snilay@cs.wisc.edu 50710447Snilay@cs.wisc.edu assign(downstream_net_name_, getNetReference(downstream_net_name_), 50810447Snilay@cs.wisc.edu upstream_net_name_, getNetReference(upstream_net_name_)); 50910447Snilay@cs.wisc.edu 51010447Snilay@cs.wisc.edu return; 51110447Snilay@cs.wisc.edu } 51210447Snilay@cs.wisc.edu 51310447Snilay@cs.wisc.edu // case 2: 'assign downstream_net_name_[begin:end] = upstream_net_name_' 51410447Snilay@cs.wisc.edu void ElectricalModel::assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_) 51510447Snilay@cs.wisc.edu { 51610447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 51710447Snilay@cs.wisc.edu downstream_net_name_ + "' does not exist!"); 51810447Snilay@cs.wisc.edu 51910447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 52010447Snilay@cs.wisc.edu upstream_net_name_ + "' does not exist!"); 52110447Snilay@cs.wisc.edu 52210447Snilay@cs.wisc.edu assign(downstream_net_name_, downstream_net_indices_, 52310447Snilay@cs.wisc.edu upstream_net_name_, getNetReference(upstream_net_name_)); 52410447Snilay@cs.wisc.edu 52510447Snilay@cs.wisc.edu return; 52610447Snilay@cs.wisc.edu } 52710447Snilay@cs.wisc.edu 52810447Snilay@cs.wisc.edu // case 3: 'assign downstream_net_name_ = upstream_net_name_[begin:end]' 52910447Snilay@cs.wisc.edu void ElectricalModel::assign(const String& downstream_net_name_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) 53010447Snilay@cs.wisc.edu { 53110447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 53210447Snilay@cs.wisc.edu downstream_net_name_ + "' does not exist!"); 53310447Snilay@cs.wisc.edu 53410447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 53510447Snilay@cs.wisc.edu upstream_net_name_ + "' does not exist!"); 53610447Snilay@cs.wisc.edu 53710447Snilay@cs.wisc.edu assign(downstream_net_name_, getNetReference(downstream_net_name_), 53810447Snilay@cs.wisc.edu upstream_net_name_, upstream_net_indices_); 53910447Snilay@cs.wisc.edu 54010447Snilay@cs.wisc.edu return; 54110447Snilay@cs.wisc.edu } 54210447Snilay@cs.wisc.edu // case 4: 'assign downstream_net_name_[begin:end] = upstream_net_name_[begin:end]' 54310447Snilay@cs.wisc.edu void ElectricalModel::assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) 54410447Snilay@cs.wisc.edu { 54510447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 54610447Snilay@cs.wisc.edu downstream_net_name_ + "' does not exist!"); 54710447Snilay@cs.wisc.edu 54810447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" + 54910447Snilay@cs.wisc.edu upstream_net_name_ + "' does not exist!"); 55010447Snilay@cs.wisc.edu 55110447Snilay@cs.wisc.edu // Check that the assignment widths are the same 55210447Snilay@cs.wisc.edu int downstream_width = downstream_net_indices_.second - downstream_net_indices_.first + 1; 55310447Snilay@cs.wisc.edu int upstream_width = upstream_net_indices_.second - upstream_net_indices_.first + 1; 55410447Snilay@cs.wisc.edu 55510447Snilay@cs.wisc.edu ASSERT(downstream_width == upstream_width, "[Error] " + getInstanceName() + " -> Assignment width mismatch: " + 55610447Snilay@cs.wisc.edu downstream_net_name_ + " (" + (String) downstream_width + ") and " + 55710447Snilay@cs.wisc.edu upstream_net_name_ + " (" + (String) upstream_width + ")"); 55810447Snilay@cs.wisc.edu 55910447Snilay@cs.wisc.edu // Loop through indices and connect them together 56010447Snilay@cs.wisc.edu int down_index = downstream_net_indices_.first; 56110447Snilay@cs.wisc.edu int up_index = upstream_net_indices_.first; 56210447Snilay@cs.wisc.edu while (down_index <= downstream_net_indices_.second) 56310447Snilay@cs.wisc.edu { 56410447Snilay@cs.wisc.edu getNet(upstream_net_name_, makeNetIndex(up_index))->addDownstreamNode( 56510447Snilay@cs.wisc.edu getNet(downstream_net_name_, makeNetIndex(down_index))); 56610447Snilay@cs.wisc.edu 56710447Snilay@cs.wisc.edu ++up_index; 56810447Snilay@cs.wisc.edu ++down_index; 56910447Snilay@cs.wisc.edu } 57010447Snilay@cs.wisc.edu 57110447Snilay@cs.wisc.edu return; 57210447Snilay@cs.wisc.edu } 57310447Snilay@cs.wisc.edu 57410447Snilay@cs.wisc.edu // Assign a net to another net through a driver multiplier 57510447Snilay@cs.wisc.edu void ElectricalModel::assignVirtualFanout(const String& downstream_net_name_, const String& upstream_net_name_) 57610447Snilay@cs.wisc.edu { 57710447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + 57810447Snilay@cs.wisc.edu " -> Net '" + upstream_net_name_ + "' does not exist!"); 57910447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + 58010447Snilay@cs.wisc.edu " -> Net '" + downstream_net_name_ + "' does not exist!"); 58110447Snilay@cs.wisc.edu 58210447Snilay@cs.wisc.edu assignVirtualFanout(downstream_net_name_, getNetReference(downstream_net_name_), upstream_net_name_, getNetReference(upstream_net_name_)); 58310447Snilay@cs.wisc.edu return; 58410447Snilay@cs.wisc.edu } 58510447Snilay@cs.wisc.edu 58610447Snilay@cs.wisc.edu // Assign a net to another net through a driver multiplier 58710447Snilay@cs.wisc.edu void ElectricalModel::assignVirtualFanout(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) 58810447Snilay@cs.wisc.edu { 58910447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + 59010447Snilay@cs.wisc.edu " -> Net '" + upstream_net_name_ + "' does not exist!"); 59110447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + 59210447Snilay@cs.wisc.edu " -> Net '" + downstream_net_name_ + "' does not exist!"); 59310447Snilay@cs.wisc.edu 59410447Snilay@cs.wisc.edu const String& drive_mult_name = upstream_net_name_ + "_" + (String) upstream_net_indices_.first + "_DriverMultiplier"; 59510447Snilay@cs.wisc.edu bool is_drive_mult_exist = getDriverMultipliers()->keyExist(drive_mult_name); 59610447Snilay@cs.wisc.edu 59710447Snilay@cs.wisc.edu // Create a driver multiplier and assign it to upstream_net since it doesn't exist 59810447Snilay@cs.wisc.edu if(!is_drive_mult_exist) 59910447Snilay@cs.wisc.edu { 60010447Snilay@cs.wisc.edu createDriverMultiplier(drive_mult_name); 60110447Snilay@cs.wisc.edu getNet(upstream_net_name_, upstream_net_indices_)->addDownstreamNode(getDriverMultiplier(drive_mult_name)); 60210447Snilay@cs.wisc.edu } 60310447Snilay@cs.wisc.edu 60410447Snilay@cs.wisc.edu // Assign downstream_net_name_[end:begin] = driver_multiplier_name_ 60510447Snilay@cs.wisc.edu ElectricalDriverMultiplier* drive_mult = getDriverMultiplier(drive_mult_name); 60610447Snilay@cs.wisc.edu int begin_index = downstream_net_indices_.first; 60710447Snilay@cs.wisc.edu int end_index = downstream_net_indices_.second; 60810447Snilay@cs.wisc.edu for(int i = begin_index; i <= end_index; ++i) 60910447Snilay@cs.wisc.edu { 61010447Snilay@cs.wisc.edu drive_mult->addDownstreamNode(getNet(downstream_net_name_, makeNetIndex(i))); 61110447Snilay@cs.wisc.edu } 61210447Snilay@cs.wisc.edu return; 61310447Snilay@cs.wisc.edu } 61410447Snilay@cs.wisc.edu 61510447Snilay@cs.wisc.edu void ElectricalModel::assignVirtualFanin(const String& downstream_net_name_, const String& upstream_net_name_) 61610447Snilay@cs.wisc.edu { 61710447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + 61810447Snilay@cs.wisc.edu " -> Net '" + upstream_net_name_ + "' does not exist!"); 61910447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + 62010447Snilay@cs.wisc.edu " -> Net '" + downstream_net_name_ + "' does not exist!"); 62110447Snilay@cs.wisc.edu 62210447Snilay@cs.wisc.edu assignVirtualFanin(downstream_net_name_, getNetReference(downstream_net_name_), upstream_net_name_, getNetReference(upstream_net_name_)); 62310447Snilay@cs.wisc.edu return; 62410447Snilay@cs.wisc.edu } 62510447Snilay@cs.wisc.edu 62610447Snilay@cs.wisc.edu void ElectricalModel::assignVirtualFanin(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_) 62710447Snilay@cs.wisc.edu { 62810447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + 62910447Snilay@cs.wisc.edu " -> Net '" + upstream_net_name_ + "' does not exist!"); 63010447Snilay@cs.wisc.edu ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + 63110447Snilay@cs.wisc.edu " -> Net '" + downstream_net_name_ + "' does not exist!"); 63210447Snilay@cs.wisc.edu 63310447Snilay@cs.wisc.edu int begin_index = upstream_net_indices_.first; 63410447Snilay@cs.wisc.edu int end_index = upstream_net_indices_.second; 63510447Snilay@cs.wisc.edu 63610447Snilay@cs.wisc.edu for(int i = begin_index; i <= end_index; ++i) 63710447Snilay@cs.wisc.edu { 63810447Snilay@cs.wisc.edu getNet(upstream_net_name_, makeNetIndex(i))->addDownstreamNode(getNet(downstream_net_name_, downstream_net_indices_)); 63910447Snilay@cs.wisc.edu } 64010447Snilay@cs.wisc.edu return; 64110447Snilay@cs.wisc.edu } 64210447Snilay@cs.wisc.edu 64310447Snilay@cs.wisc.edu void ElectricalModel::createElectricalResults() 64410447Snilay@cs.wisc.edu { 64510447Snilay@cs.wisc.edu // Add active area result 64610447Snilay@cs.wisc.edu addAreaResult(new Result("Active")); 64710447Snilay@cs.wisc.edu 64810447Snilay@cs.wisc.edu // Add wire area result 64910447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 65010447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 65110447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it; 65210447Snilay@cs.wisc.edu for(it = it_begin; it != it_end; ++it) 65310447Snilay@cs.wisc.edu { 65410447Snilay@cs.wisc.edu const String& layer_name = (*it); 65510447Snilay@cs.wisc.edu addAreaResult(new Result(layer_name + "Wire")); 65610447Snilay@cs.wisc.edu } 65710447Snilay@cs.wisc.edu 65810447Snilay@cs.wisc.edu // Add leakage result 65910447Snilay@cs.wisc.edu addNddPowerResult(new Result("Leakage")); 66010447Snilay@cs.wisc.edu 66110447Snilay@cs.wisc.edu // Add idle event result 66210447Snilay@cs.wisc.edu createElectricalEventResult("Idle"); 66310447Snilay@cs.wisc.edu return; 66410447Snilay@cs.wisc.edu } 66510447Snilay@cs.wisc.edu 66610447Snilay@cs.wisc.edu void ElectricalModel::addElectricalSubResults(const ElectricalModel* model_, double number_models_) 66710447Snilay@cs.wisc.edu { 66810447Snilay@cs.wisc.edu // Add active area sub result 66910447Snilay@cs.wisc.edu getAreaResult("Active")->addSubResult(model_->getAreaResult("Active"), model_->getInstanceName(), number_models_); 67010447Snilay@cs.wisc.edu 67110447Snilay@cs.wisc.edu // Add wire area sub result 67210447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 67310447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 67410447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it; 67510447Snilay@cs.wisc.edu for(it = it_begin; it != it_end; ++it) 67610447Snilay@cs.wisc.edu { 67710447Snilay@cs.wisc.edu const String& layer_name = (*it); 67810447Snilay@cs.wisc.edu const String& result_name = layer_name + "Wire"; 67910447Snilay@cs.wisc.edu getAreaResult(result_name)->addSubResult(model_->getAreaResult(result_name), model_->getInstanceName(), number_models_); 68010447Snilay@cs.wisc.edu } 68110447Snilay@cs.wisc.edu 68210447Snilay@cs.wisc.edu // Add leakage sub result 68310447Snilay@cs.wisc.edu getNddPowerResult("Leakage")->addSubResult(model_->getNddPowerResult("Leakage"), model_->getInstanceName(), number_models_); 68410447Snilay@cs.wisc.edu 68510447Snilay@cs.wisc.edu // Add idle event sub result 68610447Snilay@cs.wisc.edu getEventResult("Idle")->addSubResult(model_->getEventResult("Idle"), model_->getInstanceName(), number_models_); 68710447Snilay@cs.wisc.edu return; 68810447Snilay@cs.wisc.edu } 68910447Snilay@cs.wisc.edu 69010447Snilay@cs.wisc.edu void ElectricalModel::addElectricalWireSubResult(const String& wire_layer_, const Result* result_, const String& producer_, double number_results_) 69110447Snilay@cs.wisc.edu { 69210447Snilay@cs.wisc.edu getAreaResult(wire_layer_ + "Wire")->addSubResult(result_, producer_, number_results_); 69310447Snilay@cs.wisc.edu return; 69410447Snilay@cs.wisc.edu } 69510447Snilay@cs.wisc.edu 69610447Snilay@cs.wisc.edu void ElectricalModel::createElectricalAtomicResults() 69710447Snilay@cs.wisc.edu { 69810447Snilay@cs.wisc.edu // Add active area result 69910447Snilay@cs.wisc.edu addAreaResult(new AtomicResult("Active")); 70010447Snilay@cs.wisc.edu 70110447Snilay@cs.wisc.edu // Add wire area result 70210447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 70310447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 70410447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it; 70510447Snilay@cs.wisc.edu for(it = it_begin; it != it_end; ++it) 70610447Snilay@cs.wisc.edu { 70710447Snilay@cs.wisc.edu const String& layer_name = (*it); 70810447Snilay@cs.wisc.edu addAreaResult(new AtomicResult(layer_name + "Wire")); 70910447Snilay@cs.wisc.edu } 71010447Snilay@cs.wisc.edu 71110447Snilay@cs.wisc.edu // Add leakage result 71210447Snilay@cs.wisc.edu addNddPowerResult(new AtomicResult("Leakage")); 71310447Snilay@cs.wisc.edu 71410447Snilay@cs.wisc.edu // Add idle event result 71510447Snilay@cs.wisc.edu createElectricalEventAtomicResult("Idle"); 71610447Snilay@cs.wisc.edu return; 71710447Snilay@cs.wisc.edu } 71810447Snilay@cs.wisc.edu 71910447Snilay@cs.wisc.edu void ElectricalModel::addElecticalAtomicResultValues(const ElectricalModel* model_, double number_models_) 72010447Snilay@cs.wisc.edu { 72110447Snilay@cs.wisc.edu getAreaResult("Active")->addValue(model_->getAreaResult("Active")->calculateSum() * number_models_); 72210447Snilay@cs.wisc.edu 72310447Snilay@cs.wisc.edu // Add wire area sub result 72410447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 72510447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 72610447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it; 72710447Snilay@cs.wisc.edu for(it = it_begin; it != it_end; ++it) 72810447Snilay@cs.wisc.edu { 72910447Snilay@cs.wisc.edu const String& layer_name = (*it); 73010447Snilay@cs.wisc.edu const String& result_name = layer_name + "Wire"; 73110447Snilay@cs.wisc.edu getAreaResult(result_name)->addValue(model_->getAreaResult(result_name)->calculateSum() * number_models_); 73210447Snilay@cs.wisc.edu } 73310447Snilay@cs.wisc.edu 73410447Snilay@cs.wisc.edu // Add leakage sub result 73510447Snilay@cs.wisc.edu getNddPowerResult("Leakage")->addValue(model_->getNddPowerResult("Leakage")->calculateSum() * number_models_); 73610447Snilay@cs.wisc.edu 73710447Snilay@cs.wisc.edu // Add idle event sub result 73810447Snilay@cs.wisc.edu getEventResult("Idle")->addValue(model_->getEventResult("Idle")->calculateSum() * number_models_); 73910447Snilay@cs.wisc.edu return; 74010447Snilay@cs.wisc.edu } 74110447Snilay@cs.wisc.edu 74210447Snilay@cs.wisc.edu void ElectricalModel::addElecticalWireAtomicResultValue(const String& wire_layer_, double value_) 74310447Snilay@cs.wisc.edu { 74410447Snilay@cs.wisc.edu getAreaResult(wire_layer_ + "Wire")->addValue(value_); 74510447Snilay@cs.wisc.edu return; 74610447Snilay@cs.wisc.edu } 74710447Snilay@cs.wisc.edu 74810447Snilay@cs.wisc.edu void ElectricalModel::resetElectricalAtomicResults() 74910447Snilay@cs.wisc.edu { 75010447Snilay@cs.wisc.edu getAreaResult("Active")->setValue(0.0); 75110447Snilay@cs.wisc.edu 75210447Snilay@cs.wisc.edu // Reset wire area sub result 75310447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin(); 75410447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end(); 75510447Snilay@cs.wisc.edu TechModel::ConstWireLayerIterator it; 75610447Snilay@cs.wisc.edu for(it = it_begin; it != it_end; ++it) 75710447Snilay@cs.wisc.edu { 75810447Snilay@cs.wisc.edu const String& layer_name = (*it); 75910447Snilay@cs.wisc.edu const String& result_name = layer_name + "Wire"; 76010447Snilay@cs.wisc.edu getAreaResult(result_name)->setValue(0.0); 76110447Snilay@cs.wisc.edu } 76210447Snilay@cs.wisc.edu 76310447Snilay@cs.wisc.edu // Reset leakage sub result 76410447Snilay@cs.wisc.edu getNddPowerResult("Leakage")->setValue(0.0); 76510447Snilay@cs.wisc.edu 76610447Snilay@cs.wisc.edu // Reset idle event sub result 76710447Snilay@cs.wisc.edu getEventResult("Idle")->setValue(0.0); 76810447Snilay@cs.wisc.edu 76910447Snilay@cs.wisc.edu return; 77010447Snilay@cs.wisc.edu } 77110447Snilay@cs.wisc.edu 77210447Snilay@cs.wisc.edu void ElectricalModel::createElectricalEventResult(const String& name_) 77310447Snilay@cs.wisc.edu { 77410447Snilay@cs.wisc.edu // Add the event result 77510447Snilay@cs.wisc.edu addEventResult(new Result(name_)); 77610447Snilay@cs.wisc.edu // Add event info 77710447Snilay@cs.wisc.edu m_event_infos_->set(name_, new EventInfo(name_, getInputs())); 77810447Snilay@cs.wisc.edu return; 77910447Snilay@cs.wisc.edu } 78010447Snilay@cs.wisc.edu 78110447Snilay@cs.wisc.edu void ElectricalModel::createElectricalEventAtomicResult(const String& name_) 78210447Snilay@cs.wisc.edu { 78310447Snilay@cs.wisc.edu // Add the event result 78410447Snilay@cs.wisc.edu addEventResult(new AtomicResult(name_)); 78510447Snilay@cs.wisc.edu // Add event info 78610447Snilay@cs.wisc.edu m_event_infos_->set(name_, new EventInfo(name_, getInputs())); 78710447Snilay@cs.wisc.edu return; 78810447Snilay@cs.wisc.edu } 78910447Snilay@cs.wisc.edu 79010447Snilay@cs.wisc.edu void ElectricalModel::assignPortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const TransitionInfo& trans_info_) 79110447Snilay@cs.wisc.edu { 79210447Snilay@cs.wisc.edu ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() + 79310447Snilay@cs.wisc.edu " -> Downstream model does not exist"); 79410447Snilay@cs.wisc.edu 79510447Snilay@cs.wisc.edu downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info_); 79610447Snilay@cs.wisc.edu return; 79710447Snilay@cs.wisc.edu } 79810447Snilay@cs.wisc.edu 79910447Snilay@cs.wisc.edu void ElectricalModel::propagatePortTransitionInfo(const String& downstream_port_name_, const String& upstream_port_name_) 80010447Snilay@cs.wisc.edu { 80110447Snilay@cs.wisc.edu const TransitionInfo& trans_info = getInputPort(upstream_port_name_)->getTransitionInfo(); 80210447Snilay@cs.wisc.edu getOutputPort(downstream_port_name_)->setTransitionInfo(trans_info); 80310447Snilay@cs.wisc.edu return; 80410447Snilay@cs.wisc.edu } 80510447Snilay@cs.wisc.edu 80610447Snilay@cs.wisc.edu void ElectricalModel::propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const String& upstream_port_name_) 80710447Snilay@cs.wisc.edu { 80810447Snilay@cs.wisc.edu ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() + 80910447Snilay@cs.wisc.edu " -> Downstream model does not exist"); 81010447Snilay@cs.wisc.edu 81110447Snilay@cs.wisc.edu const TransitionInfo& trans_info = getInputPort(upstream_port_name_)->getTransitionInfo(); 81210447Snilay@cs.wisc.edu downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info); 81310447Snilay@cs.wisc.edu return; 81410447Snilay@cs.wisc.edu } 81510447Snilay@cs.wisc.edu 81610447Snilay@cs.wisc.edu void ElectricalModel::propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_) 81710447Snilay@cs.wisc.edu { 81810447Snilay@cs.wisc.edu ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() + 81910447Snilay@cs.wisc.edu " -> Downstream model does not exist"); 82010447Snilay@cs.wisc.edu ASSERT(upstream_model_ != NULL, "[Error] " + getInstanceName() + 82110447Snilay@cs.wisc.edu " -> Upstream model does not exist"); 82210447Snilay@cs.wisc.edu 82310447Snilay@cs.wisc.edu const TransitionInfo& trans_info = upstream_model_->getOutputPort(upstream_port_name_)->getTransitionInfo(); 82410447Snilay@cs.wisc.edu 82510447Snilay@cs.wisc.edu downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info); 82610447Snilay@cs.wisc.edu return; 82710447Snilay@cs.wisc.edu } 82810447Snilay@cs.wisc.edu 82910447Snilay@cs.wisc.edu void ElectricalModel::propagatePortTransitionInfo(const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_) 83010447Snilay@cs.wisc.edu { 83110447Snilay@cs.wisc.edu ASSERT(upstream_model_ != NULL, "[Error] " + getInstanceName() + 83210447Snilay@cs.wisc.edu " -> Upstream model does not exist"); 83310447Snilay@cs.wisc.edu 83410447Snilay@cs.wisc.edu const TransitionInfo& trans_info = upstream_model_->getOutputPort(upstream_port_name_)->getTransitionInfo(); 83510447Snilay@cs.wisc.edu getOutputPort(downstream_port_name_)->setTransitionInfo(trans_info); 83610447Snilay@cs.wisc.edu return; 83710447Snilay@cs.wisc.edu } 83810447Snilay@cs.wisc.edu 83910447Snilay@cs.wisc.edu void ElectricalModel::propagateTransitionInfo() 84010447Snilay@cs.wisc.edu { 84110447Snilay@cs.wisc.edu // by default do nothing. 84210447Snilay@cs.wisc.edu } 84310447Snilay@cs.wisc.edu 84410447Snilay@cs.wisc.edu void ElectricalModel::useModel(const String& event_name_) 84510447Snilay@cs.wisc.edu { 84610447Snilay@cs.wisc.edu getGenProperties()->set("UseModelEvent", event_name_); 84710447Snilay@cs.wisc.edu applyTransitionInfo(event_name_); 84810447Snilay@cs.wisc.edu useModel(); 84910447Snilay@cs.wisc.edu return; 85010447Snilay@cs.wisc.edu } 85110447Snilay@cs.wisc.edu 85210447Snilay@cs.wisc.edu void ElectricalModel::useModel() 85310447Snilay@cs.wisc.edu { 85410447Snilay@cs.wisc.edu propagateTransitionInfo(); 85510447Snilay@cs.wisc.edu return; 85610447Snilay@cs.wisc.edu } 85710447Snilay@cs.wisc.edu 85810447Snilay@cs.wisc.edu void ElectricalModel::applyTransitionInfo(const String& event_name_) 85910447Snilay@cs.wisc.edu { 86010447Snilay@cs.wisc.edu // Check if the event actually exists 86110447Snilay@cs.wisc.edu ASSERT(hasEventResult(event_name_), "[Error] " + getInstanceName() + 86210447Snilay@cs.wisc.edu " -> Event (" + event_name_ + ") does not exist in the result map"); 86310447Snilay@cs.wisc.edu ASSERT(m_event_infos_->keyExist(event_name_), "[Error] " + getInstanceName() + 86410447Snilay@cs.wisc.edu " -> Event (" + event_name_ + ") does not exist in the event info map"); 86510447Snilay@cs.wisc.edu 86610447Snilay@cs.wisc.edu const EventInfo* event_info = m_event_infos_->get(event_name_); 86710447Snilay@cs.wisc.edu 86810447Snilay@cs.wisc.edu // Set the input ports' transition information for the event 86910447Snilay@cs.wisc.edu Map<PortInfo*>::ConstIterator it_begin = m_input_ports_->begin(); 87010447Snilay@cs.wisc.edu Map<PortInfo*>::ConstIterator it_end = m_input_ports_->end(); 87110447Snilay@cs.wisc.edu Map<PortInfo*>::ConstIterator it; 87210447Snilay@cs.wisc.edu for(it = it_begin; it != it_end; ++it) 87310447Snilay@cs.wisc.edu { 87410447Snilay@cs.wisc.edu const String& port_name = it->first; 87510447Snilay@cs.wisc.edu PortInfo* port_info = it->second; 87610447Snilay@cs.wisc.edu const TransitionInfo& trans_info = event_info->getTransitionInfo(port_name); 87710447Snilay@cs.wisc.edu port_info->setTransitionInfo(trans_info); 87810447Snilay@cs.wisc.edu } 87910447Snilay@cs.wisc.edu 88010447Snilay@cs.wisc.edu return; 88110447Snilay@cs.wisc.edu } 88210447Snilay@cs.wisc.edu 88310447Snilay@cs.wisc.edu EventInfo* ElectricalModel::getEventInfo(const String& event_name_) 88410447Snilay@cs.wisc.edu { 88510447Snilay@cs.wisc.edu ASSERT(m_event_infos_->keyExist(event_name_), "[Error] " + getInstanceName() + 88610447Snilay@cs.wisc.edu " -> Event (" + event_name_ + ") does not exist"); 88710447Snilay@cs.wisc.edu 88810447Snilay@cs.wisc.edu return m_event_infos_->get(event_name_); 88910447Snilay@cs.wisc.edu } 89010447Snilay@cs.wisc.edu 89110447Snilay@cs.wisc.edu} // namespace DSENT 89210447Snilay@cs.wisc.edu 893