OpenASIP  2.0
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 
44 using namespace TTAMachine;
45 using std::string;
46 
47 namespace 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  */
55 FUArchitecture::FUArchitecture(TTAMachine::FunctionUnit* fu) : fu_(fu) {
56 }
57 
58 /**
59  * Copy constructor.
60  *
61  * @param original FUArchitecture to copy.
62  */
64  HWBlockArchitecture(original) {
65 
66  fu_ = original.fu_->copy();
68  guardedPorts_ = original.guardedPorts_;
69 }
70 
71 /**
72  * The destructor.
73  */
75  delete fu_;
76 }
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  */
85 bool
86 FUArchitecture::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  */
96 void
97 FUArchitecture::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  */
108 bool
109 FUArchitecture::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  */
119 void
120 FUArchitecture::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  */
145 FUArchitecture::portDirection(const std::string& portName) const {
146  FunctionUnit& fu = architecture();
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  */
195 bool
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  }
217  HWOperation* thisOp = architecture().operation(
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 =
236  MapTools::valueForKey<const FUPort*>(portMap, port);
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 
285  PipelineElementUsage usage;
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 }
HDB::FUArchitecture
Definition: FUArchitecture.hh:55
AssocTools::difference
static void difference(const ContainerType &firstContainer, const ContainerType &secondContainer, ContainerType &difference)
HDB::FUArchitecture::fu_
TTAMachine::FunctionUnit * fu_
The function unit.
Definition: FUArchitecture.hh:84
HDB::FUArchitecture::hasParameterizedWidth
bool hasParameterizedWidth(const std::string &port) const
Definition: FUArchitecture.cc:86
HDB
Definition: CostDatabase.hh:49
TTAMachine::FUPort::isOpcodeSetting
virtual bool isOpcodeSetting() const
Definition: FUPort.cc:195
TTAMachine::HWOperation
Definition: HWOperation.hh:52
ExecutionPipeline.hh
HWBlockArchitecture
Definition: HWBlockArchitecture.hh:42
FUArchitecture.hh
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
MapTools.hh
HDB::FUArchitecture::architecture
TTAMachine::FunctionUnit & architecture() const
Definition: FUArchitecture.cc:131
HDB::FUArchitecture::FUArchitecture
FUArchitecture(TTAMachine::FunctionUnit *fu)
Definition: FUArchitecture.cc:55
HDB::FUArchitecture::PipelineElementUsageTable
std::vector< PipelineElementUsage > PipelineElementUsageTable
typedef for PipelineElemetnUsageTable
Definition: FUArchitecture.hh:78
TTAMachine::ExecutionPipeline::writtenOperands
OperandSet writtenOperands(int cycle) const
Definition: ExecutionPipeline.cc:429
TTAMachine::PipelineElement::name
const std::string & name() const
TTAMachine::ExecutionPipeline::readOperands
OperandSet readOperands(int cycle) const
Definition: ExecutionPipeline.cc:408
TTAMachine::FUPort::isTriggering
virtual bool isTriggering() const
Definition: FUPort.cc:182
HDB::FUArchitecture::parameterizedPorts_
PortSet parameterizedPorts_
Parameterized ports.
Definition: FUArchitecture.hh:86
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TTAMachine::HWOperation::port
virtual FUPort * port(int operand) const
Definition: HWOperation.cc:320
TTAMachine::FUPort
Definition: FUPort.hh:46
HDB::FUArchitecture::setParameterizedWidth
void setParameterizedWidth(const std::string &port)
Definition: FUArchitecture.cc:97
TTAMachine::HWOperation::io
int io(const FUPort &port) const
Definition: HWOperation.cc:364
HDB::FUArchitecture::hasGuardSupport
bool hasGuardSupport(const std::string &port) const
Definition: FUArchitecture.cc:109
HWOperation.hh
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
InvalidData
Definition: Exception.hh:149
TTAMachine::FunctionUnit::pipelineElement
virtual PipelineElement * pipelineElement(int index) const
Definition: FunctionUnit.cc:523
HDB::FUArchitecture::PipelineElementUsage
Struct PipelineElementUsage.
Definition: FUArchitecture.hh:72
HDB::Direction
Direction
Direction of port.
Definition: HDBTypes.hh:40
HDB::BIDIR
@ BIDIR
Bidirectional port.
Definition: HDBTypes.hh:43
HDB::FUArchitecture::portDirection
HDB::Direction portDirection(const std::string &port) const
Definition: FUArchitecture.cc:145
TTAMachine::ExecutionPipeline::isPortWritten
bool isPortWritten(const FUPort &port, int cycle) const
Definition: ExecutionPipeline.cc:386
TTAMachine::HWOperation::isBound
bool isBound(const FUPort &port) const
Definition: HWOperation.cc:338
__func__
#define __func__
Definition: Application.hh:67
HDB::FUArchitecture::operator==
bool operator==(const FUArchitecture &rightHand) const
Definition: FUArchitecture.cc:196
TTAMachine::FunctionUnit::operationCount
virtual int operationCount() const
Definition: FunctionUnit.cc:419
HDB::FUArchitecture::PipelineElementUsage::usage1
std::set< const TTAMachine::PipelineElement * > usage1
Definition: FUArchitecture.hh:73
HDB::FUArchitecture::setGuardSupport
void setGuardSupport(const std::string &port)
Definition: FUArchitecture.cc:120
TTAMachine::ExecutionPipeline::OperandSet
std::set< int > OperandSet
Set for operand indexes.
Definition: ExecutionPipeline.hh:58
TTAMachine::FunctionUnit::pipelineElementCount
virtual int pipelineElementCount() const
Definition: FunctionUnit.cc:507
TTAMachine::ExecutionPipeline::isPortRead
bool isPortRead(const FUPort &port, int cycle) const
Definition: ExecutionPipeline.cc:362
TTAMachine::FunctionUnit::hasOperationPort
virtual bool hasOperationPort(const std::string &name) const
Definition: FunctionUnit.cc:204
TTAMachine::PipelineElement
Definition: PipelineElement.hh:46
HDB::FUArchitecture::~FUArchitecture
virtual ~FUArchitecture()
Definition: FUArchitecture.cc:74
AssocTools.hh
TTAMachine::Port::name
virtual std::string name() const
Definition: Port.cc:141
FUPort.hh
HDB::FUArchitecture::PipelineElementUsage::usage2
std::set< const TTAMachine::PipelineElement * > usage2
Definition: FUArchitecture.hh:74
PipelineElement.hh
HDB::IN
@ IN
Input port.
Definition: HDBTypes.hh:41
TTAMachine::HWOperation::pipeline
ExecutionPipeline * pipeline() const
Definition: HWOperation.cc:201
TTAMachine::ExecutionPipeline
Definition: ExecutionPipeline.hh:55
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
TTAMachine::HWOperation::latency
int latency() const
Definition: HWOperation.cc:216
TTAMachine::FunctionUnit::operationPort
virtual FUPort * operationPort(const std::string &name) const
Definition: FunctionUnit.cc:224
TTAMachine
Definition: Assembler.hh:48
TTAMachine::FunctionUnit::copy
virtual FunctionUnit * copy() const
Definition: FunctionUnit.cc:103
HDB::FUArchitecture::guardedPorts_
PortSet guardedPorts_
Port that support guard.
Definition: FUArchitecture.hh:88
HDB::OUT
@ OUT
Output port.
Definition: HDBTypes.hh:42
TTAMachine::BaseFUPort::width
virtual int width() const
Definition: BaseFUPort.cc:109
InstanceNotFound
Definition: Exception.hh:304
TTAMachine::ExecutionPipeline::isResourceUsed
bool isResourceUsed(const std::string &name, int cycle) const
Definition: ExecutionPipeline.cc:300
FunctionUnit.hh