/* Copyright (c) 2012 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifndef __DSENT_MODEL_ELECTRICALMODEL_H__ #define __DSENT_MODEL_ELECTRICALMODEL_H__ #include "util/CommonType.h" #include "model/Model.h" #include "model/TransitionInfo.h" namespace DSENT { class PortInfo; class EventInfo; class ElectricalDriver; class ElectricalDriverMultiplier; class ElectricalNet; class ElectricalLoad; class ElectricalDelay; // A Net index consisting of a start and end index typedef std::pair NetIndex; // Helper function to make net index inline NetIndex makeNetIndex(int start_index_, int end_index_) { ASSERT((end_index_ >= start_index_), (String)"[Error] Invalid net index range " + "[" + (String)start_index_ + ":" + (String)end_index_ + "]"); return NetIndex(start_index_, end_index_); } // Helper function to make net index inline NetIndex makeNetIndex(int index_) { return makeNetIndex(index_, index_); } // Helper function to trun NetIndex to String inline String toString(const NetIndex& net_index_) { return "[" + String(net_index_.second) + ":" + String(net_index_.first) + "]"; } // ElectricalModel specifies physical connectivity to other models as well as the port // parameters for the current model class ElectricalModel : public Model { public: ElectricalModel(const String& instance_name_, const TechModel* tech_model_); virtual ~ElectricalModel(); public: // Check if all properties needed exist in the m_properties_ virtual void checkProperties() const; // Set available driving strength vector from string void setAvailableDrivingStrengths(const String& driving_strengths_); //----------------------------------------------------------------- // Connectivity specification //----------------------------------------------------------------- // Net Indices const Map* getNetReferences() const; const NetIndex getNetReference(const String& name_) const; // Input Ports void createInputPort(const String& name_, const NetIndex& net_indices_ = NetIndex(0, 0)); const Map* getInputs() const; PortInfo* getInputPort(const String& name_); const PortInfo* getInputPort(const String& name_) const; // Output Ports void createOutputPort(const String& name_, const NetIndex& net_indices_ = NetIndex(0, 0)); const Map* getOutputs() const; PortInfo* getOutputPort(const String& name_); const PortInfo* getOutputPort(const String& name_) const; // Electrical Nets void createNet(const String& name_); void createNet(const String& name_, const NetIndex& net_indices_); const Map* getNets() const; ElectricalNet* getNet(const String& name_); ElectricalNet* getNet(const String& name_, const NetIndex& index_); // Assign a net to be downstream from another net // case 1: 'assign downstream_net_name_ = upstream_net_name_' void assign(const String& downstream_net_name_, const String& upstream_net_name_); // case 2: 'assign downstream_net_name_[end:begin] = upstream_net_name_' void assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_); // case 3: 'assign downstream_net_name_ = upstream_net_name_[end:begin]' void assign(const String& downstream_net_name_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_); // case 4: 'assign downstream_net_name_[end:begin] = upstream_net_name_[end:begin]' void assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_); // Connect a port (input or output) to some ElectricalNet // case 1: .connect_port_name_(connect_net_name_) void portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_); // case 2: .connect_port_name_(connect_net_name[end:begin]) void portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_, const NetIndex& connect_net_indices_); // Assign a net to be downstream from another net through a driver multipliers void assignVirtualFanout(const String& downstream_net_name_, const String& upstream_net_name_); void assignVirtualFanout(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_); // Assign a net to be downstream from another net // This is used to enable bit_duplication void assignVirtualFanin(const String& downstream_net_name_, const String& upstream_net_name_); void assignVirtualFanin(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_); //----------------------------------------------------------------- //----------------------------------------------------------------- // Timing Model Components //----------------------------------------------------------------- // Electrical Drivers void createDriver(const String& name_, bool sizable_); //void createDriver(const String& name_, bool sizable_, int start_index_, int end_index_); const Map* getDrivers() const; ElectricalDriver* getDriver(const String& name_); // Electrical Driver Multipliers void createDriverMultiplier(const String& name_); const Map* getDriverMultipliers() const; ElectricalDriverMultiplier* getDriverMultiplier(const String& name_); // Electrical Loads void createLoad(const String& name_); //void createLoad(const String& name_, int start_index_, int end_index_); const Map* getLoads() const; ElectricalLoad* getLoad(const String& name_); // Electrical Delay creation void createDelay(const String& name_); //void createDelay(const String& name_, int start_index_, int end_index_); const Map* getDelays() const; ElectricalDelay* getDelay(const String& name_); //----------------------------------------------------------------- // Get current driving strength double getDrivingStrength() const; // Get current driving strength index int getDrivingStrengthIdx() const; // Set driving strength by index void setDrivingStrengthIdx(int idx_); // Set the instance to minimum driving strength void setMinDrivingStrength(); // Return true if the instance has minimum driving strength bool hasMinDrivingStrength() const; // Return true if the instance has maximum driving strength bool hasMaxDrivingStrength() const; // Increase driving strength index by 1 void increaseDrivingStrength(); // Decrease driving strength index by 1 void decreaseDrivingStrength(); // Create the default sets of the electrical results void createElectricalResults(); // Add the default sets of the electrical results from a model void addElectricalSubResults(const ElectricalModel* model_, double number_models_); // Add extra wire sub results void addElectricalWireSubResult(const String& wire_layer_, const Result* result_, const String& producer_, double number_results_); // Create the default sets of the electrical atomic results void createElectricalAtomicResults(); // Accumulate the electrical atomic results' values void addElecticalAtomicResultValues(const ElectricalModel* model_, double number_models_); // Add extra wire sub results void addElecticalWireAtomicResultValue(const String& wire_layer_, double value_); // Reset the electrical atomic results' values void resetElectricalAtomicResults(); // Create an electrical event result. This will add an event associate to all input/output ports void createElectricalEventResult(const String& name_); // Create an electrical event atomic result void createElectricalEventAtomicResult(const String& name_); //----------------------------------------------------------------- // Helper functions to propagate transition information //----------------------------------------------------------------- void assignPortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const TransitionInfo& trans_info_); void propagatePortTransitionInfo(const String& downstream_port_name_, const String& upstream_port_name_); void propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const String& upstream_port_name_); void propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_); void propagatePortTransitionInfo(const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_); virtual void propagateTransitionInfo(); //----------------------------------------------------------------- //----------------------------------------------------------------- // Helper functions to insert and remove buffers //----------------------------------------------------------------- //----------------------------------------------------------------- virtual void useModel(const String& event_name_); virtual void useModel(); // TODO - add comments void applyTransitionInfo(const String& event_name_); // TODO - add comments EventInfo* getEventInfo(const String& event_name_); protected: // In an ElectricalModel, the complete port-to-port connectivity // of all sub-instance must be specified. Addition/Removal ports or // port-related nets cannot happen after this step //virtual void constructModel() = 0; // In an ElectricalModel, updateModel MUST finish all necessary // calculations such that a timing model can be run //virtual void updateModel() = 0; // In an ElectricalModel, evaluateModel should calculate all // event energies, now that the connectivity and timing has been // completed //virtual void evaluateModel() = 0; private: // Private copy constructor. Use clone to perform copy operation. ElectricalModel(const ElectricalModel& model_); private: // Contains the driving strengths in increasing order vector m_driving_strengths_; // Driving strength index in the driving strength vector int m_curr_driving_strengths_idx_; //Connectivity elements // Nets can come in various bus widths. A net reference is really // just a helper map mapping a referenced map name to a bunch of // net indices. A net index returns the starting and end indices of // a net if the net is a multi-bit bus of some sort Map* m_net_references_; // Map of the input ports Map* m_input_ports_; // Map of the output ports Map* m_output_ports_; // Map of all our electrical nets Map* m_nets_; //Timing model elements // Map of all our electrical drivers Map* m_drivers_; // Map of all our driver multipliers Map* m_driver_multipliers_; // Map of all our electrical loads Map* m_loads_; // Map of all our idealized delays Map* m_delays_; // Map of the event infos Map* m_event_infos_; }; // class ElectricalModel } // namespace DSENT #endif // __DSENT_MODEL_ELECTRICALMODEL_H__