Belle II Software  release-08-01-10
TRGCDCInterfaceBuilder.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 //-----------------------------------------------------------------------------
10 // Description : A program to generate VHDL code for the packages.
11 //-----------------------------------------------------------------------------
12 
13 #define TRG_SHORT_NAMES
14 
15 #include <cstdlib>
16 #include <iostream>
17 #include <fstream>
18 #include <string>
19 #include <vector>
20 #include <boost/algorithm/string.hpp>
21 #include <boost/lexical_cast.hpp>
22 #include "trg/trg/Utilities.h"
23 
24 using namespace std;
25 using namespace Belle2;
26 
27 #define DEBUG_LEVEL 1
28 #define NAME "TRGCDCInterfaceBuilder"
29 #define VERSION string("0.00")
30 #define ENV_PATH "BELLE2_LOCAL_DIR"
31 #define FRONT_END "/OpticalLinkFrontEnd.h"
32 #define MARKER_0 "VHDL : begin"
33 #define MARKER_1 "VHDL : end"
34 #define N_KEYWORDS 5
35 #define KEYWORD_0 "TRGOpticalLinkVersion"
36 #define KEYWORD_1 "VHDL : type" // TRGSignalVector
37 #define KEYWORD_2 "vector<const TRGSignalVector" // vector<TRGSignalVector
38 #define KEYWORD_3 "vector<const TRGSignal" // vector<TRGSignal
39 #define KEYWORD_4 "TRGSignal" // TRGSignal
40 
41 const string Keys[] = {
42  KEYWORD_0,
43  KEYWORD_1,
44  KEYWORD_2,
45  KEYWORD_3,
46  KEYWORD_4
47 };
48 vector<string> Definitions;
49 unsigned LinesOfs2 = 0;
50 const string Out0name = ".TRGCDCInterfaceBuilder0.vhdl";
51 const string Out1name = ".TRGCDCInterfaceBuilder1.vhdl";
52 const string Out2name = ".TRGCDCInterfaceBuilder2.vhdl";
53 const string Out3name = ".TRGCDCInterfaceBuilder3.vhdl";
54 ofstream Ofs0(Out0name.c_str(), ios::out);
55 ofstream Ofs1(Out1name.c_str(), ios::out);
56 ofstream Ofs2(Out2name.c_str(), ios::out);
57 ofstream Ofs3(Out3name.c_str(), ios::out);
58 const string Tab = " ";
59 
60 void Parser(ifstream&);
61 void Parser0(const string&);
62 void ParserTS(const string&);
63 void ParserVTS(const string&);
64 void ParserVTS2(const string&);
65 void ParserTSV(const string&);
66 void ParserVTSV(const string&);
67 
68 void TypeDefinition(const string& name, const string& line);
69 void TypeDefinition(const string& name, unsigned size, const string& base);
70 void Functions(const string& name, unsigned size);
71 void GetName(const string& line,
72  string& name,
73  string& base,
74  bool& array,
75  unsigned& size);
76 
77 //---
78 
79 void (* ParserN[N_KEYWORDS])(const string&) = {
80  Parser0,
81  ParserTSV,
82  ParserVTSV,
83  ParserVTS,
84  ParserTS
85 };
86 
87 int
88 main(int argc, char**) // argv[]) {
89 {
90 //main(int argc) {
91 
92  cout << NAME << " ... " << VERSION << endl;
93 
94  //...Check arguments...
95  if (argc > 2) {
96  cout << NAME << " !!! no argument is necessary" << endl;
97  return -1;
98  }
99 
100  //...Date...
101  // const string ts0 = TRGUtil::dateStringF();
102  const string ts1 = TRGUtil::dateString();
103 
104  //...Get path to include directory...
105  const string path = getenv(ENV_PATH);
106  const string indir = path + "/include/trg/cdc";
107 
108  //...Temporary output file...
109  if (Ofs0.fail()) {
110  cout << NAME << " !!! can not open file" << endl
111  << " " << Out0name << endl;
112  return -2;
113  }
114  if (Ofs1.fail()) {
115  cout << NAME << " !!! can not open file" << endl
116  << " " << Out1name << endl;
117  return -3;
118  }
119  if (Ofs2.fail()) {
120  cout << NAME << " !!! can not open file" << endl
121  << " " << Out2name << endl;
122  return -4;
123  }
124  if (Ofs3.fail()) {
125  cout << NAME << " !!! can not open file" << endl
126  << " " << Out3name << endl;
127  return -5;
128  }
129 
130  //...Banner...
131  Ofs0 << "-- Generated by " << NAME << " " << VERSION << endl;
132  Ofs0 << "-- " << ts1 << endl;
133  Ofs0 << "--" << endl;
134 
135  //...Front-end Link...
136 // TRGCDCFrontEnd::implementation(TRGCDCFrontEnd::inner, outfile);
137  const string fename = indir + FRONT_END;
138  ifstream fefile(fename.c_str(), ios::in);
139  if (fefile.fail()) {
140  cout << NAME << " !!! can not open file" << endl
141  << " " << fename << endl;
142  return -6;
143  }
144 
145  //...Header...
146  Ofs0 << "-- Data file : " << endl;
147  Ofs0 << "-- " << fename << endl;
148  Ofs0 << "--" << endl;
149  Ofs0 << "" << endl;
150  Ofs0 << "library IEEE;" << endl;
151  Ofs0 << "use IEEE.STD_LOGIC_1164.all;" << endl << endl;
152  Ofs0 << "package CDCTRG_pkg is" << endl << endl;
153 
154  Ofs1 << "package body CDCTRG_pkg is" << endl << endl;
155 
156  //...Frame...
157  Ofs2 << Tab << "-- TRGFrame" << endl;
158  Ofs2 << Tab << "function TRGFrame (" << endl;
159 
160  //...Frame body...
161  Ofs3 << Tab << "begin" << endl;
162  Ofs3 << Tab << " return" << endl;
163 
164  //...Call the Parser...
165  Parser(fefile);
166 
167  //...Copy Ofs2 and reopen it...
168  Ofs2.close();
169  string tmp = Out2name + ".tmp";
170  string cmd = "cp " + Out2name + " " + tmp;
171  system(cmd.c_str());
172  ofstream ofs2(Out2name.c_str(), ios::app);
173 
174  //...For function body of TRGFrame...
175  string tmq = Out2name + ".tmp2";
176  cmd = "sed -e 's/std_logic_vector;/std_logic_vector is/g' " + tmp
177  + " > " + tmq;
178  system(cmd.c_str());
179 
180  //...Trailer...
181  ofs2 << "end;" << endl << endl;
182 
183  //...End of writing tmp files...
184  Ofs0.close();
185  Ofs1.close();
186  ofs2.close();
187  Ofs3.close();
188 
189  //...Merge files...
190  cmd = "cat " + Out0name + " " + Out2name + " " + Out1name + " "
191  + tmq + " " + Out3name + " > TRGCDCInterfaceBuilder.vhdl";
192  system(cmd.c_str());
193 
194  //...Termination...
195  cout << NAME << " ... terminated" << endl;
196 }
197 
198 void
199 Parser(ifstream& ifs)
200 {
201 
202  //...Main loop...
203  char b[800];
204  bool beginConversion = false;
205  bool endConversion = false;
206  while (! ifs.eof()) {
207  ifs.getline(b, 800);
208  string l(b);
209 
210  //...Check 'begin' and 'end' markers...
211  string::size_type pos = l.find(MARKER_0);
212  if (pos != string::npos) {
213  beginConversion = true;
214  continue;
215  }
216  pos = l.find(MARKER_1);
217  if (pos != string::npos) {
218  endConversion = true;
219  continue;
220  }
221 
222  //...Do convert...
223  if (beginConversion && (! endConversion)) {
224 
225  //...Keyword loop...
226  for (unsigned i = 0; i < N_KEYWORDS; i++) {
227 
228  //...Check keywords...
229  pos = l.find(Keys[i].c_str());
230  if (pos != string::npos) {
231  ParserN[i](l);
232  break;
233  }
234  }
235  } else if (endConversion) {
236 
237  //...Do the final job...
238  Ofs2 << ")" << endl;
239  Ofs2 << Tab << " return std_logic_vector;" << endl << endl;
240 
241  Ofs3 << ");" << endl;
242  Ofs3 << Tab << "end TRGFrame;" << endl;
243  Ofs3 << "end;" << endl;
244 
245  break;
246  }
247  }
248 }
249 
250 //...Parser for the keyword TRGOpticalLinkVersion...
251 void
252 Parser0(const string& line)
253 {
254  string l = line;
255  // const string car0 = TRGUtil::carstring(l);
256  l = TRGUtil::cdrstring(l);
257  const string car1 = TRGUtil::carstring(l);
258  l = TRGUtil::cdrstring(l);
259  const string car2 = TRGUtil::carstring(l);
260  l = TRGUtil::cdrstring(l);
261  Ofs0 << "-- Version : " << car1 << " " << car2 << endl;
262  Ofs0 << "" << endl;
263 }
264 
265 //...Parser for the keyword TRGSignal...
266 void
267 ParserTS(const string& l)
268 {
269  string name;
270  string none;
271  bool array = false;
272  unsigned size = 0;
273  GetName(l, name, none, array, size);
274 
275  //...Termination mark...
276  if (LinesOfs2) {
277  Ofs2 << ";" << endl;
278  Ofs3 << " &" << endl;
279  }
280 
281  //...TRGFrame definition...
282  char v = 'a' + LinesOfs2;
283  Ofs2 << Tab << " " << v << " : in " << name;
284 
285  //...TRGFrame body...
286  Ofs3 << Tab << " ToLogicVector(" << name << ")";
287 
288  ++LinesOfs2;
289 }
290 
291 //...Parser for the keyword VHDL...
292 void
293 ParserTSV(const string& line)
294 {
295  string l = line;
296  // const string car0 = TRGUtil::carstring(l);
297  l = TRGUtil::cdrstring(l);
298  // const string car1 = TRGUtil::carstring(l);
299  l = TRGUtil::cdrstring(l);
300  // const string car2 = TRGUtil::carstring(l);
301  l = TRGUtil::cdrstring(l);
302  // const string car3 = TRGUtil::carstring(l);
303 
304  //...Definition...
305  string m = TRGUtil::cdrstring(l);
306  string car4 = TRGUtil::carstring(m);
307  string vnv = car4;
308  Definitions.push_back(car4);
309 
310  //...Look for array size...
311  string last = car4;
312  string top = "";
313  while (1) {
314  car4 = TRGUtil::carstring(m);
315  m = TRGUtil::cdrstring(m);
316  if (car4 == "downto") {
317  top = last;
318  break;
319  }
320  last = car4;
321  }
322  string dim;
323  for (unsigned i = 0; i < top.size(); i++) {
324  if (isdigit(top[i]))
325  dim += top[i];
326  else
327  dim = "";
328  }
329  unsigned arraySize = boost::lexical_cast<int>(dim) + 1;
330 
331  //...Type definition...
332  TypeDefinition(vnv, l);
333 
334  //...Functions...
335  Functions(vnv, arraySize);
336 }
337 
338 //...Parser for the keyword vector<TRGSignal...
339 void
340 ParserVTS(const string& l)
341 {
342 
343  string name;
344  string base;
345  bool array = false;
346  unsigned size = 0;
347  GetName(l, name, base, array, size);
348 
349  //...Check definitions...
350  bool defined = false;
351  for (unsigned i = 0; i < Definitions.size(); i++) {
352  if (Definitions[i] == name) {
353  defined = true;
354  break;
355  }
356  }
357  if (! defined)
358  cout << "TRGCDCInterfaceBuilder::ParserVTS !!! " << name
359  << " is not defined" << endl;
360 
361  //...Type definition...
362  TypeDefinition(name, size, "std_logic");
363 
364  //...Functions...
365  Functions(name, size);
366 
367  //...TRGFrame...
368  ParserTS(l);
369 }
370 
371 //...Parser for the keyword vector<TRGSignalVector...
372 void
373 ParserVTSV(const string& l)
374 {
375 
376  string name;
377  string base;
378  bool array = false;
379  unsigned size = 0;
380  GetName(l, name, base, array, size);
381 
382  //...Check definitions...
383  bool defined = false;
384  for (unsigned i = 0; i < Definitions.size(); i++) {
385  if (Definitions[i] == name) {
386  defined = true;
387  break;
388  }
389  }
390  if (! defined)
391  cout << "TRGCDCInterfaceBuilder::ParserVTS !!! " << name
392  << " is not defined" << endl;
393 
394  //...Type definition...
395  TypeDefinition(name, size, base);
396 
397  //...Functions...
398  Functions(name, size);
399 
400  //...TRGFrame...
401  ParserTS(l);
402 }
403 
404 void
405 TypeDefinition(const string& name, const string& l)
406 {
407 
408  //...Type definition...
409  Ofs0 << Tab << "-- " << name << endl;
410  Ofs0 << Tab << l << endl;
411  Ofs0 << endl;
412 }
413 
414 void
415 TypeDefinition(const string& name, unsigned size, const string& base)
416 {
417 
418  //...Type definition...
419  Ofs0 << Tab << "-- " << name << endl;
420  Ofs0 << Tab << "type " << name << " is array (" << size - 1
421  << " downto 0) of " << base << ";" << endl;
422  Ofs0 << endl;
423 }
424 
425 void
426 Functions(const string& name, unsigned arraySize)
427 {
428 
429  //...Conersion function : ToLogicVector...
430  Ofs0 << Tab << "-- " << name << endl;
431  Ofs0 << Tab << "function ToLogicVector (a : in " << name
432  << ") return std_logic_vector;" << endl;
433 
434  //...Body...
435  Ofs1 << Tab << "-- " << name << " to std_logic_vector" << endl;
436  Ofs1 << Tab << "function ToLogicVector (a : in " << name
437  << ") return std_logic_vector is" << endl;
438  Ofs1 << Tab << "begin" << endl;
439  Ofs1 << Tab << " return" << endl;
440  for (unsigned i = arraySize; i > 0; --i) {
441  if (i > 1)
442  Ofs1 << Tab << " a(" << i - 1 << ") &"
443  << endl;
444  else
445  Ofs1 << Tab << " a(" << i - 1 << ");"
446  << endl;
447  }
448  Ofs1 << Tab << "end ToLogicVector;" << endl;
449  Ofs1 << endl;
450 
451  //...Conersion function : to name...
452  Ofs0 << Tab << "functino To" << name
453  << " (a : in std_logic_vector) return " << name << ";" << endl;
454  Ofs0 << endl;
455 
456  //...Body...
457  Ofs1 << Tab << "-- std_logic_vector to " << name << endl;
458  Ofs1 << Tab << "function To" << name
459  << " (a : in std_logic_vector) return " << name << " is" << endl;
460  Ofs1 << Tab << "begin" << endl;
461  Ofs1 << Tab << " return" << endl;
462  for (unsigned i = arraySize; i > 0; --i) {
463  if (i > 1)
464  Ofs1 << Tab << " a(" << i - 1 << ") &" << endl;
465  else
466  Ofs1 << Tab << " a(" << i - 1 << ");" << endl;
467  }
468  Ofs1 << Tab << "end " << name << ";" << endl;
469  Ofs1 << endl;
470 }
471 
472 void
473 GetName(const string& line,
474  string& name,
475  string& base,
476  bool& array,
477  unsigned& size)
478 {
479 
480  string l = line;
481 
482  //...Is this a vector? Then make an array...
483  array = false;
484  string::size_type pos = l.find("std::vector");
485  if (pos != string::npos)
486  array = true;
487 
488  //...Keep the last word as a variable name...
489  name = "";
490  while (1) {
491  string car = TRGUtil::carstring(l);
492  l = TRGUtil::cdrstring(l);
493 
494  if (l.size() == 0) {
495  name = car;
496  break;
497  }
498  }
499 
500  //...Change variable name from C++ style...
501  string vnv = name.substr(1, name.size() - 2);
502  string vnf = vnv.substr(0, 1);
503  boost::to_upper(vnf);
504  vnv[0] = vnf[0];
505  name = vnv;
506 
507  //...Array...
508  size = 0;
509  base = "";
510  if (array) {
511 
512  //...Last part of a name must be size of array...
513  string dim;
514  for (unsigned i = 0; i < vnv.size(); i++) {
515  if (isdigit(vnv[i])) {
516  dim += vnv[i];
517  } else {
518  dim = "";
519  base += vnv[i];
520  }
521  }
522  size = boost::lexical_cast<int>(dim);
523  }
524 }
Abstract base class for different kinds of events.
int main(int argc, char **argv)
Run all tests.
Definition: test_main.cc:91