Belle II Software  release-06-02-00
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  unsigned lines = 0;
205  bool beginConversion = false;
206  bool endConversion = false;
207  while (! ifs.eof()) {
208  ++lines;
209  ifs.getline(b, 800);
210  string l(b);
211 
212  //...Check 'begin' and 'end' markers...
213  string::size_type pos = l.find(MARKER_0);
214  if (pos != string::npos) {
215  beginConversion = true;
216  continue;
217  }
218  pos = l.find(MARKER_1);
219  if (pos != string::npos) {
220  endConversion = true;
221  continue;
222  }
223 
224  //...Do convert...
225  if (beginConversion && (! endConversion)) {
226 
227  //...Keyword loop...
228  for (unsigned i = 0; i < N_KEYWORDS; i++) {
229 
230  //...Check keywords...
231  pos = l.find(Keys[i].c_str());
232  if (pos != string::npos) {
233  ParserN[i](l);
234  break;
235  }
236  }
237  } else if (endConversion) {
238 
239  //...Do the final job...
240  Ofs2 << ")" << endl;
241  Ofs2 << Tab << " return std_logic_vector;" << endl << endl;
242 
243  Ofs3 << ");" << endl;
244  Ofs3 << Tab << "end TRGFrame;" << endl;
245  Ofs3 << "end;" << endl;
246 
247  break;
248  }
249  }
250 }
251 
252 //...Parser for the keyword TRGOpticalLinkVersion...
253 void
254 Parser0(const string& line)
255 {
256  string l = line;
257  // const string car0 = TRGUtil::carstring(l);
258  l = TRGUtil::cdrstring(l);
259  const string car1 = TRGUtil::carstring(l);
260  l = TRGUtil::cdrstring(l);
261  const string car2 = TRGUtil::carstring(l);
262  l = TRGUtil::cdrstring(l);
263  Ofs0 << "-- Version : " << car1 << " " << car2 << endl;
264  Ofs0 << "" << endl;
265 }
266 
267 //...Parser for the keyword TRGSignal...
268 void
269 ParserTS(const string& l)
270 {
271  string name;
272  string none;
273  bool array = false;
274  unsigned size = 0;
275  GetName(l, name, none, array, size);
276 
277  //...Termination mark...
278  if (LinesOfs2) {
279  Ofs2 << ";" << endl;
280  Ofs3 << " &" << endl;
281  }
282 
283  //...TRGFrame definition...
284  char v = 'a' + LinesOfs2;
285  Ofs2 << Tab << " " << v << " : in " << name;
286 
287  //...TRGFrame body...
288  Ofs3 << Tab << " ToLogicVector(" << name << ")";
289 
290  ++LinesOfs2;
291 }
292 
293 //...Parser for the keyword VHDL...
294 void
295 ParserTSV(const string& line)
296 {
297  string l = line;
298  // const string car0 = TRGUtil::carstring(l);
299  l = TRGUtil::cdrstring(l);
300  // const string car1 = TRGUtil::carstring(l);
301  l = TRGUtil::cdrstring(l);
302  // const string car2 = TRGUtil::carstring(l);
303  l = TRGUtil::cdrstring(l);
304  // const string car3 = TRGUtil::carstring(l);
305 
306  //...Definition...
307  string m = TRGUtil::cdrstring(l);
308  string car4 = TRGUtil::carstring(m);
309  string vnv = car4;
310  Definitions.push_back(car4);
311 
312  //...Look for array size...
313  string last = car4;
314  string top = "";
315  while (1) {
316  car4 = TRGUtil::carstring(m);
317  m = TRGUtil::cdrstring(m);
318  if (car4 == "downto") {
319  top = last;
320  break;
321  }
322  last = car4;
323  }
324  string dim;
325  for (unsigned i = 0; i < top.size(); i++) {
326  if (isdigit(top[i]))
327  dim += top[i];
328  else
329  dim = "";
330  }
331  unsigned arraySize = boost::lexical_cast<int>(dim) + 1;
332 
333  //...Type definition...
334  TypeDefinition(vnv, l);
335 
336  //...Functions...
337  Functions(vnv, arraySize);
338 }
339 
340 //...Parser for the keyword vector<TRGSignal...
341 void
342 ParserVTS(const string& l)
343 {
344 
345  string name;
346  string base;
347  bool array = false;
348  unsigned size = 0;
349  GetName(l, name, base, array, size);
350 
351  //...Check definitions...
352  bool defined = false;
353  for (unsigned i = 0; i < Definitions.size(); i++) {
354  if (Definitions[i] == name) {
355  defined = true;
356  break;
357  }
358  }
359  if (! defined)
360  cout << "TRGCDCInterfaceBuilder::ParserVTS !!! " << name
361  << " is not defined" << endl;
362 
363  //...Type definition...
364  TypeDefinition(name, size, "std_logic");
365 
366  //...Functions...
367  Functions(name, size);
368 
369  //...TRGFrame...
370  ParserTS(l);
371 }
372 
373 //...Parser for the keyword vector<TRGSignalVector...
374 void
375 ParserVTSV(const string& l)
376 {
377 
378  string name;
379  string base;
380  bool array = false;
381  unsigned size = 0;
382  GetName(l, name, base, array, size);
383 
384  //...Check definitions...
385  bool defined = false;
386  for (unsigned i = 0; i < Definitions.size(); i++) {
387  if (Definitions[i] == name) {
388  defined = true;
389  break;
390  }
391  }
392  if (! defined)
393  cout << "TRGCDCInterfaceBuilder::ParserVTS !!! " << name
394  << " is not defined" << endl;
395 
396  //...Type definition...
397  TypeDefinition(name, size, base);
398 
399  //...Functions...
400  Functions(name, size);
401 
402  //...TRGFrame...
403  ParserTS(l);
404 }
405 
406 void
407 TypeDefinition(const string& name, const string& l)
408 {
409 
410  //...Type definition...
411  Ofs0 << Tab << "-- " << name << endl;
412  Ofs0 << Tab << l << endl;
413  Ofs0 << endl;
414 }
415 
416 void
417 TypeDefinition(const string& name, unsigned size, const string& base)
418 {
419 
420  //...Type definition...
421  Ofs0 << Tab << "-- " << name << endl;
422  Ofs0 << Tab << "type " << name << " is array (" << size - 1
423  << " downto 0) of " << base << ";" << endl;
424  Ofs0 << endl;
425 }
426 
427 void
428 Functions(const string& name, unsigned arraySize)
429 {
430 
431  //...Conersion function : ToLogicVector...
432  Ofs0 << Tab << "-- " << name << endl;
433  Ofs0 << Tab << "function ToLogicVector (a : in " << name
434  << ") return std_logic_vector;" << endl;
435 
436  //...Body...
437  Ofs1 << Tab << "-- " << name << " to std_logic_vector" << endl;
438  Ofs1 << Tab << "function ToLogicVector (a : in " << name
439  << ") return std_logic_vector is" << endl;
440  Ofs1 << Tab << "begin" << endl;
441  Ofs1 << Tab << " return" << endl;
442  for (unsigned i = arraySize; i > 0; --i) {
443  if (i > 1)
444  Ofs1 << Tab << " a(" << i - 1 << ") &"
445  << endl;
446  else
447  Ofs1 << Tab << " a(" << i - 1 << ");"
448  << endl;
449  }
450  Ofs1 << Tab << "end ToLogicVector;" << endl;
451  Ofs1 << endl;
452 
453  //...Conersion function : to name...
454  Ofs0 << Tab << "functino To" << name
455  << " (a : in std_logic_vector) return " << name << ";" << endl;
456  Ofs0 << endl;
457 
458  //...Body...
459  Ofs1 << Tab << "-- std_logic_vector to " << name << endl;
460  Ofs1 << Tab << "function To" << name
461  << " (a : in std_logic_vector) return " << name << " is" << endl;
462  Ofs1 << Tab << "begin" << endl;
463  Ofs1 << Tab << " return" << endl;
464  for (unsigned i = arraySize; i > 0; --i) {
465  if (i > 1)
466  Ofs1 << Tab << " a(" << i - 1 << ") &" << endl;
467  else
468  Ofs1 << Tab << " a(" << i - 1 << ");" << endl;
469  }
470  Ofs1 << Tab << "end " << name << ";" << endl;
471  Ofs1 << endl;
472 }
473 
474 void
475 GetName(const string& line,
476  string& name,
477  string& base,
478  bool& array,
479  unsigned& size)
480 {
481 
482  string l = line;
483 
484  //...Is this a vector? Then make an array...
485  array = false;
486  string::size_type pos = l.find("std::vector");
487  if (pos != string::npos)
488  array = true;
489 
490  //...Keep the last word as a variable name...
491  name = "";
492  while (1) {
493  string car = TRGUtil::carstring(l);
494  l = TRGUtil::cdrstring(l);
495 
496  if (l.size() == 0) {
497  name = car;
498  break;
499  }
500  }
501 
502  //...Change variable name from C++ style...
503  string vnv = name.substr(1, name.size() - 2);
504  string vnf = vnv.substr(0, 1);
505  boost::to_upper(vnf);
506  vnv[0] = vnf[0];
507  name = vnv;
508 
509  //...Array...
510  size = 0;
511  base = "";
512  if (array) {
513 
514  //...Last part of a name must be size of array...
515  string dim;
516  for (unsigned i = 0; i < vnv.size(); i++) {
517  if (isdigit(vnv[i])) {
518  dim += vnv[i];
519  } else {
520  dim = "";
521  base += vnv[i];
522  }
523  }
524  size = boost::lexical_cast<int>(dim);
525  }
526 }
Abstract base class for different kinds of events.
int main(int argc, char **argv)
Run all tests.
Definition: test_main.cc:75