1/* Copyright (c) 2012 Massachusetts Institute of Technology
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 * THE SOFTWARE.
20 */
21
22#ifndef __DSENT_MODEL_ELECTRICALMODEL_H__
23#define __DSENT_MODEL_ELECTRICALMODEL_H__
24
25#include "util/CommonType.h"
26#include "model/Model.h"
27#include "model/TransitionInfo.h"
28
29namespace DSENT
30{
31    class PortInfo;
32    class EventInfo;
33    class ElectricalDriver;
34    class ElectricalDriverMultiplier;
35    class ElectricalNet;
36    class ElectricalLoad;
37    class ElectricalDelay;
38
39    // A Net index consisting of a start and end index
40    typedef std::pair<int, int> NetIndex;
41
42    // Helper function to make net index
43    inline NetIndex makeNetIndex(int start_index_, int end_index_)
44    {
45        ASSERT((end_index_ >= start_index_), (String)"[Error] Invalid net index range " +
46
47                "[" + (String)start_index_ + ":" + (String)end_index_ + "]");
48
49        return NetIndex(start_index_, end_index_);
50    }
51
52    // Helper function to make net index
53    inline NetIndex makeNetIndex(int index_)
54    {
55        return makeNetIndex(index_, index_);
56    }
57
58    // Helper function to trun NetIndex to String
59    inline String toString(const NetIndex& net_index_)
60    {
61        return "[" + String(net_index_.second) + ":" + String(net_index_.first) + "]";
62    }
63
64    // ElectricalModel specifies physical connectivity to other models as well as the port
65    // parameters for the current model
66    class ElectricalModel : public Model
67    {
68        public:
69            ElectricalModel(const String& instance_name_, const TechModel* tech_model_);
70            virtual ~ElectricalModel();
71
72        public:
73            // Check if all properties needed exist in the m_properties_
74            virtual void checkProperties() const;
75            // Set available driving strength vector from string
76            void setAvailableDrivingStrengths(const String& driving_strengths_);
77
78            //-----------------------------------------------------------------
79            // Connectivity specification
80            //-----------------------------------------------------------------
81            // Net Indices
82            const Map<NetIndex>* getNetReferences() const;
83            const NetIndex getNetReference(const String& name_) const;
84            // Input Ports
85            void createInputPort(const String& name_, const NetIndex& net_indices_ = NetIndex(0, 0));
86            const Map<PortInfo*>* getInputs() const;
87            PortInfo* getInputPort(const String& name_);
88            const PortInfo* getInputPort(const String& name_) const;
89            // Output Ports
90            void createOutputPort(const String& name_, const NetIndex& net_indices_ = NetIndex(0, 0));
91            const Map<PortInfo*>* getOutputs() const;
92            PortInfo* getOutputPort(const String& name_);
93            const PortInfo* getOutputPort(const String& name_) const;
94            // Electrical Nets
95            void createNet(const String& name_);
96            void createNet(const String& name_, const NetIndex& net_indices_);
97            const Map<ElectricalNet*>* getNets() const;
98            ElectricalNet* getNet(const String& name_);
99            ElectricalNet* getNet(const String& name_, const NetIndex& index_);
100
101            // Assign a net to be downstream from another net
102            // case 1: 'assign downstream_net_name_ = upstream_net_name_'
103            void assign(const String& downstream_net_name_, const String& upstream_net_name_);
104            // case 2: 'assign downstream_net_name_[end:begin] = upstream_net_name_'
105            void assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_);
106            // case 3: 'assign downstream_net_name_ = upstream_net_name_[end:begin]'
107            void assign(const String& downstream_net_name_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_);
108            // case 4: 'assign downstream_net_name_[end:begin] = upstream_net_name_[end:begin]'
109            void assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_);
110
111            // Connect a port (input or output) to some ElectricalNet
112            // case 1: .connect_port_name_(connect_net_name_)
113            void portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_);
114            // case 2: .connect_port_name_(connect_net_name[end:begin])
115            void portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_, const NetIndex& connect_net_indices_);
116
117            // Assign a net to be downstream from another net through a driver multipliers
118            void assignVirtualFanout(const String& downstream_net_name_, const String& upstream_net_name_);
119            void assignVirtualFanout(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_);
120            // Assign a net to be downstream from another net
121            // This is used to enable bit_duplication
122            void assignVirtualFanin(const String& downstream_net_name_, const String& upstream_net_name_);
123            void assignVirtualFanin(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_);
124            //-----------------------------------------------------------------
125
126            //-----------------------------------------------------------------
127            // Timing Model Components
128            //-----------------------------------------------------------------
129            // Electrical Drivers
130            void createDriver(const String& name_, bool sizable_);
131            //void createDriver(const String& name_, bool sizable_, int start_index_, int end_index_);
132            const Map<ElectricalDriver*>* getDrivers() const;
133            ElectricalDriver* getDriver(const String& name_);
134            // Electrical Driver Multipliers
135            void createDriverMultiplier(const String& name_);
136            const Map<ElectricalDriverMultiplier*>* getDriverMultipliers() const;
137            ElectricalDriverMultiplier* getDriverMultiplier(const String& name_);
138
139
140            // Electrical Loads
141            void createLoad(const String& name_);
142            //void createLoad(const String& name_, int start_index_, int end_index_);
143            const Map<ElectricalLoad*>* getLoads() const;
144            ElectricalLoad* getLoad(const String& name_);
145            // Electrical Delay creation
146            void createDelay(const String& name_);
147            //void createDelay(const String& name_, int start_index_, int end_index_);
148            const Map<ElectricalDelay*>* getDelays() const;
149            ElectricalDelay* getDelay(const String& name_);
150            //-----------------------------------------------------------------
151
152            // Get current driving strength
153            double getDrivingStrength() const;
154            // Get current driving strength index
155            int getDrivingStrengthIdx() const;
156            // Set driving strength by index
157            void setDrivingStrengthIdx(int idx_);
158            // Set the instance to minimum driving strength
159            void setMinDrivingStrength();
160            // Return true if the instance has minimum driving strength
161            bool hasMinDrivingStrength() const;
162            // Return true if the instance has maximum driving strength
163            bool hasMaxDrivingStrength() const;
164            // Increase driving strength index by 1
165            void increaseDrivingStrength();
166            // Decrease driving strength index by 1
167            void decreaseDrivingStrength();
168
169            // Create the default sets of the electrical results
170            void createElectricalResults();
171            // Add the default sets of the electrical results from a model
172            void addElectricalSubResults(const ElectricalModel* model_, double number_models_);
173            // Add extra wire sub results
174            void addElectricalWireSubResult(const String& wire_layer_, const Result* result_, const String& producer_, double number_results_);
175            // Create the default sets of the electrical atomic results
176            void createElectricalAtomicResults();
177            // Accumulate the electrical atomic results' values
178            void addElecticalAtomicResultValues(const ElectricalModel* model_, double number_models_);
179            // Add extra wire sub results
180            void addElecticalWireAtomicResultValue(const String& wire_layer_, double value_);
181            // Reset the electrical atomic results' values
182            void resetElectricalAtomicResults();
183            // Create an electrical event result. This will add an event associate to all input/output ports
184            void createElectricalEventResult(const String& name_);
185            // Create an electrical event atomic result
186            void createElectricalEventAtomicResult(const String& name_);
187
188            //-----------------------------------------------------------------
189            // Helper functions to propagate transition information
190            //-----------------------------------------------------------------
191            void assignPortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const TransitionInfo& trans_info_);
192            void propagatePortTransitionInfo(const String& downstream_port_name_, const String& upstream_port_name_);
193            void propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const String& upstream_port_name_);
194            void propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_);
195            void propagatePortTransitionInfo(const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_);
196            virtual void propagateTransitionInfo();
197            //-----------------------------------------------------------------
198
199            //-----------------------------------------------------------------
200            // Helper functions to insert and remove buffers
201            //-----------------------------------------------------------------
202
203            //-----------------------------------------------------------------
204
205            virtual void useModel(const String& event_name_);
206            virtual void useModel();
207            // TODO - add comments
208            void applyTransitionInfo(const String& event_name_);
209            // TODO - add comments
210            EventInfo* getEventInfo(const String& event_name_);
211
212        protected:
213            // In an ElectricalModel, the complete port-to-port connectivity
214            // of all sub-instance must be specified. Addition/Removal ports or
215            // port-related nets cannot happen after this step
216            //virtual void constructModel() = 0;
217            // In an ElectricalModel, updateModel MUST finish all necessary
218            // calculations such that a timing model can be run
219            //virtual void updateModel() = 0;
220            // In an ElectricalModel, evaluateModel should calculate all
221            // event energies, now that the connectivity and timing has been
222            // completed
223            //virtual void evaluateModel() = 0;
224
225        private:
226            // Private copy constructor. Use clone to perform copy operation.
227            ElectricalModel(const ElectricalModel& model_);
228
229        private:
230            // Contains the driving strengths in increasing order
231            vector<double> m_driving_strengths_;
232            // Driving strength index in the driving strength vector
233            int m_curr_driving_strengths_idx_;
234
235            //Connectivity elements
236            // Nets can come in various bus widths. A net reference is really
237            // just a helper map mapping a referenced map name to a bunch of
238            // net indices. A net index returns the starting and end indices of
239            // a net if the net is a multi-bit bus of some sort
240            Map<NetIndex>* m_net_references_;
241            // Map of the input ports
242            Map<PortInfo*>* m_input_ports_;
243            // Map of the output ports
244            Map<PortInfo*>* m_output_ports_;
245            // Map of all our electrical nets
246            Map<ElectricalNet*>* m_nets_;
247
248            //Timing model elements
249            // Map of all our electrical drivers
250            Map<ElectricalDriver*>* m_drivers_;
251            // Map of all our driver multipliers
252            Map<ElectricalDriverMultiplier*>* m_driver_multipliers_;
253            // Map of all our electrical loads
254            Map<ElectricalLoad*>* m_loads_;
255            // Map of all our idealized delays
256            Map<ElectricalDelay*>* m_delays_;
257
258            // Map of the event infos
259            Map<EventInfo*>* m_event_infos_;
260
261    }; // class ElectricalModel
262} // namespace DSENT
263
264#endif // __DSENT_MODEL_ELECTRICALMODEL_H__
265
266