Deleted Added
sdiff udiff text old ( 10447:a465576671d4 ) new ( 10448:bc1a3b7ab5ef )
full compact
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#include "model/ElectricalModel.h"
23
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"
31
32namespace DSENT
33{
34 ElectricalModel::ElectricalModel(const String& instance_name_, const TechModel* tech_model_)
35 : Model(instance_name_, tech_model_)
36 {
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*>;
47 }
48
49 ElectricalModel::~ElectricalModel()
50 {
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;
63 m_drivers_ = NULL;
64 m_driver_multipliers_ = NULL;
65 m_nets_ = NULL;
66 m_loads_ = NULL;
67 m_net_references_ = NULL;
68 m_event_infos_ = NULL;
69 }
70
71 void ElectricalModel::checkProperties() const
72 {
73 // Check if the specified driving strength exists in the available driving strengths
74 if(getProperties()->keyExist("DrivingStrength"))
75 {
76 const double driving_strength = getProperty("DrivingStrength");
77 bool is_found = false;
78 for(int i = 0; i < (int)m_driving_strengths_.size(); ++i)
79 {
80 if(driving_strength == m_driving_strengths_[i])
81 {
82 is_found = true;
83 break;
84 }
85 }
86 ASSERT(is_found, "[Error] " + getInstanceName() +
87 " -> Driving strength (" + String(driving_strength) + ")"
88 " not found in available driving strengths (" +
89 getParameter("AvailableDrivingStrengths"));
90 }
91
92 // Do normal check on the properties
93 Model::checkProperties();
94 return;
95 }
96
97 double ElectricalModel::getDrivingStrength() const
98 {
99 if(m_curr_driving_strengths_idx_ == -1)
100 {
101 return 0;
102 }
103 else
104 {
105 return m_driving_strengths_[m_curr_driving_strengths_idx_];
106 }
107 }
108
109 int ElectricalModel::getDrivingStrengthIdx() const
110 {
111 return m_curr_driving_strengths_idx_;
112 }
113
114 void ElectricalModel::setDrivingStrengthIdx(int idx_)
115 {
116 ASSERT(((idx_ >= 0) && (idx_ < (int)m_driving_strengths_.size())),
117 "[Error] " + getInstanceName() +
118 " -> Driving strength index out of range (" + String(idx_) + ")");
119
120 m_curr_driving_strengths_idx_ = idx_;
121 setProperty("DrivingStrength", m_driving_strengths_[m_curr_driving_strengths_idx_]);
122
123 Log::printLine(getInstanceName() + " -> Changing drive strength to " + (String) m_driving_strengths_[m_curr_driving_strengths_idx_]);
124 update();
125 return;
126 }
127
128 void ElectricalModel::setMinDrivingStrength()
129 {
130 setDrivingStrengthIdx(0);
131 return;
132 }
133
134 bool ElectricalModel::hasMinDrivingStrength() const
135 {
136 return (m_curr_driving_strengths_idx_ == 0);
137 }
138
139 bool ElectricalModel::hasMaxDrivingStrength() const
140 {
141 return (m_curr_driving_strengths_idx_ == ((int)m_driving_strengths_.size() - 1));
142 }
143
144 void ElectricalModel::increaseDrivingStrength()
145 {
146 if(!hasMaxDrivingStrength())
147 {
148 setDrivingStrengthIdx(m_curr_driving_strengths_idx_ + 1);
149 }
150 return;
151 }
152
153 void ElectricalModel::decreaseDrivingStrength()
154 {
155 if(!hasMinDrivingStrength())
156 {
157 setDrivingStrengthIdx(m_curr_driving_strengths_idx_ - 1);
158 }
159 return;
160 }
161
162 void ElectricalModel::setAvailableDrivingStrengths(const String& driving_strengths_)
163 {
164 setParameter("AvailableDrivingStrengths", driving_strengths_);
165 const vector<String>& split_str = driving_strengths_.split("[,");
166
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_ + ")");
171
172 // TODO - check if the driving strengths is sorted
173
174 // Overwrite the available driving strengths
175 m_driving_strengths_.clear();
176 for(int i = 0; i < (int)split_str.size(); ++i)
177 {
178 m_driving_strengths_.push_back(split_str[i].toDouble());
179 }
180
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_]);
184 return;
185 }
186
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_)
189 {
190 ASSERT(m_net_references_->keyExist(connect_net_name_), "[Error] " + getInstanceName() +
191 " -> Net '" + connect_net_name_ + "' does not exist!");
192
193 portConnect(connect_model_, connect_port_name_, connect_net_name_, m_net_references_->get(connect_net_name_));
194 }
195
196 void ElectricalModel::portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_, const NetIndex& connect_net_indices_)
197 {
198 ASSERT(m_net_references_->keyExist(connect_net_name_), "[Error] " + getInstanceName() +
199 " -> Net '" + connect_net_name_ + "' does not exist!");
200
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_);
204
205 ASSERT(is_input || is_output, "[Error] " + getInstanceName() + " -> Model '" + connect_model_->getInstanceName() +
206 "' does not have a port named '" + connect_port_name_ + "'!");
207
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;
211
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_) + "'!");
215
216 int port_index = port_indices.first;
217 int connect_net_index = connect_net_indices_.first;
218
219 if(is_input)
220 {
221 while(port_index <= port_indices.second)
222 {
223 getNet(connect_net_name_, makeNetIndex(connect_net_index))->addDownstreamNode(
224 connect_model_->getNet(connect_port_name_, makeNetIndex(port_index)));
225 ++port_index;
226 ++connect_net_index;
227 }
228 }
229 else if(is_output)
230 {
231 while (port_index <= port_indices.second)
232 {
233 connect_model_->getNet(connect_port_name_, makeNetIndex(port_index))->addDownstreamNode(
234 getNet(connect_net_name_, makeNetIndex(connect_net_index)));
235 ++port_index;
236 ++connect_net_index;
237 }
238 }
239 }
240
241 //Get Drivers
242 const Map<ElectricalDriver*>* ElectricalModel::getDrivers() const
243 {
244 return m_drivers_;
245 }
246
247 ElectricalDriver* ElectricalModel::getDriver(const String& name_)
248 {
249 return m_drivers_->get(name_);
250 }
251
252 //Get Driver Multipliers
253 const Map<ElectricalDriverMultiplier*>* ElectricalModel::getDriverMultipliers() const
254 {
255 return m_driver_multipliers_;
256 }
257
258 ElectricalDriverMultiplier* ElectricalModel::getDriverMultiplier(const String& name_)
259 {
260 return m_driver_multipliers_->get(name_);
261 }
262
263 //Get Nets
264 const Map<ElectricalNet*>* ElectricalModel::getNets() const
265 {
266 return m_nets_;
267 }
268
269 ElectricalNet* ElectricalModel::getNet(const String& name_)
270 {
271 return getNet(name_, m_net_references_->get(name_));
272 }
273
274 ElectricalNet* ElectricalModel::getNet(const String& name_, const NetIndex& index_)
275 {
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 + "]");
279 }
280
281 //Get Loads
282 const Map<ElectricalLoad*>* ElectricalModel::getLoads() const
283 {
284 return m_loads_;
285 }
286
287 ElectricalLoad* ElectricalModel::getLoad(const String& name_)
288 {
289 return m_loads_->get(name_);
290 }
291
292 //Get Delays
293 const Map<ElectricalDelay*>* ElectricalModel::getDelays() const
294 {
295 return m_delays_;
296 }
297
298 ElectricalDelay* ElectricalModel::getDelay(const String& name_)
299 {
300 return m_delays_->get(name_);
301 }
302
303 //Get Inputs
304 const Map<PortInfo*>* ElectricalModel::getInputs() const
305 {
306 return m_input_ports_;
307 }
308
309 PortInfo* ElectricalModel::getInputPort(const String& name_)
310 {
311 ASSERT(m_input_ports_->keyExist(name_), "[Error] " + getInstanceName() +
312 " -> Input port (" + name_ + ") does not exist");
313
314 return m_input_ports_->get(name_);
315 }
316
317 const PortInfo* ElectricalModel::getInputPort(const String& name_) const
318 {
319 ASSERT(m_input_ports_->keyExist(name_), "[Error] " + getInstanceName() +
320 " -> Input port (" + name_ + ") does not exist");
321
322 return m_input_ports_->get(name_);
323 }
324
325 //Get Outputs
326 const Map<PortInfo*>* ElectricalModel::getOutputs() const
327 {
328 return m_output_ports_;
329 }
330
331 PortInfo* ElectricalModel::getOutputPort(const String& name_)
332 {
333 ASSERT(m_output_ports_->keyExist(name_), "[Error] " + getInstanceName() +
334 " -> Output port (" + name_ + ") does not exist");
335
336 return m_output_ports_->get(name_);
337 }
338
339 const PortInfo* ElectricalModel::getOutputPort(const String& name_) const
340 {
341 ASSERT(m_output_ports_->keyExist(name_), "[Error] " + getInstanceName() +
342 " -> Output port (" + name_ + ") does not exist");
343
344 return m_output_ports_->get(name_);
345 }
346
347 const Map<NetIndex>* ElectricalModel::getNetReferences() const
348 {
349 return m_net_references_;
350 }
351
352 const NetIndex ElectricalModel::getNetReference(const String& name_) const
353 {
354 return m_net_references_->get(name_);
355 }
356
357 //-------------------------------------------------------------------------
358 // Electrical Connectivity and Timing Element Creation Functions
359 //-------------------------------------------------------------------------
360
361 // Input Port creation
362 void ElectricalModel::createInputPort(const String& name_, const NetIndex& net_indices_)
363 {
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_));
369 return;
370 }
371
372 // Output Port creation
373 void ElectricalModel::createOutputPort(const String& name_, const NetIndex& net_indices_)
374 {
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_));
380 return;
381 }
382
383 // Net creation
384 void ElectricalModel::createNet(const String& name_)
385 {
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));
389 return;
390 }
391
392 void ElectricalModel::createNet(const String& name_, const NetIndex& net_indices_)
393 {
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_);
397
398 int start = net_indices_.first;
399 int end = net_indices_.second;
400
401 for (int index = start; index <= end; ++index)
402 {
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);
408 }
409 // Add net to net references
410 m_net_references_->set(name_, net_indices_);
411 return;
412 }
413
414 // Driver creation
415 void ElectricalModel::createDriver(const String& name_, bool sizable_)
416 {
417 // Check that it hasn't been previously declared
418 ASSERT( !m_drivers_->keyExist(name_),
419 "[Error] " + getInstanceName() + " -> Redeclaration of driver " + name_);
420
421 ElectricalDriver* driver = new ElectricalDriver(name_, this, sizable_);
422 m_drivers_->set(name_, driver);
423 return;
424 }
425
426 /*
427 void ElectricalModel::createDriver(const String& name_, bool sizable_, int start_index_, int end_index_)
428 {
429 for (int index = start_index_; index <= end_index_; ++index)
430 {
431 createDriver(name_ + "[" + (String) index + "]", sizable_);
432 }
433 return;
434 }
435 */
436
437 // Driver Multiplier creation
438 void ElectricalModel::createDriverMultiplier(const String& name_)
439 {
440 // Check that it hasn't been previously declared
441 ASSERT( !m_driver_multipliers_->keyExist(name_),
442 "[Error] " + getInstanceName() + " -> Redeclaration of driver_multiplier " + name_);
443
444 ElectricalDriverMultiplier* driver_multiplier = new ElectricalDriverMultiplier(name_, this);
445 m_driver_multipliers_->set(name_, driver_multiplier);
446 return;
447 }
448
449 // Load creation
450
451 void ElectricalModel::createLoad(const String& name_)
452 {
453 // Check that it hasn't been previously declared
454 ASSERT( !m_loads_->keyExist(name_),
455 "[Error] " + getInstanceName() + " -> Redeclaration of load " + name_);
456
457 ElectricalLoad* load = new ElectricalLoad(name_, this);
458 m_loads_->set(name_, load);
459 return;
460 }
461
462 /*
463 void ElectricalModel::createLoad(const String& name_, int start_index_, int end_index_)
464 {
465 for (int index = start_index_; index <= end_index_; ++index)
466 {
467 createLoad(name_ + "[" + (String) index + "]");
468 }
469 return;
470 }
471 */
472
473 // Delay creation
474 void ElectricalModel::createDelay(const String& name_)
475 {
476 // Check that it hasn't been previously declared
477 ASSERT( !m_delays_->keyExist(name_),
478 "[Error] " + getInstanceName() + " -> Redeclaration of delay " + name_);
479
480 ElectricalDelay* delay = new ElectricalDelay(name_, this);
481 m_delays_->set(name_, delay);
482 return;
483 }
484
485 /*
486 void ElectricalModel::createDelay(const String& name_, int start_index_, int end_index_)
487 {
488 for (int index = start_index_; index <= end_index_; ++index)
489 {
490 createDelay(name_ + "[" + (String) index + "]");
491 }
492 return;
493 }
494 */
495 //-------------------------------------------------------------------------
496
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_)
500 {
501 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
502 downstream_net_name_ + "' does not exist!");
503
504 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
505 upstream_net_name_ + "' does not exist!");
506
507 assign(downstream_net_name_, getNetReference(downstream_net_name_),
508 upstream_net_name_, getNetReference(upstream_net_name_));
509
510 return;
511 }
512
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_)
515 {
516 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
517 downstream_net_name_ + "' does not exist!");
518
519 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
520 upstream_net_name_ + "' does not exist!");
521
522 assign(downstream_net_name_, downstream_net_indices_,
523 upstream_net_name_, getNetReference(upstream_net_name_));
524
525 return;
526 }
527
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_)
530 {
531 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
532 downstream_net_name_ + "' does not exist!");
533
534 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
535 upstream_net_name_ + "' does not exist!");
536
537 assign(downstream_net_name_, getNetReference(downstream_net_name_),
538 upstream_net_name_, upstream_net_indices_);
539
540 return;
541 }
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_)
544 {
545 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
546 downstream_net_name_ + "' does not exist!");
547
548 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
549 upstream_net_name_ + "' does not exist!");
550
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;
554
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 + ")");
558
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)
563 {
564 getNet(upstream_net_name_, makeNetIndex(up_index))->addDownstreamNode(
565 getNet(downstream_net_name_, makeNetIndex(down_index)));
566
567 ++up_index;
568 ++down_index;
569 }
570
571 return;
572 }
573
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_)
576 {
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!");
581
582 assignVirtualFanout(downstream_net_name_, getNetReference(downstream_net_name_), upstream_net_name_, getNetReference(upstream_net_name_));
583 return;
584 }
585
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_)
588 {
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!");
593
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);
596
597 // Create a driver multiplier and assign it to upstream_net since it doesn't exist
598 if(!is_drive_mult_exist)
599 {
600 createDriverMultiplier(drive_mult_name);
601 getNet(upstream_net_name_, upstream_net_indices_)->addDownstreamNode(getDriverMultiplier(drive_mult_name));
602 }
603
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)
609 {
610 drive_mult->addDownstreamNode(getNet(downstream_net_name_, makeNetIndex(i)));
611 }
612 return;
613 }
614
615 void ElectricalModel::assignVirtualFanin(const String& downstream_net_name_, const String& upstream_net_name_)
616 {
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!");
621
622 assignVirtualFanin(downstream_net_name_, getNetReference(downstream_net_name_), upstream_net_name_, getNetReference(upstream_net_name_));
623 return;
624 }
625
626 void ElectricalModel::assignVirtualFanin(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_)
627 {
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!");
632
633 int begin_index = upstream_net_indices_.first;
634 int end_index = upstream_net_indices_.second;
635
636 for(int i = begin_index; i <= end_index; ++i)
637 {
638 getNet(upstream_net_name_, makeNetIndex(i))->addDownstreamNode(getNet(downstream_net_name_, downstream_net_indices_));
639 }
640 return;
641 }
642
643 void ElectricalModel::createElectricalResults()
644 {
645 // Add active area result
646 addAreaResult(new Result("Active"));
647
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)
653 {
654 const String& layer_name = (*it);
655 addAreaResult(new Result(layer_name + "Wire"));
656 }
657
658 // Add leakage result
659 addNddPowerResult(new Result("Leakage"));
660
661 // Add idle event result
662 createElectricalEventResult("Idle");
663 return;
664 }
665
666 void ElectricalModel::addElectricalSubResults(const ElectricalModel* model_, double number_models_)
667 {
668 // Add active area sub result
669 getAreaResult("Active")->addSubResult(model_->getAreaResult("Active"), model_->getInstanceName(), number_models_);
670
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)
676 {
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_);
680 }
681
682 // Add leakage sub result
683 getNddPowerResult("Leakage")->addSubResult(model_->getNddPowerResult("Leakage"), model_->getInstanceName(), number_models_);
684
685 // Add idle event sub result
686 getEventResult("Idle")->addSubResult(model_->getEventResult("Idle"), model_->getInstanceName(), number_models_);
687 return;
688 }
689
690 void ElectricalModel::addElectricalWireSubResult(const String& wire_layer_, const Result* result_, const String& producer_, double number_results_)
691 {
692 getAreaResult(wire_layer_ + "Wire")->addSubResult(result_, producer_, number_results_);
693 return;
694 }
695
696 void ElectricalModel::createElectricalAtomicResults()
697 {
698 // Add active area result
699 addAreaResult(new AtomicResult("Active"));
700
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)
706 {
707 const String& layer_name = (*it);
708 addAreaResult(new AtomicResult(layer_name + "Wire"));
709 }
710
711 // Add leakage result
712 addNddPowerResult(new AtomicResult("Leakage"));
713
714 // Add idle event result
715 createElectricalEventAtomicResult("Idle");
716 return;
717 }
718
719 void ElectricalModel::addElecticalAtomicResultValues(const ElectricalModel* model_, double number_models_)
720 {
721 getAreaResult("Active")->addValue(model_->getAreaResult("Active")->calculateSum() * number_models_);
722
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)
728 {
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_);
732 }
733
734 // Add leakage sub result
735 getNddPowerResult("Leakage")->addValue(model_->getNddPowerResult("Leakage")->calculateSum() * number_models_);
736
737 // Add idle event sub result
738 getEventResult("Idle")->addValue(model_->getEventResult("Idle")->calculateSum() * number_models_);
739 return;
740 }
741
742 void ElectricalModel::addElecticalWireAtomicResultValue(const String& wire_layer_, double value_)
743 {
744 getAreaResult(wire_layer_ + "Wire")->addValue(value_);
745 return;
746 }
747
748 void ElectricalModel::resetElectricalAtomicResults()
749 {
750 getAreaResult("Active")->setValue(0.0);
751
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)
757 {
758 const String& layer_name = (*it);
759 const String& result_name = layer_name + "Wire";
760 getAreaResult(result_name)->setValue(0.0);
761 }
762
763 // Reset leakage sub result
764 getNddPowerResult("Leakage")->setValue(0.0);
765
766 // Reset idle event sub result
767 getEventResult("Idle")->setValue(0.0);
768
769 return;
770 }
771
772 void ElectricalModel::createElectricalEventResult(const String& name_)
773 {
774 // Add the event result
775 addEventResult(new Result(name_));
776 // Add event info
777 m_event_infos_->set(name_, new EventInfo(name_, getInputs()));
778 return;
779 }
780
781 void ElectricalModel::createElectricalEventAtomicResult(const String& name_)
782 {
783 // Add the event result
784 addEventResult(new AtomicResult(name_));
785 // Add event info
786 m_event_infos_->set(name_, new EventInfo(name_, getInputs()));
787 return;
788 }
789
790 void ElectricalModel::assignPortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const TransitionInfo& trans_info_)
791 {
792 ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() +
793 " -> Downstream model does not exist");
794
795 downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info_);
796 return;
797 }
798
799 void ElectricalModel::propagatePortTransitionInfo(const String& downstream_port_name_, const String& upstream_port_name_)
800 {
801 const TransitionInfo& trans_info = getInputPort(upstream_port_name_)->getTransitionInfo();
802 getOutputPort(downstream_port_name_)->setTransitionInfo(trans_info);
803 return;
804 }
805
806 void ElectricalModel::propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const String& upstream_port_name_)
807 {
808 ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() +
809 " -> Downstream model does not exist");
810
811 const TransitionInfo& trans_info = getInputPort(upstream_port_name_)->getTransitionInfo();
812 downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info);
813 return;
814 }
815
816 void ElectricalModel::propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_)
817 {
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");
822
823 const TransitionInfo& trans_info = upstream_model_->getOutputPort(upstream_port_name_)->getTransitionInfo();
824
825 downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info);
826 return;
827 }
828
829 void ElectricalModel::propagatePortTransitionInfo(const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_)
830 {
831 ASSERT(upstream_model_ != NULL, "[Error] " + getInstanceName() +
832 " -> Upstream model does not exist");
833
834 const TransitionInfo& trans_info = upstream_model_->getOutputPort(upstream_port_name_)->getTransitionInfo();
835 getOutputPort(downstream_port_name_)->setTransitionInfo(trans_info);
836 return;
837 }
838
839 void ElectricalModel::propagateTransitionInfo()
840 {
841 // by default do nothing.
842 }
843
844 void ElectricalModel::useModel(const String& event_name_)
845 {
846 getGenProperties()->set("UseModelEvent", event_name_);
847 applyTransitionInfo(event_name_);
848 useModel();
849 return;
850 }
851
852 void ElectricalModel::useModel()
853 {
854 propagateTransitionInfo();
855 return;
856 }
857
858 void ElectricalModel::applyTransitionInfo(const String& event_name_)
859 {
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");
865
866 const EventInfo* event_info = m_event_infos_->get(event_name_);
867
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)
873 {
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);
878 }
879
880 return;
881 }
882
883 EventInfo* ElectricalModel::getEventInfo(const String& event_name_)
884 {
885 ASSERT(m_event_infos_->keyExist(event_name_), "[Error] " + getInstanceName() +
886 " -> Event (" + event_name_ + ") does not exist");
887
888 return m_event_infos_->get(event_name_);
889 }
890
891} // namespace DSENT
892