OpenASIP  2.0
SmartHWOperation.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 SmartHWOperation.cc
26  *
27  * Implementation of SmartHWOperation class.
28  *
29  * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30  * @note rating: yellow
31  */
32 
33 #include "SmartHWOperation.hh"
34 #include "UniversalFunctionUnit.hh"
35 #include "Operation.hh"
36 #include "FUPort.hh"
37 #include "ExecutionPipeline.hh"
38 #include "TCEString.hh"
39 
40 using std::string;
41 using namespace TTAMachine;
42 
43 /**
44  * The constructor.
45  *
46  * Creates the pipeline automatically.
47  *
48  * @param operation The operation to be constructed.
49  * @param parent The parent unit of the operation.
50  * @exception ComponentAlreadyExists If there is already an operation by the
51  * same name in the given function unit.
52  * @exception InvalidName If the given operation does not have a valid name.
53  */
55  const Operation& operation, UniversalFunctionUnit& parent)
56  : HWOperation(operation.name(), parent), operation_(operation) {
59 
60  int inputs = operation.numberOfInputs();
61  int outputs = operation.numberOfOutputs();
62 
63  // create pipeline
64  ExecutionPipeline* pLine = pipeline();
65  for (int operand = 1; operand <= inputs; operand++) {
66  pLine->addPortRead(operand, 0, 1);
67  }
68  for (int operand = inputs + 1; operand <= inputs + outputs; operand++) {
69  pLine->addPortWrite(operand, 0, 1);
70  }
71 }
72 
73 /**
74  * The destructor.
75  */
77 }
78 
79 
80 /**
81  * Aborts the program. It is not allowed to set the name of SmartHWOperation.
82  * DO NOT CALL THIS METHOD!
83  *
84  * @param name Never used.
85  * @exception ComponentAlreadyExists Never thrown.
86  * @exception InvalidName Never thrown.
87  */
88 void
89 SmartHWOperation::setName(const std::string&) {
90  const string procName = "SmartHWOperation::setName";
91  const string errorMsg = "Tried to set name of SmartHWOperation!";
92  Application::writeToErrorLog(__FILE__, __LINE__, procName, errorMsg);
94 }
95 
96 /**
97  * Returns the port bound to the given operand. If the given operand is not
98  * bound yet, it is automatically bound to a port.
99  *
100  * The port to which the operand will be bound depends on the bindings
101  * of other operands. Input operands are bound to input ports and
102  * output operands to output ports, of course. If all the input
103  * operands are bound already except the given one, the given operand
104  * will be bound to the operation code setting port.
105  *
106  * @param operand The operand.
107  * @return The port to which the operand is bound.
108  */
109 FUPort*
110 SmartHWOperation::port(int operand) const {
111 
112  // if the operand is bound already, just return the port
113  if (HWOperation::port(operand) != NULL) {
114  return HWOperation::port(operand);
115  }
116 
117  bool input = true;
118 
119  // check whether the operand is input or output operand
120  if (operand > operation_.numberOfInputs() +
122  return NULL;
123  } else if (operand > operation_.numberOfInputs()) {
124  input = false;
125  }
126 
127  int bitWidth = is32BitOperation_ ? 32 : 64;
128  int portCount = parentUnit()->portCountWithWidth(bitWidth);
129 
130  if (input) {
131  if (otherMandatoryInputsBound(operand)) {
132  // bind to opcode port if other inputs are bound already
133  FUPort* opcodePort;
134  if (is32BitOperation_) {
135  opcodePort =
136  static_cast<FunctionUnit*>(parentUnit())->operationPort(
138  } else {
139  opcodePort =
140  static_cast<FunctionUnit*>(parentUnit())->operationPort(
142  }
143  const_cast<SmartHWOperation*>(this)->
144  HWOperation::bindPort(operand, *opcodePort);
145  return opcodePort;
146 
147  } else {
148  // bind to a non-opcode input port otherwise
149  for (int i = 0; i < portCount; i++) {
150  FUPort& port = parentUnit()->portWithWidth(i, bitWidth);
151  if (!isBound(port) && port.inputSocket() != NULL &&
152  !port.isOpcodeSetting()) {
153  const_cast<SmartHWOperation*>(this)->
154  HWOperation::bindPort(operand, port);
155  return &port;
156  }
157  }
158  }
159 
160  } else {
161  // bind to some output port
162  for (int i = 0; i < portCount; i++) {
163  FUPort& port = parentUnit()->portWithWidth(i, bitWidth);
164  if (!isBound(port) && port.outputSocket() != NULL) {
165  const_cast<SmartHWOperation*>(this)->
166  HWOperation::bindPort(operand, port);
167  return &port;
168  }
169  }
170  }
171 
172  assert(false);
173 
174  // dummy return to avoid compilation warning
175  return NULL;
176 }
177 
178 
179 /**
180  * Returns the parent unit of the operation.
181  *
182  * @return The parent unit.
183  */
186  FunctionUnit* parent = HWOperation::parentUnit();
187  UniversalFunctionUnit* uFU =
188  dynamic_cast<UniversalFunctionUnit*>(parent);
189  assert(uFU != NULL);
190  return uFU;
191 }
192 
193 
194 /**
195  * Aborts the program. It is not allowed to bind ports manually. DO NOT
196  * CALL THIS METHOD!
197  *
198  * @param operand Never used.
199  * @param port Never used.
200  * @exception IllegalRegistration Never thrown.
201  * @exception ComponentAlreadyExists Never thrown.
202  * @exception OutOfRange Never thrown.
203  */
204 void
206  const string procName = "SmartHWOperation::bindPort";
207  const string errorMsg =
208  "Tried to bind port of SmartHWOperation manually!";
209  Application::writeToErrorLog(__FILE__, __LINE__, procName, errorMsg);
211 }
212 
213 /**
214  * Aborts the program. It is not allowed to unbind ports manually. DO NOT
215  * CALL THIS METHOD!
216  *
217  * @param port Never used.
218  */
219 void
221  const string procName = "SmartHWOperation::unbindPort";
222  const string errorMsg =
223  "Tried unbind port of SmartHWOperation manually!";
224  Application::writeToErrorLog(__FILE__, __LINE__, procName, errorMsg);
226 }
227 
228 
229 /**
230  * Aborts the program. It is not allowed to load state of SmartHWOperation
231  * from an ObjectState tree. DO NOT CALL THIS METHOD!
232  *
233  * @param state Never used.
234  * @exception ObjectStateLoadingException Never thrown.
235  */
236 void
238  const string procName = "SmartHWOperation::loadState";
239  const string errorMsg =
240  "Tried load state of SmartHWOperation from an ObjectState tree!";
241  Application::writeToErrorLog(__FILE__, __LINE__, procName, errorMsg);
243 }
244 
245 /**
246  * Tells whether other input operands except the given one are bound to some
247  * port.
248  *
249  * @param operand The operand.
250  * @return True if other inputs are bound, otherwise false.
251  */
252 bool
254 
255  assert(operand <= operation_.numberOfInputs());
256 
257  for (int opIndex = 1; opIndex <= operation_.numberOfInputs();
258  opIndex++) {
259  if (opIndex == operand) {
260  continue;
261  } else {
262  if (HWOperation::port(opIndex) == NULL) {
263  return false;
264  }
265  }
266  }
267 
268  return true;
269 }
TTAMachine::Port::inputSocket
virtual Socket * inputSocket() const
Definition: Port.cc:261
UniversalFunctionUnit::OC_SETTING_PORT_32
static const std::string OC_SETTING_PORT_32
Name of the 32 bit wide opcode setting port.
Definition: UniversalFunctionUnit.hh:66
UniversalFunctionUnit::is32BitOperation
static bool is32BitOperation(const std::string &opName)
Definition: UniversalFunctionUnit.cc:358
UniversalFunctionUnit::portCountWithWidth
int portCountWithWidth(int width) const
Definition: UniversalFunctionUnit.cc:164
SmartHWOperation::setName
virtual void setName(const std::string &name)
Definition: SmartHWOperation.cc:89
TTAMachine::FUPort::isOpcodeSetting
virtual bool isOpcodeSetting() const
Definition: FUPort.cc:195
TTAMachine::HWOperation
Definition: HWOperation.hh:52
UniversalFunctionUnit::portWithWidth
TTAMachine::FUPort & portWithWidth(int index, int width) const
Definition: UniversalFunctionUnit.cc:190
ExecutionPipeline.hh
Application::writeToErrorLog
static void writeToErrorLog(const std::string fileName, const int lineNumber, const std::string functionName, const std::string message, const int neededVerbosity=0)
Definition: Application.cc:224
Operation::numberOfInputs
virtual int numberOfInputs() const
Definition: Operation.cc:192
SmartHWOperation::parentUnit
UniversalFunctionUnit * parentUnit() const
Definition: SmartHWOperation.cc:185
ObjectState
Definition: ObjectState.hh:59
UniversalFunctionUnit
Definition: UniversalFunctionUnit.hh:50
UniversalFunctionUnit::OC_SETTING_PORT_64
static const std::string OC_SETTING_PORT_64
Name of the 64 bit wide opcode setting port.
Definition: UniversalFunctionUnit.hh:68
SmartHWOperation
Definition: SmartHWOperation.hh:47
SmartHWOperation::operation_
const Operation & operation_
The operation represented by this SmartHWOperation instance.
Definition: SmartHWOperation.hh:66
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
TCEString.hh
assert
#define assert(condition)
Definition: Application.hh:86
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TTAMachine::FUPort
Definition: FUPort.hh:46
SmartHWOperation::~SmartHWOperation
virtual ~SmartHWOperation()
Definition: SmartHWOperation.cc:76
SmartHWOperation.hh
UniversalFunctionUnit.hh
TTAMachine::HWOperation::isBound
bool isBound(const FUPort &port) const
Definition: HWOperation.cc:338
TTAMachine::ExecutionPipeline::addPortRead
void addPortRead(int operand, int start, int duration)
Definition: ExecutionPipeline.cc:141
Operation.hh
Operation
Definition: Operation.hh:59
SmartHWOperation::port
TTAMachine::FUPort * port(int operand) const
Definition: SmartHWOperation.cc:110
SmartHWOperation::loadState
virtual void loadState(const ObjectState *state)
Definition: SmartHWOperation.cc:237
FUPort.hh
SmartHWOperation::bindPort
virtual void bindPort(int operand, const TTAMachine::FUPort &port)
Definition: SmartHWOperation.cc:205
SmartHWOperation::unbindPort
virtual void unbindPort(const TTAMachine::FUPort &port)
Definition: SmartHWOperation.cc:220
TTAMachine::Port::outputSocket
virtual Socket * outputSocket() const
Definition: Port.cc:281
TTAMachine::HWOperation::pipeline
ExecutionPipeline * pipeline() const
Definition: HWOperation.cc:201
TTAMachine::ExecutionPipeline
Definition: ExecutionPipeline.hh:55
TTAMachine::ExecutionPipeline::addPortWrite
void addPortWrite(int operand, int start, int duration)
Definition: ExecutionPipeline.cc:167
TTAMachine
Definition: Assembler.hh:48
Application::abortProgram
static void abortProgram() __attribute__((noreturn))
Definition: Application.cc:266
Operation::numberOfOutputs
virtual int numberOfOutputs() const
Definition: Operation.cc:202
SmartHWOperation::otherMandatoryInputsBound
bool otherMandatoryInputsBound(int operand) const
Definition: SmartHWOperation.cc:253
SmartHWOperation::SmartHWOperation
SmartHWOperation(const Operation &operation, UniversalFunctionUnit &parent)
Definition: SmartHWOperation.cc:54
SmartHWOperation::is32BitOperation_
bool is32BitOperation_
Tells whether this operation has 32 bits wide operands.
Definition: SmartHWOperation.hh:68