OpenASIP  2.0
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 
45 using std::string;
46 using std::set;
47 using boost::format;
48 
49 namespace TTAMachine {
50 
51 // initialization of static data members
52 const string FUPort::OSNAME_FUPORT = "fu_port";
53 const string FUPort::OSKEY_TRIGGERING = "triggering";
54 const string FUPort::OSKEY_OPCODE_SETTING = "oc_setting";
55 const 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  */
153 FUPort::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  */
169  cleanupGuards();
171 }
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  */
181 bool
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  */
194 bool
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  */
211 void
212 FUPort::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  */
241  state->setName(OSNAME_FUPORT);
245  return state;
246 }
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  */
256 void
258  const string procName = "FUPort::loadState";
259 
260  if (state->name() != OSNAME_FUPORT) {
261  throw ObjectStateLoadingException(__FILE__, __LINE__, procName);
262  }
263 
265  BaseFUPort::loadState(state);
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  */
279 std::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  */
293 void
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  */
331 bool
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  */
353 void
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  */
387 void
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  */
415 void
417  const string procName = "FUPort::loadStateWithoutReferences";
418 
419  try {
422  if (state->boolAttribute(OSKEY_OPCODE_SETTING)) {
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  */
468 bool
470  return noRegister_;
471 }
472 
473 /*
474  * Defines whether or not FUPort has internal register.
475  *
476  *
477  */
478 void
479 FUPort::setNoRegister(bool noRegister) {
481 }
482 
483 }
TTAMachine::Guard
Definition: Guard.hh:55
TTAMachine::FUPort::noRegister
bool noRegister() const
Definition: FUPort.cc:469
TTAMachine::FUPort::bindingString_
std::string bindingString_
Binding string describes the operation bindings of of the port to allow fast binding comparison.
Definition: FUPort.hh:96
TTAMachine::FUPort::cleanupOperandBindings
void cleanupOperandBindings() const
Definition: FUPort.cc:388
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
TTAMachine::PortGuard::port
FUPort * port() const
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
TTAMachine::FUPort::isOpcodeSetting
virtual bool isOpcodeSetting() const
Definition: FUPort.cc:195
TTAMachine::HWOperation
Definition: HWOperation.hh:52
ObjectStateLoadingException
Definition: Exception.hh:551
TTAMachine::BaseFUPort::parentUnit
FunctionUnit * parentUnit() const
Definition: BaseFUPort.cc:96
TTAMachine::Bus
Definition: Bus.hh:53
TTAMachine::BaseFUPort
Definition: BaseFUPort.hh:44
TTAMachine::FUPort::~FUPort
virtual ~FUPort()
Definition: FUPort.cc:168
TTAMachine::FUPort::setNoRegister
void setNoRegister(bool noRegister)
Definition: FUPort.cc:479
TTAMachine::FUPort::triggers_
bool triggers_
Specifies whether this is a triggering port.
Definition: FUPort.hh:91
TTAMachine::FUPort::OSKEY_NO_REGISTER
static const std::string OSKEY_NO_REGISTER
ObjectState attribute key for noRegister setting feature.
Definition: FUPort.hh:77
ObjectState
Definition: ObjectState.hh:59
TTAMachine::FUPort::setsOpcode_
bool setsOpcode_
Specifies whether this is an operation selecting port.
Definition: FUPort.hh:93
TTAMachine::FunctionUnit::port
virtual BaseFUPort * port(const std::string &name) const
Definition: FunctionUnit.cc:145
TTAMachine::Machine::Navigator::count
int count() const
Texts::TextGenerator::text
virtual boost::format text(int textId)
Definition: TextGenerator.cc:94
ObjectState::setName
void setName(const std::string &name)
TTAMachine::FUPort::isTriggering
virtual bool isTriggering() const
Definition: FUPort.cc:182
Conversion::toString
static std::string toString(const T &source)
MOMTextGenerator::TXT_OPCODE_SETTING_MUST_BE_TRIGGERING
@ TXT_OPCODE_SETTING_MUST_BE_TRIGGERING
Definition: MOMTextGenerator.hh:66
TTAMachine::BaseFUPort::isOpcodeSetting
virtual bool isOpcodeSetting() const =0
TTAMachine::FUPort::updateBindingString
void updateBindingString() const
Definition: FUPort.cc:294
assert
#define assert(condition)
Definition: Application.hh:86
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TTAMachine::FUPort
Definition: FUPort.hh:46
TTAMachine::BaseFUPort::loadState
virtual void loadState(const ObjectState *state)
Definition: BaseFUPort.cc:153
TTAMachine::FUPort::bindingString
std::string bindingString() const
Definition: FUPort.cc:280
IllegalParameters
Definition: Exception.hh:113
HWOperation.hh
TTAMachine::Unit
Definition: Unit.hh:51
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
TTAMachine::FUPort::cleanupGuards
void cleanupGuards() const
Definition: FUPort.cc:354
TTAMachine::FUPort::saveState
virtual ObjectState * saveState() const
Definition: FUPort.cc:239
TTAMachine::Port
Definition: Port.hh:54
TTAMachine::HWOperation::unbindPort
virtual void unbindPort(const FUPort &port)
Definition: HWOperation.cc:296
TTAMachine::FUPort::OSNAME_FUPORT
static const std::string OSNAME_FUPORT
ObjectState name for FUPort.
Definition: FUPort.hh:71
TTAMachine::FUPort::OSKEY_OPCODE_SETTING
static const std::string OSKEY_OPCODE_SETTING
ObjectState attribute key for operand code setting feature.
Definition: FUPort.hh:75
TTAMachine::HWOperation::isBound
bool isBound(const FUPort &port) const
Definition: HWOperation.cc:338
ObjectState.hh
Guard.hh
TTAMachine::FunctionUnit::operationCount
virtual int operationCount() const
Definition: FunctionUnit.cc:419
Machine.hh
Exception
Definition: Exception.hh:54
ObjectState::name
std::string name() const
TTAMachine::BaseFUPort::isTriggering
virtual bool isTriggering() const =0
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
TTAMachine::Unit::portCount
virtual int portCount() const
Definition: Unit.cc:135
Exception::errorMessage
std::string errorMessage() const
Definition: Exception.cc:123
TTAMachine::FUPort::noRegister_
bool noRegister_
Definition: FUPort.hh:98
TTAMachine::BaseFUPort::saveState
virtual ObjectState * saveState() const
Definition: BaseFUPort.cc:136
false
find Finds info of the inner loops in the false
Definition: InnerLoopFinder.cc:81
TTAMachine::Component::machine
virtual Machine * machine() const
TTAMachine::Port::name
virtual std::string name() const
Definition: Port.cc:141
MOMTextGenerator
Definition: MOMTextGenerator.hh:40
ObjectState::boolAttribute
bool boolAttribute(const std::string &name) const
Definition: ObjectState.cc:338
FUPort.hh
TTAMachine::FUPort::setTriggering
void setTriggering(bool triggers)
Definition: FUPort.cc:212
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
ComponentAlreadyExists
Definition: Exception.hh:510
MOMTextGenerator.hh
ObjectState::intAttribute
int intAttribute(const std::string &name) const
Definition: ObjectState.cc:276
TTAMachine::FUPort::loadStateWithoutReferences
void loadStateWithoutReferences(const ObjectState *state)
Definition: FUPort.cc:416
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
TTAMachine::PortGuard
Definition: Guard.hh:99
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
TTAMachine
Definition: Assembler.hh:48
TTAMachine::FUPort::loadState
virtual void loadState(const ObjectState *state)
Definition: FUPort.cc:257
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
MOMTextGenerator::TXT_OPCODE_SETTING_PORT_EXISTS
@ TXT_OPCODE_SETTING_PORT_EXISTS
Definition: MOMTextGenerator.hh:65
TTAMachine::BaseFUPort::width
virtual int width() const
Definition: BaseFUPort.cc:109
ObjectState::setAttribute
void setAttribute(const std::string &name, const std::string &value)
Definition: ObjectState.cc:100
TTAMachine::FUPort::FUPort
FUPort(const std::string &name, int width, FunctionUnit &parent, bool triggers, bool setsOpcode, bool noRegister=false)
Definition: FUPort.cc:76
TTAMachine::Machine
Definition: Machine.hh:73
TTAMachine::FUPort::isArchitectureEqual
bool isArchitectureEqual(FUPort *port)
Definition: FUPort.cc:332
FunctionUnit.hh
TTAMachine::FUPort::OSKEY_TRIGGERING
static const std::string OSKEY_TRIGGERING
ObjectState attribute key for triggering feature.
Definition: FUPort.hh:73
TTAMachine::Port::parentUnit
Unit * parentUnit() const