OpenASIP  2.0
Unit.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 Unit.cc
26  *
27  * Implementation of Unit class.
28  *
29  * @author Lasse Laasonen 2003 (lasse.laasonen-no.spam-tut.fi)
30  * @note rating: red
31  * @note reviewed 22 Jun 2004 by ao, ml, vpj, ll
32  */
33 
34 #include "Unit.hh"
35 #include "Machine.hh"
36 #include "Port.hh"
37 #include "FUPort.hh"
38 #include "RFPort.hh"
39 #include "SpecialRegisterPort.hh"
40 #include "FunctionUnit.hh"
41 #include "Application.hh"
42 #include "ContainerTools.hh"
43 #include "AssocTools.hh"
44 #include "ObjectState.hh"
45 
46 using std::string;
47 
48 namespace TTAMachine {
49 
50 // initialization of static data members
51 const string Unit::OSNAME_UNIT = "unit";
52 
53 /**
54  * Constructor.
55  *
56  * @param name The name of the unit.
57  * @exception InvalidName If the given name is not a valid component name.
58  */
59 Unit::Unit(const std::string& name) : Component(name) {}
60 
61 /**
62  * Constructor.
63  *
64  * Loads the state of the unit from the given ObjectState instance. Does not
65  * load connections to other components.
66  *
67  * @param state The ObjectState instance from which the name is taken.
68  * @exception ObjectStateLoadingException If the given ObjectState instance
69  * is invalid.
70  */
71 Unit::Unit(const ObjectState* state) : Component(state) {
72  try {
74  } catch (const Exception&) {
75  // delete the ports that were loaded
77  throw;
78  }
79 }
80 
81 /**
82  * Destructor.
83  */
86 }
87 
88 
89 /**
90  * Returns true if the requested port is found, otherwise false.
91  *
92  * @param name Name of the port.
93  * @return Tru if the port is found, otherwise false.
94  */
95 bool
96 Unit::hasPort(const std::string& name) const {
97  PortTable::const_iterator iter = ports_.begin();
98  while (iter != ports_.end()) {
99  if ((*iter)->name() == name) {
100  return true;
101  }
102  iter++;
103  }
104  return false;
105 }
106 
107 
108 /**
109  * Returns the requested port.
110  *
111  * @param name Name of the port.
112  * @return The requested port.
113  * @exception InstanceNotFound If a port is not found by the given name.
114  */
115 Port*
116 Unit::port(const std::string& name) const {
117  PortTable::const_iterator iter = ports_.begin();
118  while (iter != ports_.end()) {
119  if ((*iter)->name() == name) {
120  return *iter;
121  }
122  iter++;
123  }
124 
125  string procName = "Unit::port";
126  throw InstanceNotFound(__FILE__, __LINE__, procName);
127 }
128 
129 /**
130  * Returns the number of ports in the unit.
131  *
132  * @return The number of ports in the unit.
133  */
134 int
136  return ports_.size();
137 }
138 
139 
140 /**
141  * @param countBidir True if we should count bidirectional ports
142  * @return The number of output ports in the unit.
143  */
144 int
145 Unit::outputPortCount(bool countBidir) const {
146  unsigned count = 0;
147  for (auto &port : ports_) {
148  if (port->isOutput() && (!port->isInput() || countBidir))
149  count++;
150  }
151  return count;
152 }
153 
154 
155 /**
156  * @param countBidir True if we should count bidirectional ports
157  * @return The number of input ports in the unit.
158  */
159 int
160 Unit::inputPortCount(bool countBidir) const {
161  unsigned count = 0;
162  for (auto &port : ports_) {
163  if (port->isInput() && (!port->isOutput() || countBidir))
164  count++;
165  }
166  return count;
167 }
168 
169 
170 /**
171  * @return The number of bidirectional ports in the unit.
172  */
173 int
175  unsigned count = 0;
176  for (auto &port : ports_) {
177  if (port->isInput() && port->isOutput())
178  count++;
179  }
180  return count;
181 }
182 
183 
184 /**
185  * Returns a port by the given index.
186  *
187  * The index must be greater or equal to 0 and smaller than the number of
188  * ports in the unit.
189  *
190  * @param index Index.
191  * @return The port by the given index.
192  * @exception OutOfRange If the given index is out of range.
193  */
194 Port*
195 Unit::port(int index) const {
196  if (index < 0 || index >= portCount()) {
197  string procName = "Unit::port";
198  throw OutOfRange(__FILE__, __LINE__, procName);
199  }
200  return ports_[index];
201 }
202 
203 /**
204  * Adds a port to the unit.
205  *
206  * This method can be called from Port constructor only.
207  *
208  * @param port Port to be added.
209  * @exception ComponentAlreadyExists If another port with the same name
210  * exists.
211  */
212 void
214  // check that this method is called from Port constructor only
215  assert(port.parentUnit() == NULL);
216 
217  // check that a port with same name does not exist
218  if (!hasPort(port.name())) {
219  ports_.push_back(&port);
220  return;
221  }
222 
223  string procName = "Unit::addPort";
224  throw ComponentAlreadyExists(__FILE__, __LINE__, procName);
225 }
226 
227 /**
228  * Removes the given port.
229  *
230  * This method should only be called by Port destructor.
231  *
232  * @param port Port to be removed.
233  */
234 void
236 
237  // sanity check to verify that this is called from Port's destructor
238  // only
239  assert(port.parentUnit() == NULL);
241  assert(removed);
242 }
243 
244 
245 /**
246  * Registers the unit to a machine.
247  *
248  * @param mach Machine to which the unit is to be registered.
249  * @exception ComponentAlreadyExists If there is another unit by the same
250  * name and type in the machine.
251  */
252 void
254  internalSetMachine(mach);
255  mach.addUnit(*this);
256 }
257 
258 /**
259  * Removes registration of the unit from its current machine.
260  */
261 void
263 
264  if (machine() == NULL) {
265  return;
266  }
267 
269 
270  // detach all ports from sockets
271  int ports = portCount();
272  for (int i = 0; i < ports; i++) {
273  Port* unitPort = port(i);
274  unitPort->detachAllSockets();
275  }
276 }
277 
278 
279 /**
280  * Saves the state of the object to an ObjectState tree.
281  *
282  * @return The newly created ObjectState tree.
283  */
286 
288  state->setName(OSNAME_UNIT);
289 
290  // add ports
291  for (int i = 0; i < portCount(); i++) {
292  Port* port = this->port(i);
293  state->addChild(port->saveState());
294  }
295 
296  return state;
297 }
298 
299 
300 /**
301  * Loads the state of the unit from the given ObjectState instance.
302  *
303  * @param state The ObjectState instance.
304  * @exception ObjectStateLoadingException If the given ObjectState instance
305  * is invalid or if references to
306  * sockets cannot be made.
307  */
308 void
311 
312  // create port-socket connections
313  for (int i = 0; i < state->childCount(); i++) {
314  ObjectState* child = state->child(i);
315  if (child->name() == FUPort::OSNAME_FUPORT ||
316  child->name() == RFPort::OSNAME_RFPORT ||
318  string portName = child->stringAttribute(Port::OSKEY_NAME);
319  Port* port = this->port(portName);
320  port->loadState(child);
321  }
322  }
323 }
324 
325 /**
326  * Loads its state from the given ObjectState instance without references to
327  * other components.
328  *
329  * @param state The ObjectState instance.
330  * @exception ObjectStateLoadingException If the given ObjectState instance
331  * is invalid.
332  */
333 void
335  const string procName = "Unit::loadStateWithoutReferences";
336 
337  // load ports
338  try {
339  // cannot delete all the ports because there might be guards
340  // referencing to them
341  NameSet newPortNames = portNames(state);
342  deleteOtherPorts(newPortNames);
343 
344  for (int i = 0; i < state->childCount(); i++) {
345  ObjectState* child = state->child(i);
346  string portName = child->stringAttribute(Port::OSKEY_NAME);
347 
348  if (!hasPort(portName)) {
349  if (child->name() == RFPort::OSNAME_RFPORT) {
350  // port is attached automatically
351  new RFPort(child, *this);
352  } else if (child->name() == FUPort::OSNAME_FUPORT) {
353  // port is attached automatically
354  new FUPort(child, *this);
355  } else if (child->name() ==
357  // port is attached automatically
358  new SpecialRegisterPort(child, *this);
359  }
360  }
361  }
362 
363  } catch (const Exception& exception) {
365  __FILE__, __LINE__, procName, exception.errorMessage());
366  }
367 }
368 
369 /**
370  * Deletes all the ports from the unit.
371  */
372 void
374  while (ports_.size() > 0) {
375  // the size of the vector is decreased when the code of Port
376  // destructor is executed
377  delete ports_[0];
378  }
379 }
380 
381 
382 /**
383  * Deletes all the ports which has a name that does not appear in the given
384  * name set.
385  *
386  * @param portsToLeave A set of names of ports to leave.
387  */
388 void
389 Unit::deleteOtherPorts(const NameSet& portsToLeave) {
390  for (int i = 0; i < portCount();) {
391  Port* port = this->port(i);
392  if (!AssocTools::containsKey(portsToLeave, port->name())) {
393  delete port;
394  } else {
395  i++;
396  }
397  }
398 }
399 
400 
401 /**
402  * Creates a set of port names that exists in the given ObjectState tree.
403  *
404  * @param state An ObjectState instance representing an unit.
405  * @return Set of port names.
406  * @exception KeyNotFound If the given ObjectState instance is invalid.
407  */
410  NameSet names;
411  for (int i = 0; i < state->childCount(); i++) {
412  ObjectState* child = state->child(i);
413  names.insert(child->stringAttribute(Port::OSKEY_NAME));
414  }
415 
416  return names;
417 }
418 }
TTAMachine::RFPort::OSNAME_RFPORT
static const std::string OSNAME_RFPORT
ObjectState name for register file port.
Definition: RFPort.hh:58
TTAMachine::Component::internalUnsetMachine
void internalUnsetMachine()
TTAMachine::Unit::addPort
void addPort(Port &port)
Definition: Unit.cc:213
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
ObjectState::stringAttribute
std::string stringAttribute(const std::string &name) const
Definition: ObjectState.cc:249
TTAMachine::Port::saveState
virtual ObjectState * saveState() const
Definition: Port.cc:404
ObjectStateLoadingException
Definition: Exception.hh:551
TTAMachine::Unit::removePort
virtual void removePort(Port &port)
Definition: Unit.cc:235
TTAMachine::Unit::deleteOtherPorts
void deleteOtherPorts(const NameSet &portsToLeave)
Definition: Unit.cc:389
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
OutOfRange
Definition: Exception.hh:320
TTAMachine::Component::saveState
virtual ObjectState * saveState() const
Definition: MachinePart.cc:189
TTAMachine::Unit::deleteAllPorts
void deleteAllPorts()
Definition: Unit.cc:373
TTAMachine::Unit::loadState
virtual void loadState(const ObjectState *state)
Definition: Unit.cc:309
ObjectState
Definition: ObjectState.hh:59
TTAMachine::Machine::addUnit
void addUnit(Unit &unit)
Definition: Machine.cc:175
TTAMachine::Unit::bidirPortCount
virtual int bidirPortCount() const
Definition: Unit.cc:174
ObjectState::setName
void setName(const std::string &name)
TTAMachine::Component::internalSetMachine
void internalSetMachine(Machine &machine)
TTAMachine::RFPort
Definition: RFPort.hh:45
Unit.hh
TTAMachine::Port::loadState
virtual void loadState(const ObjectState *state)
Definition: Port.cc:459
assert
#define assert(condition)
Definition: Application.hh:86
TTAMachine::Unit::ports_
PortTable ports_
Contains all the ports of the unit.
Definition: Unit.hh:96
Port.hh
TTAMachine::FUPort
Definition: FUPort.hh:46
TTAMachine::Unit::NameSet
std::set< std::string > NameSet
Set type for strings.
Definition: Unit.hh:82
TTAMachine::Unit::saveState
virtual ObjectState * saveState() const
Definition: Unit.cc:285
TTAMachine::Unit::~Unit
virtual ~Unit()
Definition: Unit.cc:84
TTAMachine::SpecialRegisterPort
Definition: SpecialRegisterPort.hh:48
ContainerTools::removeValueIfExists
static bool removeValueIfExists(ContainerType &aContainer, const ElementType &aKey)
TTAMachine::Port
Definition: Port.hh:54
TTAMachine::FUPort::OSNAME_FUPORT
static const std::string OSNAME_FUPORT
ObjectState name for FUPort.
Definition: FUPort.hh:71
Application.hh
TTAMachine::Unit::port
virtual Port * port(const std::string &name) const
Definition: Unit.cc:116
ObjectState.hh
TTAMachine::Component
Definition: MachinePart.hh:90
ObjectState::child
ObjectState * child(int index) const
Definition: ObjectState.cc:471
ObjectState::addChild
void addChild(ObjectState *child)
Definition: ObjectState.cc:376
TTAMachine::Unit::hasPort
virtual bool hasPort(const std::string &name) const
Definition: Unit.cc:96
ObjectState::childCount
int childCount() const
Machine.hh
Exception
Definition: Exception.hh:54
TTAMachine::Unit::loadStateWithoutReferences
void loadStateWithoutReferences(const ObjectState *state)
Definition: Unit.cc:334
ObjectState::name
std::string name() const
TTAMachine::Port::isOutput
virtual bool isOutput() const
Definition: Port.cc:308
TTAMachine::Unit::portCount
virtual int portCount() const
Definition: Unit.cc:135
Exception::errorMessage
std::string errorMessage() const
Definition: Exception.cc:123
TTAMachine::Unit::outputPortCount
virtual int outputPortCount(bool countBidir=false) const
Definition: Unit.cc:145
TTAMachine::Unit::portNames
static NameSet portNames(const ObjectState *state)
Definition: Unit.cc:409
TTAMachine::Unit::inputPortCount
virtual int inputPortCount(bool countBidir=false) const
Definition: Unit.cc:160
TTAMachine::SpecialRegisterPort::OSNAME_SPECIAL_REG_PORT
static const std::string OSNAME_SPECIAL_REG_PORT
ObjectState name for special register port.
Definition: SpecialRegisterPort.hh:62
TTAMachine::Component::machine
virtual Machine * machine() const
AssocTools.hh
TTAMachine::Port::name
virtual std::string name() const
Definition: Port.cc:141
TTAMachine::Unit::setMachine
virtual void setMachine(Machine &mach)
Definition: Unit.cc:253
FUPort.hh
TTAMachine::Port::OSKEY_NAME
static const std::string OSKEY_NAME
ObjectState attribute key for the name of the port.
Definition: Port.hh:82
SpecialRegisterPort.hh
ComponentAlreadyExists
Definition: Exception.hh:510
TTAMachine::Port::isInput
virtual bool isInput() const
Definition: Port.cc:298
TTAMachine::Unit::OSNAME_UNIT
static const std::string OSNAME_UNIT
ObjectState name for Unit.
Definition: Unit.hh:70
RFPort.hh
TTAMachine
Definition: Assembler.hh:48
TTAMachine::Unit::Unit
Unit(const std::string &name)
Definition: Unit.cc:59
TTAMachine::Port::detachAllSockets
virtual void detachAllSockets()
Definition: Port.cc:536
TTAMachine::Unit::unsetMachine
virtual void unsetMachine()
Definition: Unit.cc:262
InstanceNotFound
Definition: Exception.hh:304
TTAMachine::Machine
Definition: Machine.hh:73
FunctionUnit.hh
ContainerTools.hh
TTAMachine::Port::parentUnit
Unit * parentUnit() const