OpenASIP 2.2
Loading...
Searching...
No Matches
GenerateProcessor.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 GenerateProcessor.cc
26 *
27 * Implementation of GenerateProcessor class and the main program of
28 * "generateprocessor".
29 *
30 * @author Lasse Laasonen 2005 (lasse.laasonen-no.spam-tut.fi)
31 * @author Otto Esko 2008 (otto.esko-no.spam-tut.fi)
32 * @author Pekka Jaaskelainen 2011
33 * @author Vinogradov Viacheslav(added Verilog generating) 2012
34 * @note rating: red
35 */
36
37#include <string>
38#include <iostream>
39
40#include "GenerateProcessor.hh"
42#include "FileSystem.hh"
43#include "Environment.hh"
44#include "PluginTools.hh"
46#include "Machine.hh"
47#include "BinaryEncoding.hh"
50#include "KoskiIntegrator.hh"
51#include "AvalonIntegrator.hh"
52#include "AlmaIFIntegrator.hh"
53#include "MemoryGenerator.hh"
54#include "StringTools.hh"
55
56using namespace ProGe;
57using std::cerr;
58using std::cout;
59using std::endl;
60using std::string;
61using std::vector;
62
64
65/**
66 * The main program of generateprocessor application.
67 */
68int main(int argc, char* argv[]) {
70 bool successful = ui.generateProcessor(argc, argv);
71 if (successful) {
72 return EXIT_SUCCESS;
73 } else {
74 return EXIT_FAILURE;
75 }
76}
77
78
79/**
80 * The constructor.
81 */
84
85
86/**
87 * The destructor.
88 */
91
92
93/**
94 * Parses the command line arguments and generates the processor.
95 *
96 * @return True if the generation of the processor was succesful, otherwise
97 * false.
98 */
99bool
101
103 string entity = "";
104
105 try {
106
107 options.parse(argv, argc);
108 ProGeOptions progeOptions(options);
109
110 std::string pluginParamQuery = options.pluginParametersQuery();
111 if (pluginParamQuery != "") {
112 return listICDecPluginParameters(pluginParamQuery);
113 }
114
118 }
119
122 }
123
124 if (options.listAvailableIntegrators()) {
126 return true;
127 }
128
129 if (options.numberOfArguments() == 0) {
131 return false;
132 }
133
136 return false;
137 }
138
139 if (!options.forceOutputDirectory() &&
141 cerr << "Error: Output directory " << progeOptions.outputDirectory
142 << " already exists." << endl;
143 return false;
144 }
145
146 string processorDefinition = options.processorToGenerate();
147 if (FileSystem::fileExtension(processorDefinition) == ".adf") {
148 loadMachine(processorDefinition);
149 } else if (FileSystem::fileExtension(processorDefinition) ==
150 ".pcf") {
151 loadProcessorConfiguration(processorDefinition);
152 } else {
153 cerr << "Unknown file: " << processorDefinition
154 << ". The given file must be either an ADF or PCF file."
155 << endl;
156 throw IllegalCommandLine(__FILE__, __LINE__, __func__);
157 }
158
159 string bem = options.bemFile();
160 string idf = options.idfFile();
161 string hdl = options.hdl();
162
163 int imemWidthInMAUs = DEFAULT_IMEMWIDTH_IN_MAUS;
164 if (machine_->isRISCVMachine()) {
165 imemWidthInMAUs = 4;
166 }
167
168 if (bem != "") {
170 }
171 if (idf != "") {
173 }
174
176 progeOptions, imemWidthInMAUs, std::cerr, std::cerr, std::cerr);
177 } catch (ParserStopRequest const&) {
178 return false;
179 } catch (const IllegalCommandLine& exception) {
180 cerr << exception.errorMessage() << endl;
181 return false;
182 } catch (const Exception& e) {
183 cerr << e.errorMessage() << endl;
184 cerr << "Exception thrown at: " << e.fileName() << ":"
185 << e.lineNum() << endl;
186 cerr << " message: " << e.errorMessage() << endl;
187 return false;
188 }
189
190 ProGeOptions progeOptions(options);
191
192 string integrator = options.integratorName();
193 if (!integrator.empty()) {
194 if (progeOptions.language == Verilog) {
195 std::cerr << "Verilog is not yet supported by Platform Integrator"
196 << std::endl;
197 return false;
198 }
199
200 string progeOutDir = progeOptions.outputDirectory;
201 string sharedOutDir = progeOptions.sharedOutputDirectory;
202 if (!options.useAbsolutePaths()) {
203 string cwd = FileSystem::currentWorkingDir();
204 FileSystem::relativeDir(cwd, progeOutDir);
205 FileSystem::relativeDir(cwd, sharedOutDir);
206 }
207
208 string platformDir = progeOutDir + FileSystem::DIRECTORY_SEPARATOR +
209 "platform";
210 string program =
211 StringTools::chopString(options.tpefName(), ".tpef").at(0);
212 MemType imem = string2MemType(options.imemType());
213 MemType dmem = string2MemType(options.dmemType());
214 int fmax = options.clockFrequency();
215 string devFamily = options.deviceFamilyName();
216 string devName = options.deviceName();
217 bool syncReset = options.syncReset();
218
219 try {
221 std::cout, std::cerr, progeOutDir, sharedOutDir, integrator,
222 progeOptions.entityName, program, devFamily, devName, imem,
223 dmem, progeOptions.language, fmax, syncReset,
224 options.generateTestbench());
225 } catch (const Exception& e) {
226 std::cerr << "Processor integration failed: "
227 << e.procedureName() << ": "
228 << e.errorMessage() << endl;
229 return false;
230 }
231 }
232
233 if (options.generateTestbench()) {
234 string testBenchDir = progeOptions.outputDirectory +
236 try {
238 progeOptions.language, testBenchDir,
239 progeOptions.outputDirectory);
240 } catch (const Exception& e) {
241 std::cerr << "Warning: Processor Generator failed to "
242 << "generate testbench." << std::endl;
243 std::cerr << e.errorMessage() << std::endl;
244 }
245
246 try {
248 progeOptions.language, progeOptions.outputDirectory,
249 progeOptions.outputDirectory,
250 progeOptions.sharedOutputDirectory, testBenchDir,
251 progeOptions.simulationRuntime);
252 } catch (const Exception& e) {
253 std::cerr << "Warning: Processor Generator failed to "
254 << "generate simulation/compilation scripts."
255 << std::endl;
256 std::cerr << e.errorMessage() << std::endl;
257 }
258 }
259
260 return true;
261}
262
263/**
264 * Generates the output directory name.
265 *
266 * @param options Proge command line options.
267 * @param outputDir String where output directory name is to be stored.
268 */
269void
272 std::string& outputDir) {
273
274 outputDir = options.outputDirectory();
275
276 if (outputDir == "") {
277 outputDir = FileSystem::currentWorkingDir() +
278 FileSystem::DIRECTORY_SEPARATOR + "proge-output";
279 } else {
280 outputDir = FileSystem::expandTilde(outputDir);
281 outputDir = FileSystem::absolutePathOf(outputDir);
282 }
283}
284
285/**
286 * Prints listing of IC/Decoder generator plugin parameters to stdout.
287 *
288 * @param pluginFile Full path to the plugin file.
289 */
290bool
292 const std::string& pluginFile) const {
293
294 // An ugly way to determine the plugin name which should be the
295 // file name minus the "Plugin.so" ending.
296 string pluginName = FileSystem::fileOfPath(pluginFile);
297 pluginName = FileSystem::fileNameBody(pluginFile);
298 if (pluginName.length() < 6 ||
299 pluginName.substr(pluginName.length() - 6) != "Plugin") {
300
301 cerr << "Unable to determine plugin name. Plugin file must be named "
302 << "'<plugin name>Plugin.so'." << endl;;
303 return false;
304 }
305
306 pluginName = pluginName.substr(0, pluginName.length() - 6);
307
308 // initialize plugin tool
309 PluginTools pluginTool;
310 std::vector<string> pluginPaths = Environment::icDecoderPluginPaths();
311 for (std::vector<string>::const_iterator iter = pluginPaths.begin();
312 iter != pluginPaths.end(); iter++) {
313 try {
314 pluginTool.addSearchPath(*iter);
315 } catch (const FileNotFound&) {
316 }
317 }
318
319 try {
320 pluginTool.registerModule(pluginFile);
321 } catch (const FileNotFound&) {
322 cerr << "Plugin file '" << pluginFile << "' not found." << endl;
323 return false;
324 } catch (Exception& e) {
325 cerr << "Error loading plugin file '" << pluginFile << "': "
326 << e.errorMessage() << endl;
327
328 return false;
329 }
330
331
332 ICDecoderGeneratorPlugin* (*creator)(
334
336
338 BinaryEncoding bem;
339
340 try {
341 pluginTool.importSymbol(
342 "create_generator_plugin_" + pluginName, creator, pluginFile);
343
344 plugin = creator(machine, bem);
345 } catch (Exception& e) {
346 cerr << "Error loading plugin '" << pluginName << "' from '"
347 << pluginFile << "':" << endl;
348 cerr << e.errorMessage() << endl;
349 return false;
350 }
351
352 assert(plugin != NULL);
353
354 cout << pluginName << ":" << endl;
355 cout << plugin->pluginDescription() << endl << endl;
356 cout << "Recognized parameters:" << endl
357 << "----------------------" << endl;
358
359 for (int i = 0; i < plugin->recognizedParameterCount(); i++) {
360 std::string paramName = plugin->recognizedParameter(i);
361 cout << paramName << endl;
362 cout << " " << plugin->parameterDescription(paramName) << endl;
363 cout << endl;
364 }
365 cout << "----------------------" << endl;
366
367 delete plugin;
368 return true;
369}
370
371
372void
374
375 std::vector<PlatformIntegrator*> integrators;
376 // append new integrators here
377 integrators.push_back(new Stratix2DSPBoardIntegrator());
378 integrators.push_back(new Stratix3DevKitIntegrator());
379 integrators.push_back(new KoskiIntegrator());
380 integrators.push_back(new AvalonIntegrator());
381 integrators.push_back(new AlmaIFIntegrator());
382
383 for (unsigned int i = 0; i < integrators.size(); i++) {
384 integrators.at(i)->printInfo(std::cout);
385 delete integrators.at(i);
386 }
387 std::cout << "Please refer to the user manual for more information on "
388 << "Platform Integrators." << std::endl;
389}
390
391
392bool
394 const ProGeCmdLineOptions& options) const {
395
396 if (options.integratorName().empty()) {
397 return true;
398 }
399 string entity = options.entityName();
400 if (entity.empty()) {
401 std::cerr << "Entity name must be given" << endl;
402 return false;
403 }
404 string program = options.tpefName();
405 if (program.empty()) {
406 std::cerr
407 << "Tpef is required for platform integration" << endl;
408 return false;
409 }
410 if (!StringTools::endsWith(program, ".tpef")) {
411 std::cerr << "Program does not have '.tpef' ending" << endl;
412 return false;
413 }
414
415 string imem = options.imemType();
416 if (imem.empty()) {
417 std::cerr << "Instruction memory type is required for platform "
418 << "integration" << endl;
419 return false;
420 }
421 string dmem = options.dmemType();
422 if (dmem.empty()) {
423 std::cerr << "Data memory type is required for platform integration"
424 << endl;
425 return false;
426 }
427 if (string2MemType(imem) == UNKNOWN) {
428 std::cerr
429 << "Invalid instruction memory type " << imem << endl;
430 return false;
431 }
432 if (string2MemType(dmem) == UNKNOWN) {
433 std::cerr << "Invalid data memory type " << dmem << endl;
434 return false;
435 }
436 return true;
437}
438
439
441GenerateProcessor::string2MemType(const std::string& memoryString) const {
442
443 MemType memory = UNKNOWN;
444 if (memoryString == "none") {
445 memory = NONE;
446 } else if (memoryString == "vhdl_array") {
447 memory = VHDL_ARRAY;
448 } else if (memoryString == "onchip") {
449 memory = ONCHIP;
450 } else if (memoryString == "sram") {
451 memory = SRAM;
452 } else if (memoryString == "dram") {
453 memory = DRAM;
454 }
455 return memory;
456}
#define __func__
#define assert(condition)
TTAMachine::Machine * machine
the architecture definition of the estimated processor
const int DEFAULT_IMEMWIDTH_IN_MAUS
int main(int argc, char *argv[])
int const DEFAULT_IMEMWIDTH_IN_MAUS
find Finds info of the inner loops in the program
static MachInfoCmdLineOptions options
Definition MachInfo.cc:46
@ VHDL_ARRAY
@ ONCHIP
@ UNKNOWN
@ SRAM
@ NONE
@ DRAM
static const int VERBOSE_LEVEL_INCREASED
Increased verbose level - print information about modules etc.
static const int VERBOSE_LEVEL_SPAM
More Increased verbose level - spam about ddg heights of loops.
static void setVerboseLevel(const int level=VERBOSE_LEVEL_DEFAULT)
void parse(char *argv[], int argc)
virtual bool isVerboseSwitchDefined() const
virtual bool isVerboseSpamSwitchDefined() const
virtual int numberOfArguments() const
static std::vector< std::string > icDecoderPluginPaths(bool libraryPathsOnly=false)
std::string fileName() const
std::string errorMessage() const
Definition Exception.cc:123
std::string procedureName() const
int lineNum() const
static std::string absolutePathOf(const std::string &pathName)
static const std::string DIRECTORY_SEPARATOR
static std::string fileNameBody(const std::string &fileName)
static std::string fileOfPath(const std::string pathName)
static std::string fileExtension(const std::string &fileName)
static std::string currentWorkingDir()
static bool relativeDir(const std::string &baseDir, std::string &toRelDir)
static bool fileExists(const std::string fileName)
static std::string expandTilde(const std::string &stringWithTilde)
bool generateProcessor(int argc, char *argv[])
bool validIntegratorParameters(const ProGeCmdLineOptions &options) const
void getOutputDir(const ProGeCmdLineOptions &options, std::string &outputDir)
void listIntegrators() const
MemType string2MemType(const std::string &memoryString) const
bool listICDecPluginParameters(const std::string &pluginFile) const
virtual void printHelp() const
void importSymbol(const std::string &symbolName, T *&target, const std::string &module)
void addSearchPath(const std::string &searchPath)
void registerModule(const std::string &module)
TTAMachine::Machine * machine_
The loaded machine.
Definition ProGeUI.hh:107
void loadBinaryEncoding(const BinaryEncoding &bem)
Definition ProGeUI.cc:170
void generateScripts(const ProGe::HDL language, const std::string &dstDir, const std::string &progeOutDir, const std::string &sharedOutDir, const std::string &testBenchDir, const std::string &simulationRuntime)
Definition ProGeUI.cc:416
void loadMachineImplementation(const IDF::MachineImplementation &idf)
Definition ProGeUI.cc:175
void generateProcessor(const ProGeOptions &options, int imemWidthInMAUs, std::ostream &errorStream, std::ostream &warningStream, std::ostream &verboseStream)
Definition ProGeUI.cc:298
void generateTestBench(const ProGe::HDL language, const std::string &dstDir, const std::string &progeOutDir)
Definition ProGeUI.cc:375
void integrateProcessor(std::ostream &warningStream, std::ostream &errorStream, std::string progeOutDir, std::string sharedOutputDir, const std::string &platformIntegrator, const std::string &coreEntityName, const std::string &programName, const std::string &deviceFamily, const std::string &deviceName, MemType imem, MemType dmem, HDL language, int fmax, bool syncReset, bool generateIntegratedTestbench)
Definition ProGeUI.cc:443
void loadProcessorConfiguration(const std::string &configurationFile)
Definition ProGeUI.cc:190
void loadMachine(const TTAMachine::Machine &adf)
Definition ProGeUI.cc:165
static bool endsWith(const std::string &source, const std::string &searchString)
static std::vector< TCEString > chopString(const std::string &source, const std::string &delimiters)
bool isRISCVMachine() const
Definition Machine.cc:1057
Definition FUGen.hh:54
@ Verilog
Verilog.
Definition ProGeTypes.hh:42
std::string sharedOutputDirectory
ProGe::HDL language
std::string simulationRuntime
std::string outputDirectory
std::string entityName