Belle II Software development
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
24using namespace std;
25using 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
41const string Keys[] = {
42 KEYWORD_0,
43 KEYWORD_1,
44 KEYWORD_2,
45 KEYWORD_3,
46 KEYWORD_4
47};
48vector<string> Definitions;
49unsigned LinesOfs2 = 0;
50const string Out0name = ".TRGCDCInterfaceBuilder0.vhdl";
51const string Out1name = ".TRGCDCInterfaceBuilder1.vhdl";
52const string Out2name = ".TRGCDCInterfaceBuilder2.vhdl";
53const string Out3name = ".TRGCDCInterfaceBuilder3.vhdl";
54ofstream Ofs0(Out0name.c_str(), ios::out);
55ofstream Ofs1(Out1name.c_str(), ios::out);
56ofstream Ofs2(Out2name.c_str(), ios::out);
57ofstream Ofs3(Out3name.c_str(), ios::out);
58const string Tab = " ";
59
60void Parser(ifstream&);
61void Parser0(const string&);
62void ParserTS(const string&);
63void ParserVTS(const string&);
64void ParserVTS2(const string&);
65void ParserTSV(const string&);
66void ParserVTSV(const string&);
67
68void TypeDefinition(const string& name, const string& line);
69void TypeDefinition(const string& name, unsigned size, const string& base);
70void Functions(const string& name, unsigned size);
71void GetName(const string& line,
72 string& name,
73 string& base,
74 bool& array,
75 unsigned& size);
76
77//---
78
79void (* ParserN[N_KEYWORDS])(const string&) = {
80 Parser0,
81 ParserTSV,
82 ParserVTSV,
83 ParserVTS,
84 ParserTS
85};
86
87int
88main(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
198void
199Parser(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...
251void
252Parser0(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...
266void
267ParserTS(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...
292void
293ParserTSV(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...
339void
340ParserVTS(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...
372void
373ParserVTSV(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
404void
405TypeDefinition(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
414void
415TypeDefinition(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
425void
426Functions(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
472void
473GetName(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.
STL namespace.