| /* 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<int, int> 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<NetIndex>* 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<PortInfo*>* 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<PortInfo*>* 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<ElectricalNet*>* 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<ElectricalDriver*>* getDrivers() const; |
| ElectricalDriver* getDriver(const String& name_); |
| // Electrical Driver Multipliers |
| void createDriverMultiplier(const String& name_); |
| const Map<ElectricalDriverMultiplier*>* 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<ElectricalLoad*>* 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<ElectricalDelay*>* 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<double> 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<NetIndex>* m_net_references_; |
| // Map of the input ports |
| Map<PortInfo*>* m_input_ports_; |
| // Map of the output ports |
| Map<PortInfo*>* m_output_ports_; |
| // Map of all our electrical nets |
| Map<ElectricalNet*>* m_nets_; |
| |
| //Timing model elements |
| // Map of all our electrical drivers |
| Map<ElectricalDriver*>* m_drivers_; |
| // Map of all our driver multipliers |
| Map<ElectricalDriverMultiplier*>* m_driver_multipliers_; |
| // Map of all our electrical loads |
| Map<ElectricalLoad*>* m_loads_; |
| // Map of all our idealized delays |
| Map<ElectricalDelay*>* m_delays_; |
| |
| // Map of the event infos |
| Map<EventInfo*>* m_event_infos_; |
| |
| }; // class ElectricalModel |
| } // namespace DSENT |
| |
| #endif // __DSENT_MODEL_ELECTRICALMODEL_H__ |
| |