OpenASIP 2.2
Loading...
Searching...
No Matches
FUPort.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 FUPort.cc
26 *
27 * Implementation of class FUPort.
28 *
29 * @author Lasse Laasonen 2003 (lasse.laasonen-no.spam-tut.fi)
30 * @note reviewed 14 Jun 2004 by am, tr, ao, ll
31 * @note rating: red
32 */
33
34#include <string>
35#include <set>
36
37#include "Machine.hh"
38#include "Guard.hh"
39#include "FUPort.hh"
40#include "FunctionUnit.hh"
41#include "HWOperation.hh"
42#include "MOMTextGenerator.hh"
43#include "ObjectState.hh"
44
45using std::string;
46using std::set;
47using boost::format;
48
49namespace TTAMachine {
50
51// initialization of static data members
52const string FUPort::OSNAME_FUPORT = "fu_port";
53const string FUPort::OSKEY_TRIGGERING = "triggering";
54const string FUPort::OSKEY_OPCODE_SETTING = "oc_setting";
55const string FUPort::OSKEY_NO_REGISTER = "no_register";
56/**
57 * Constructor.
58 *
59 * @param name Name of the port.
60 * @param width Bit width of the port.
61 * @param parent The function unit to which the port belongs.
62 * @param triggers If true, writing (or reading) this port starts the
63 * execution of a new operation.
64 * @param setsOpcode If true, writing (or reading) this port selects the
65 * operation to be executed. Opcode-setting ports must
66 * be triggering.
67 * @param noRegister If true, the port do not have internal register.
68 * @exception ComponentAlreadyExists If the function unit already has another
69 * port by the same name or another port
70 * that sets operation code.
71 * @exception OutOfRange If the given bit width is less or equal to zero.
72 * @exception IllegalParameters If setsOpcode argument is true and
73 * isTriggering false.
74 * @exception InvalidName If the given name is not a valid component name.
75 */
77 const std::string& name, int width, FunctionUnit& parent, bool triggers,
78 bool setsOpcode, bool noRegister)
79 : BaseFUPort(name, width, parent),
80 triggers_(triggers),
81 setsOpcode_(setsOpcode),
82 noRegister_(noRegister) {
83 const std::string procName = "FUPort::FUPort";
84
85 if (setsOpcode && !triggers) {
86 throw IllegalParameters(__FILE__, __LINE__, procName);
87 }
88
89 // check that parent unit will not have two operation code setting
90 // ports
91 if (setsOpcode) {
92 for (int i = 0; i < parent.portCount(); i++) {
93 BaseFUPort* port = parent.port(i);
94 if (port->isOpcodeSetting() && port != this) {
96 __FILE__, __LINE__, procName);
97 }
98 }
99 }
100}
101
102/**
103 * Constructor.
104 *
105 * This constructor does not check that the parent unit will not have
106 * two operation code setting ports. This constructor is used by
107 * UniversalFUPort class.
108 *
109 * @param name Name of the port.
110 * @param width Bit width of the port.
111 * @param parent The function unit to which the port belongs.
112 * @param triggers If true, writing (or reading) this port starts the
113 * execution of a new operation.
114 * @param setsOpcode If true, writing (or reading) this port selects the
115 * operation to be executed. Opcode-setting ports must
116 * be triggering.
117 * @param noRegister If true, the port do not have internal register.
118 * @param dummy This parameter is not used and exists only to make some
119 * difference to the other constructor.
120 * @exception ComponentAlreadyExists If the function unit already has another
121 * port by the same name.
122 * @exception OutOfRange If the given bit width is less or equal to zero.
123 * @exception IllegalParameters If setsOpcode argument is true and
124 * isTriggering false.
125 * @exception InvalidName If the given name is not a valid component name.
126 */
128 const std::string& name, int width, FunctionUnit& parent, bool triggers,
129 bool setsOpcode, bool noRegister, bool /*dummy*/)
130 : BaseFUPort(name, width, parent),
131 triggers_(triggers),
132 setsOpcode_(setsOpcode),
133 noRegister_(noRegister) {
134 if (setsOpcode != triggers) {
135 const std::string procName = "FUPort::FUPort";
136 const std::string error = "Port must trigger iff sets opcode.";
137 throw IllegalParameters(__FILE__, __LINE__, procName, error);
138 }
139}
140
141/**
142 * Constructor.
143 *
144 * Loads its state from the given ObjectState instance but does not create
145 * connections to sockets. This constructor is used when the state of a
146 * function unit is loaded. Do not use this constructor.
147 *
148 * @param state The ObjectState instance.
149 * @param parent The parent function unit which contains the port.
150 * @exception ObjectStateLoadingException If the given ObjectState instance
151 * is invalid.
152 */
153FUPort::FUPort(const ObjectState* state, Unit& parent)
154 : BaseFUPort(state, parent), triggers_(false), setsOpcode_(false) {
156
157 if (setsOpcode_ != triggers_) {
158 const std::string procName = "FUPort::FUPort";
159 const std::string error = "Port must trigger iff sets opcode.";
160 throw ObjectStateLoadingException(__FILE__, __LINE__, procName,
161 error);
162 }
163}
164
165/**
166 * Destructor.
167 */
172
173
174/**
175 * Returns true if reading (or writing) this port starts the execution of a
176 * new operation, otherwise false.
177 *
178 * @return True if reading (or writing) this port starts the execution of a
179 * new operation, otherwise false.
180 */
181bool
183 return triggers_;
184}
185
186
187/**
188 * Returns true if reading (or writing) this port selects the operation to be
189 * executed, otherwise false.
190 *
191 * @return True if reading (or writing) this port selects the operation to be
192 * executed, otherwise false.
193 */
194bool
196 return setsOpcode_;
197}
198
199
200/**
201 * Sets/unsets the port to a triggering and opcode setting.
202 *
203 * Triggering port is always the opcode setting port in TCE v1.0 and
204 * only one port can trigger in TCE v1.0.
205 * If ports parent unit already has a triggering port this ports triggering
206 * status is removed.
207 *
208 * @param triggers When true, the port is set to a triggering and opcode
209 * setting port.
210 */
211void
212FUPort::setTriggering(bool triggers) {
213 if (triggers) {
214 setsOpcode_ = true;
215
216 FunctionUnit* parent = this->parentUnit();
217 if (parent != NULL) {
218 for (int i = 0; i < parent->portCount(); i++) {
219 BaseFUPort* port = parent->port(i);
220 if (port->isTriggering() && port != this) {
221 dynamic_cast<FUPort*>(port)->setTriggering(false);
222 break; // only one other port can be triggering
223 }
224 }
225 }
226 } else {
227 setsOpcode_ = false;
228 }
229 triggers_ = triggers;
230}
231
232
233/**
234 * Saves the state of the object to an ObjectState instance.
235 *
236 * @return The newly created ObjectState instance.
237 */
247
248
249/**
250 * Loads the state of the object from the given ObjectState instance.
251 *
252 * @param state The ObjectState instance.
253 * @exception ObjectStateLoadingException If an error occurs while loading
254 * the state.
255 */
256void
258 const string procName = "FUPort::loadState";
259
260 if (state->name() != OSNAME_FUPORT) {
261 throw ObjectStateLoadingException(__FILE__, __LINE__, procName);
262 }
263
267}
268
269/**
270 * Returns a description of operand bindings of the port.
271 *
272 * This returned string can be used to compare the bindings of to FUPorts using a string
273 * comparison because Operations are listed in alphapetical order.
274 *
275 * @todo this should be moved to BaseFUPort.
276 *
277 * @return String describing the operand bindings of the port.
278 */
279std::string
281 return bindingString_;
282}
283
284/**
285 * Updates the string of bindings of the port.
286 *
287 * Separated to another method so it's not recomputed every time it's asked.
288 *
289 * @todo this should be moved to BaseFUPort.
290 *
291 * @return String of bindings. Operations are listed in alphapetical order.
292 */
293void
295
296 if (parentUnit() == NULL) {
297 bindingString_ = "";
298 return;
299 }
300
301 set<string> bindings;
302 for (int i = 0; i < parentUnit()->operationCount(); i++) {
303 if (parentUnit()->operation(i)->isBound(*this)) {
304 string binding = parentUnit()->operation(i)->name();
305 binding += ".";
306 binding += Conversion::toString(
307 parentUnit()->operation(i)->io(*this));
308 bindings.insert(binding);
309 }
310 }
311 set<string>::const_iterator iter = bindings.begin();
312 string result;
313 while (iter != bindings.end()) {
314 result += (*iter);
315 iter++;
316 if (iter != bindings.end()) {
317 result += ",";
318 }
319 }
320 bindingString_ = result;
321}
322
323
324/**
325 * Checks if the two ports have same architecture.
326 *
327 * Compares also operation bindings. Names are allowed to differ.
328 *
329 * @return True if the two ports have equal architecture.
330 */
331bool
333
334 if (triggers_ != port->isTriggering()) {
335 return false;
336 }
337 if (setsOpcode_ != port->isOpcodeSetting()) {
338 return false;
339 }
340 if (width() != port->width()) {
341 return false;
342 }
343 if (bindingString() != port->bindingString()) {
344 return false;
345 }
346 return true;
347}
348
349
350/**
351 * Cleans up the guards that refer to this port.
352 */
353void
355
356 // delete guards referencing to this port
357 Unit* parent = Port::parentUnit();
358 Machine* machine = parent->machine();
359
360 if (machine != NULL) {
362
363 for (int busIndex = 0; busIndex < navi.count(); busIndex++) {
364 Bus* bus = navi.item(busIndex);
365 int guardIndex = 0;
366
367 while (guardIndex < bus->guardCount()) {
368 Guard* guard = bus->guard(guardIndex);
369 PortGuard* portGuard = dynamic_cast<PortGuard*>(guard);
370
371 if (portGuard != NULL && portGuard->port() == this) {
372 // guard is removed automatically from bus
373 delete portGuard;
374 } else {
375 guardIndex++;
376 }
377 }
378 }
379 }
380}
381
382
383
384/**
385 * Removes all the operand bindings of the parent unit that use this port.
386 */
387void
389
390 // NOTE! Cannot call directly FUPort::parentUnit because this method is
391 // called from FUPort's destructor and it is possible that FunctionUnit
392 // instance does not exist any more. This is the case if FunctionUnit is
393 // deleted because its destructor is called before Unit's destructor.
395 FunctionUnit* parentFU = dynamic_cast<FunctionUnit*>(parentUnit);
396
397 if (parentFU != NULL) {
398 for (int i = 0; i < parentFU->operationCount(); i++) {
399 HWOperation* operation = parentFU->operation(i);
400 operation->unbindPort(*this);
401 }
402 }
403 bindingString_ = "";
404}
405
406
407/**
408 * Loads its state from the given ObjectState instance but does not create
409 * connections to sockets.
410 *
411 * @param state The ObjectState instance.
412 * @exception ObjectStateLoadingException If the given ObjectState instance
413 * is invalid.
414 */
415void
417 const string procName = "FUPort::loadStateWithoutReferences";
418
419 try {
423
424 // Check that parent unit does not contain another operation
425 // code setting port. Cannot call directly setOpcodeSetting
426 // method because FunctionUnit part of parent unit may not have
427 // been instantiated when this method is called (for example if
428 // FunctionUnit is created by FunctionUnit(ObjectState*).
429
431 MOMTextGenerator textGenerator;
432
433 for (int i = 0; i < parentUnit->portCount(); i++) {
434 Port* port = parentUnit->port(i);
435 BaseFUPort* fuPort = dynamic_cast<BaseFUPort*>(port);
436 assert(fuPort != NULL);
437 if (fuPort->isOpcodeSetting() && fuPort != this) {
438 format text = textGenerator.text(
440 text % parentUnit->name();
442 __FILE__, __LINE__, procName, text.str());
443 }
444 }
445
446 setsOpcode_ = true;
447 if (!triggers_) {
448 format text = textGenerator.text(
450 text % name() % parentUnit->name();
452 __FILE__, __LINE__, procName, text.str());
453 }
454 }
455
456 } catch (Exception& e) {
458 __FILE__, __LINE__, procName, e.errorMessage());
459 }
461}
462
463/*
464 * Returns true if FU port do not have register.
465 *
466 *
467 */
468bool
470 return noRegister_;
471}
472
473/*
474 * Defines whether or not FUPort has internal register.
475 *
476 *
477 */
478void
479FUPort::setNoRegister(bool noRegister) {
481}
482
483}
#define assert(condition)
TTAMachine::Machine * machine
the architecture definition of the estimated processor
find Finds info of the inner loops in the false
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)
bool boolAttribute(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 width() const
virtual bool isOpcodeSetting() const =0
virtual void loadState(const ObjectState *state)
virtual bool isTriggering() const =0
virtual ObjectState * saveState() const
Guard * guard(int index) const
Definition Bus.cc:456
virtual Machine * machine() const
virtual TCEString name() const
void cleanupOperandBindings() const
Definition FUPort.cc:388
void loadStateWithoutReferences(const ObjectState *state)
Definition FUPort.cc:416
void setNoRegister(bool noRegister)
Definition FUPort.cc:479
virtual bool isTriggering() const
Definition FUPort.cc:182
void setTriggering(bool triggers)
Definition FUPort.cc:212
virtual bool isOpcodeSetting() const
Definition FUPort.cc:195
static const std::string OSNAME_FUPORT
ObjectState name for FUPort.
Definition FUPort.hh:71
static const std::string OSKEY_OPCODE_SETTING
ObjectState attribute key for operand code setting feature.
Definition FUPort.hh:75
std::string bindingString_
Binding string describes the operation bindings of of the port to allow fast binding comparison.
Definition FUPort.hh:96
void updateBindingString() const
Definition FUPort.cc:294
bool triggers_
Specifies whether this is a triggering port.
Definition FUPort.hh:91
static const std::string OSKEY_NO_REGISTER
ObjectState attribute key for noRegister setting feature.
Definition FUPort.hh:77
std::string bindingString() const
Definition FUPort.cc:280
virtual ~FUPort()
Definition FUPort.cc:168
virtual ObjectState * saveState() const
Definition FUPort.cc:239
FUPort(const std::string &name, int width, FunctionUnit &parent, bool triggers, bool setsOpcode, bool noRegister=false)
Definition FUPort.cc:76
static const std::string OSKEY_TRIGGERING
ObjectState attribute key for triggering feature.
Definition FUPort.hh:73
bool noRegister() const
Definition FUPort.cc:469
void cleanupGuards() const
Definition FUPort.cc:354
virtual void loadState(const ObjectState *state)
Definition FUPort.cc:257
bool setsOpcode_
Specifies whether this is an operation selecting port.
Definition FUPort.hh:93
bool isArchitectureEqual(FUPort *port)
Definition FUPort.cc:332
virtual HWOperation * operation(const std::string &name) const
virtual int operationCount() const
virtual BaseFUPort * port(const std::string &name) const
virtual void unbindPort(const FUPort &port)
const std::string & name() const
bool isBound(const FUPort &port) const
ComponentType * item(int index) const
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
FUPort * port() const
Unit * parentUnit() const
virtual std::string name() const
Definition Port.cc:141
virtual int portCount() const
Definition Unit.cc:135
virtual boost::format text(int textId)