ElectricalModel.cc (10447:a465576671d4) ElectricalModel.cc (10448:bc1a3b7ab5ef)
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
1#include "model/ElectricalModel.h"
2
3#include "model/PortInfo.h"
4#include "model/EventInfo.h"
5#include "model/timing_graph/ElectricalDriver.h"
6#include "model/timing_graph/ElectricalDriverMultiplier.h"
7#include "model/timing_graph/ElectricalNet.h"
8#include "model/timing_graph/ElectricalLoad.h"
9#include "model/timing_graph/ElectricalDelay.h"
10
11namespace DSENT
12{
13 ElectricalModel::ElectricalModel(const String& instance_name_, const TechModel* tech_model_)
14 : Model(instance_name_, tech_model_)
15 {
16 m_curr_driving_strengths_idx_ = -1;
17 m_input_ports_ = new Map<PortInfo*>;
18 m_output_ports_ = new Map<PortInfo*>;
19 m_net_references_ = new Map<NetIndex>;
20 m_drivers_ = new Map<ElectricalDriver*>;
21 m_driver_multipliers_ = new Map<ElectricalDriverMultiplier*>;
22 m_nets_ = new Map<ElectricalNet*>;
23 m_loads_ = new Map<ElectricalLoad*>;
24 m_delays_ = new Map<ElectricalDelay*>;
25 m_event_infos_ = new Map<EventInfo*>;
26 }
27
28 ElectricalModel::~ElectricalModel()
29 {
30 deletePtrMap<PortInfo>(m_input_ports_);
31 deletePtrMap<PortInfo>(m_output_ports_);
32 delete m_net_references_;
33 deletePtrMap<ElectricalDriver>(m_drivers_);
34 deletePtrMap<ElectricalDriverMultiplier>(m_driver_multipliers_);
35 deletePtrMap<ElectricalNet>(m_nets_);
36 deletePtrMap<ElectricalLoad>(m_loads_);
37 deletePtrMap<ElectricalDelay>(m_delays_);
38 deletePtrMap<EventInfo>(m_event_infos_);
39 m_input_ports_ = NULL;
40 m_output_ports_ = NULL;
41 m_net_references_ = NULL;
42 m_drivers_ = NULL;
43 m_driver_multipliers_ = NULL;
44 m_nets_ = NULL;
45 m_loads_ = NULL;
46 m_net_references_ = NULL;
47 m_event_infos_ = NULL;
48 }
49
50 void ElectricalModel::checkProperties() const
51 {
52 // Check if the specified driving strength exists in the available driving strengths
53 if(getProperties()->keyExist("DrivingStrength"))
54 {
55 const double driving_strength = getProperty("DrivingStrength");
56 bool is_found = false;
57 for(int i = 0; i < (int)m_driving_strengths_.size(); ++i)
58 {
59 if(driving_strength == m_driving_strengths_[i])
60 {
61 is_found = true;
62 break;
63 }
64 }
65 ASSERT(is_found, "[Error] " + getInstanceName() +
66 " -> Driving strength (" + String(driving_strength) + ")"
67 " not found in available driving strengths (" +
68 getParameter("AvailableDrivingStrengths"));
69 }
70
71 // Do normal check on the properties
72 Model::checkProperties();
73 return;
74 }
75
76 double ElectricalModel::getDrivingStrength() const
77 {
78 if(m_curr_driving_strengths_idx_ == -1)
79 {
80 return 0;
81 }
82 else
83 {
84 return m_driving_strengths_[m_curr_driving_strengths_idx_];
85 }
86 }
87
88 int ElectricalModel::getDrivingStrengthIdx() const
89 {
90 return m_curr_driving_strengths_idx_;
91 }
92
93 void ElectricalModel::setDrivingStrengthIdx(int idx_)
94 {
95 ASSERT(((idx_ >= 0) && (idx_ < (int)m_driving_strengths_.size())),
96 "[Error] " + getInstanceName() +
97 " -> Driving strength index out of range (" + String(idx_) + ")");
98
99 m_curr_driving_strengths_idx_ = idx_;
100 setProperty("DrivingStrength", m_driving_strengths_[m_curr_driving_strengths_idx_]);
101
102 Log::printLine(getInstanceName() + " -> Changing drive strength to " + (String) m_driving_strengths_[m_curr_driving_strengths_idx_]);
103 update();
104 return;
105 }
106
107 void ElectricalModel::setMinDrivingStrength()
108 {
109 setDrivingStrengthIdx(0);
110 return;
111 }
112
113 bool ElectricalModel::hasMinDrivingStrength() const
114 {
115 return (m_curr_driving_strengths_idx_ == 0);
116 }
117
118 bool ElectricalModel::hasMaxDrivingStrength() const
119 {
120 return (m_curr_driving_strengths_idx_ == ((int)m_driving_strengths_.size() - 1));
121 }
122
123 void ElectricalModel::increaseDrivingStrength()
124 {
125 if(!hasMaxDrivingStrength())
126 {
127 setDrivingStrengthIdx(m_curr_driving_strengths_idx_ + 1);
128 }
129 return;
130 }
131
132 void ElectricalModel::decreaseDrivingStrength()
133 {
134 if(!hasMinDrivingStrength())
135 {
136 setDrivingStrengthIdx(m_curr_driving_strengths_idx_ - 1);
137 }
138 return;
139 }
140
141 void ElectricalModel::setAvailableDrivingStrengths(const String& driving_strengths_)
142 {
143 setParameter("AvailableDrivingStrengths", driving_strengths_);
144 const vector<String>& split_str = driving_strengths_.split("[,");
145
146 // Check if there is at least one driving strength specified
147 ASSERT(!split_str.empty(), "[Error] " + getInstanceName() +
148 " -> Specified driving strength string does not contain any driving strengths (" +
149 driving_strengths_ + ")");
150
151 // TODO - check if the driving strengths is sorted
152
153 // Overwrite the available driving strengths
154 m_driving_strengths_.clear();
155 for(int i = 0; i < (int)split_str.size(); ++i)
156 {
157 m_driving_strengths_.push_back(split_str[i].toDouble());
158 }
159
160 // Set the driving strength to minimum
161 m_curr_driving_strengths_idx_ = 0;
162 setProperty("DrivingStrength", m_driving_strengths_[m_curr_driving_strengths_idx_]);
163 return;
164 }
165
166 // Connect a port (input or output) to some ElectricalNet
167 void ElectricalModel::portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_)
168 {
169 ASSERT(m_net_references_->keyExist(connect_net_name_), "[Error] " + getInstanceName() +
170 " -> Net '" + connect_net_name_ + "' does not exist!");
171
172 portConnect(connect_model_, connect_port_name_, connect_net_name_, m_net_references_->get(connect_net_name_));
173 }
174
175 void ElectricalModel::portConnect(ElectricalModel* connect_model_, const String& connect_port_name_, const String& connect_net_name_, const NetIndex& connect_net_indices_)
176 {
177 ASSERT(m_net_references_->keyExist(connect_net_name_), "[Error] " + getInstanceName() +
178 " -> Net '" + connect_net_name_ + "' does not exist!");
179
180 // Check whether the port name is an input or output, ASSERTion error if neither
181 bool is_input = connect_model_->getInputs()->keyExist(connect_port_name_);
182 bool is_output = connect_model_->getOutputs()->keyExist(connect_port_name_);
183
184 ASSERT(is_input || is_output, "[Error] " + getInstanceName() + " -> Model '" + connect_model_->getInstanceName() +
185 "' does not have a port named '" + connect_port_name_ + "'!");
186
187 int connect_net_width = connect_net_indices_.second - connect_net_indices_.first + 1;
188 const NetIndex& port_indices = connect_model_->getNetReference(connect_port_name_);
189 int port_width = port_indices.second - port_indices.first + 1;
190
191 ASSERT(connect_net_width == port_width, "[Error] " + getInstanceName() + " -> Port width mismatch for Model '" +
192 connect_model_->getInstanceName() + "." + connect_port_name_ + toString(port_indices) +
193 "' and net '" + connect_net_name_ + toString(connect_net_indices_) + "'!");
194
195 int port_index = port_indices.first;
196 int connect_net_index = connect_net_indices_.first;
197
198 if(is_input)
199 {
200 while(port_index <= port_indices.second)
201 {
202 getNet(connect_net_name_, makeNetIndex(connect_net_index))->addDownstreamNode(
203 connect_model_->getNet(connect_port_name_, makeNetIndex(port_index)));
204 ++port_index;
205 ++connect_net_index;
206 }
207 }
208 else if(is_output)
209 {
210 while (port_index <= port_indices.second)
211 {
212 connect_model_->getNet(connect_port_name_, makeNetIndex(port_index))->addDownstreamNode(
213 getNet(connect_net_name_, makeNetIndex(connect_net_index)));
214 ++port_index;
215 ++connect_net_index;
216 }
217 }
218 }
219
220 //Get Drivers
221 const Map<ElectricalDriver*>* ElectricalModel::getDrivers() const
222 {
223 return m_drivers_;
224 }
225
226 ElectricalDriver* ElectricalModel::getDriver(const String& name_)
227 {
228 return m_drivers_->get(name_);
229 }
230
231 //Get Driver Multipliers
232 const Map<ElectricalDriverMultiplier*>* ElectricalModel::getDriverMultipliers() const
233 {
234 return m_driver_multipliers_;
235 }
236
237 ElectricalDriverMultiplier* ElectricalModel::getDriverMultiplier(const String& name_)
238 {
239 return m_driver_multipliers_->get(name_);
240 }
241
242 //Get Nets
243 const Map<ElectricalNet*>* ElectricalModel::getNets() const
244 {
245 return m_nets_;
246 }
247
248 ElectricalNet* ElectricalModel::getNet(const String& name_)
249 {
250 return getNet(name_, m_net_references_->get(name_));
251 }
252
253 ElectricalNet* ElectricalModel::getNet(const String& name_, const NetIndex& index_)
254 {
255 ASSERT(index_.first == index_.second, "[Error] " + getInstanceName() +
256 " -> Ambiguous get net since (" + name_ + ") is a bus consisting of several nets!");
257 return m_nets_->get(name_ + "[" + (String) index_.first + "]");
258 }
259
260 //Get Loads
261 const Map<ElectricalLoad*>* ElectricalModel::getLoads() const
262 {
263 return m_loads_;
264 }
265
266 ElectricalLoad* ElectricalModel::getLoad(const String& name_)
267 {
268 return m_loads_->get(name_);
269 }
270
271 //Get Delays
272 const Map<ElectricalDelay*>* ElectricalModel::getDelays() const
273 {
274 return m_delays_;
275 }
276
277 ElectricalDelay* ElectricalModel::getDelay(const String& name_)
278 {
279 return m_delays_->get(name_);
280 }
281
282 //Get Inputs
283 const Map<PortInfo*>* ElectricalModel::getInputs() const
284 {
285 return m_input_ports_;
286 }
287
288 PortInfo* ElectricalModel::getInputPort(const String& name_)
289 {
290 ASSERT(m_input_ports_->keyExist(name_), "[Error] " + getInstanceName() +
291 " -> Input port (" + name_ + ") does not exist");
292
293 return m_input_ports_->get(name_);
294 }
295
296 const PortInfo* ElectricalModel::getInputPort(const String& name_) const
297 {
298 ASSERT(m_input_ports_->keyExist(name_), "[Error] " + getInstanceName() +
299 " -> Input port (" + name_ + ") does not exist");
300
301 return m_input_ports_->get(name_);
302 }
303
304 //Get Outputs
305 const Map<PortInfo*>* ElectricalModel::getOutputs() const
306 {
307 return m_output_ports_;
308 }
309
310 PortInfo* ElectricalModel::getOutputPort(const String& name_)
311 {
312 ASSERT(m_output_ports_->keyExist(name_), "[Error] " + getInstanceName() +
313 " -> Output port (" + name_ + ") does not exist");
314
315 return m_output_ports_->get(name_);
316 }
317
318 const PortInfo* ElectricalModel::getOutputPort(const String& name_) const
319 {
320 ASSERT(m_output_ports_->keyExist(name_), "[Error] " + getInstanceName() +
321 " -> Output port (" + name_ + ") does not exist");
322
323 return m_output_ports_->get(name_);
324 }
325
326 const Map<NetIndex>* ElectricalModel::getNetReferences() const
327 {
328 return m_net_references_;
329 }
330
331 const NetIndex ElectricalModel::getNetReference(const String& name_) const
332 {
333 return m_net_references_->get(name_);
334 }
335
336 //-------------------------------------------------------------------------
337 // Electrical Connectivity and Timing Element Creation Functions
338 //-------------------------------------------------------------------------
339
340 // Input Port creation
341 void ElectricalModel::createInputPort(const String& name_, const NetIndex& net_indices_)
342 {
343 // Create the new nets (including its net reference)
344 // This should already check that it has not been previously declared
345 createNet(name_, net_indices_);
346 // Add the net name to list of input ports
347 m_input_ports_->set(name_, new PortInfo(name_, net_indices_));
348 return;
349 }
350
351 // Output Port creation
352 void ElectricalModel::createOutputPort(const String& name_, const NetIndex& net_indices_)
353 {
354 // Create the new nets (including its net reference)
355 // This should already check that it has not been previously declared
356 createNet(name_, net_indices_);
357 // Add the net name to list of output ports
358 m_output_ports_->set(name_, new PortInfo(name_, net_indices_));
359 return;
360 }
361
362 // Net creation
363 void ElectricalModel::createNet(const String& name_)
364 {
365 // Creating a net with specifying an index range means that the net is just
366 // a 1-bit wire indexed at [0]
367 createNet(name_, makeNetIndex(0, 0));
368 return;
369 }
370
371 void ElectricalModel::createNet(const String& name_, const NetIndex& net_indices_)
372 {
373 // Check that it hasn't been previously declared
374 ASSERT( !m_nets_->keyExist(name_) && !m_net_references_->keyExist(name_),
375 "[Error] " + getInstanceName() + " -> Redeclaration of net " + name_);
376
377 int start = net_indices_.first;
378 int end = net_indices_.second;
379
380 for (int index = start; index <= end; ++index)
381 {
382 String indexed_name = name_ + "[" + (String) index + "]";
383 // Create the new net
384 ElectricalNet* net = new ElectricalNet(indexed_name, this);
385 // Add the net to net map
386 m_nets_->set(indexed_name, net);
387 }
388 // Add net to net references
389 m_net_references_->set(name_, net_indices_);
390 return;
391 }
392
393 // Driver creation
394 void ElectricalModel::createDriver(const String& name_, bool sizable_)
395 {
396 // Check that it hasn't been previously declared
397 ASSERT( !m_drivers_->keyExist(name_),
398 "[Error] " + getInstanceName() + " -> Redeclaration of driver " + name_);
399
400 ElectricalDriver* driver = new ElectricalDriver(name_, this, sizable_);
401 m_drivers_->set(name_, driver);
402 return;
403 }
404
405 /*
406 void ElectricalModel::createDriver(const String& name_, bool sizable_, int start_index_, int end_index_)
407 {
408 for (int index = start_index_; index <= end_index_; ++index)
409 {
410 createDriver(name_ + "[" + (String) index + "]", sizable_);
411 }
412 return;
413 }
414 */
415
416 // Driver Multiplier creation
417 void ElectricalModel::createDriverMultiplier(const String& name_)
418 {
419 // Check that it hasn't been previously declared
420 ASSERT( !m_driver_multipliers_->keyExist(name_),
421 "[Error] " + getInstanceName() + " -> Redeclaration of driver_multiplier " + name_);
422
423 ElectricalDriverMultiplier* driver_multiplier = new ElectricalDriverMultiplier(name_, this);
424 m_driver_multipliers_->set(name_, driver_multiplier);
425 return;
426 }
427
428 // Load creation
429
430 void ElectricalModel::createLoad(const String& name_)
431 {
432 // Check that it hasn't been previously declared
433 ASSERT( !m_loads_->keyExist(name_),
434 "[Error] " + getInstanceName() + " -> Redeclaration of load " + name_);
435
436 ElectricalLoad* load = new ElectricalLoad(name_, this);
437 m_loads_->set(name_, load);
438 return;
439 }
440
441 /*
442 void ElectricalModel::createLoad(const String& name_, int start_index_, int end_index_)
443 {
444 for (int index = start_index_; index <= end_index_; ++index)
445 {
446 createLoad(name_ + "[" + (String) index + "]");
447 }
448 return;
449 }
450 */
451
452 // Delay creation
453 void ElectricalModel::createDelay(const String& name_)
454 {
455 // Check that it hasn't been previously declared
456 ASSERT( !m_delays_->keyExist(name_),
457 "[Error] " + getInstanceName() + " -> Redeclaration of delay " + name_);
458
459 ElectricalDelay* delay = new ElectricalDelay(name_, this);
460 m_delays_->set(name_, delay);
461 return;
462 }
463
464 /*
465 void ElectricalModel::createDelay(const String& name_, int start_index_, int end_index_)
466 {
467 for (int index = start_index_; index <= end_index_; ++index)
468 {
469 createDelay(name_ + "[" + (String) index + "]");
470 }
471 return;
472 }
473 */
474 //-------------------------------------------------------------------------
475
476 // Assign a net to be downstream from another net
477 // case 1: 'assign downstream_net_name_ = upstream_net_name_'
478 void ElectricalModel::assign(const String& downstream_net_name_, const String& upstream_net_name_)
479 {
480 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
481 downstream_net_name_ + "' does not exist!");
482
483 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
484 upstream_net_name_ + "' does not exist!");
485
486 assign(downstream_net_name_, getNetReference(downstream_net_name_),
487 upstream_net_name_, getNetReference(upstream_net_name_));
488
489 return;
490 }
491
492 // case 2: 'assign downstream_net_name_[begin:end] = upstream_net_name_'
493 void ElectricalModel::assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_)
494 {
495 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
496 downstream_net_name_ + "' does not exist!");
497
498 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
499 upstream_net_name_ + "' does not exist!");
500
501 assign(downstream_net_name_, downstream_net_indices_,
502 upstream_net_name_, getNetReference(upstream_net_name_));
503
504 return;
505 }
506
507 // case 3: 'assign downstream_net_name_ = upstream_net_name_[begin:end]'
508 void ElectricalModel::assign(const String& downstream_net_name_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_)
509 {
510 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
511 downstream_net_name_ + "' does not exist!");
512
513 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
514 upstream_net_name_ + "' does not exist!");
515
516 assign(downstream_net_name_, getNetReference(downstream_net_name_),
517 upstream_net_name_, upstream_net_indices_);
518
519 return;
520 }
521 // case 4: 'assign downstream_net_name_[begin:end] = upstream_net_name_[begin:end]'
522 void ElectricalModel::assign(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_)
523 {
524 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
525 downstream_net_name_ + "' does not exist!");
526
527 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() + " -> Net '" +
528 upstream_net_name_ + "' does not exist!");
529
530 // Check that the assignment widths are the same
531 int downstream_width = downstream_net_indices_.second - downstream_net_indices_.first + 1;
532 int upstream_width = upstream_net_indices_.second - upstream_net_indices_.first + 1;
533
534 ASSERT(downstream_width == upstream_width, "[Error] " + getInstanceName() + " -> Assignment width mismatch: " +
535 downstream_net_name_ + " (" + (String) downstream_width + ") and " +
536 upstream_net_name_ + " (" + (String) upstream_width + ")");
537
538 // Loop through indices and connect them together
539 int down_index = downstream_net_indices_.first;
540 int up_index = upstream_net_indices_.first;
541 while (down_index <= downstream_net_indices_.second)
542 {
543 getNet(upstream_net_name_, makeNetIndex(up_index))->addDownstreamNode(
544 getNet(downstream_net_name_, makeNetIndex(down_index)));
545
546 ++up_index;
547 ++down_index;
548 }
549
550 return;
551 }
552
553 // Assign a net to another net through a driver multiplier
554 void ElectricalModel::assignVirtualFanout(const String& downstream_net_name_, const String& upstream_net_name_)
555 {
556 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() +
557 " -> Net '" + upstream_net_name_ + "' does not exist!");
558 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() +
559 " -> Net '" + downstream_net_name_ + "' does not exist!");
560
561 assignVirtualFanout(downstream_net_name_, getNetReference(downstream_net_name_), upstream_net_name_, getNetReference(upstream_net_name_));
562 return;
563 }
564
565 // Assign a net to another net through a driver multiplier
566 void ElectricalModel::assignVirtualFanout(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_)
567 {
568 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() +
569 " -> Net '" + upstream_net_name_ + "' does not exist!");
570 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() +
571 " -> Net '" + downstream_net_name_ + "' does not exist!");
572
573 const String& drive_mult_name = upstream_net_name_ + "_" + (String) upstream_net_indices_.first + "_DriverMultiplier";
574 bool is_drive_mult_exist = getDriverMultipliers()->keyExist(drive_mult_name);
575
576 // Create a driver multiplier and assign it to upstream_net since it doesn't exist
577 if(!is_drive_mult_exist)
578 {
579 createDriverMultiplier(drive_mult_name);
580 getNet(upstream_net_name_, upstream_net_indices_)->addDownstreamNode(getDriverMultiplier(drive_mult_name));
581 }
582
583 // Assign downstream_net_name_[end:begin] = driver_multiplier_name_
584 ElectricalDriverMultiplier* drive_mult = getDriverMultiplier(drive_mult_name);
585 int begin_index = downstream_net_indices_.first;
586 int end_index = downstream_net_indices_.second;
587 for(int i = begin_index; i <= end_index; ++i)
588 {
589 drive_mult->addDownstreamNode(getNet(downstream_net_name_, makeNetIndex(i)));
590 }
591 return;
592 }
593
594 void ElectricalModel::assignVirtualFanin(const String& downstream_net_name_, const String& upstream_net_name_)
595 {
596 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() +
597 " -> Net '" + upstream_net_name_ + "' does not exist!");
598 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() +
599 " -> Net '" + downstream_net_name_ + "' does not exist!");
600
601 assignVirtualFanin(downstream_net_name_, getNetReference(downstream_net_name_), upstream_net_name_, getNetReference(upstream_net_name_));
602 return;
603 }
604
605 void ElectricalModel::assignVirtualFanin(const String& downstream_net_name_, const NetIndex& downstream_net_indices_, const String& upstream_net_name_, const NetIndex& upstream_net_indices_)
606 {
607 ASSERT(getNetReferences()->keyExist(upstream_net_name_), "[Error] " + getInstanceName() +
608 " -> Net '" + upstream_net_name_ + "' does not exist!");
609 ASSERT(getNetReferences()->keyExist(downstream_net_name_), "[Error] " + getInstanceName() +
610 " -> Net '" + downstream_net_name_ + "' does not exist!");
611
612 int begin_index = upstream_net_indices_.first;
613 int end_index = upstream_net_indices_.second;
614
615 for(int i = begin_index; i <= end_index; ++i)
616 {
617 getNet(upstream_net_name_, makeNetIndex(i))->addDownstreamNode(getNet(downstream_net_name_, downstream_net_indices_));
618 }
619 return;
620 }
621
622 void ElectricalModel::createElectricalResults()
623 {
624 // Add active area result
625 addAreaResult(new Result("Active"));
626
627 // Add wire area result
628 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin();
629 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end();
630 TechModel::ConstWireLayerIterator it;
631 for(it = it_begin; it != it_end; ++it)
632 {
633 const String& layer_name = (*it);
634 addAreaResult(new Result(layer_name + "Wire"));
635 }
636
637 // Add leakage result
638 addNddPowerResult(new Result("Leakage"));
639
640 // Add idle event result
641 createElectricalEventResult("Idle");
642 return;
643 }
644
645 void ElectricalModel::addElectricalSubResults(const ElectricalModel* model_, double number_models_)
646 {
647 // Add active area sub result
648 getAreaResult("Active")->addSubResult(model_->getAreaResult("Active"), model_->getInstanceName(), number_models_);
649
650 // Add wire area sub result
651 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin();
652 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end();
653 TechModel::ConstWireLayerIterator it;
654 for(it = it_begin; it != it_end; ++it)
655 {
656 const String& layer_name = (*it);
657 const String& result_name = layer_name + "Wire";
658 getAreaResult(result_name)->addSubResult(model_->getAreaResult(result_name), model_->getInstanceName(), number_models_);
659 }
660
661 // Add leakage sub result
662 getNddPowerResult("Leakage")->addSubResult(model_->getNddPowerResult("Leakage"), model_->getInstanceName(), number_models_);
663
664 // Add idle event sub result
665 getEventResult("Idle")->addSubResult(model_->getEventResult("Idle"), model_->getInstanceName(), number_models_);
666 return;
667 }
668
669 void ElectricalModel::addElectricalWireSubResult(const String& wire_layer_, const Result* result_, const String& producer_, double number_results_)
670 {
671 getAreaResult(wire_layer_ + "Wire")->addSubResult(result_, producer_, number_results_);
672 return;
673 }
674
675 void ElectricalModel::createElectricalAtomicResults()
676 {
677 // Add active area result
678 addAreaResult(new AtomicResult("Active"));
679
680 // Add wire area result
681 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin();
682 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end();
683 TechModel::ConstWireLayerIterator it;
684 for(it = it_begin; it != it_end; ++it)
685 {
686 const String& layer_name = (*it);
687 addAreaResult(new AtomicResult(layer_name + "Wire"));
688 }
689
690 // Add leakage result
691 addNddPowerResult(new AtomicResult("Leakage"));
692
693 // Add idle event result
694 createElectricalEventAtomicResult("Idle");
695 return;
696 }
697
698 void ElectricalModel::addElecticalAtomicResultValues(const ElectricalModel* model_, double number_models_)
699 {
700 getAreaResult("Active")->addValue(model_->getAreaResult("Active")->calculateSum() * number_models_);
701
702 // Add wire area sub result
703 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin();
704 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end();
705 TechModel::ConstWireLayerIterator it;
706 for(it = it_begin; it != it_end; ++it)
707 {
708 const String& layer_name = (*it);
709 const String& result_name = layer_name + "Wire";
710 getAreaResult(result_name)->addValue(model_->getAreaResult(result_name)->calculateSum() * number_models_);
711 }
712
713 // Add leakage sub result
714 getNddPowerResult("Leakage")->addValue(model_->getNddPowerResult("Leakage")->calculateSum() * number_models_);
715
716 // Add idle event sub result
717 getEventResult("Idle")->addValue(model_->getEventResult("Idle")->calculateSum() * number_models_);
718 return;
719 }
720
721 void ElectricalModel::addElecticalWireAtomicResultValue(const String& wire_layer_, double value_)
722 {
723 getAreaResult(wire_layer_ + "Wire")->addValue(value_);
724 return;
725 }
726
727 void ElectricalModel::resetElectricalAtomicResults()
728 {
729 getAreaResult("Active")->setValue(0.0);
730
731 // Reset wire area sub result
732 TechModel::ConstWireLayerIterator it_begin = getTechModel()->getAvailableWireLayers()->begin();
733 TechModel::ConstWireLayerIterator it_end = getTechModel()->getAvailableWireLayers()->end();
734 TechModel::ConstWireLayerIterator it;
735 for(it = it_begin; it != it_end; ++it)
736 {
737 const String& layer_name = (*it);
738 const String& result_name = layer_name + "Wire";
739 getAreaResult(result_name)->setValue(0.0);
740 }
741
742 // Reset leakage sub result
743 getNddPowerResult("Leakage")->setValue(0.0);
744
745 // Reset idle event sub result
746 getEventResult("Idle")->setValue(0.0);
747
748 return;
749 }
750
751 void ElectricalModel::createElectricalEventResult(const String& name_)
752 {
753 // Add the event result
754 addEventResult(new Result(name_));
755 // Add event info
756 m_event_infos_->set(name_, new EventInfo(name_, getInputs()));
757 return;
758 }
759
760 void ElectricalModel::createElectricalEventAtomicResult(const String& name_)
761 {
762 // Add the event result
763 addEventResult(new AtomicResult(name_));
764 // Add event info
765 m_event_infos_->set(name_, new EventInfo(name_, getInputs()));
766 return;
767 }
768
769 void ElectricalModel::assignPortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const TransitionInfo& trans_info_)
770 {
771 ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() +
772 " -> Downstream model does not exist");
773
774 downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info_);
775 return;
776 }
777
778 void ElectricalModel::propagatePortTransitionInfo(const String& downstream_port_name_, const String& upstream_port_name_)
779 {
780 const TransitionInfo& trans_info = getInputPort(upstream_port_name_)->getTransitionInfo();
781 getOutputPort(downstream_port_name_)->setTransitionInfo(trans_info);
782 return;
783 }
784
785 void ElectricalModel::propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const String& upstream_port_name_)
786 {
787 ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() +
788 " -> Downstream model does not exist");
789
790 const TransitionInfo& trans_info = getInputPort(upstream_port_name_)->getTransitionInfo();
791 downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info);
792 return;
793 }
794
795 void ElectricalModel::propagatePortTransitionInfo(ElectricalModel* downstream_model_, const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_)
796 {
797 ASSERT(downstream_model_ != NULL, "[Error] " + getInstanceName() +
798 " -> Downstream model does not exist");
799 ASSERT(upstream_model_ != NULL, "[Error] " + getInstanceName() +
800 " -> Upstream model does not exist");
801
802 const TransitionInfo& trans_info = upstream_model_->getOutputPort(upstream_port_name_)->getTransitionInfo();
803
804 downstream_model_->getInputPort(downstream_port_name_)->setTransitionInfo(trans_info);
805 return;
806 }
807
808 void ElectricalModel::propagatePortTransitionInfo(const String& downstream_port_name_, const ElectricalModel* upstream_model_, const String& upstream_port_name_)
809 {
810 ASSERT(upstream_model_ != NULL, "[Error] " + getInstanceName() +
811 " -> Upstream model does not exist");
812
813 const TransitionInfo& trans_info = upstream_model_->getOutputPort(upstream_port_name_)->getTransitionInfo();
814 getOutputPort(downstream_port_name_)->setTransitionInfo(trans_info);
815 return;
816 }
817
818 void ElectricalModel::propagateTransitionInfo()
819 {
820 // by default do nothing.
821 }
822
823 void ElectricalModel::useModel(const String& event_name_)
824 {
825 getGenProperties()->set("UseModelEvent", event_name_);
826 applyTransitionInfo(event_name_);
827 useModel();
828 return;
829 }
830
831 void ElectricalModel::useModel()
832 {
833 propagateTransitionInfo();
834 return;
835 }
836
837 void ElectricalModel::applyTransitionInfo(const String& event_name_)
838 {
839 // Check if the event actually exists
840 ASSERT(hasEventResult(event_name_), "[Error] " + getInstanceName() +
841 " -> Event (" + event_name_ + ") does not exist in the result map");
842 ASSERT(m_event_infos_->keyExist(event_name_), "[Error] " + getInstanceName() +
843 " -> Event (" + event_name_ + ") does not exist in the event info map");
844
845 const EventInfo* event_info = m_event_infos_->get(event_name_);
846
847 // Set the input ports' transition information for the event
848 Map<PortInfo*>::ConstIterator it_begin = m_input_ports_->begin();
849 Map<PortInfo*>::ConstIterator it_end = m_input_ports_->end();
850 Map<PortInfo*>::ConstIterator it;
851 for(it = it_begin; it != it_end; ++it)
852 {
853 const String& port_name = it->first;
854 PortInfo* port_info = it->second;
855 const TransitionInfo& trans_info = event_info->getTransitionInfo(port_name);
856 port_info->setTransitionInfo(trans_info);
857 }
858
859 return;
860 }
861
862 EventInfo* ElectricalModel::getEventInfo(const String& event_name_)
863 {
864 ASSERT(m_event_infos_->keyExist(event_name_), "[Error] " + getInstanceName() +
865 " -> Event (" + event_name_ + ") does not exist");
866
867 return m_event_infos_->get(event_name_);
868 }
869
870} // namespace DSENT
871
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