OpenASIP 2.2
Loading...
Searching...
No Matches
FUArchitecture.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 FUArchitecture.cc
26 *
27 * Implementation of FUArchitecture class.
28 *
29 * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
30 * @note rating: red
31 */
32
33#include <string>
34
35#include "FUArchitecture.hh"
36#include "FunctionUnit.hh"
37#include "HWOperation.hh"
38#include "ExecutionPipeline.hh"
39#include "AssocTools.hh"
40#include "MapTools.hh"
41#include "FUPort.hh"
42#include "PipelineElement.hh"
43
44using namespace TTAMachine;
45using std::string;
46
47namespace HDB {
48
49/**
50 * The constructor.
51 *
52 * @param fu The function unit of which architecture is represented. Becomes
53 * property of the FUArchitecture object.
54 */
57
58/**
59 * Copy constructor.
60 *
61 * @param original FUArchitecture to copy.
62 */
64 HWBlockArchitecture(original) {
65
66 fu_ = original.fu_->copy();
69}
70
71/**
72 * The destructor.
73 */
77
78
79/**
80 * Tells whether the given port has parameterized width.
81 *
82 * @param port Name of the port.
83 * @return True if the port is parameterized, otherwise false.
84 */
85bool
86FUArchitecture::hasParameterizedWidth(const std::string& port) const {
88}
89
90
91/**
92 * Sets parameterized width for the given port.
93 *
94 * @param port Name of the port.
95 */
96void
97FUArchitecture::setParameterizedWidth(const std::string& port) {
98 parameterizedPorts_.insert(port);
99}
100
101
102/**
103 * Tells whether the given port is guarded.
104 *
105 * @param port Name of the port.
106 * @return True if the port is guarded, otherwise false.
107 */
108bool
109FUArchitecture::hasGuardSupport(const std::string& port) const {
111}
112
113
114/**
115 * Sets guard support for the given port.
116 *
117 * @param port Name of the port.
118 */
119void
120FUArchitecture::setGuardSupport(const std::string& port) {
121 guardedPorts_.insert(port);
122}
123
124
125/**
126 * Returns the FunctionUnit instance that represents the architecture.
127 *
128 * @return The FunctionUnit instance.
129 */
132 return *fu_;
133}
134
135
136/**
137 * Tells the direction of the given port.
138 *
139 * @param portName Name of the port in the FU architecture.
140 * @exception InstanceNotFound If the FU architecture does not have the given
141 * port.
142 * @exception InvalidData If the given port is not used by any pipeline.
143 */
145FUArchitecture::portDirection(const std::string& portName) const {
147 if (!fu.hasOperationPort(portName)) {
148 throw InstanceNotFound(__FILE__, __LINE__, __func__);
149 }
150
151 FUPort* port = fu.operationPort(portName);
152 bool read = false;
153 bool written = false;
154
155 int operationCount = fu.operationCount();
156 for (int i = 0; i < operationCount; i++) {
157 HWOperation* operation = fu.operation(i);
158 ExecutionPipeline* pLine = operation->pipeline();
159 int latency = operation->latency();
160 for (int cycle = 0; cycle < latency; cycle++) {
161 if (!read) {
162 if (pLine->isPortRead(*port, cycle)) {
163 read = true;
164 }
165 }
166 if (!written) {
167 if (pLine->isPortWritten(*port, cycle)) {
168 written = true;
169 }
170 }
171 }
172 if (read && written) {
173 break;
174 }
175 }
176
177 if (read && written) {
178 return HDB::BIDIR;
179 } else if (read) {
180 return HDB::IN;
181 } else if (written) {
182 return HDB::OUT;
183 } else {
184 throw InvalidData(__FILE__, __LINE__, __func__);
185 }
186}
187
188/**
189 * Checks whether the given FU has a mathing architecture with the given FU
190 * architecture instance.
191 *
192 * @param rightHand Right hand operand.
193 * @return True if the architectures match, otherwise false.
194 */
195bool
197
198 if (rightHand.architecture().operationCount() !=
199 this->architecture().operationCount()) {
200 return false;
201 }
202
203 std::map<const FUPort*, const FUPort*> portMap;
204 for (int i = 0; i < rightHand.architecture().operationPortCount(); i++) {
205 portMap.insert(
206 std::pair<const FUPort*, const FUPort*>(
207 rightHand.architecture().operationPort(i), NULL));
208 }
209
210 PipelineElementUsageTable plineElementUsages;
211
212 for (int i = 0; i < rightHand.architecture().operationCount(); i++) {
213 HWOperation* rightHandOp = rightHand.architecture().operation(i);
214 if (!architecture().hasOperation(rightHandOp->name())) {
215 return false;
216 }
218 rightHandOp->name());
219 if (rightHandOp->latency() != thisOp->latency()) {
220 return false;
221 }
222
223 // check operand bindings
224 for (int i = 0;
225 i < rightHand.architecture().operationPortCount();
226 i++) {
227
228 FUPort* port = rightHand.architecture().operationPort(i);
229 if (rightHandOp->isBound(*port)) {
230 int io = rightHandOp->io(*port);
231 FUPort* samePort = thisOp->port(io);
232 if (samePort == NULL) {
233 return false;
234 }
235 const FUPort* existingSamePort =
237 if (existingSamePort != NULL &&
238 existingSamePort != samePort) {
239 return false;
240 }
241
242 // check the width of the ports
243 // widths must equal
244 if (hasParameterizedWidth(samePort->name()) !=
245 rightHand.hasParameterizedWidth(port->name())) {
246 return false;
247 }
248
249 // if the FUArchitectures have parameterized port width
250 // those ports widths are not needed to check
251 if (!hasParameterizedWidth(samePort->name()) &&
252 samePort->width() != port->width()) {
253 return false;
254 }
255
256 if (port->isOpcodeSetting() != samePort->isOpcodeSetting() ||
257 port->isTriggering() != samePort->isTriggering()) {
258 return false;
259 }
260 portMap.erase(port);
261 portMap.insert(
262 std::pair<const FUPort*, const FUPort*>(port, samePort));
263 }
264 }
265
266 // check operation pipeline
267 ExecutionPipeline* opPipeline = rightHandOp->pipeline();
268 ExecutionPipeline* thisOpPipeline = thisOp->pipeline();
269 for (int cycle = 0; cycle < rightHandOp->latency(); cycle++) {
271 opPipeline->writtenOperands(cycle);
273 thisOpPipeline->writtenOperands(cycle);
274 if (written1 != written2) {
275 return false;
276 }
278 opPipeline->readOperands(cycle);
280 thisOpPipeline->readOperands(cycle);
281 if (read1 != read2) {
282 return false;
283 }
284
286 for (int i = 0;
287 i < rightHand.architecture().pipelineElementCount();
288 i++) {
289
290 const PipelineElement* elem =
291 rightHand.architecture().pipelineElement(i);
292 if (opPipeline->isResourceUsed(elem->name(),cycle)) {
293 usage.usage1.insert(elem);
294 }
295 }
296
297 for (int i = 0; i < architecture().pipelineElementCount(); i++) {
298 const PipelineElement* elem =
300 if (thisOpPipeline->isResourceUsed(elem->name(), cycle)) {
301 usage.usage2.insert(elem);
302 }
303 }
304 plineElementUsages.push_back(usage);
305 }
306 }
307
308 std::set<const TTAMachine::PipelineElement*> difference;
309 for (size_t i = 0; i < plineElementUsages.size(); i++) {
310 AssocTools::difference(plineElementUsages[i].usage1,
311 plineElementUsages[i].usage2,
312 difference);
313 }
314 if (!difference.empty()) {
315 return false;
316 }
317 return true;
318}
319}
#define __func__
static void difference(const ContainerType &firstContainer, const ContainerType &secondContainer, ContainerType &difference)
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
bool hasGuardSupport(const std::string &port) const
std::vector< PipelineElementUsage > PipelineElementUsageTable
typedef for PipelineElemetnUsageTable
TTAMachine::FunctionUnit * fu_
The function unit.
HDB::Direction portDirection(const std::string &port) const
void setGuardSupport(const std::string &port)
FUArchitecture(TTAMachine::FunctionUnit *fu)
PortSet parameterizedPorts_
Parameterized ports.
PortSet guardedPorts_
Port that support guard.
bool operator==(const FUArchitecture &rightHand) const
void setParameterizedWidth(const std::string &port)
bool hasParameterizedWidth(const std::string &port) const
TTAMachine::FunctionUnit & architecture() const
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
virtual int width() const
OperandSet writtenOperands(int cycle) const
OperandSet readOperands(int cycle) const
std::set< int > OperandSet
Set for operand indexes.
bool isPortWritten(const FUPort &port, int cycle) const
bool isPortRead(const FUPort &port, int cycle) const
bool isResourceUsed(const std::string &name, int cycle) const
virtual bool isTriggering() const
Definition FUPort.cc:182
virtual bool isOpcodeSetting() const
Definition FUPort.cc:195
virtual int pipelineElementCount() const
virtual HWOperation * operation(const std::string &name) const
virtual FunctionUnit * copy() const
virtual int operationCount() const
virtual FUPort * operationPort(const std::string &name) const
virtual bool hasOperationPort(const std::string &name) const
virtual PipelineElement * pipelineElement(int index) const
ExecutionPipeline * pipeline() const
virtual FUPort * port(int operand) const
int io(const FUPort &port) const
const std::string & name() const
bool isBound(const FUPort &port) const
const std::string & name() const
virtual std::string name() const
Definition Port.cc:141
Direction
Direction of port.
Definition HDBTypes.hh:40
@ OUT
Output port.
Definition HDBTypes.hh:42
@ BIDIR
Bidirectional port.
Definition HDBTypes.hh:43
@ IN
Input port.
Definition HDBTypes.hh:41
std::set< const TTAMachine::PipelineElement * > usage1
std::set< const TTAMachine::PipelineElement * > usage2