OpenASIP  2.0
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"
41 #include "ProGeCmdLineOptions.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 
56 using namespace ProGe;
57 using std::cerr;
58 using std::cout;
59 using std::endl;
60 using std::string;
61 using std::vector;
62 
64 
65 /**
66  * The main program of generateprocessor application.
67  */
68 int 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  */
83 }
84 
85 
86 /**
87  * The destructor.
88  */
90 }
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  */
99 bool
100 GenerateProcessor::generateProcessor(int argc, char* argv[]) {
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()) {
125  listIntegrators();
126  return true;
127  }
128 
129  if (options.numberOfArguments() == 0) {
130  options.printHelp();
131  return false;
132  }
133 
134  if (!validIntegratorParameters(options)) {
135  options.printHelp();
136  return false;
137  }
138 
139  if (!options.forceOutputDirectory() &&
140  FileSystem::fileExists(progeOptions.outputDirectory)) {
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 != "") {
169  loadBinaryEncoding(bem);
170  }
171  if (idf != "") {
172  loadMachineImplementation(idf);
173  }
174 
176  progeOptions, imemWidthInMAUs, std::cerr, std::cerr, std::cerr);
177  } catch (ParserStopRequest) {
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  if (options.generateTestbench()) {
193  string testBenchDir = progeOptions.outputDirectory +
195  try {
197  progeOptions.language, testBenchDir,
198  progeOptions.outputDirectory);
199  } catch (const Exception& e) {
200  std::cerr << "Warning: Processor Generator failed to "
201  << "generate testbench." << std::endl;
202  std::cerr << e.errorMessage() << std::endl;
203  }
204 
205  try {
207  progeOptions.language, progeOptions.outputDirectory,
208  progeOptions.outputDirectory,
209  progeOptions.sharedOutputDirectory, testBenchDir,
210  progeOptions.simulationRuntime);
211  } catch (const Exception& e) {
212  std::cerr << "Warning: Processor Generator failed to "
213  << "generate simulation/compilation scripts."
214  << std::endl;
215  std::cerr << e.errorMessage() << std::endl;
216  }
217  }
218 
219  string integrator = options.integratorName();
220  if (!integrator.empty()) {
221  if (progeOptions.language == Verilog) {
222  std::cerr << "Verilog is not yet supported by Platform Integrator"
223  << std::endl;
224  return false;
225  }
226 
227  string progeOutDir = progeOptions.outputDirectory;
228  string sharedOutDir = progeOptions.sharedOutputDirectory;
229  if (!options.useAbsolutePaths()) {
230  string cwd = FileSystem::currentWorkingDir();
231  FileSystem::relativeDir(cwd, progeOutDir);
232  FileSystem::relativeDir(cwd, sharedOutDir);
233  }
234 
235  string platformDir = progeOutDir + FileSystem::DIRECTORY_SEPARATOR +
236  "platform";
237  string program =
238  StringTools::chopString(options.tpefName(), ".tpef").at(0);
239  MemType imem = string2MemType(options.imemType());
240  MemType dmem = string2MemType(options.dmemType());
241  int fmax = options.clockFrequency();
242  string devFamily = options.deviceFamilyName();
243  string devName = options.deviceName();
244  bool syncReset = options.syncReset();
245 
246  try {
248  std::cout, std::cerr, progeOutDir, sharedOutDir, integrator,
249  progeOptions.entityName, program, devFamily, devName, imem,
250  dmem, progeOptions.language, fmax, syncReset);
251  } catch (const Exception& e) {
252  std::cerr << "Processor integration failed: "
253  << e.procedureName() << ": "
254  << e.errorMessage() << endl;
255  return false;
256  }
257  }
258 
259  return true;
260 }
261 
262 /**
263  * Generates the output directory name.
264  *
265  * @param options Proge command line options.
266  * @param outputDir String where output directory name is to be stored.
267  */
268 void
271  std::string& outputDir) {
272 
273  outputDir = options.outputDirectory();
274 
275  if (outputDir == "") {
276  outputDir = FileSystem::currentWorkingDir() +
277  FileSystem::DIRECTORY_SEPARATOR + "proge-output";
278  } else {
279  outputDir = FileSystem::expandTilde(outputDir);
280  outputDir = FileSystem::absolutePathOf(outputDir);
281  }
282 }
283 
284 /**
285  * Prints listing of IC/Decoder generator plugin parameters to stdout.
286  *
287  * @param pluginFile Full path to the plugin file.
288  */
289 bool
291  const std::string& pluginFile) const {
292 
293  // An ugly way to determine the plugin name which should be the
294  // file name minus the "Plugin.so" ending.
295  string pluginName = FileSystem::fileOfPath(pluginFile);
296  pluginName = FileSystem::fileNameBody(pluginFile);
297  if (pluginName.length() < 6 ||
298  pluginName.substr(pluginName.length() - 6) != "Plugin") {
299 
300  cerr << "Unable to determine plugin name. Plugin file must be named "
301  << "'<plugin name>Plugin.so'." << endl;;
302  return false;
303  }
304 
305  pluginName = pluginName.substr(0, pluginName.length() - 6);
306 
307  // initialize plugin tool
308  PluginTools pluginTool;
309  std::vector<string> pluginPaths = Environment::icDecoderPluginPaths();
310  for (std::vector<string>::const_iterator iter = pluginPaths.begin();
311  iter != pluginPaths.end(); iter++) {
312  try {
313  pluginTool.addSearchPath(*iter);
314  } catch (const FileNotFound&) {
315  }
316  }
317 
318  try {
319  pluginTool.registerModule(pluginFile);
320  } catch (const FileNotFound&) {
321  cerr << "Plugin file '" << pluginFile << "' not found." << endl;
322  return false;
323  } catch (Exception& e) {
324  cerr << "Error loading plugin file '" << pluginFile << "': "
325  << e.errorMessage() << endl;
326 
327  return false;
328  }
329 
330 
331  ICDecoderGeneratorPlugin* (*creator)(
333 
334  ICDecoderGeneratorPlugin* plugin;
335 
337  BinaryEncoding bem;
338 
339  try {
340  pluginTool.importSymbol(
341  "create_generator_plugin_" + pluginName, creator, pluginFile);
342 
343  plugin = creator(machine, bem);
344  } catch (Exception& e) {
345  cerr << "Error loading plugin '" << pluginName << "' from '"
346  << pluginFile << "':" << endl;
347  cerr << e.errorMessage() << endl;
348  return false;
349  }
350 
351  assert(plugin != NULL);
352 
353  cout << pluginName << ":" << endl;
354  cout << plugin->pluginDescription() << endl << endl;
355  cout << "Recognized parameters:" << endl
356  << "----------------------" << endl;
357 
358  for (int i = 0; i < plugin->recognizedParameterCount(); i++) {
359  std::string paramName = plugin->recognizedParameter(i);
360  cout << paramName << endl;
361  cout << " " << plugin->parameterDescription(paramName) << endl;
362  cout << endl;
363  }
364  cout << "----------------------" << endl;
365 
366  delete plugin;
367  return true;
368 }
369 
370 
371 void
373 
374  std::vector<PlatformIntegrator*> integrators;
375  // append new integrators here
376  integrators.push_back(new Stratix2DSPBoardIntegrator());
377  integrators.push_back(new Stratix3DevKitIntegrator());
378  integrators.push_back(new KoskiIntegrator());
379  integrators.push_back(new AvalonIntegrator());
380  integrators.push_back(new AlmaIFIntegrator());
381 
382  for (unsigned int i = 0; i < integrators.size(); i++) {
383  integrators.at(i)->printInfo(std::cout);
384  delete integrators.at(i);
385  }
386  std::cout << "Please refer to the user manual for more information on "
387  << "Platform Integrators." << std::endl;
388 }
389 
390 
391 bool
393  const ProGeCmdLineOptions& options) const {
394 
395  if (options.integratorName().empty()) {
396  return true;
397  }
398  string entity = options.entityName();
399  if (entity.empty()) {
400  std::cerr << "Entity name must be given" << endl;
401  return false;
402  }
403  string program = options.tpefName();
404  if (program.empty()) {
405  std::cerr
406  << "Tpef is required for platform integration" << endl;
407  return false;
408  }
409  if (!StringTools::endsWith(program, ".tpef")) {
410  std::cerr << "Program does not have '.tpef' ending" << endl;
411  return false;
412  }
413 
414  string imem = options.imemType();
415  if (imem.empty()) {
416  std::cerr << "Instruction memory type is required for platform "
417  << "integration" << endl;
418  return false;
419  }
420  string dmem = options.dmemType();
421  if (dmem.empty()) {
422  std::cerr << "Data memory type is required for platform integration"
423  << endl;
424  return false;
425  }
426  if (string2MemType(imem) == UNKNOWN) {
427  std::cerr
428  << "Invalid instruction memory type " << imem << endl;
429  return false;
430  }
431  if (string2MemType(dmem) == UNKNOWN) {
432  std::cerr << "Invalid data memory type " << dmem << endl;
433  return false;
434  }
435  return true;
436 }
437 
438 
439 MemType
440 GenerateProcessor::string2MemType(const std::string& memoryString) const {
441 
442  MemType memory = UNKNOWN;
443  if (memoryString == "none") {
444  memory = NONE;
445  } else if (memoryString == "vhdl_array") {
446  memory = VHDL_ARRAY;
447  } else if (memoryString == "onchip") {
448  memory = ONCHIP;
449  } else if (memoryString == "sram") {
450  memory = SRAM;
451  } else if (memoryString == "dram") {
452  memory = DRAM;
453  }
454  return memory;
455 }
GenerateProcessor::generateProcessor
bool generateProcessor(int argc, char *argv[])
Definition: GenerateProcessor.cc:100
StringTools::endsWith
static bool endsWith(const std::string &source, const std::string &searchString)
Definition: StringTools.cc:126
GenerateProcessor
Definition: GenerateProcessor.hh:46
GenerateProcessor.hh
ProGeCmdLineOptions.hh
MachInfoCmdLineOptions::printHelp
virtual void printHelp() const
Definition: MachInfoCmdLineOptions.cc:89
BinaryEncoding
Definition: BinaryEncoding.hh:61
Exception::procedureName
std::string procedureName() const
AvalonIntegrator
Definition: AvalonIntegrator.hh:39
FileSystem.hh
Exception::lineNum
int lineNum() const
FileNotFound
Definition: Exception.hh:224
loadMachine
static Machine * loadMachine(const std::string &adfFile)
Definition: CreateBEM.cc:62
GenerateProcessor::validIntegratorParameters
bool validIntegratorParameters(const ProGeCmdLineOptions &options) const
Definition: GenerateProcessor.cc:392
ProGe::ProGeUI::integrateProcessor
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)
Definition: ProGeUI.cc:443
ParserStopRequest
Definition: Exception.hh:491
ProGe::Verilog
@ Verilog
Verilog.
Definition: ProGeTypes.hh:42
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
CmdLineParser::numberOfArguments
virtual int numberOfArguments() const
PluginTools
Definition: PluginTools.hh:53
SRAM
@ SRAM
Definition: MemoryGenerator.hh:62
GenerateProcessor::listICDecPluginParameters
bool listICDecPluginParameters(const std::string &pluginFile) const
Definition: GenerateProcessor.cc:290
ProGe::ICDecoderGeneratorPlugin
Definition: ICDecoderGeneratorPlugin.hh:68
MemoryGenerator.hh
ProGeOptions
Definition: ProGeOptions.hh:41
Application::setVerboseLevel
static void setVerboseLevel(const int level=VERBOSE_LEVEL_DEFAULT)
Definition: Application.hh:186
KoskiIntegrator
Definition: KoskiIntegrator.hh:40
Environment::icDecoderPluginPaths
static std::vector< std::string > icDecoderPluginPaths(bool libraryPathsOnly=false)
Definition: Environment.cc:635
Stratix3DevKitIntegrator
Definition: Stratix3DevKitIntegrator.hh:44
IllegalCommandLine
Definition: Exception.hh:438
ProGeOptions::outputDirectory
std::string outputDirectory
Definition: ProGeOptions.hh:83
FileSystem::absolutePathOf
static std::string absolutePathOf(const std::string &pathName)
Definition: FileSystem.cc:303
FileSystem::relativeDir
static bool relativeDir(const std::string &baseDir, std::string &toRelDir)
Definition: FileSystem.cc:762
FileSystem::fileOfPath
static std::string fileOfPath(const std::string pathName)
Definition: FileSystem.cc:101
ICDecoderGeneratorPlugin.hh
DRAM
@ DRAM
Definition: MemoryGenerator.hh:63
DEFAULT_IMEMWIDTH_IN_MAUS
const int DEFAULT_IMEMWIDTH_IN_MAUS
Definition: GenerateProcessor.cc:63
Exception::fileName
std::string fileName() const
Stratix2DSPBoardIntegrator.hh
StringTools.hh
assert
#define assert(condition)
Definition: Application.hh:86
ProGeCmdLineOptions
Definition: ProGeCmdLineOptions.hh:43
AlmaIFIntegrator.hh
ProGe::ProGeUI::generateTestBench
void generateTestBench(const ProGe::HDL language, const std::string &dstDir, const std::string &progeOutDir)
Definition: ProGeUI.cc:375
PluginTools::importSymbol
void importSymbol(const std::string &symbolName, T *&target, const std::string &module)
ProGeOptions::language
ProGe::HDL language
Definition: ProGeOptions.hh:82
KoskiIntegrator.hh
BinaryEncoding.hh
FileSystem::fileExtension
static std::string fileExtension(const std::string &fileName)
Definition: FileSystem.cc:279
GenerateProcessor::GenerateProcessor
GenerateProcessor()
Definition: GenerateProcessor.cc:82
Stratix2DSPBoardIntegrator
Definition: Stratix2DSPBoardIntegrator.hh:52
ProGeOptions::entityName
std::string entityName
Definition: ProGeOptions.hh:93
__func__
#define __func__
Definition: Application.hh:67
PluginTools::registerModule
void registerModule(const std::string &module)
Definition: PluginTools.cc:138
GenerateProcessor::getOutputDir
void getOutputDir(const ProGeCmdLineOptions &options, std::string &outputDir)
Definition: GenerateProcessor.cc:269
GenerateProcessor::listIntegrators
void listIntegrators() const
Definition: GenerateProcessor.cc:372
Environment.hh
ProGe::ProGeUI::generateScripts
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
AlmaIFIntegrator
Definition: AlmaIFIntegrator.hh:40
Machine.hh
CmdLineOptions::isVerboseSwitchDefined
virtual bool isVerboseSwitchDefined() const
Definition: CmdLineOptions.cc:300
Exception
Definition: Exception.hh:54
PluginTools.hh
FileSystem::expandTilde
static std::string expandTilde(const std::string &stringWithTilde)
Definition: FileSystem.cc:217
Application::VERBOSE_LEVEL_INCREASED
static const int VERBOSE_LEVEL_INCREASED
Increased verbose level - print information about modules etc.
Definition: Application.hh:224
GenerateProcessor::string2MemType
MemType string2MemType(const std::string &memoryString) const
Definition: GenerateProcessor.cc:440
Exception::errorMessage
std::string errorMessage() const
Definition: Exception.cc:123
CmdLineOptions::parse
void parse(char *argv[], int argc)
Definition: CmdLineOptions.cc:107
FileSystem::DIRECTORY_SEPARATOR
static const std::string DIRECTORY_SEPARATOR
Definition: FileSystem.hh:189
NONE
@ NONE
Definition: MemoryGenerator.hh:59
options
static MachInfoCmdLineOptions options
Definition: MachInfo.cc:46
MemType
MemType
Definition: MemoryGenerator.hh:57
ONCHIP
@ ONCHIP
Definition: MemoryGenerator.hh:61
AvalonIntegrator.hh
ProGe
Definition: FUGen.hh:54
PluginTools::addSearchPath
void addSearchPath(const std::string &searchPath)
Definition: PluginTools.cc:95
FileSystem::fileExists
static bool fileExists(const std::string fileName)
StringTools::chopString
static std::vector< TCEString > chopString(const std::string &source, const std::string &delimiters)
Definition: StringTools.cc:181
UNKNOWN
@ UNKNOWN
Definition: MemoryGenerator.hh:58
Application::VERBOSE_LEVEL_SPAM
static const int VERBOSE_LEVEL_SPAM
More Increased verbose level - spam about ddg heights of loops.
Definition: Application.hh:226
VHDL_ARRAY
@ VHDL_ARRAY
Definition: MemoryGenerator.hh:60
Stratix3DevKitIntegrator.hh
FileSystem::currentWorkingDir
static std::string currentWorkingDir()
Definition: FileSystem.cc:142
program
find Finds info of the inner loops in the program
Definition: InnerLoopFinder.cc:80
ProGeOptions::simulationRuntime
std::string simulationRuntime
Definition: ProGeOptions.hh:98
FileSystem::fileNameBody
static std::string fileNameBody(const std::string &fileName)
Definition: FileSystem.cc:291
GenerateProcessor::~GenerateProcessor
virtual ~GenerateProcessor()
Definition: GenerateProcessor.cc:89
main
int main(int argc, char *argv[])
Definition: GenerateProcessor.cc:68
ProGe::ProGeUI::generateProcessor
void generateProcessor(const ProGeOptions &options, int imemWidthInMAUs, std::ostream &errorStream, std::ostream &warningStream, std::ostream &verboseStream)
Definition: ProGeUI.cc:298
TTAMachine::Machine
Definition: Machine.hh:73
ProGeOptions::sharedOutputDirectory
std::string sharedOutputDirectory
Definition: ProGeOptions.hh:84
CmdLineOptions::isVerboseSpamSwitchDefined
virtual bool isVerboseSpamSwitchDefined() const
Definition: CmdLineOptions.cc:310