OpenASIP  2.0
MultiLatencyOperationExecutor.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2010 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 MultiLatencyOperationExecutor.cc
26  *
27  * Definition of MultiLatencyOperationExecutor class.
28  *
29  * @author Pekka Jääskeläinen 2008,2010 (pekka.jaaskelainen-no.spam-tut.fi)
30  * @note rating: red
31  */
32 
34 #include "Operation.hh"
35 #include "OperationContext.hh"
36 #include "PortState.hh"
37 #include "SimulatorToolbox.hh"
38 #include "OperationPool.hh"
39 #include "Application.hh"
40 #include "HWOperation.hh"
42 
43 using std::vector;
44 using std::string;
45 
46 //#define DEBUG_OPERATION_SIMULATION
47 
48 /**
49  * Constructor.
50  *
51  * @param parent Parent of the OperationExecutor.
52  * @param hwOp The hardware operation to simulate.
53  */
55  FUState& parent, TTAMachine::HWOperation& hwOp) :
56  OperationExecutor(parent), context_(NULL), hwOperation_(&hwOp),
57  freeExecOp_(NULL), execOperationsInitialized_(false),
58  opSimulator_(NULL) {
59 
60  OperationPool ops;
61  operation_ = &ops.operation(hwOp.name().c_str());
62  /**
63  * Initialize a list of pending executing operations that is the
64  * size of the maximum on flight operations. Each element in the
65  * list is initialized to contain a large enough I/O vector for
66  * inputs and outputs. In addition, the models for simulating the
67  * output latencies are initialized so it's as fast as possible
68  * to trigger new operations.
69  */
70  const std::size_t inputOperands = operation_->numberOfInputs();
71  const std::size_t outputOperands = operation_->numberOfOutputs();
72  const std::size_t operandCount = inputOperands + outputOperands;
73 
74  hasPendingOperations_ = true;
76  eop.iostorage_.resize(operandCount);
77  executingOps_.resize(hwOp.latency(), eop);
78 
79 }
80 
81 /**
82  * Destructor.
83  */
85 }
86 
87 
90  ExecutingOperation* execOp = NULL;
91  if (freeExecOp_ != NULL) {
92  execOp = freeExecOp_;
93  freeExecOp_ = NULL;
94  } else {
95  for (std::size_t i = 0; i < executingOps_.size(); ++i) {
96  execOp = &executingOps_[i];
97  if (execOp->free_) {
98  break;
99  }
100  }
101  }
102  assert(execOp != NULL &&
103  "Did not find a free ExecutingOperation.");
104  return *execOp;
105 }
106 
107 /**
108  * Starts new operation.
109  *
110  * First original inputs and outputs are stored. Then outputs of the operation
111  * are stored. Then operation is triggered.
112  *
113  * @param op Operation to be triggered.
114  * @todo This can be optimized a lot: try to initialize the vector as rarely
115  * as possible.
116  */
117 void
119 
120  const std::size_t inputOperands = operation_->numberOfInputs();
121  const std::size_t outputOperands = operation_->numberOfOutputs();
122  const std::size_t operandCount = inputOperands + outputOperands;
124 
126  // cannot initialize in the constructor as the
127  // FUPort -> operand bindings have not been initialized at
128  // that point
129  for (std::size_t i = 0; i < executingOps_.size(); ++i) {
130  ExecutingOperation& execOp = executingOps_[i];
131  execOp.initIOVec();
132  // set the widths of the storage values to enforce correct
133  // clipping of values
134  for (std::size_t o = 1; o <= operandCount; ++o) {
135  execOp.iostorage_[o - 1].setBitWidth(
136  binding(o).value().width());
137  }
138  // set operation output storages to point to the corresponding
139  // output ports and setup their delayed appearance
140  for (std::size_t o = inputOperands + 1; o <= operandCount; ++o) {
141  PortState& port = binding(o);
142  const int resultLatency = hwOperation_->latency(o);
143 
145  execOp.iostorage_[o - 1], port, resultLatency);
146  execOp.pendingResults_.push_back(res);
147  }
148  }
150  }
151  // copy the input values to the on flight operation executor model
152  for (std::size_t i = 1; i <= inputOperands; ++i) {
153  execOp.iostorage_[i - 1] = binding(i).value();
154  }
155 #ifdef DEBUG_OPERATION_SIMULATION
157  << &execOp << " (" << execOp.operation().name()
158  << ") started" << std::endl;
159 #endif
160  execOp.start();
161  hasPendingOperations_ = true;
162 }
163 
164 /**
165  * Advances clock by one cycle.
166  */
167 void
169 
170  bool foundActiveOperation = false;
171  size_t executingOpCount = executingOps_.size();
172  for (std::size_t i = 0; i < executingOpCount; ++i) {
173  ExecutingOperation& execOp = executingOps_[i];
174  if (execOp.free_) {
175  freeExecOp_ = &execOp;
176  continue;
177  }
178 
179  foundActiveOperation = true;
180  bool customSimulated =
181  opSimulator_ != NULL && opSimulator_->simulateStage(execOp);
182  if (execOp.stage_ == 0 && !customSimulated)
183  operation_->simulateTrigger(&execOp.iovec_[0], *context_);
184  execOp.advanceCycle();
185 
186  if (execOp.stage_ == hwOperation_->latency()) {
187 #ifdef DEBUG_OPERATION_SIMULATION
189  << &execOp << " (" << execOp.operation().name()
190  << ") finished" << std::endl;
191 #endif
192  execOp.stop();
193  }
194  }
195  hasPendingOperations_ = foundActiveOperation;
196 }
197 
198 /**
199  * Copies OperationExecutor.
200  *
201  * @return The copied OperationExecutor.
202  */
205  return new MultiLatencyOperationExecutor(*this);
206 }
207 
208 /**
209  * Sets the OperationContext for the OperationExecutor.
210  *
211  * @param context New OperationContext.
212  */
213 void
215  context_ = &context;
216 }
217 
218 /**
219  * Resets the state to allow simulation restart.
220  * hasPendingOperations_ is resetted because otherwise some operations
221  * could be left in middle of execution if there was a runtime error
222  * during operation.
223  */
224 void
226  hasPendingOperations_ = false;
227 }
MultiLatencyOperationExecutor::executingOps_
std::vector< ExecutingOperation > executingOps_
The operations "on flight" in this operation executor.
Definition: MultiLatencyOperationExecutor.hh:93
MultiLatencyOperationExecutor::reset
virtual void reset()
Definition: MultiLatencyOperationExecutor.cc:225
OperationPool::operation
Operation & operation(const char *name)
Definition: OperationPool.cc:99
ExecutingOperation::PendingResult
Definition: ExecutingOperation.hh:90
DetailedOperationSimulator::simulateStage
virtual bool simulateStage(ExecutingOperation &operation)=0
DetailedOperationSimulator.hh
MultiLatencyOperationExecutor::execOperationsInitialized_
bool execOperationsInitialized_
Definition: MultiLatencyOperationExecutor.hh:96
ExecutingOperation::stage_
int stage_
Definition: ExecutingOperation.hh:134
MultiLatencyOperationExecutor::setContext
virtual void setContext(OperationContext &context)
Definition: MultiLatencyOperationExecutor.cc:214
TTAMachine::HWOperation
Definition: HWOperation.hh:52
ExecutingOperation::operation
const Operation & operation() const
Definition: ExecutingOperation.hh:63
OperationContext
Definition: OperationContext.hh:56
ExecutingOperation::iostorage_
std::vector< SimValue > iostorage_
Definition: ExecutingOperation.hh:125
Operation::numberOfInputs
virtual int numberOfInputs() const
Definition: Operation.cc:192
MultiLatencyOperationExecutor.hh
MultiLatencyOperationExecutor::findFreeExecutingOperation
ExecutingOperation & findFreeExecutingOperation()
Definition: MultiLatencyOperationExecutor.cc:89
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
ExecutingOperation::free_
bool free_
Definition: ExecutingOperation.hh:138
ExecutingOperation::initIOVec
void initIOVec()
Definition: ExecutingOperation.hh:116
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
FUState
Definition: FUState.hh:58
assert
#define assert(condition)
Definition: Application.hh:86
RegisterState::value
virtual const SimValue & value() const
Definition: RegisterState.cc:92
SimulatorToolbox.hh
OperationExecutor::hasPendingOperations_
bool hasPendingOperations_
This is set to true if the OperationExecutor is not in 'idle' mode.
Definition: OperationExecutor.hh:73
HWOperation.hh
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
MultiLatencyOperationExecutor::freeExecOp_
ExecutingOperation * freeExecOp_
If non-NULL, points to a known free ExecutingOperation slot.
Definition: MultiLatencyOperationExecutor.hh:95
MultiLatencyOperationExecutor::advanceClock
virtual void advanceClock()
Definition: MultiLatencyOperationExecutor.cc:168
Application.hh
MultiLatencyOperationExecutor::startOperation
virtual void startOperation(Operation &op)
Definition: MultiLatencyOperationExecutor.cc:118
Operation.hh
MultiLatencyOperationExecutor::~MultiLatencyOperationExecutor
virtual ~MultiLatencyOperationExecutor()
Definition: MultiLatencyOperationExecutor.cc:84
PortState
Definition: PortState.hh:51
MultiLatencyOperationExecutor::MultiLatencyOperationExecutor
MultiLatencyOperationExecutor()
Definition: MultiLatencyOperationExecutor.hh:65
ExecutingOperation
Definition: ExecutingOperation.hh:48
OperationExecutor
Definition: OperationExecutor.hh:49
Operation
Definition: Operation.hh:59
MultiLatencyOperationExecutor::opSimulator_
DetailedOperationSimulator * opSimulator_
If non-NULL, points to a detailed cycle-by-cycle simulation model for the operation simulated by this...
Definition: MultiLatencyOperationExecutor.hh:99
MultiLatencyOperationExecutor::operation_
Operation * operation_
The OSAL operation.
Definition: MultiLatencyOperationExecutor.hh:91
false
find Finds info of the inner loops in the false
Definition: InnerLoopFinder.cc:81
Operation::simulateTrigger
virtual bool simulateTrigger(SimValue **, OperationContext &context) const
Definition: Operation.cc:555
MultiLatencyOperationExecutor::hwOperation_
TTAMachine::HWOperation * hwOperation_
The hardware operation this executor simulates.
Definition: MultiLatencyOperationExecutor.hh:89
ExecutingOperation::stop
void stop()
Definition: ExecutingOperation.cc:65
TTAMachine::HWOperation::latency
int latency() const
Definition: HWOperation.cc:216
OperationPool
Definition: OperationPool.hh:52
ExecutingOperation::advanceCycle
void advanceCycle()
Definition: ExecutingOperation.cc:73
ExecutingOperation::pendingResults_
std::vector< PendingResult > pendingResults_
Definition: ExecutingOperation.hh:132
OperationPool.hh
Operation::numberOfOutputs
virtual int numberOfOutputs() const
Definition: Operation.cc:202
OperationExecutor::binding
PortState & binding(int io) const
MultiLatencyOperationExecutor::context_
OperationContext * context_
Operation context.
Definition: MultiLatencyOperationExecutor.hh:87
OperationContext.hh
MultiLatencyOperationExecutor::copy
virtual OperationExecutor * copy()
Definition: MultiLatencyOperationExecutor.cc:204
PortState.hh
ExecutingOperation::start
void start()
Definition: ExecutingOperation.cc:51
ExecutingOperation::iovec_
std::vector< SimValue * > iovec_
OSAL simulateTrigger() compatible I/O vector for fast execution.
Definition: ExecutingOperation.hh:127