OpenASIP 2.2
Loading...
Searching...
No Matches
InputPSocketBroker.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 InputPSocketBroker.cc
26 *
27 * Implementation of InputPSocketBroker class.
28 *
29 * @author Ari Mets�halme 2006 (ari.metsahalme-no.spam-tut.fi)
30 * @author Vladimir Guzma 2007 (vladimir.guzma-no.spam-tut.fi)
31 * @note rating: red
32 */
33
34#include <boost/format.hpp>
35
36#include "InputPSocketBroker.hh"
38#include "ResourceMapper.hh"
39#include "Machine.hh"
40#include "Segment.hh"
41#include "FUPort.hh"
42#include "Terminal.hh"
43#include "UniversalMachine.hh"
44#include "MapTools.hh"
45#include "Move.hh"
46#include "MoveNode.hh"
47#include "TerminalRegister.hh"
48
49using std::string;
50
51using namespace TTAMachine;
52using namespace TTAProgram;
53
54/**
55 * Constructor.
56 */
58 std::string name, ResourceBroker& fub, unsigned int initiationInterval):
59 ResourceBroker(name, initiationInterval),
60 inputFUBroker_(fub), busBroker_(NULL) {
61}
62
63/**
64 * Destructor.
65 */
68
69/**
70 * Return all resources managed by this broker that can be assigned to
71 * the given node in the given cycle.
72 *
73 * @param cycle Cycle.
74 * @param node Node.
75 * @return All resources managed by this broker that can be assigned to
76 * the given node in the given cycle.
77 */
80 int cycle,
81 const MoveNode& node, const TTAMachine::Bus*,
84 int,
85 const TTAMachine::ImmediateUnit*, int) const {
86
87 cycle = instructionIndex(cycle);
88 if (!isApplicable(node)) {
89 string msg = "Broker not capable of assigning resources to node!";
90 throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
91 }
92
93 Move& move = const_cast<MoveNode&>(node).move();
94
95 SchedulingResourceSet resourceSet;
96
97 if (move.destination().isFUPort()) {
98 // psocket already implicitly assigned by fubroker
99 Socket& inputSocket = *move.destination().port().inputSocket();
100 SchedulingResource* res = resourceOf(inputSocket);
101 if (res->canAssign(cycle, node)) {
102 resourceSet.insert(*res);
103 }
104 return resourceSet;
105
106 } else {
107 // assign psocket for writing rf
108 // ImmediateUnits can not be writen to this way
109
110 const RegisterFile& rf = move.destination().registerFile();
111
112 for (int i = 0; i < rf.portCount(); i++) {
113 Port& port = *rf.port(i);
114 Socket* inputSocket = port.inputSocket();
115 if (inputSocket != NULL) {
116 SchedulingResource* res = resourceOf(*inputSocket);
117 if (res->canAssign(cycle, node)) {
118 resourceSet.insert(*res);
119 }
120 }
121 }
122 return resourceSet;
123 }
124}
125
126/**
127 * Return the earliest cycle, starting from given cycle, where a
128 * resource of the type managed by this broker can be assigned to the
129 * given node.
130 *
131 * @param cycle Cycle.
132 * @param node Node.
133 * @return The earliest cycle, starting from given cycle, where a
134 * resource of the type managed by this broker can be assigned to the
135 * given node.
136 */
137int
139 const TTAMachine::Bus*,
141 const TTAMachine::FunctionUnit*, int,
143 int) const {
144 abortWithError("Not implemented.");
145 return -1;
146}
147
148/**
149 * Return the latest cycle, starting from given cycle, where a
150 * resource of the type managed by this broker can be assigned to the
151 * given node.
152 *
153 * @param cycle Cycle.
154 * @param node Node.
155 * @return The latest cycle, starting from given cycle, where a
156 * resource of the type managed by this broker can be assigned to the
157 * given node.
158 */
159int
161 const TTAMachine::Bus*,
163 const TTAMachine::FunctionUnit*, int,
164 const TTAMachine::ImmediateUnit*, int) const {
165 abortWithError("Not implemented.");
166 return -1;
167}
168
169/**
170 * Return true if the given node is already assigned a resource of the
171 * type managed by this broker, and the assignment appears valid (that
172 * is, the broker has marked that resource as in use in the given
173 * cycle).
174 *
175 * @param cycle Cycle.
176 * @param node Node.
177 * @return True if the given node is already assigned a resource of the
178 * type managed by this broker, and the assignment appears valid (that
179 * is, the broker has marked that resource as in use in the given
180 * cycle).
181 */
182bool
184 int cycle, const MoveNode& node, const TTAMachine::Bus*) const{
185 cycle = instructionIndex(cycle);
186 Terminal& dst = const_cast<MoveNode&>(node).move().destination();
187 const Port& port = dst.port();
188 if (port.inputSocket() == NULL)
189 return false;
191 if (res != NULL && res->isInUse(cycle) &&
193 return true;
194 } else {
195 return false;
196 }
197}
198
199/**
200 * Return true if the given node needs a resource of the type managed
201 * by this broker, false otherwise.
202 *
203 * This broker is applicable for all moves, but not long immediates.
204 *
205 * @param node Node.
206 * @return True if the given node needs a resource of the type managed
207 * by this broker, false otherwise.
208 */
209bool
211 const MoveNode& node, const TTAMachine::Bus*) const {
212 return node.isMove();
213}
214
215/**
216 * Mark given resource as in use for the given node, and assign the
217 * corresponding machine part (if applicable) to the node's move.
218 *
219 * If the node is already assigned to given resource, this method does
220 * nothing.
221 *
222 * @param cycle Cycle.
223 * @param node Node to assign.
224 * @param res Resource representing input PSocket
225 * @exception WrongSubclass If this broker does not recognise the given
226 * type of resource.
227 * @exception InvalidParameters If he given resource cannot be assigned to
228 * given node or no corresponding machine part is found.
229 * @todo Add caching of assigned resource objects (a MoveNode-Resource
230 * mapping).
231 */
232void
234 int cycle, MoveNode& node, SchedulingResource& res, int, int) {
235 if (!isApplicable(node)) {
236 string msg = "Broker not capable of assigning resources to node!";
237 throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
238 }
239
240 if (!hasResource(res)) {
241 string msg = "Broker does not contain given resource.";
242 throw InvalidData(__FILE__, __LINE__, __func__, msg);
243 }
244
245 Move& move = node.move();
246
247 if (move.destination().isGPR()) {
248
249 Port* port = NULL;
250 const Socket& socket = static_cast<const Socket&>(machinePartOf(res));
251 for (int i = 0; i < socket.portCount(); i++) {
252 if (socket.port(i)->inputSocket() == &socket) {
253 if (socket.port(i)->parentUnit() !=
254 &move.destination().registerFile())
255 continue;
256
257 port = socket.port(i);
258 break;
259 }
260 }
261 if (port == NULL){
262 throw InvalidData(
263 __FILE__, __LINE__, __func__,
264 "Broker does not have necessary Port registered!");
265 }
266 TerminalRegister* newDst =
267 new TerminalRegister(*port, move.destination().index());
268 move.setDestination(newDst);
269 }
270
271 res.assign(instructionIndex(cycle), node);
272 assignedResources_.insert(
273 std::pair<const MoveNode*, SchedulingResource*>(&node,&res));
274}
275
276/**
277 * Free the resource type managed by this broker and unassign it from
278 * given node.
279 *
280 * If this broker is not applicable to the given node, or the node is
281 * not assigned a resource of the managed type, this method does
282 * nothing.
283 *
284 * @param node Node.
285 * @todo Remove from cache of assigned resource objects.
286 */
287void
289 if (!isApplicable(node)) {
290 return;
291 }
292
294 Move& move = const_cast<MoveNode&>(node).move();
295 Terminal& dst = move.destination();
298 assignedResources_, &node)) != &res) {
299 std::string msg =
300 "InputPSocketBroker: assigned resource changed!";
301 throw ModuleRunTimeError(__FILE__,__LINE__, __func__, msg);
302 }
303 res.unassign(node.cycle(), node);
304 assignedResources_.erase(&node);
305 }
306}
307
308/**
309 * Build all resource objects of the controlled type required to model
310 * scheduling resources of the given target processor.
311 *
312 * This method cannot set up the resource links (dependent and related
313 * resources) of the constructed resource objects.
314 *
315 * @param target Target machine.
316 */
317void
320 for (int i = 0; i < navi.count(); i++) {
321 Socket* socket = navi.item(i);
322 if (socket->direction() == Socket::INPUT) {
323 InputPSocketResource* ipsResource =
325 ResourceBroker::addResource(*socket, ipsResource);
326 }
327 }
328}
329
330/**
331 * Complete resource initialisation by creating the references to
332 * other resources due to a dependency or a relation.
333 *
334 * Use the given resource mapper to lookup dependent and related resources
335 * using machine parts as keys.
336 *
337 * @param mapper Resource mapper.
338 */
339void
341
342 setResourceMapper(mapper);
343
344 for (ResourceMap::iterator resIter = resMap_.begin();
345 resIter != resMap_.end(); resIter++) {
346
347 const Socket* socket =
348 dynamic_cast<const Socket*>((*resIter).first);
349 if (socket == NULL){
350 throw InvalidData(
351 __FILE__, __LINE__, __func__,
352 "Broker does not have necessary Socket registered!");
353 }
354 SchedulingResource* socketResource = (*resIter).second;
355
356 for (int i = 0; i < socket->portCount(); i++) {
357 Port* port = socket->port(i);
358 FunctionUnit* fu = dynamic_cast<FunctionUnit*>(port->parentUnit());
359
360 if (fu != NULL) {
361 SchedulingResource& relRes =
363 socketResource->addToRelatedGroup(0, relRes);
364 }
365 }
366
367 for (int i = 0; i < socket->segmentCount(); i++) {
368 Segment* segment = socket->segment(i);
369 Bus* bus = segment->parentBus();
370 try {
371 SchedulingResource& relRes =
372 *busBroker_->resourceOf(*bus);
373 socketResource->addToRelatedGroup(1, relRes);
374 } catch (const KeyNotFound& e) {
375 std::string msg = "InputPSocketBroker: finding ";
376 msg += " resource for Segment ";
377 msg += " failed with error: ";
378 msg += e.errorMessageStack();
379 throw KeyNotFound(
380 __FILE__, __LINE__, __func__, msg);
381 }
382 }
383 }
384}
385
386/**
387 * Gives reference to segmentbroker to this broker.
388 *
389 * Cannot be given in constructor because SegmentBroker is created later.
390 */
#define __func__
#define abortWithError(message)
std::string errorMessageStack(bool messagesOnly=false) const
Definition Exception.cc:138
virtual int latestCycle(int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
virtual bool isApplicable(const MoveNode &node, const TTAMachine::Bus *preassignedBus=NULL) const override
virtual void assign(int cycle, MoveNode &node, SchedulingResource &res, int immWriteCycle, int immRegIndex) override
virtual bool isAlreadyAssigned(int cycle, const MoveNode &node, const TTAMachine::Bus *) const override
ResourceBroker * busBroker_
virtual int earliestCycle(int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
void setBusBroker(ResourceBroker &sb)
virtual SchedulingResourceSet allAvailableResources(int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
virtual void setupResourceLinks(const ResourceMapper &mapper) override
ResourceBroker & inputFUBroker_
InputPSocketBroker(std::string name, ResourceBroker &fub, unsigned int initiationInterval=0)
virtual void buildResources(const TTAMachine::Machine &target) override
virtual void unassign(MoveNode &node) override
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
static bool containsKey(const MapType &aMap, const KeyType &aKey)
int cycle() const
Definition MoveNode.cc:421
bool isMove() const
TTAProgram::Move & move()
void addResource(const TTAMachine::MachinePart &mp, SchedulingResource *res)
MoveResMap assignedResources_
SchedulingResource * resourceOf(const TTAMachine::MachinePart &mp) const
unsigned int instructionIndex(unsigned int) const
bool hasResource(const SchedulingResource &r) const
void setResourceMapper(const ResourceMapper &mapper)
unsigned int initiationInterval_
virtual const TTAMachine::MachinePart & machinePartOf(const SchedulingResource &r) const
ResourceMap resMap_
void insert(SchedulingResource &resource)
virtual void unassign(const int cycle, MoveNode &node)=0
virtual bool canAssign(const int cycle, const MoveNode &node) const =0
virtual void addToRelatedGroup(const int group, SchedulingResource &resource)
virtual void assign(const int cycle, MoveNode &node)=0
virtual bool isInUse(const int cycle) const =0
virtual RFPort * port(const std::string &name) const
virtual TCEString name() const
ComponentType * item(int index) const
virtual SocketNavigator socketNavigator() const
Definition Machine.cc:368
Unit * parentUnit() const
virtual Socket * inputSocket() const
Definition Port.cc:261
Bus * parentBus() const
@ INPUT
Data goes from bus to port.
Definition Socket.hh:59
Direction direction() const
Port * port(int index) const
Definition Socket.cc:266
Segment * segment(int index) const
Definition Socket.cc:401
int segmentCount() const
int portCount() const
virtual int portCount() const
Definition Unit.cc:135
Terminal & destination() const
Definition Move.cc:323
void setDestination(Terminal *dst)
Definition Move.cc:333
virtual int index() const
Definition Terminal.cc:274
virtual bool isGPR() const
Definition Terminal.cc:107
virtual const TTAMachine::Port & port() const
Definition Terminal.cc:378
virtual const TTAMachine::RegisterFile & registerFile() const
Definition Terminal.cc:225
virtual bool isFUPort() const
Definition Terminal.cc:118