OpenASIP 2.2
Loading...
Searching...
No Matches
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"
40#include "FunctionUnit.hh"
41#include "Application.hh"
42#include "ContainerTools.hh"
43#include "AssocTools.hh"
44#include "ObjectState.hh"
45
46using std::string;
47
48namespace TTAMachine {
49
50// initialization of static data members
51const 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 */
59Unit::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 */
71Unit::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 */
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 */
95bool
96Unit::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 */
115Port*
116Unit::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 */
134int
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 */
144int
145Unit::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 */
159int
160Unit::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 */
173int
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 */
194Port*
195Unit::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 */
212void
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 */
234void
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 */
252void
254 internalSetMachine(mach);
255 mach.addUnit(*this);
256}
257
258/**
259 * Removes registration of the unit from its current machine.
260 */
261void
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 */
308void
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 */
333void
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 */
372void
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 */
388void
389Unit::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}
#define assert(condition)
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
static bool removeValueIfExists(ContainerType &aContainer, const ElementType &aKey)
std::string errorMessage() const
Definition Exception.cc:123
void setName(const std::string &name)
ObjectState * child(int index) const
void addChild(ObjectState *child)
std::string stringAttribute(const std::string &name) const
std::string name() const
int childCount() const
virtual Machine * machine() const
void internalSetMachine(Machine &machine)
virtual TCEString name() const
virtual ObjectState * saveState() const
static const std::string OSNAME_FUPORT
ObjectState name for FUPort.
Definition FUPort.hh:71
void addUnit(Unit &unit)
Definition Machine.cc:175
virtual bool isInput() const
Definition Port.cc:298
virtual bool isOutput() const
Definition Port.cc:308
virtual void detachAllSockets()
Definition Port.cc:536
Unit * parentUnit() const
virtual ObjectState * saveState() const
Definition Port.cc:404
virtual void loadState(const ObjectState *state)
Definition Port.cc:459
virtual std::string name() const
Definition Port.cc:141
static const std::string OSKEY_NAME
ObjectState attribute key for the name of the port.
Definition Port.hh:82
static const std::string OSNAME_RFPORT
ObjectState name for register file port.
Definition RFPort.hh:58
static const std::string OSNAME_SPECIAL_REG_PORT
ObjectState name for special register port.
virtual void unsetMachine()
Definition Unit.cc:262
virtual bool hasPort(const std::string &name) const
Definition Unit.cc:96
void loadStateWithoutReferences(const ObjectState *state)
Definition Unit.cc:334
PortTable ports_
Contains all the ports of the unit.
Definition Unit.hh:96
void addPort(Port &port)
Definition Unit.cc:213
void deleteAllPorts()
Definition Unit.cc:373
virtual ~Unit()
Definition Unit.cc:84
virtual int portCount() const
Definition Unit.cc:135
std::set< std::string > NameSet
Set type for strings.
Definition Unit.hh:82
virtual void setMachine(Machine &mach)
Definition Unit.cc:253
virtual Port * port(const std::string &name) const
Definition Unit.cc:116
static NameSet portNames(const ObjectState *state)
Definition Unit.cc:409
virtual int bidirPortCount() const
Definition Unit.cc:174
virtual int inputPortCount(bool countBidir=false) const
Definition Unit.cc:160
virtual void loadState(const ObjectState *state)
Definition Unit.cc:309
virtual ObjectState * saveState() const
Definition Unit.cc:285
Unit(const std::string &name)
Definition Unit.cc:59
static const std::string OSNAME_UNIT
ObjectState name for Unit.
Definition Unit.hh:70
virtual int outputPortCount(bool countBidir=false) const
Definition Unit.cc:145
virtual void removePort(Port &port)
Definition Unit.cc:235
void deleteOtherPorts(const NameSet &portsToLeave)
Definition Unit.cc:389