OpenASIP 2.2
Loading...
Searching...
No Matches
OutputPSocketResource.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2011 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 OutputPSocketResource.cc
26 *
27 * Implementation of OutputPSocketResource class.
28 *
29 * @author Vladimir Guzma 2006 (vladimir.guzma-no.spam-tut.fi)
30 * @author Pekka Jääskeläinen 2011
31 * @note rating: red
32 */
33#include <iostream>
35#include "MapTools.hh"
36#include "Move.hh"
37#include "MoveNode.hh"
38#include "MoveGuard.hh"
39#include "Guard.hh"
40#include "Terminal.hh"
41#include "Port.hh"
42
43/**
44 * Constructor.
45 *
46 * @param name Name of resource.
47 */
48OutputPSocketResource::OutputPSocketResource(const std::string& name, unsigned int initiationInterval) :
49 PSocketResource(name, initiationInterval), activeCycle_(-1) {}
50
51/**
52 * Destructor.
53 */
55
56/**
57 * Test if resource OutputPSocketResource is available.
58 *
59 * @param cycle Cycle which to test.
60 * @return Always true, multiple reads are possible.
61 */
62bool
64 return true;
65}
66
67/**
68 * Return true always.
69 *
70 * @return True always.
71 */
72bool
76/**
77 * Assign resource to given node for given cycle.
78 *
79 * @param cycle Cycle to assign
80 * @param node MoveNode to assign
81 */
82void
84{
85 PSocketResource::assign(cycle, node);
86 auto i = storedPorts_.find(instructionIndex(cycle));
87 if (i == storedPorts_.end()) {
88 const TTAMachine::Port* newPort = &node.move().source().port();
90 std::make_pair(newPort,1);
91 } else {
92 i->second.second++;
93 }
94}
95
96/**
97 * Unassign resource from given node for given cycle.
98 *
99 * @param cycle Cycle to remove assignment from
100 * @param node MoveNode to remove assignment from
101 */
102void
104{
105 PSocketResource::unassign(cycle, node);
106 auto i = storedPorts_.find(instructionIndex(cycle));
107 if (i != storedPorts_.end()) {
108 if (i->second.second == 1) {
109 storedPorts_.erase(i);
110 } else {
111 i->second.second--;
112 }
113 }
114}
115
116/**
117 * Return true if resource can be assigned for given resource in given cycle.
118 *
119 * @param cycle Cycle to test
120 * @param node MoveNode to test
121 * @return true if node can be assigned to cycle
122 */
123bool
124OutputPSocketResource::canAssign(const int cycle, const MoveNode& node)
125 const {
126 MoveNode& mNode = const_cast<MoveNode&>(node);
127 auto i = storedPorts_.find(instructionIndex(cycle));
128 if (mNode.move().source().isFUPort()) {
129 if (i != storedPorts_.end()) {
130 const TTAMachine::Port* storedP = i->second.first;
131 if (&mNode.move().source().port() != storedP) {
132 return false;
133 }
134 }
135 }
136 if (mNode.move().source().isImmediateRegister()) {
137 if (i != storedPorts_.end()) {
138 return false;
139 }
140 }
141 if (node.move().source().isGPR()) {
142 if (i != storedPorts_.end()) {
143 const TTAMachine::Port* storedP =
144 i->second.first;
145 if (mNode.move().source().port().parentUnit() !=
146 storedP->parentUnit()) {
147 return false;
148 }
149 }
150
151 ResourceRecordType::const_iterator iter = resourceRecord_.find(cycle);
152 if (iter != resourceRecord_.end()) {
153 std::set<MoveNode*> movesInCycle = iter->second;
154 for (std::set<MoveNode*>::iterator it = movesInCycle.begin();
155 it != movesInCycle.end(); it++) {
156#ifdef NO_OVERCOMMIT
157 return false;
158#else
159 MoveNode* mn = *it;
160 if (node.move().isUnconditional() ||
161 mn->move().isUnconditional()) {
162 if (node.move().source().port().parentUnit() !=
163 mn->move().source().port().parentUnit() ||
164 node.move().source().index() !=
165 mn->move().source().index()) {
166 return false;
167 } else {
168 continue;
169 }
170
171 }
172 if (!node.move().guard().guard().isOpposite(
173 mn->move().guard().guard())) {
174 if (!node.move().source().equals(
175 mn->move().source())) {
176 return false;
177 }
178 }
179#endif
180 }
181 }
182 }
183 activeCycle_ = cycle;
184 return true;
185}
186
187/**
188 * Tests if all referred resources in dependent groups are of
189 * proper types.
190 *
191 * @return True if all dependent groups are empty.
192 */
193bool
195 for (int i = 0; i < dependentResourceGroupCount(); i++) {
196 if (dependentResourceCount(i) > 0) {
197 return false;
198 }
199 }
200 return true;
201}
202
203/**
204 * Tests if all referred resources in related groups are of
205 * proper types.
206 *
207 * @return True if all resources in related groups are Segment or OutputFU
208 * or IU resources.
209 */
210bool
212 for (int i = 0; i < relatedResourceGroupCount(); i++) {
213 for (int j = 0, count = relatedResourceCount(i); j < count; j++) {
214 if (!(relatedResource(i, j).isOutputFUResource() ||
216 relatedResource(i, j).isIUResource())) {
217 return false;
218 }
219 }
220 }
221 return true;
222}
223
224/**
225 * Comparison operator.
226 *
227 * Favours sockets which have less connections.
228 *
229 * TODO: precalc/cache these to optimize scheduling time?
230 */
231bool
233 const OutputPSocketResource *opsr =
234 dynamic_cast<const OutputPSocketResource*>(&other);
235 if (opsr == NULL) {
236 return false;
237 }
238
239 // first priority is to put reads from same source to same psocket.
240 // so favour the one with most moves in current cycle.
241 int myCount = 0;
242 int otherCount = 0;
243 ResourceRecordType::const_iterator myIter = resourceRecord_.find(activeCycle_);
244 if (myIter != resourceRecord_.end()) {
245 myCount = myIter->second.size();
246 }
247
248 ResourceRecordType::const_iterator otherIter = opsr->resourceRecord_.find(opsr->activeCycle_);
249 if (otherIter != opsr->resourceRecord_.end()) {
250 otherCount = otherIter->second.size();
251 }
252 if (myCount < otherCount) {
253 return false;
254 } else if (myCount > otherCount) {
255 return true;
256 }
257
258 // favour sockets which have connections to busses with fewest connections
259 // calculate the connections..
260 int connCount = 0;
261 int connCount2 = 0;
262
263 int rrCount2 = relatedResourceCount(2);
264 for (int i = 0; i < rrCount2; i++) {
266 connCount += r.relatedResourceCount(0);
267 }
268
269 int oRRCount2 = other.relatedResourceCount(2);
270
271 for (int i = 0; i < oRRCount2; i++) {
272 SchedulingResource& r = other.relatedResource(2,i);
273 connCount2 += r.relatedResourceCount(0);
274 }
275
276 // then the comparison.
277 if (connCount < connCount2) {
278 return true;
279 }
280
281 if (connCount > connCount2) {
282 return false;
283 }
284
285 // favour sockets with less buses.
286 if (rrCount2 < oRRCount2) {
287 return true;
288 }
289 if (rrCount2 > oRRCount2) {
290 return false;
291 }
292
293 // then use the default use count, name comparison,
294 // but in opposite direction, facouring already used
295 return other.SchedulingResource::operator<(*this);
296}
297
298/**
299 * Clears bookkeeping of the scheduling resource.
300 *
301 * After this call the state of the resource should be identical to a
302 * newly-created and initialized resource.
303 */
304void
TTAProgram::Move & move()
std::map< int, std::pair< const TTAMachine::Port *, int > > storedPorts_
virtual void unassign(const int cycle, MoveNode &node) override
virtual bool isOutputPSocketResource() const override
virtual bool validateDependentGroups() override
virtual bool canAssign(const int cycle, const MoveNode &node) const override
virtual bool isAvailable(const int cycle) const override
virtual void assign(const int cycle, MoveNode &node) override
virtual bool operator<(const SchedulingResource &other) const override
OutputPSocketResource(const std::string &name, unsigned int initiationInterval=0)
virtual bool validateRelatedGroups() override
void clear() override
ResourceRecordType resourceRecord_
virtual void assign(const int cycle, MoveNode &node) override
virtual void unassign(const int cycle, MoveNode &node) override
virtual bool isOutputFUResource() const
virtual bool isBusResource() const
virtual SchedulingResource & relatedResource(const int group, const int index) const
int instructionIndex(int cycle) const
int relatedResourceCount(const int group) const
virtual bool isIUResource() const
int dependentResourceCount(const int group) const
virtual int relatedResourceGroupCount() const
virtual int dependentResourceGroupCount() const
virtual bool isOpposite(const Guard &guard) const =0
Unit * parentUnit() const
const TTAMachine::Guard & guard() const
Definition MoveGuard.cc:86
MoveGuard & guard() const
Definition Move.cc:345
bool isUnconditional() const
Definition Move.cc:154
Terminal & source() const
Definition Move.cc:302
virtual int index() const
Definition Terminal.cc:274
virtual bool equals(const Terminal &other) const =0
virtual bool isGPR() const
Definition Terminal.cc:107
virtual bool isImmediateRegister() const
Definition Terminal.cc:97
virtual const TTAMachine::Port & port() const
Definition Terminal.cc:378
virtual bool isFUPort() const
Definition Terminal.cc:118