OpenASIP 2.2
Loading...
Searching...
No Matches
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"
35#include "Operation.hh"
36#include "FUPort.hh"
37#include "ExecutionPipeline.hh"
38#include "TCEString.hh"
39
40using std::string;
41using 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 */
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 */
88void
89SmartHWOperation::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 */
109FUPort*
110SmartHWOperation::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 &&
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 */
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 */
204void
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 */
219void
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 */
236void
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 */
252bool
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}
#define assert(condition)
static void abortProgram() __attribute__((noreturn))
static void writeToErrorLog(const std::string fileName, const int lineNumber, const std::string functionName, const std::string message, const int neededVerbosity=0)
virtual TCEString name() const
Definition Operation.cc:93
virtual int numberOfInputs() const
Definition Operation.cc:192
virtual int numberOfOutputs() const
Definition Operation.cc:202
virtual void loadState(const ObjectState *state)
SmartHWOperation(const Operation &operation, UniversalFunctionUnit &parent)
virtual void unbindPort(const TTAMachine::FUPort &port)
bool otherMandatoryInputsBound(int operand) const
const Operation & operation_
The operation represented by this SmartHWOperation instance.
TTAMachine::FUPort * port(int operand) const
virtual ~SmartHWOperation()
virtual void setName(const std::string &name)
bool is32BitOperation_
Tells whether this operation has 32 bits wide operands.
virtual void bindPort(int operand, const TTAMachine::FUPort &port)
UniversalFunctionUnit * parentUnit() const
void addPortRead(int operand, int start, int duration)
void addPortWrite(int operand, int start, int duration)
virtual bool isOpcodeSetting() const
Definition FUPort.cc:195
ExecutionPipeline * pipeline() const
virtual void bindPort(int operand, const FUPort &port)
virtual FUPort * port(int operand) const
bool isBound(const FUPort &port) const
FunctionUnit * parentUnit() const
virtual Socket * outputSocket() const
Definition Port.cc:281
virtual Socket * inputSocket() const
Definition Port.cc:261
int portCountWithWidth(int width) const
static const std::string OC_SETTING_PORT_64
Name of the 64 bit wide opcode setting port.
static bool is32BitOperation(const std::string &opName)
static const std::string OC_SETTING_PORT_32
Name of the 32 bit wide opcode setting port.
TTAMachine::FUPort & portWithWidth(int index, int width) const