OpenASIP 2.2
Loading...
Searching...
No Matches
BusResource.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 BusResource.cc
26 *
27 * Implementation of prototype of Resource Model:
28 * implementation of the BusResource.
29 *
30 * @author Vladimir Guzma 2006 (vladimir.guzma-no.spam-tut.fi)
31 * @author Heikki Kultala 2014 (heikki.kultala-no.spam-tut.fi)
32 * @note rating: red
33 */
34
35#include "BusResource.hh"
36#include "Application.hh"
37#include "Exception.hh"
38#include "Conversion.hh"
39#include "MoveNode.hh"
40#include "Port.hh"
41#include "Terminal.hh"
42#include "Move.hh"
43#include "ProgramOperation.hh"
44#include "Operation.hh"
45#include "Operand.hh"
46
47/**
48 * Constructor
49 * Creates new resource with defined name
50 * @param name Name of resource
51 * @param width short immediate width of the bus
52 * @param limmSlotCount how many itemplates use this bus in limm field
53 */
55 const std::string& name, int width, int limmSlotCount, int nopSlotCount,
56 int guardCount,
57 int immSize, int socketCount, unsigned int initiationInterval) :
58 SchedulingResource(name, initiationInterval), busWidth_(width),
59 limmSlotCount_(limmSlotCount), nopSlotCount_(nopSlotCount),
60 guardCount_(guardCount),
61 immSize_(immSize), socketCount_(socketCount) {
62}
63
64/**
65 * Empty destructor
66 */
68
69/**
70 * Test if resource BusResource is used in given cycle
71 * @param cycle Cycle which to test
72 * @return True if any of segments of bus isInUse in given cycle
73 */
74bool
75BusResource::isInUse(const int cycle) const {
76 ResourceRecordType::const_iterator i =
78 if (i != resourceRecord_.end() && i->second != 0) {
79 return true;
80 }
81 return false;
82}
83
84/**
85 * Test if resource BusResource is available
86 * @param cycle Cycle which to test
87 * @return False if all the segments of bus are InUse
88 */
89bool
90BusResource::isAvailable(const int cycle) const {
91 return !isInUse(cycle);
92}
93
94/**
95 * Test if resource BusResource is available.
96 *
97 * @param cycle Cycle which to test
98 * @return False if all the segments of bus are InUse
99 */
100bool
102 const int cycle,
103 const SchedulingResource& inputPSocket,
104 const SchedulingResource& outputPSocket) const {
105
106 if (!(hasRelatedResource(inputPSocket) &&
107 hasRelatedResource(outputPSocket))) {
108 // BusBroker does not need to test if sockets
109 // are connected to the bus...
110 return false;
111 }
112
113 return isAvailable(cycle);
114}
115
116/**
117 * Assign resource to given node for given cycle without testing
118 * Input or Output PSocket, assign ALL segments of bus.
119 * @param cycle Cycle to assign
120 * @param node MoveNode assigned
121 * @throw In case assignment can not be done
122 */
123void
124BusResource::assign(const int cycle, MoveNode& node)
125{
126 if (canAssign(cycle, node)) {
129 return;
130 }
131}
132
133/**
134 * Unassign resource from given node for given cycle without testing
135 * Input or Output PSocket, unassign all segments of bus
136 *
137 * @param cycle Cycle to remove assignment from
138 * @param node MoveNode to remove assignment from
139 * @throw In case bus was not assigned
140 */
141void
142BusResource::unassign(const int cycle, MoveNode&) {
143
144 if (isInUse(cycle)) {
146 return;
147 } else{
148 std::string msg = "Bus ";
149 msg += name();
150 msg += " can not be unassigned in cycle ";
151 msg += Conversion::toString(cycle);
152 msg += ", it was not in use!";
153 throw ModuleRunTimeError(__FILE__, __LINE__,__func__, msg);
154 }
155}
156
157/**
158 * Return true if resource can be assigned for given node in given cycle
159 * @param cycle Cycle to test
160 * @param node MoveNode to test
161 * @return true if node can be assigned to cycle
162 */
163bool
164BusResource::canAssign(const int cycle, const MoveNode&) const {
165 return isAvailable(cycle);
166}
167
168/**
169 * Return true if resource can be assigned for given node in given cycle
170 * @param cycle Cycle to test
171 * @param node MoveNode to test
172 * @param inputPSocket PSocket connected to source of move
173 * @param outputPSocket PSocket connected to destination of move
174 * @return true if node can be assigned to cycle
175 */
176bool
178 const int cycle,
179 const MoveNode& node,
180 const SchedulingResource& inputPSocket,
181 const SchedulingResource& outputPSocket) const {
182
183 if (!isAvailable(cycle, inputPSocket, outputPSocket)) {
184 return false;
185 }
186
187 int defBits = node.isSourceConstant()?
188 busWidth_ : node.move().source().port().width();
189 // TODO: Check if source is from an operation result that defines less bits.
190 int useBits = node.move().destination().port().width();
191 if (useBits > busWidth_ && node.destinationOperationCount()) {
192 // Writing undefined bits *1 to upper bits of the destination port.
193 // Check if none of the destinations use those bits.
194 // *1: DefaultICDecoderPlugin zero extends when writing to port from
195 // narrower bus, but this is not documented semantic?
196 int maxOpdWidth = 0;
197 for (size_t i = 0; i < node.destinationOperationCount(); i++) {
198 const auto& op = node.destinationOperation(i).operation();
199 int opdIdx = node.move().destination().operationIndex();
200 int opdWidth = op.operand(opdIdx).width();
201 maxOpdWidth = std::max(maxOpdWidth, opdWidth);
202 }
203 assert(maxOpdWidth > 0);
204 useBits = std::min(useBits, maxOpdWidth);
205 }
206 // Define bit width of the value transportation as in below statement to
207 // allow cases such as:
208 // - Move from ALU compare to boolean reg.
209 // - Move from boolean reg to LSU store.
210 int transportWidth = std::min(defBits, useBits);
211 if (transportWidth > busWidth_) {
212 return false;
213 }
214
215 if (!inputPSocket.isOutputPSocketResource() ||
216 !hasRelatedResource(inputPSocket)) {
217 return false;
218 }
219 if (!outputPSocket.isInputPSocketResource() ||
220 !hasRelatedResource(outputPSocket)) {
221 return false;
222 }
223
224 return true;
225}
226
227/**
228 * Return allways true
229 * @return true
230 */
231bool
233 return true;
234}
235
236/**
237 * Tests if all referred resources in dependent groups are of
238 * proper types
239 * @return true If all resources in dependent groups are
240 * Segment resources
241 */
242bool
244 return true;
245}
246
247/**
248 * Tests if all resources in related resource groups are of
249 * proper types
250 * @return true If all resources in related resource groups are
251 * PSockets
252 */
253bool
255 for (int i = 0; i < relatedResourceGroupCount(); i++) {
256 for (int j = 0, count = relatedResourceCount(i);
257 j < count;
258 j++) {
261 return false;
262 }
263 }
264 return true;
265}
266
267/**
268 * Comparison operator.
269 *
270 * Favours busses which have less limm slots associated to then in
271 * instruction templates, ie. busses which do not get into way of
272 * limm writes.
273 */
274bool
276 const BusResource *busr = static_cast<const BusResource*>(&other);
277
278 // favour buses with less nop slots
279 if (nopSlotCount_ < busr->nopSlotCount_) {
280 return true;
281 }
282 if (nopSlotCount_ > busr->nopSlotCount_) {
283 return false;
284 }
285
286 if (busr == NULL) {
287 return false;
288 }
289
290 // then try to use busses without guards, if possible.
291 if (guardCount_ < busr->guardCount_) {
292 return true;
293 }
294 if (guardCount_ > busr->guardCount_) {
295 return false;
296 }
297
298 // then favour busses with less sockets.
299 if (socketCount_ < busr->socketCount_) {
300 return true;
301 }
302 if (socketCount_ > busr->socketCount_) {
303 return false;
304 }
305
306 // first priority are limm slots.
307 if (limmSlotCount_ < busr->limmSlotCount_) {
308 return true;
309 }
310 if (limmSlotCount_ > busr->limmSlotCount_) {
311 return false;
312 }
313
314 // then favour busses with smallest immediate.
315 if (immSize_ < busr->immSize_) {
316 return true;
317 }
318 if (immSize_ > busr->immSize_) {
319 return false;
320 }
321
322 // then use the default use count, name comparison,
323 // but in opposite direction, facouring already used
324 return other.SchedulingResource::operator<(*this);
325}
326
327/**
328 * Clears bookkeeping of the scheduling resource.
329 *
330 * After this call the state of the resource should be identical to a
331 * newly-created and initialized resource.
332 */
333void
#define __func__
#define assert(condition)
virtual bool validateDependentGroups() override
virtual bool canAssign(const int cycle, const MoveNode &node) const override
virtual ~BusResource()
virtual bool isInUse(const int cycle) const override
virtual bool validateRelatedGroups() override
virtual void assign(const int cycle, MoveNode &node) override
virtual void unassign(const int cycle, MoveNode &node) override
ResourceRecordType resourceRecord_
void clear() override
virtual bool isBusResource() const override
virtual bool isAvailable(const int cycle) const override
BusResource(const std::string &name, int width, int limmSlotCount, int nopSlotCount, int guardCount, int immSize, int socketCount, unsigned int initiationInterval=0)
virtual bool operator<(const SchedulingResource &other) const override
static std::string toString(const T &source)
unsigned int destinationOperationCount() const
TTAProgram::Move & move()
bool isSourceConstant() const
Definition MoveNode.cc:238
ProgramOperation & destinationOperation(unsigned int index=0) const
const Operation & operation() const
virtual void increaseUseCount()
virtual SchedulingResource & relatedResource(const int group, const int index) const
int instructionIndex(int cycle) const
int relatedResourceCount(const int group) const
virtual bool isInputPSocketResource() const
virtual const std::string & name() const
virtual bool hasRelatedResource(const SchedulingResource &sResource) const
virtual bool isOutputPSocketResource() const
virtual int relatedResourceGroupCount() const
virtual int width() const =0
Terminal & source() const
Definition Move.cc:302
Terminal & destination() const
Definition Move.cc:323
virtual int operationIndex() const
Definition Terminal.cc:364
virtual const TTAMachine::Port & port() const
Definition Terminal.cc:378