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