summaryrefslogtreecommitdiff
path: root/ext/dsent/model/ElectricalModel.h
blob: 15dfefd78769e8f2e201cabfc1356ca20252fee1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#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__