OpenASIP 2.2
Loading...
Searching...
No Matches
VectorLSGenerator.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2012 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 VectorLSGenerator.cc
26 *
27 * Explorer plugin creates wide load/store unit.
28 *
29 * @author Vladimir Guzma 2012 (vladimir.guzma-no.spam-tut.fi)
30 * @note rating: red
31 */
32
33#include <vector>
34#include <string>
36#include "DSDBManager.hh"
37#include "Machine.hh"
38#include "HDBRegistry.hh"
39#include "StringTools.hh"
40#include "RFPort.hh"
41#include "FUPort.hh"
43#include "Exception.hh"
44#include "Segment.hh"
45#include "HWOperation.hh"
46#include "ExecutionPipeline.hh"
47#include "Guard.hh"
48#include "OperationPool.hh"
49#include "OperationIndex.hh"
50#include "Operation.hh"
51#include "MathTools.hh"
52#include "Conversion.hh"
53
54//using namespace TTAProgram;
55using namespace TTAMachine;
56using namespace HDB;
57using std::endl;
58
59/**
60 * Explorer plugin that creates wide load store unit.
61 *
62 * Supported parameters:
63 * - node_count, number of times the input architecture is copied to new one,
64 * default is 4.
65 * - address_spaces, semicolon separated names of the address spaces for which
66 * the LSUs will be created, default is 'data'
67 */
69 PLUGIN_DESCRIPTION("Explorer plugin that creates wide load/store unit.");
70
72 nodeCount_(4),
73 addressSpaces_("data") {
74
75
76 // parameters that have a default value
81
82 }
83
84 virtual bool requiresStartingPointArchitecture() const { return true; }
85 virtual bool producesArchitecture() const { return true; }
86 virtual bool requiresHDB() const { return false; }
87 virtual bool requiresSimulationData() const { return false; }
88 virtual bool requiresApplication() const { return false; }
89
90 /**
91 * Explorer plugin that adds machine components to a given machine with
92 * adf parameter or with configuration id in dsdb.
93 */
94 virtual std::vector<RowID>
95 explore(const RowID& configurationID, const unsigned int&) {
97 std::vector<RowID> result;
98
99 DSDBManager& dsdb = db();
101 dsdb.configuration(configurationID);
102 TTAMachine::Machine* mach = NULL;
103 try {
104 mach = dsdb.architecture(conf.architectureID);
105 } catch (const Exception& e) {
106 throw Exception(
107 __FILE__, __LINE__, __func__, e.errorMessageStack());
108 }
109
111 mach->addressSpaceNavigator();
112 TTAMachine::AddressSpace* addrSpace = NULL;
113 std::vector<TCEString> addressSpaces =
115 for (unsigned int i = 0; i < addressSpaces.size(); i++) {
116 if (!addrNav.hasItem(addressSpaces[i])) {
117 TCEString msg = "Original architecture does not have \""
118 + addressSpaces[i] +"\" address space. Not adding Vector LSU.";
119 throw Exception(
120 __FILE__, __LINE__, __func__, msg);
121 }
122
123 addrSpace = addrNav.item(addressSpaces[i]);
124
125 if (addrSpace == NULL) {
126 }
127 TTAMachine::FunctionUnit* lsUnit =
128 new TTAMachine::FunctionUnit("VectorLSU_" + addrSpace->name());
129
130 createVectorLSU(*lsUnit, *addrSpace);
131
132 try {
133 mach->addFunctionUnit(*lsUnit);
134 } catch (const Exception& e) {
135 throw Exception(
136 __FILE__, __LINE__, __func__, e.errorMessageStack());
137 }
138 try {
139 lsUnit->setAddressSpace(addrSpace);
140 } catch (const Exception& e) {
141 throw Exception(
142 __FILE__, __LINE__, __func__, e.errorMessageStack());
143 }
144 }
145
147 try {
148 tempConf.architectureID = dsdb.addArchitecture(*mach);
149 tempConf.hasImplementation = false;
150 } catch (const RelationalDBException& e) {
151 TCEString msg = "Error while adding ADF to the dsdb. "
152 "ADF probably too big.";
153 throw Exception(
154 __FILE__, __LINE__, __func__, msg);
155 }
156 // add config to database to pass it to
157 // RemoveUnconnectedComponents plugin
158 RowID tempConfID = dsdb.addConfiguration(tempConf);
159 result.push_back(tempConfID);
160 return result;
161
162 }
163
164private:
165 /// Selector used by the plugin.
167
168 static const TCEString NodeCountPN_;
170
173
174 /**
175 * Reads the parameters given to the plugin.
176 */
181 /**
182 * Adds operation to function unit, sets the port bindings and pipeline
183 * parameters.
184 */
186 TTAMachine::FunctionUnit& lsUnit, Operation& op, bool scalar) {
187
189 new TTAMachine::HWOperation(op.name(), lsUnit);
190 TTAMachine::ExecutionPipeline* pipeline = hwOp->pipeline();
191
192 // Specificly define the triggering port
193 hwOp->bindPort(1, *lsUnit.operationPort("in1t"));
194 pipeline->addPortRead(1,0,1);
195 if (scalar) {
196 if (op.numberOfInputs() == 2) {
197 // this is stw operation
198 hwOp->bindPort(2, *lsUnit.operationPort("in_extra2"));
199 pipeline->addPortRead(2, 0, 1);
200 }
201 if (op.numberOfOutputs() == 1) {
202 // this is ldw operation
203 hwOp->bindPort(2, *lsUnit.operationPort("out_extra1"));
204 pipeline->addPortWrite(2, 2, 1);
205 }
206 assert(hwOp->isBound(*lsUnit.operationPort("in1t")));
207 return;
208 }
209 // Add other inputs, after triggering port.
210 for (int i = 1; i < op.numberOfInputs(); i++) {
211 hwOp->bindPort(
212 i+1, *lsUnit.operationPort("in" + Conversion::toString(i+1)));
213 pipeline->addPortRead(i+1,0,1);
214 }
215 // Add other outputs, after triggering port.
216 for (int i = 1; i <= op.numberOfOutputs(); i++) {
217 hwOp->bindPort(
218 i+1, *lsUnit.operationPort("out" + Conversion::toString(i)));
219 pipeline->addPortWrite(i+1,2,1);
220 }
221 assert(hwOp->isBound(*lsUnit.operationPort("in1t")));
222 }
223
224 /**
225 * Create single instance of vector load store unit, starting from empty
226 * unit.
227 */
230 TTAMachine::AddressSpace& addrSpace) {
231
232 TTAMachine::FUPort* trigger =
233 new TTAMachine::FUPort("in1t",
234 MathTools::requiredBits(addrSpace.end()),
235 lsUnit, true, true);
236 assert(trigger->isTriggering());
237 int width = (nodeCount_ >= 8) ? 8 :
238 (nodeCount_ >= 4) ? 4 :
239 (nodeCount_ >= 2) ? 2 : 0;
240 if (width == 0) {
241 TCEString msg = "No reason for creating wide LSU since number"
242 " of nodes in cluster is just " + Conversion::toString(nodeCount_);
243 throw Exception(
244 __FILE__, __LINE__, __func__, msg);
245 }
246 for (int i = 1; i <= width; i++) {
247 TTAMachine::FUPort* inPort =
249 "in" + Conversion::toString(i+1), 32, lsUnit, false, false);
250 assert(inPort->isOpcodeSetting() == false);
251 TTAMachine::FUPort* outPort =
253 "out" + Conversion::toString(i), 32, lsUnit, false, false);
254 assert(outPort->isOpcodeSetting() == false);
255 }
256 TTAMachine::FUPort* inPort =
258 "in_extra" + Conversion::toString(2), 32, lsUnit, false, false);
259 assert(inPort->isOpcodeSetting() == false);
260 TTAMachine::FUPort* outPort =
262 "out_extra" + Conversion::toString(1), 32, lsUnit, false, false);
263 assert(outPort->isOpcodeSetting() == false);
264
265 // Adds aditional read and write port for use with scalar load
266 // and stores from the extras
267
268 OperationPool pool;
269 OperationIndex& index = pool.index();
270 for (int m = 0; m < index.moduleCount(); m++) {
271 OperationModule& module = index.module(m);
272 for (int i = 0; i < index.operationCount(module); i++) {
273 TCEString opName = index.operationName(i, module);
274 Operation& op = pool.operation(opName.c_str());
275 // Creates HWOperations for memory access operations with
276 // number as suffix. ATM this means vector operation.
277 if (op.usesMemory() &&
278 (opName.endsWith("2") ||
279 opName.endsWith("4") ||
280 opName.endsWith("8"))) {
281 if (!lsUnit.hasOperation(opName) &&
282 op.numberOfInputs() <= nodeCount_ +1 &&
283 op.numberOfOutputs() <= nodeCount_) {
284 addOperation(lsUnit, op, false);
285 }
286 }
287 if (op.usesMemory() &&
288 opName.startsWith("LD") &&
289 op.numberOfInputs() == 1 &&
290 op.numberOfOutputs() == 1 &&
291 !lsUnit.hasOperation(opName)) {
292 addOperation(lsUnit, op, true);
293 }
294 if (op.usesMemory() &&
295 opName.startsWith("ST") &&
296 op.numberOfInputs() == 2 &&
297 op.numberOfOutputs() == 0 &&
298 !lsUnit.hasOperation(opName)) {
299 addOperation(lsUnit, op, true);
300 }
301 }
302 }
303
304 }
305};
306
307// parameters
309const TCEString VectorLSGenerator::AddressSpacesPN_("address_spaces");
310
#define __func__
#define assert(condition)
int RowID
Type definition of row ID in relational databases.
Definition DBTypes.hh:37
#define EXPORT_DESIGN_SPACE_EXPLORER_PLUGIN(PLUGIN_NAME__)
#define UINT(OPERAND)
Definition OSAL.hh:313
static std::string toString(const T &source)
RowID addArchitecture(const TTAMachine::Machine &mom)
TTAMachine::Machine * architecture(RowID id) const
MachineConfiguration configuration(RowID id) const
RowID addConfiguration(const MachineConfiguration &conf)
void readOptionalParameter(const std::string paramName, T &param) const
void addParameter(TCEString name, ExplorerPluginParameterType type, bool compulsory=true, TCEString defaultValue="", TCEString description="")
virtual DSDBManager & db()
std::string errorMessageStack(bool messagesOnly=false) const
Definition Exception.cc:138
static int requiredBits(unsigned long int number)
std::string operationName(int i, const OperationModule &om)
int operationCount(const OperationModule &om)
int moduleCount() const
virtual TCEString name() const
Definition Operation.cc:93
virtual bool usesMemory() const
Definition Operation.cc:232
virtual int numberOfInputs() const
Definition Operation.cc:192
virtual int numberOfOutputs() const
Definition Operation.cc:202
static std::vector< TCEString > chopString(const std::string &source, const std::string &delimiters)
bool startsWith(const std::string &str) const
bool endsWith(const std::string &str) const
virtual ULongWord end() const
virtual TCEString name() const
void addPortRead(int operand, int start, int duration)
void addPortWrite(int operand, int start, int duration)
virtual bool isTriggering() const
Definition FUPort.cc:182
virtual bool isOpcodeSetting() const
Definition FUPort.cc:195
virtual FUPort * operationPort(const std::string &name) const
virtual void setAddressSpace(AddressSpace *as)
virtual bool hasOperation(const std::string &name) const
ExecutionPipeline * pipeline() const
virtual void bindPort(int operand, const FUPort &port)
bool isBound(const FUPort &port) const
ComponentType * item(int index) const
bool hasItem(const std::string &name) const
virtual void addFunctionUnit(FunctionUnit &unit)
Definition Machine.cc:202
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition Machine.cc:392
virtual bool requiresSimulationData() const
virtual bool requiresApplication() const
virtual bool requiresStartingPointArchitecture() const
ComponentImplementationSelector selector_
Selector used by the plugin.
void createVectorLSU(TTAMachine::FunctionUnit &lsUnit, TTAMachine::AddressSpace &addrSpace)
virtual bool requiresHDB() const
static const TCEString AddressSpacesPN_
virtual std::vector< RowID > explore(const RowID &configurationID, const unsigned int &)
void addOperation(TTAMachine::FunctionUnit &lsUnit, Operation &op, bool scalar)
PLUGIN_DESCRIPTION("Explorer plugin that creates wide load/store unit.")
virtual bool producesArchitecture() const
static const TCEString NodeCountPN_