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