1 /* Copyright (c) 2012 Massachusetts Institute of Technology
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:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
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
22 #include "model/ElectricalModel.h"
24 #include "model/PortInfo.h"
25 #include "model/EventInfo.h"
26 #include "model/timing_graph/ElectricalDriver.h"
27 #include "model/timing_graph/ElectricalDriverMultiplier.h"
28 #include "model/timing_graph/ElectricalNet.h"
29 #include "model/timing_graph/ElectricalLoad.h"
30 #include "model/timing_graph/ElectricalDelay.h"
34 ElectricalModel::ElectricalModel(const String
& instance_name_
, const TechModel
* tech_model_
)
35 : Model(instance_name_
, tech_model_
)
37 m_curr_driving_strengths_idx_
= -1;
38 m_input_ports_
= new Map
<PortInfo
*>;
39 m_output_ports_
= new Map
<PortInfo
*>;
40 m_net_references_
= new Map
<NetIndex
>;
41 m_drivers_
= new Map
<ElectricalDriver
*>;
42 m_driver_multipliers_
= new Map
<ElectricalDriverMultiplier
*>;
43 m_nets_
= new Map
<ElectricalNet
*>;
44 m_loads_
= new Map
<ElectricalLoad
*>;
45 m_delays_
= new Map
<ElectricalDelay
*>;
46 m_event_infos_
= new Map
<EventInfo
*>;
49 ElectricalModel::~ElectricalModel()
51 deletePtrMap
<PortInfo
>(m_input_ports_
);
52 deletePtrMap
<PortInfo
>(m_output_ports_
);
53 delete m_net_references_
;
54 deletePtrMap
<ElectricalDriver
>(m_drivers_
);
55 deletePtrMap
<ElectricalDriverMultiplier
>(m_driver_multipliers_
);
56 deletePtrMap
<ElectricalNet
>(m_nets_
);
57 deletePtrMap
<ElectricalLoad
>(m_loads_
);
58 deletePtrMap
<ElectricalDelay
>(m_delays_
);
59 deletePtrMap
<EventInfo
>(m_event_infos_
);
60 m_input_ports_
= NULL
;
61 m_output_ports_
= NULL
;
62 m_net_references_
= NULL
;
64 m_driver_multipliers_
= NULL
;
67 m_net_references_
= NULL
;
68 m_event_infos_
= NULL
;
71 void ElectricalModel::checkProperties() const
73 // Check if the specified driving strength exists in the available driving strengths
74 if(getProperties()->keyExist("DrivingStrength"))
76 const double driving_strength
= getProperty("DrivingStrength");
77 bool is_found
= false;
78 for(int i
= 0; i
< (int)m_driving_strengths_
.size(); ++i
)
80 if(driving_strength
== m_driving_strengths_
[i
])
86 ASSERT(is_found
, "[Error] " + getInstanceName() +
87 " -> Driving strength (" + String(driving_strength
) + ")"
88 " not found in available driving strengths (" +
89 getParameter("AvailableDrivingStrengths"));
92 // Do normal check on the properties
93 Model::checkProperties();
97 double ElectricalModel::getDrivingStrength() const
99 if(m_curr_driving_strengths_idx_
== -1)
105 return m_driving_strengths_
[m_curr_driving_strengths_idx_
];
109 int ElectricalModel::getDrivingStrengthIdx() const
111 return m_curr_driving_strengths_idx_
;
114 void ElectricalModel::setDrivingStrengthIdx(int idx_
)
116 ASSERT(((idx_
>= 0) && (idx_
< (int)m_driving_strengths_
.size())),
117 "[Error] " + getInstanceName() +
118 " -> Driving strength index out of range (" + String(idx_
) + ")");
120 m_curr_driving_strengths_idx_
= idx_
;
121 setProperty("DrivingStrength", m_driving_strengths_
[m_curr_driving_strengths_idx_
]);
123 Log::printLine(getInstanceName() + " -> Changing drive strength to " + (String
) m_driving_strengths_
[m_curr_driving_strengths_idx_
]);
128 void ElectricalModel::setMinDrivingStrength()
130 setDrivingStrengthIdx(0);
134 bool ElectricalModel::hasMinDrivingStrength() const
136 return (m_curr_driving_strengths_idx_
== 0);
139 bool ElectricalModel::hasMaxDrivingStrength() const
141 return (m_curr_driving_strengths_idx_
== ((int)m_driving_strengths_
.size() - 1));
144 void ElectricalModel::increaseDrivingStrength()
146 if(!hasMaxDrivingStrength())
148 setDrivingStrengthIdx(m_curr_driving_strengths_idx_
+ 1);
153 void ElectricalModel::decreaseDrivingStrength()
155 if(!hasMinDrivingStrength())
157 setDrivingStrengthIdx(m_curr_driving_strengths_idx_
- 1);
162 void ElectricalModel::setAvailableDrivingStrengths(const String
& driving_strengths_
)
164 setParameter("AvailableDrivingStrengths", driving_strengths_
);
165 const vector
<String
>& split_str
= driving_strengths_
.split("[,");
167 // Check if there is at least one driving strength specified
168 ASSERT(!split_str
.empty(), "[Error] " + getInstanceName() +
169 " -> Specified driving strength string does not contain any driving strengths (" +
170 driving_strengths_
+ ")");
172 // TODO - check if the driving strengths is sorted
174 // Overwrite the available driving strengths
175 m_driving_strengths_
.clear();
176 for(int i
= 0; i
< (int)split_str
.size(); ++i
)
178 m_driving_strengths_
.push_back(split_str
[i
].toDouble());
181 // Set the driving strength to minimum
182 m_curr_driving_strengths_idx_
= 0;
183 setProperty("DrivingStrength", m_driving_strengths_
[m_curr_driving_strengths_idx_
]);
187 // Connect a port (input or output) to some ElectricalNet
188 void ElectricalModel::portConnect(ElectricalModel
* connect_model_
, const String
& connect_port_name_
, const String
& connect_net_name_
)
190 ASSERT(m_net_references_
->keyExist(connect_net_name_
), "[Error] " + getInstanceName() +
191 " -> Net '" + connect_net_name_
+ "' does not exist!");
193 portConnect(connect_model_
, connect_port_name_
, connect_net_name_
, m_net_references_
->get(connect_net_name_
));
196 void ElectricalModel::portConnect(ElectricalModel
* connect_model_
, const String
& connect_port_name_
, const String
& connect_net_name_
, const NetIndex
& connect_net_indices_
)
198 ASSERT(m_net_references_
->keyExist(connect_net_name_
), "[Error] " + getInstanceName() +
199 " -> Net '" + connect_net_name_
+ "' does not exist!");
201 // Check whether the port name is an input or output, ASSERTion error if neither
202 bool is_input
= connect_model_
->getInputs()->keyExist(connect_port_name_
);
203 bool is_output
= connect_model_
->getOutputs()->keyExist(connect_port_name_
);
205 ASSERT(is_input
|| is_output
, "[Error] " + getInstanceName() + " -> Model '" + connect_model_
->getInstanceName() +
206 "' does not have a port named '" + connect_port_name_
+ "'!");
208 int connect_net_width
= connect_net_indices_
.second
- connect_net_indices_
.first
+ 1;
209 const NetIndex
& port_indices
= connect_model_
->getNetReference(connect_port_name_
);
210 int port_width
= port_indices
.second
- port_indices
.first
+ 1;
212 ASSERT(connect_net_width
== port_width
, "[Error] " + getInstanceName() + " -> Port width mismatch for Model '" +
213 connect_model_
->getInstanceName() + "." + connect_port_name_
+ toString(port_indices
) +
214 "' and net '" + connect_net_name_
+ toString(connect_net_indices_
) + "'!");
216 int port_index
= port_indices
.first
;
217 int connect_net_index
= connect_net_indices_
.first
;
221 while(port_index
<= port_indices
.second
)
223 getNet(connect_net_name_
, makeNetIndex(connect_net_index
))->addDownstreamNode(
224 connect_model_
->getNet(connect_port_name_
, makeNetIndex(port_index
)));
231 while (port_index
<= port_indices
.second
)
233 connect_model_
->getNet(connect_port_name_
, makeNetIndex(port_index
))->addDownstreamNode(
234 getNet(connect_net_name_
, makeNetIndex(connect_net_index
)));
242 const Map
<ElectricalDriver
*>* ElectricalModel::getDrivers() const
247 ElectricalDriver
* ElectricalModel::getDriver(const String
& name_
)
249 return m_drivers_
->get(name_
);
252 //Get Driver Multipliers
253 const Map
<ElectricalDriverMultiplier
*>* ElectricalModel::getDriverMultipliers() const
255 return m_driver_multipliers_
;
258 ElectricalDriverMultiplier
* ElectricalModel::getDriverMultiplier(const String
& name_
)
260 return m_driver_multipliers_
->get(name_
);
264 const Map
<ElectricalNet
*>* ElectricalModel::getNets() const
269 ElectricalNet
* ElectricalModel::getNet(const String
& name_
)
271 return getNet(name_
, m_net_references_
->get(name_
));
274 ElectricalNet
* ElectricalModel::getNet(const String
& name_
, const NetIndex
& index_
)
276 ASSERT(index_
.first
== index_
.second
, "[Error] " + getInstanceName() +
277 " -> Ambiguous get net since (" + name_
+ ") is a bus consisting of several nets!");
278 return m_nets_
->get(name_
+ "[" + (String
) index_
.first
+ "]");
282 const Map
<ElectricalLoad
*>* ElectricalModel::getLoads() const
287 ElectricalLoad
* ElectricalModel::getLoad(const String
& name_
)
289 return m_loads_
->get(name_
);
293 const Map
<ElectricalDelay
*>* ElectricalModel::getDelays() const
298 ElectricalDelay
* ElectricalModel::getDelay(const String
& name_
)
300 return m_delays_
->get(name_
);
304 const Map
<PortInfo
*>* ElectricalModel::getInputs() const
306 return m_input_ports_
;
309 PortInfo
* ElectricalModel::getInputPort(const String
& name_
)
311 ASSERT(m_input_ports_
->keyExist(name_
), "[Error] " + getInstanceName() +
312 " -> Input port (" + name_
+ ") does not exist");
314 return m_input_ports_
->get(name_
);
317 const PortInfo
* ElectricalModel::getInputPort(const String
& name_
) const
319 ASSERT(m_input_ports_
->keyExist(name_
), "[Error] " + getInstanceName() +
320 " -> Input port (" + name_
+ ") does not exist");
322 return m_input_ports_
->get(name_
);
326 const Map
<PortInfo
*>* ElectricalModel::getOutputs() const
328 return m_output_ports_
;
331 PortInfo
* ElectricalModel::getOutputPort(const String
& name_
)
333 ASSERT(m_output_ports_
->keyExist(name_
), "[Error] " + getInstanceName() +
334 " -> Output port (" + name_
+ ") does not exist");
336 return m_output_ports_
->get(name_
);
339 const PortInfo
* ElectricalModel::getOutputPort(const String
& name_
) const
341 ASSERT(m_output_ports_
->keyExist(name_
), "[Error] " + getInstanceName() +
342 " -> Output port (" + name_
+ ") does not exist");
344 return m_output_ports_
->get(name_
);
347 const Map
<NetIndex
>* ElectricalModel::getNetReferences() const
349 return m_net_references_
;
352 const NetIndex
ElectricalModel::getNetReference(const String
& name_
) const
354 return m_net_references_
->get(name_
);
357 //-------------------------------------------------------------------------
358 // Electrical Connectivity and Timing Element Creation Functions
359 //-------------------------------------------------------------------------
361 // Input Port creation
362 void ElectricalModel::createInputPort(const String
& name_
, const NetIndex
& net_indices_
)
364 // Create the new nets (including its net reference)
365 // This should already check that it has not been previously declared
366 createNet(name_
, net_indices_
);
367 // Add the net name to list of input ports
368 m_input_ports_
->set(name_
, new PortInfo(name_
, net_indices_
));
372 // Output Port creation
373 void ElectricalModel::createOutputPort(const String
& name_
, const NetIndex
& net_indices_
)
375 // Create the new nets (including its net reference)
376 // This should already check that it has not been previously declared
377 createNet(name_
, net_indices_
);
378 // Add the net name to list of output ports
379 m_output_ports_
->set(name_
, new PortInfo(name_
, net_indices_
));
384 void ElectricalModel::createNet(const String
& name_
)
386 // Creating a net with specifying an index range means that the net is just
387 // a 1-bit wire indexed at [0]
388 createNet(name_
, makeNetIndex(0, 0));
392 void ElectricalModel::createNet(const String
& name_
, const NetIndex
& net_indices_
)
394 // Check that it hasn't been previously declared
395 ASSERT( !m_nets_
->keyExist(name_
) && !m_net_references_
->keyExist(name_
),
396 "[Error] " + getInstanceName() + " -> Redeclaration of net " + name_
);
398 int start
= net_indices_
.first
;
399 int end
= net_indices_
.second
;
401 for (int index
= start
; index
<= end
; ++index
)
403 String indexed_name
= name_
+ "[" + (String
) index
+ "]";
404 // Create the new net
405 ElectricalNet
* net
= new ElectricalNet(indexed_name
, this);
406 // Add the net to net map
407 m_nets_
->set(indexed_name
, net
);
409 // Add net to net references
410 m_net_references_
->set(name_
, net_indices_
);
415 void ElectricalModel::createDriver(const String
& name_
, bool sizable_
)
417 // Check that it hasn't been previously declared
418 ASSERT( !m_drivers_
->keyExist(name_
),
419 "[Error] " + getInstanceName() + " -> Redeclaration of driver " + name_
);
421 ElectricalDriver
* driver
= new ElectricalDriver(name_
, this, sizable_
);
422 m_drivers_
->set(name_
, driver
);
427 void ElectricalModel::createDriver(const String& name_, bool sizable_, int start_index_, int end_index_)
429 for (int index = start_index_; index <= end_index_; ++index)
431 createDriver(name_ + "[" + (String) index + "]", sizable_);
437 // Driver Multiplier creation
438 void ElectricalModel::createDriverMultiplier(const String
& name_
)
440 // Check that it hasn't been previously declared
441 ASSERT( !m_driver_multipliers_
->keyExist(name_
),
442 "[Error] " + getInstanceName() + " -> Redeclaration of driver_multiplier " + name_
);
444 ElectricalDriverMultiplier
* driver_multiplier
= new ElectricalDriverMultiplier(name_
, this);
445 m_driver_multipliers_
->set(name_
, driver_multiplier
);
451 void ElectricalModel::createLoad(const String
& name_
)
453 // Check that it hasn't been previously declared
454 ASSERT( !m_loads_
->keyExist(name_
),
455 "[Error] " + getInstanceName() + " -> Redeclaration of load " + name_
);
457 ElectricalLoad
* load
= new ElectricalLoad(name_
, this);
458 m_loads_
->set(name_
, load
);
463 void ElectricalModel::createLoad(const String& name_, int start_index_, int end_index_)
465 for (int index = start_index_; index <= end_index_; ++index)
467 createLoad(name_ + "[" + (String) index + "]");
474 void ElectricalModel::createDelay(const String
& name_
)
476 // Check that it hasn't been previously declared
477 ASSERT( !m_delays_
->keyExist(name_
),
478 "[Error] " + getInstanceName() + " -> Redeclaration of delay " + name_
);
480 ElectricalDelay
* delay
= new ElectricalDelay(name_
, this);
481 m_delays_
->set(name_
, delay
);
486 void ElectricalModel::createDelay(const String& name_, int start_index_, int end_index_)
488 for (int index = start_index_; index <= end_index_; ++index)
490 createDelay(name_ + "[" + (String) index + "]");
495 //-------------------------------------------------------------------------
497 // Assign a net to be downstream from another net
498 // case 1: 'assign downstream_net_name_ = upstream_net_name_'
499 void ElectricalModel::assign(const String
& downstream_net_name_
, const String
& upstream_net_name_
)
501 ASSERT(getNetReferences()->keyExist(downstream_net_name_
), "[Error] " + getInstanceName() + " -> Net '" +
502 downstream_net_name_
+ "' does not exist!");
504 ASSERT(getNetReferences()->keyExist(upstream_net_name_
), "[Error] " + getInstanceName() + " -> Net '" +
505 upstream_net_name_
+ "' does not exist!");
507 assign(downstream_net_name_
, getNetReference(downstream_net_name_
),
508 upstream_net_name_
, getNetReference(upstream_net_name_
));
513 // case 2: 'assign downstream_net_name_[begin:end] = upstream_net_name_'
514 void ElectricalModel::assign(const String
& downstream_net_name_
, const NetIndex
& downstream_net_indices_
, const String
& upstream_net_name_
)
516 ASSERT(getNetReferences()->keyExist(downstream_net_name_
), "[Error] " + getInstanceName() + " -> Net '" +
517 downstream_net_name_
+ "' does not exist!");
519 ASSERT(getNetReferences()->keyExist(upstream_net_name_
), "[Error] " + getInstanceName() + " -> Net '" +
520 upstream_net_name_
+ "' does not exist!");
522 assign(downstream_net_name_
, downstream_net_indices_
,
523 upstream_net_name_
, getNetReference(upstream_net_name_
));
528 // case 3: 'assign downstream_net_name_ = upstream_net_name_[begin:end]'
529 void ElectricalModel::assign(const String
& downstream_net_name_
, const String
& upstream_net_name_
, const NetIndex
& upstream_net_indices_
)
531 ASSERT(getNetReferences()->keyExist(downstream_net_name_
), "[Error] " + getInstanceName() + " -> Net '" +
532 downstream_net_name_
+ "' does not exist!");
534 ASSERT(getNetReferences()->keyExist(upstream_net_name_
), "[Error] " + getInstanceName() + " -> Net '" +
535 upstream_net_name_
+ "' does not exist!");
537 assign(downstream_net_name_
, getNetReference(downstream_net_name_
),
538 upstream_net_name_
, upstream_net_indices_
);
542 // case 4: 'assign downstream_net_name_[begin:end] = upstream_net_name_[begin:end]'
543 void ElectricalModel::assign(const String
& downstream_net_name_
, const NetIndex
& downstream_net_indices_
, const String
& upstream_net_name_
, const NetIndex
& upstream_net_indices_
)
545 ASSERT(getNetReferences()->keyExist(downstream_net_name_
), "[Error] " + getInstanceName() + " -> Net '" +
546 downstream_net_name_
+ "' does not exist!");
548 ASSERT(getNetReferences()->keyExist(upstream_net_name_
), "[Error] " + getInstanceName() + " -> Net '" +
549 upstream_net_name_
+ "' does not exist!");
551 // Check that the assignment widths are the same
552 int downstream_width
= downstream_net_indices_
.second
- downstream_net_indices_
.first
+ 1;
553 int upstream_width
= upstream_net_indices_
.second
- upstream_net_indices_
.first
+ 1;
555 ASSERT(downstream_width
== upstream_width
, "[Error] " + getInstanceName() + " -> Assignment width mismatch: " +
556 downstream_net_name_
+ " (" + (String
) downstream_width
+ ") and " +
557 upstream_net_name_
+ " (" + (String
) upstream_width
+ ")");
559 // Loop through indices and connect them together
560 int down_index
= downstream_net_indices_
.first
;
561 int up_index
= upstream_net_indices_
.first
;
562 while (down_index
<= downstream_net_indices_
.second
)
564 getNet(upstream_net_name_
, makeNetIndex(up_index
))->addDownstreamNode(
565 getNet(downstream_net_name_
, makeNetIndex(down_index
)));
574 // Assign a net to another net through a driver multiplier
575 void ElectricalModel::assignVirtualFanout(const String
& downstream_net_name_
, const String
& upstream_net_name_
)
577 ASSERT(getNetReferences()->keyExist(upstream_net_name_
), "[Error] " + getInstanceName() +
578 " -> Net '" + upstream_net_name_
+ "' does not exist!");
579 ASSERT(getNetReferences()->keyExist(downstream_net_name_
), "[Error] " + getInstanceName() +
580 " -> Net '" + downstream_net_name_
+ "' does not exist!");
582 assignVirtualFanout(downstream_net_name_
, getNetReference(downstream_net_name_
), upstream_net_name_
, getNetReference(upstream_net_name_
));
586 // Assign a net to another net through a driver multiplier
587 void ElectricalModel::assignVirtualFanout(const String
& downstream_net_name_
, const NetIndex
& downstream_net_indices_
, const String
& upstream_net_name_
, const NetIndex
& upstream_net_indices_
)
589 ASSERT(getNetReferences()->keyExist(upstream_net_name_
), "[Error] " + getInstanceName() +
590 " -> Net '" + upstream_net_name_
+ "' does not exist!");
591 ASSERT(getNetReferences()->keyExist(downstream_net_name_
), "[Error] " + getInstanceName() +
592 " -> Net '" + downstream_net_name_
+ "' does not exist!");
594 const String
& drive_mult_name
= upstream_net_name_
+ "_" + (String
) upstream_net_indices_
.first
+ "_DriverMultiplier";
595 bool is_drive_mult_exist
= getDriverMultipliers()->keyExist(drive_mult_name
);
597 // Create a driver multiplier and assign it to upstream_net since it doesn't exist
598 if(!is_drive_mult_exist
)
600 createDriverMultiplier(drive_mult_name
);
601 getNet(upstream_net_name_
, upstream_net_indices_
)->addDownstreamNode(getDriverMultiplier(drive_mult_name
));
604 // Assign downstream_net_name_[end:begin] = driver_multiplier_name_
605 ElectricalDriverMultiplier
* drive_mult
= getDriverMultiplier(drive_mult_name
);
606 int begin_index
= downstream_net_indices_
.first
;
607 int end_index
= downstream_net_indices_
.second
;
608 for(int i
= begin_index
; i
<= end_index
; ++i
)
610 drive_mult
->addDownstreamNode(getNet(downstream_net_name_
, makeNetIndex(i
)));
615 void ElectricalModel::assignVirtualFanin(const String
& downstream_net_name_
, const String
& upstream_net_name_
)
617 ASSERT(getNetReferences()->keyExist(upstream_net_name_
), "[Error] " + getInstanceName() +
618 " -> Net '" + upstream_net_name_
+ "' does not exist!");
619 ASSERT(getNetReferences()->keyExist(downstream_net_name_
), "[Error] " + getInstanceName() +
620 " -> Net '" + downstream_net_name_
+ "' does not exist!");
622 assignVirtualFanin(downstream_net_name_
, getNetReference(downstream_net_name_
), upstream_net_name_
, getNetReference(upstream_net_name_
));
626 void ElectricalModel::assignVirtualFanin(const String
& downstream_net_name_
, const NetIndex
& downstream_net_indices_
, const String
& upstream_net_name_
, const NetIndex
& upstream_net_indices_
)
628 ASSERT(getNetReferences()->keyExist(upstream_net_name_
), "[Error] " + getInstanceName() +
629 " -> Net '" + upstream_net_name_
+ "' does not exist!");
630 ASSERT(getNetReferences()->keyExist(downstream_net_name_
), "[Error] " + getInstanceName() +
631 " -> Net '" + downstream_net_name_
+ "' does not exist!");
633 int begin_index
= upstream_net_indices_
.first
;
634 int end_index
= upstream_net_indices_
.second
;
636 for(int i
= begin_index
; i
<= end_index
; ++i
)
638 getNet(upstream_net_name_
, makeNetIndex(i
))->addDownstreamNode(getNet(downstream_net_name_
, downstream_net_indices_
));
643 void ElectricalModel::createElectricalResults()
645 // Add active area result
646 addAreaResult(new Result("Active"));
648 // Add wire area result
649 TechModel::ConstWireLayerIterator it_begin
= getTechModel()->getAvailableWireLayers()->begin();
650 TechModel::ConstWireLayerIterator it_end
= getTechModel()->getAvailableWireLayers()->end();
651 TechModel::ConstWireLayerIterator it
;
652 for(it
= it_begin
; it
!= it_end
; ++it
)
654 const String
& layer_name
= (*it
);
655 addAreaResult(new Result(layer_name
+ "Wire"));
658 // Add leakage result
659 addNddPowerResult(new Result("Leakage"));
661 // Add idle event result
662 createElectricalEventResult("Idle");
666 void ElectricalModel::addElectricalSubResults(const ElectricalModel
* model_
, double number_models_
)
668 // Add active area sub result
669 getAreaResult("Active")->addSubResult(model_
->getAreaResult("Active"), model_
->getInstanceName(), number_models_
);
671 // Add wire area sub result
672 TechModel::ConstWireLayerIterator it_begin
= getTechModel()->getAvailableWireLayers()->begin();
673 TechModel::ConstWireLayerIterator it_end
= getTechModel()->getAvailableWireLayers()->end();
674 TechModel::ConstWireLayerIterator it
;
675 for(it
= it_begin
; it
!= it_end
; ++it
)
677 const String
& layer_name
= (*it
);
678 const String
& result_name
= layer_name
+ "Wire";
679 getAreaResult(result_name
)->addSubResult(model_
->getAreaResult(result_name
), model_
->getInstanceName(), number_models_
);
682 // Add leakage sub result
683 getNddPowerResult("Leakage")->addSubResult(model_
->getNddPowerResult("Leakage"), model_
->getInstanceName(), number_models_
);
685 // Add idle event sub result
686 getEventResult("Idle")->addSubResult(model_
->getEventResult("Idle"), model_
->getInstanceName(), number_models_
);
690 void ElectricalModel::addElectricalWireSubResult(const String
& wire_layer_
, const Result
* result_
, const String
& producer_
, double number_results_
)
692 getAreaResult(wire_layer_
+ "Wire")->addSubResult(result_
, producer_
, number_results_
);
696 void ElectricalModel::createElectricalAtomicResults()
698 // Add active area result
699 addAreaResult(new AtomicResult("Active"));
701 // Add wire area result
702 TechModel::ConstWireLayerIterator it_begin
= getTechModel()->getAvailableWireLayers()->begin();
703 TechModel::ConstWireLayerIterator it_end
= getTechModel()->getAvailableWireLayers()->end();
704 TechModel::ConstWireLayerIterator it
;
705 for(it
= it_begin
; it
!= it_end
; ++it
)
707 const String
& layer_name
= (*it
);
708 addAreaResult(new AtomicResult(layer_name
+ "Wire"));
711 // Add leakage result
712 addNddPowerResult(new AtomicResult("Leakage"));
714 // Add idle event result
715 createElectricalEventAtomicResult("Idle");
719 void ElectricalModel::addElecticalAtomicResultValues(const ElectricalModel
* model_
, double number_models_
)
721 getAreaResult("Active")->addValue(model_
->getAreaResult("Active")->calculateSum() * number_models_
);
723 // Add wire area sub result
724 TechModel::ConstWireLayerIterator it_begin
= getTechModel()->getAvailableWireLayers()->begin();
725 TechModel::ConstWireLayerIterator it_end
= getTechModel()->getAvailableWireLayers()->end();
726 TechModel::ConstWireLayerIterator it
;
727 for(it
= it_begin
; it
!= it_end
; ++it
)
729 const String
& layer_name
= (*it
);
730 const String
& result_name
= layer_name
+ "Wire";
731 getAreaResult(result_name
)->addValue(model_
->getAreaResult(result_name
)->calculateSum() * number_models_
);
734 // Add leakage sub result
735 getNddPowerResult("Leakage")->addValue(model_
->getNddPowerResult("Leakage")->calculateSum() * number_models_
);
737 // Add idle event sub result
738 getEventResult("Idle")->addValue(model_
->getEventResult("Idle")->calculateSum() * number_models_
);
742 void ElectricalModel::addElecticalWireAtomicResultValue(const String
& wire_layer_
, double value_
)
744 getAreaResult(wire_layer_
+ "Wire")->addValue(value_
);
748 void ElectricalModel::resetElectricalAtomicResults()
750 getAreaResult("Active")->setValue(0.0);
752 // Reset wire area sub result
753 TechModel::ConstWireLayerIterator it_begin
= getTechModel()->getAvailableWireLayers()->begin();
754 TechModel::ConstWireLayerIterator it_end
= getTechModel()->getAvailableWireLayers()->end();
755 TechModel::ConstWireLayerIterator it
;
756 for(it
= it_begin
; it
!= it_end
; ++it
)
758 const String
& layer_name
= (*it
);
759 const String
& result_name
= layer_name
+ "Wire";
760 getAreaResult(result_name
)->setValue(0.0);
763 // Reset leakage sub result
764 getNddPowerResult("Leakage")->setValue(0.0);
766 // Reset idle event sub result
767 getEventResult("Idle")->setValue(0.0);
772 void ElectricalModel::createElectricalEventResult(const String
& name_
)
774 // Add the event result
775 addEventResult(new Result(name_
));
777 m_event_infos_
->set(name_
, new EventInfo(name_
, getInputs()));
781 void ElectricalModel::createElectricalEventAtomicResult(const String
& name_
)
783 // Add the event result
784 addEventResult(new AtomicResult(name_
));
786 m_event_infos_
->set(name_
, new EventInfo(name_
, getInputs()));
790 void ElectricalModel::assignPortTransitionInfo(ElectricalModel
* downstream_model_
, const String
& downstream_port_name_
, const TransitionInfo
& trans_info_
)
792 ASSERT(downstream_model_
!= NULL
, "[Error] " + getInstanceName() +
793 " -> Downstream model does not exist");
795 downstream_model_
->getInputPort(downstream_port_name_
)->setTransitionInfo(trans_info_
);
799 void ElectricalModel::propagatePortTransitionInfo(const String
& downstream_port_name_
, const String
& upstream_port_name_
)
801 const TransitionInfo
& trans_info
= getInputPort(upstream_port_name_
)->getTransitionInfo();
802 getOutputPort(downstream_port_name_
)->setTransitionInfo(trans_info
);
806 void ElectricalModel::propagatePortTransitionInfo(ElectricalModel
* downstream_model_
, const String
& downstream_port_name_
, const String
& upstream_port_name_
)
808 ASSERT(downstream_model_
!= NULL
, "[Error] " + getInstanceName() +
809 " -> Downstream model does not exist");
811 const TransitionInfo
& trans_info
= getInputPort(upstream_port_name_
)->getTransitionInfo();
812 downstream_model_
->getInputPort(downstream_port_name_
)->setTransitionInfo(trans_info
);
816 void ElectricalModel::propagatePortTransitionInfo(ElectricalModel
* downstream_model_
, const String
& downstream_port_name_
, const ElectricalModel
* upstream_model_
, const String
& upstream_port_name_
)
818 ASSERT(downstream_model_
!= NULL
, "[Error] " + getInstanceName() +
819 " -> Downstream model does not exist");
820 ASSERT(upstream_model_
!= NULL
, "[Error] " + getInstanceName() +
821 " -> Upstream model does not exist");
823 const TransitionInfo
& trans_info
= upstream_model_
->getOutputPort(upstream_port_name_
)->getTransitionInfo();
825 downstream_model_
->getInputPort(downstream_port_name_
)->setTransitionInfo(trans_info
);
829 void ElectricalModel::propagatePortTransitionInfo(const String
& downstream_port_name_
, const ElectricalModel
* upstream_model_
, const String
& upstream_port_name_
)
831 ASSERT(upstream_model_
!= NULL
, "[Error] " + getInstanceName() +
832 " -> Upstream model does not exist");
834 const TransitionInfo
& trans_info
= upstream_model_
->getOutputPort(upstream_port_name_
)->getTransitionInfo();
835 getOutputPort(downstream_port_name_
)->setTransitionInfo(trans_info
);
839 void ElectricalModel::propagateTransitionInfo()
841 // by default do nothing.
844 void ElectricalModel::useModel(const String
& event_name_
)
846 getGenProperties()->set("UseModelEvent", event_name_
);
847 applyTransitionInfo(event_name_
);
852 void ElectricalModel::useModel()
854 propagateTransitionInfo();
858 void ElectricalModel::applyTransitionInfo(const String
& event_name_
)
860 // Check if the event actually exists
861 ASSERT(hasEventResult(event_name_
), "[Error] " + getInstanceName() +
862 " -> Event (" + event_name_
+ ") does not exist in the result map");
863 ASSERT(m_event_infos_
->keyExist(event_name_
), "[Error] " + getInstanceName() +
864 " -> Event (" + event_name_
+ ") does not exist in the event info map");
866 const EventInfo
* event_info
= m_event_infos_
->get(event_name_
);
868 // Set the input ports' transition information for the event
869 Map
<PortInfo
*>::ConstIterator it_begin
= m_input_ports_
->begin();
870 Map
<PortInfo
*>::ConstIterator it_end
= m_input_ports_
->end();
871 Map
<PortInfo
*>::ConstIterator it
;
872 for(it
= it_begin
; it
!= it_end
; ++it
)
874 const String
& port_name
= it
->first
;
875 PortInfo
* port_info
= it
->second
;
876 const TransitionInfo
& trans_info
= event_info
->getTransitionInfo(port_name
);
877 port_info
->setTransitionInfo(trans_info
);
883 EventInfo
* ElectricalModel::getEventInfo(const String
& event_name_
)
885 ASSERT(m_event_infos_
->keyExist(event_name_
), "[Error] " + getInstanceName() +
886 " -> Event (" + event_name_
+ ") does not exist");
888 return m_event_infos_
->get(event_name_
);