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