OpenASIP 2.2
Loading...
Searching...
No Matches
Guard.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file Guard.cc
26 *
27 * Implementation of Guard class and its derived classes.
28 *
29 * @author Lasse Laasonen 2003 (lasse.laasonen-no.spam-tut.fi)
30 */
31
32#include <string>
33
34#include "Guard.hh"
35#include "FUPort.hh"
36#include "RegisterFile.hh"
37#include "FunctionUnit.hh"
38#include "ControlUnit.hh"
39#include "Bus.hh"
40#include "MOMTextGenerator.hh"
41#include "Conversion.hh"
42#include "ObjectState.hh"
43
44using std::string;
45using boost::format;
46
47namespace TTAMachine {
48
49/////////////////////////////////////////////////////////////////////////////
50// Guard
51/////////////////////////////////////////////////////////////////////////////
52
53// initialization of static data members
54const string Guard::OSNAME_GUARD = "guard";
55const string Guard::OSKEY_INVERTED = "inverted";
56
57
58/**
59 * Constructor.
60 *
61 * @param inverted Indicates whether the condition term is inverted.
62 * @param parentBus Parent bus component of the guard.
63 */
64Guard::Guard(bool inverted, Bus* parentBus) :
65 inverted_(inverted), parent_(parentBus) {
66
67 // parentBus.addGuard() cannot be called here because isEqual method
68 // does not work until the whole
69 // (RegisterGuard/PortGuard/UnconditionalGuard) is instantiated
70}
71
72
73/**
74 * Constructor.
75 *
76 * Loads its state from the given ObjectState instance.
77 *
78 * @param state The ObjectState instance from which the state is loaded.
79 * @param parentBus Parent bus of the guard.
80 * @exception ObjectStateLoadingException If the given ObjectState instance
81 * is invalid.
82 */
83Guard::Guard(const ObjectState* state, Bus& parentBus) : parent_(&parentBus) {
84 loadState(state);
85}
86
87/**
88 * Destructor.
89 */
91 Bus* parent = parent_;
92 parent_ = NULL;
93 if (parent) {
94 parent->removeGuard(*this);
95 }
96}
97
98
99/**
100 * Checks whether this guard is more restrictive than the given one.
101 *
102 * This method is meant for complex (two-term) guards but they are not
103 * supported yet, so returns always false.
104 *
105 * @param guard The guard to compare.
106 * @return False.
107 */
108bool
109Guard::isMoreRestrictive(const Guard& /*guard*/) const {
110 return false;
111}
112
113
114/**
115 * Checks whether this guard is less restrictive than the given one.
116 *
117 * This method is meant for complex (two-term) guards but they are not
118 * supported yet, so returns always false.
119 *
120 * @param guard The guard to compare.
121 * @return False.
122 */
123bool
124Guard::isLessRestrictive(const Guard& /*guard*/) const {
125 return false;
126}
127
128
129/**
130 * Checks whether this guard and given one are disjoint.
131 *
132 * The guards are disjoint if neither is the exact subset of the other.
133 *
134 * @param guard The guard to compare.
135 * @return True if the guards are disjoint, otherwise false.
136 */
137bool
138Guard::isDisjoint(const Guard& guard) const {
139 return !isEqual(guard);
140}
141
142
143/**
144 * Saves the state of the object to an ObjectState object.
145 *
146 * @return The newly created ObjectState object.
147 */
152 return state;
153}
154
155
156/**
157 * Loads its state from the given ObjectState instance.
158 *
159 * @param state The ObjectState instance.
160 * @exception ObjectStateLoadingException If the given ObjectState is
161 * invalid.
162 */
163void
165 try {
167 } catch (Exception& e) {
168 string procName = "Guard::loadState";
170 __FILE__, __LINE__, procName,
171 e.errorMessage());
172 }
173}
174
175/////////////////////////////////////////////////////////////////////////////
176// PortGuard
177/////////////////////////////////////////////////////////////////////////////
178
179// initialization of static strings used to identify the ObjectState instance
180const string PortGuard::OSNAME_PORT_GUARD = "portguard";
181const string PortGuard::OSKEY_FU = "fu";
182const string PortGuard::OSKEY_PORT = "port";
183
184
185/**
186 * Constructor.
187 *
188 * @param inverted Incates whether the condition term is inverted.
189 * @param port Port from which the condition term is taken.
190 * @param parentBus Parent bus component of the guard.
191 * @exception IllegalRegistration If the given port is not registered to the
192 * same machine as the given parent bus.
193 * @exception ComponentAlreadyExists If the parent bus already has an equal
194 * guard.
195 */
196PortGuard::PortGuard(bool inverted, FUPort& port, Bus& parentBus)
197 : Guard(inverted, &parentBus), port_(&port) {
198 FunctionUnit* unit = port.parentUnit();
200 parentBus.addGuard(*this);
201}
202
203/**
204 * Constructor.
205 *
206 * Loads its state from the given ObjectState instance.
207 *
208 * @param state The ObjectState instance.
209 * @param parentBus Parent bus of the guard.
210 * @exception ObjectStateLoadingException If the reference to the function
211 * unit port cannot be resolved or if
212 * the given ObjectState instance is
213 * invalid.
214 */
215PortGuard::PortGuard(const ObjectState* state, Bus& parentBus)
216 : Guard(state, parentBus) {
217 loadState(state);
218 try {
219 parentBus.addGuard(*this);
220 } catch (const ComponentAlreadyExists&) {
221 const string procName = "PortGuard::PortGuard";
222 MOMTextGenerator textGen;
223 format errorMsg = textGen.text(
225 errorMsg % port()->name() % port()->parentUnit()->name() %
226 parentBus.name();
228 __FILE__, __LINE__, procName, errorMsg.str());
229 }
230}
231
232/**
233 * Destructor.
234 */
237
238
239/**
240 * Returns true if the guard is equal with the given guard.
241 *
242 * @param guard The other guard.
243 * @return True if the guard is equal with the given guard.
244 */
245bool
246PortGuard::isEqual(const Guard& guard) const {
247 const PortGuard* portGuard = dynamic_cast<const PortGuard*>(&guard);
248 if (portGuard == NULL) {
249 return false;
250 } else {
251 if (port() == portGuard->port() &&
252 isInverted() == portGuard->isInverted()) {
253 return true;
254 } else {
255 return false;
256 }
257 }
258}
259
260/**
261 * Returns true if the guard is opposite with the given guard,
262 * ie. always if one is executed, another is not executed.
263 *
264 * @param guard The other guard.
265 * @return True if the guard is opposite with the given guard.
266 */
267bool
268PortGuard::isOpposite(const Guard& guard) const {
269 const PortGuard* portGuard = dynamic_cast<const PortGuard*>(&guard);
270 if (portGuard == NULL) {
271 return false;
272 } else {
273 if (port() == portGuard->port() &&
274 isInverted() != portGuard->isInverted()) {
275 return true;
276 } else {
277 return false;
278 }
279 }
280}
281
282
283/**
284 * Saves the contents to an ObjectState object.
285 *
286 * @return The created tree ObjectState object.
287 */
290
291 ObjectState* guardState = Guard::saveState();
292 guardState->setName(OSNAME_PORT_GUARD);
293
294 FunctionUnit* unit = port_->parentUnit();
295 guardState->setAttribute(OSKEY_FU, unit->name());
296 guardState->setAttribute(OSKEY_PORT, port_->name());
297
298 return guardState;
299}
300
301
302/**
303 * Loads its state from the given ObjectState instance.
304 *
305 * @param state The ObjectState instance.
306 * @exception ObjectStateLoadingException If the given ObjectState instance
307 * is invalid or if the reference to
308 * the function unit port cannot be
309 * resolved.
310 */
311void
313 string procName = "PortGuard::loadState";
314 MOMTextGenerator textGenerator;
315
316 if (state->name() != OSNAME_PORT_GUARD) {
317 throw ObjectStateLoadingException(__FILE__, __LINE__, procName);
318 }
319
320 Guard::loadState(state);
321
322 try {
323 string fuName = state->stringAttribute(OSKEY_FU);
324 string portName = state->stringAttribute(OSKEY_PORT);
325
326 Machine* mach = parentBus()->machine();
327 if (mach == NULL) {
328 format text = textGenerator.text(MOMTextGenerator::
329 TXT_GUARD_REF_LOAD_ERR);
330 text % parentBus()->name();
331 throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
332 text.str());
333 }
334
336 FunctionUnit* fu = NULL;
337 FUPort* port = NULL;
338
339 try {
340 fu = fuNav.item(fuName);
341 } catch (InstanceNotFound& e) {
342 format text = textGenerator.text(MOMTextGenerator::
343 TXT_GUARD_REF_LOAD_ERR_FU);
344 text % parentBus()->name() % fuName;
345 throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
346 text.str());
347 }
348
349 try {
350 port = fu->operationPort(portName);
351 } catch (InstanceNotFound& e) {
352 format text = textGenerator.text(MOMTextGenerator::
353 TXT_GUARD_REF_LOAD_ERR_PORT);
354 text % parentBus()->name() % portName % fuName;
355 throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
356 text.str());
357 }
358
359 port_ = port;
360
361 } catch (Exception& e) {
362 throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
363 e.errorMessage());
364 }
365}
366
367/////////////////////////////////////////////////////////////////////////////
368// RegisterGuard
369/////////////////////////////////////////////////////////////////////////////
370
371// initialization of static data members
372const string RegisterGuard::OSNAME_REGISTER_GUARD = "registerguard";
373const string RegisterGuard::OSKEY_REGFILE = "regfile";
374const string RegisterGuard::OSKEY_INDEX = "index";
375
376/**
377 * Constructor.
378 *
379 * @param inverted Indicates whether the condition term is inverted.
380 * @param regFile RegisterFile from which the condition term is taken.
381 * @param registerIndex Index of the register from which the condition
382 * term is taken.
383 * @param parentBus Parent bus component of the guard.
384 * @exception IllegalRegistration If the given register file is not
385 * registered to the same machine as the
386 * parent bus of the guard.
387 * @exception ComponentAlreadyExists If the parent bus already has an equal
388 * guard.
389 * @exception OutOfRange If the given register file does not have a register
390 * by the given register index.
391 * @exception InvalidData If local + global guard latency would be zero.
392 */
394 bool inverted, const RegisterFile& regFile, unsigned int registerIndex,
395 Bus* parentBus)
396 : Guard(inverted, parentBus),
397 regFile_(&regFile),
398 registerIndex_(registerIndex) {
399 if (parentBus) {
401 }
402 if ((unsigned)regFile.numberOfRegisters() <= registerIndex) {
403 string procName = "RegisterGuard::RegisterGuard";
404 throw OutOfRange(__FILE__, __LINE__, procName);
405 }
406
407 if (parentBus) {
408 // make sure global + local guard latency > 0
409 Machine* mach = parentBus->machine();
410 ControlUnit* gcu = mach->controlUnit();
411 if (gcu != NULL && gcu->globalGuardLatency() == 0 &&
412 regFile.guardLatency() == 0) {
413 MOMTextGenerator textGen;
414 boost::format text = textGen.text(
416 throw InvalidData(__FILE__, __LINE__, __func__, text.str());
417 }
418 parentBus->addGuard(*this);
419 }
420}
421
422/**
423 * Constructor.
424 *
425 * Creates a skeleton object without references to other machine parts.
426 * Loads its state from the given ObjectState instance. This constructor
427 * should be used by Bus::loadStateWithoutReferences only. Do not use this
428 * constructor.
429 *
430 * @param state The ObjectState instance.
431 * @param parentBus Parent bus of the guard.
432 * @exception ObjectStateLoadingException If the given ObjectState instance
433 * is invalid or if the reference to
434 * the register cannot be resolved.
435 */
437 : Guard(state, parentBus) {
438 loadState(state);
439 try {
440 parentBus.addGuard(*this);
441 } catch (const ComponentAlreadyExists&) {
442 const string procName = "RegisterGuard::RegisterGuard";
443 MOMTextGenerator textGen;
444 format errorMsg = textGen.text(
446 errorMsg % registerIndex() % registerFile()->name() %
447 parentBus.name();
449 __FILE__, __LINE__, procName, errorMsg.str());
450 }
451}
452
453/**
454 * Destructor.
455 */
458
459
460/**
461 * Returns true if the guard is equal with the given guard.
462 *
463 * @param guard The other guard.
464 * @return True if the guard is equal with the given guard.
465 */
466bool
467RegisterGuard::isEqual(const Guard& guard) const {
468 const RegisterGuard* regGuard =
469 dynamic_cast<const RegisterGuard*>(&guard);
470 if (regGuard == NULL) {
471 return false;
472 } else {
473 if (registerFile() == regGuard->registerFile() &&
474 registerIndex() == regGuard->registerIndex() &&
475 isInverted() == regGuard->isInverted()) {
476 return true;
477 } else {
478 return false;
479 }
480 }
481}
482
483/**
484 * Returns true if the guard is opposite with the given guard,
485 * ie. always if one is executed, another is not executed.
486 *
487 * @param guard The other guard.
488 * @return True if the guard is opposite with the given guard.
489 */
490bool
491RegisterGuard::isOpposite(const Guard& guard) const {
492 const RegisterGuard* regGuard =
493 dynamic_cast<const RegisterGuard*>(&guard);
494 if (regGuard == NULL) {
495 return false;
496 } else {
497 if (registerFile() == regGuard->registerFile() &&
498 registerIndex() == regGuard->registerIndex() &&
499 isInverted() != regGuard->isInverted()) {
500 return true;
501 } else {
502 return false;
503 }
504 }
505}
506
507
508/**
509 * Saves the contents to an ObjectState object.
510 *
511 * @return The created ObjectState object..
512 */
515
516 ObjectState* guardState = Guard::saveState();
517 guardState->setName(OSNAME_REGISTER_GUARD);
518 guardState->setAttribute(OSKEY_REGFILE, regFile_->name());
520
521 return guardState;
522}
523
524
525/**
526 * Loads its state from the given ObjectState instance.
527 *
528 * @param state The ObjectState instance.
529 * @exception ObjectStateLoadingException If the given ObjectState instance
530 * is invalid or if the reference to
531 * the register file cannot be
532 * resolved.
533 */
534void
536 string procName = "RegisterGuard::loadState";
537 MOMTextGenerator textGenerator;
538
539 if (state->name() != OSNAME_REGISTER_GUARD) {
540 throw ObjectStateLoadingException(__FILE__, __LINE__, procName);
541 }
542
543 if (!parentBus()->isRegistered()) {
544 format text = textGenerator.text(MOMTextGenerator::
545 TXT_GUARD_REF_LOAD_ERR);
546 text % parentBus()->name();
547 throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
548 text.str());
549 }
550
551 Guard::loadState(state);
552
553 try {
554 string regFileName = state->stringAttribute(OSKEY_REGFILE);
555 int regIndex = state->intAttribute(OSKEY_INDEX);
556
557 Machine* mach = parentBus()->machine();
559 mach->registerFileNavigator();
560 if (regNav.hasItem(regFileName)) {
561 RegisterFile* regFile = regNav.item(regFileName);
562
563 // check local + global guard latency > 0
564 ControlUnit* gcu = mach->controlUnit();
565 if (regFile->guardLatency() == 0 && gcu != NULL &&
566 gcu->globalGuardLatency() == 0) {
567 format text = textGenerator.text(
570 __FILE__, __LINE__, __func__, text.str());
571 }
572
573 if (regFile->numberOfRegisters() > regIndex) {
574 regFile_ = regFile;
575 registerIndex_ = regIndex;
576 } else {
577 format text = textGenerator.text(
579 text % parentBus()->name() % Conversion::toString(regIndex)
580 % regFileName %
582 throw ObjectStateLoadingException(__FILE__, __LINE__,
583 procName, text.str());
584 }
585 } else {
586 format text = textGenerator.text(MOMTextGenerator::
587 TXT_GUARD_REF_LOAD_ERR_RF);
588 text % parentBus()->name() % regFileName;
589 throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
590 text.str());
591 }
592 } catch (Exception& e) {
593 throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
594 e.errorMessage());
595 }
596}
597
598/////////////////////////////////////////////////////////////////////////////
599// UnconditionalGuard
600/////////////////////////////////////////////////////////////////////////////
601
602// initialization of static data members
603const string
605
606/**
607 * Constructor.
608 *
609 * @param inverted If true, the guard condition is always false and
610 * vice versa.
611 * @param parentBus Parent bus component of the guard.
612 * @exception ComponentAlreadyExists If the parent bus already has an equal
613 * guard.
614 */
616 : Guard(inverted, &parentBus) {
617 parentBus.addGuard(*this);
618}
619
620/**
621 * Constructor.
622 *
623 * Loads its state from the given ObjectState instance.
624 *
625 * @param state The ObjectState instance.
626 * @param parentBus The parent bus of the guard.
627 * @exception ObjectStateLoadingException If the given ObjectState instance
628 * is invalid.
629 */
631 : Guard(state, parentBus) {
632 loadState(state);
633 try {
634 parentBus.addGuard(*this);
635 } catch (const ComponentAlreadyExists&) {
636 const string procName = "UnconditionalGuard::UnconditionalGuard";
637 MOMTextGenerator textGen;
638 format errorMsg = textGen.text(
640 errorMsg % parentBus.name();
642 __FILE__, __LINE__, procName, errorMsg.str());
643 }
644}
645
646/**
647 * Destructor.
648 */
651
652
653/**
654 * Returns true if the guard is equal with the given guard.
655 *
656 * @param guard The other guard.
657 * @return True if the guard is equal with the given guard.
658 */
659bool
661 const UnconditionalGuard* ucGuard =
662 dynamic_cast<const UnconditionalGuard*>(&guard);
663 if (ucGuard == NULL) {
664 return false;
665 } else {
666 if (isInverted() == ucGuard->isInverted()) {
667 return true;
668 } else {
669 return false;
670 }
671 }
672}
673
674
675/**
676 * Saves the contents to an ObjectState object.
677 *
678 * @return The created ObjectState object.
679 */
682 ObjectState* guardState = Guard::saveState();
684 return guardState;
685}
686
687
688/**
689 * Loads its state from the given ObjectState instance.
690 *
691 * @param state The ObjectState instance.
692 * @exception ObjectStateLoadingException If the given ObjectState instance
693 * is invalid.
694 */
695void
697 string procName = "UnconditionalGuard::loadState";
698
699 if (state->name() != OSNAME_UNCONDITIONAL_GUARD) {
700 throw ObjectStateLoadingException(__FILE__, __LINE__, procName);
701 }
702
703 Guard::loadState(state);
704}
705}
#define __func__
static std::string toString(const T &source)
std::string errorMessage() const
Definition Exception.cc:123
void setName(const std::string &name)
void setAttribute(const std::string &name, const std::string &value)
std::string stringAttribute(const std::string &name) const
int intAttribute(const std::string &name) const
std::string name() const
FunctionUnit * parentUnit() const
Definition BaseFUPort.cc:96
virtual int numberOfRegisters() const
void addGuard(Guard &guard)
Definition Bus.cc:410
virtual void removeGuard(Guard &guard)
Definition Bus.cc:428
virtual Machine * machine() const
virtual void ensureRegistration(const Component &component) const
virtual TCEString name() const
int globalGuardLatency() const
virtual FUPort * operationPort(const std::string &name) const
virtual void loadState(const ObjectState *state)
Definition Guard.cc:164
virtual bool isLessRestrictive(const Guard &guard) const
Definition Guard.cc:124
bool inverted_
Indicated whether the condition term is inverted.
Definition Guard.hh:85
static const std::string OSKEY_INVERTED
ObjectState attribute key for inverted feature.
Definition Guard.hh:77
static const std::string OSNAME_GUARD
ObjectState name for guard.
Definition Guard.hh:75
virtual bool isInverted() const
virtual bool isDisjoint(const Guard &guard) const
Definition Guard.cc:138
virtual bool isEqual(const Guard &guard) const =0
virtual Bus * parentBus() const
Bus * parent_
The parent bus of the guard.
Definition Guard.hh:87
virtual bool isMoreRestrictive(const Guard &guard) const
Definition Guard.cc:109
virtual ObjectState * saveState() const
Definition Guard.cc:149
virtual ~Guard()
Definition Guard.cc:90
Guard(bool inverted, Bus *parentBus)
Definition Guard.cc:64
ComponentType * item(int index) const
bool hasItem(const std::string &name) const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
static const std::string OSKEY_PORT
ObjectState attribute key for port name.
Definition Guard.hh:121
ObjectState * saveState() const
Definition Guard.cc:289
bool isOpposite(const Guard &guard) const
Definition Guard.cc:268
void loadState(const ObjectState *state)
Definition Guard.cc:312
PortGuard(bool inverted, FUPort &port, Bus &parentBus)
Definition Guard.cc:196
static const std::string OSKEY_FU
ObjectState attribute key for function unit name.
Definition Guard.hh:119
bool isEqual(const Guard &guard) const
Definition Guard.cc:246
FUPort * port_
Port from which the condition term is taken.
Definition Guard.hh:125
virtual ~PortGuard()
Definition Guard.cc:235
static const std::string OSNAME_PORT_GUARD
ObjectState name for PortGuard ObjectState.
Definition Guard.hh:117
FUPort * port() const
virtual std::string name() const
Definition Port.cc:141
virtual int guardLatency() const
void loadState(const ObjectState *state)
Definition Guard.cc:535
static const std::string OSNAME_REGISTER_GUARD
ObjectState name for RegisterGuard.
Definition Guard.hh:159
ObjectState * saveState() const
Definition Guard.cc:514
static const std::string OSKEY_INDEX
ObjectState attribute key for register index.
Definition Guard.hh:163
int registerIndex_
Index of the register from which the condition term is taken.
Definition Guard.hh:169
bool isEqual(const Guard &guard) const
Definition Guard.cc:467
RegisterGuard(bool inverted, const RegisterFile &regFile, unsigned int registerIndex, Bus *parentBus)
Definition Guard.cc:393
const RegisterFile * regFile_
RegisterFile from which the condition term is taken.
Definition Guard.hh:167
const RegisterFile * registerFile() const
bool isOpposite(const Guard &guard) const
Definition Guard.cc:491
static const std::string OSKEY_REGFILE
ObjectState attribute key for register file name.
Definition Guard.hh:161
void loadState(const ObjectState *state)
Definition Guard.cc:696
bool isEqual(const Guard &guard) const
Definition Guard.cc:660
UnconditionalGuard(bool inverted, Bus &parentBus)
Definition Guard.cc:615
ObjectState * saveState() const
Definition Guard.cc:681
static const std::string OSNAME_UNCONDITIONAL_GUARD
ObjectState name for UnconditionalGuard.
Definition Guard.hh:195
virtual boost::format text(int textId)