]> AND Private Git Repository - blast.git/blob - VHDLConverter.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
changed VHDL converter
[blast.git] / VHDLConverter.cpp
1 #include "VHDLConverter.h"\r
2 \r
3 using namespace std;\r
4 using namespace Qt;\r
5 \r
6 VHDLConverter::VHDLConverter(QWidget *parent) : QWidget(parent) {\r
7     \r
8     QLabel *labelAppli, *lblBrief, *lblDesc, *lblName, *lblPort, *lblGen;\r
9 \r
10     loadBut = new QPushButton("load VHDL");\r
11     genBut = new QPushButton("generate XML");\r
12     QHBoxLayout *widgetLayout = new QHBoxLayout;\r
13     QVBoxLayout *left = new QVBoxLayout;\r
14     QVBoxLayout *right = new QVBoxLayout;\r
15 \r
16     scrollDataPort = new QScrollArea;\r
17     scrollDataPort->setWidgetResizable(true);\r
18     twDataPort = new QTableWidget(this);\r
19     scrollDataPort->setWidget(twDataPort);\r
20     scrollGenerics = new QScrollArea;\r
21     scrollGenerics->setWidgetResizable(true);\r
22     twGenerics = new QTableWidget(this);\r
23     scrollGenerics->setWidget(twGenerics);\r
24     teName = new QTextEdit;\r
25     teBrief = new QTextEdit;\r
26     teDesc = new QTextEdit;\r
27     lblName = new QLabel("Block name :");\r
28     lblBrief = new QLabel("Enter a brief description : ");\r
29     lblDesc = new QLabel("Enter a detailled description : ");\r
30     lblPort = new QLabel("Ports :");\r
31     lblGen = new QLabel("Generics :");\r
32 \r
33     connect(loadBut, SIGNAL(clicked()),this, SLOT(loadVHDLFile()));\r
34     connect(genBut, SIGNAL(clicked()), this, SLOT(generateXml()));\r
35 \r
36     left->addWidget(loadBut);\r
37     left->addWidget(lblPort);\r
38     left->addWidget(scrollDataPort);\r
39     left->addWidget(lblGen);\r
40     left->addWidget(scrollGenerics);\r
41 \r
42     right->addWidget(lblName);\r
43     right->addWidget(teName);\r
44     right->addWidget(lblBrief);\r
45     right->addWidget(teBrief);\r
46     right->addWidget(lblDesc);\r
47     right->addWidget(teDesc);\r
48     right->addWidget(genBut);\r
49 \r
50     widgetLayout->addLayout(left);\r
51     widgetLayout->addLayout(right);\r
52     setLayout(widgetLayout);\r
53     show();\r
54 }\r
55 \r
56 VHDLConverter::~VHDLConverter() {\r
57 \r
58 }\r
59 \r
60 QString VHDLConverter::skipBlankAndComments(QTextStream &in) {\r
61   \r
62   QString line = "";\r
63   \r
64  // skipping blank/comment lines \r
65   while ( (line.isEmpty()) || ((line.at(0) == '-') && (line.at(1) == '-')) ) {\r
66     if (in.atEnd()) {\r
67       return "";\r
68     }\r
69     line = in.readLine();\r
70     if (!line.isEmpty()) line = line.simplified();\r
71   }\r
72   line.remove(QRegularExpression("--.*$"));\r
73   return line;\r
74 }\r
75 \r
76 QString VHDLConverter::readLibraries(QTextStream &in) throw(Exception) {\r
77   \r
78   QRegularExpression rxLib("^library[\\s\\t]*(.+);$",QRegularExpression::CaseInsensitiveOption);\r
79   QRegularExpression rxPack("^use[\\s\\t]*([^.]+)[.](.+);$",QRegularExpression::CaseInsensitiveOption);\r
80   QString line = "";\r
81   \r
82   line = skipBlankAndComments(in);\r
83   if (line == "") {\r
84     throw(Exception(VHDLFILE_CORRUPTED));\r
85   }    \r
86   \r
87   while (! line.contains("entity",Qt::CaseInsensitive)) {\r
88     \r
89     QRegularExpressionMatch matchLib = rxLib.match(line);\r
90     QRegularExpressionMatch matchPack = rxPack.match(line);\r
91     \r
92     if (matchLib.hasMatch()) {\r
93       \r
94       QString libName = matchLib.captured(1);\r
95       libName = libName.toLower();\r
96       \r
97       cout << "matching library: " << qPrintable(libName) << endl;      \r
98       \r
99       if (!packages.contains(libName)) {        \r
100         packages.insert(libName,new QList<QString>());      \r
101       }      \r
102     }\r
103     else if (matchPack.hasMatch()) {\r
104       cout << "matching packages" << endl;\r
105       \r
106       QString libName = matchPack.captured(1);\r
107       QString packName = matchPack.captured(2);      \r
108       \r
109       libName = libName.toLower();\r
110       packName = packName.toLower();      \r
111             \r
112       if (libName == "work") {\r
113         if (!packages.contains("work")) {\r
114           packages.insert("work",new QList<QString>());\r
115         }\r
116       }\r
117       else if (libName == "std") {\r
118         if (!packages.contains("std")) {\r
119           packages.insert("std",new QList<QString>());\r
120         }\r
121       }\r
122       else if (!packages.contains(libName)) throw(Exception(VHDLFILE_CORRUPTED));\r
123       \r
124       QList<QString>* lstPack = packages.value(libName);\r
125       QString s = libName + "." + packName;      \r
126       lstPack->append(s);\r
127       cout << qPrintable(s) << endl;\r
128       \r
129     }\r
130     \r
131     line = skipBlankAndComments(in);\r
132     if (line == "") {\r
133       throw(Exception(VHDLFILE_CORRUPTED));\r
134     }\r
135     cout << "read line = " << qPrintable(line) << endl;\r
136   }\r
137 \r
138   return line;\r
139 }\r
140 \r
141 QString VHDLConverter::readEntity(QTextStream &in) throw(Exception) {\r
142 \r
143   QRegularExpression rxGen("^generic[\\s\\t]*[(](.*)$",QRegularExpression::CaseInsensitiveOption);\r
144   QRegularExpression rxPorts("^port[\\s\\t]*[(](.*)$",QRegularExpression::CaseInsensitiveOption);\r
145 \r
146   QString line = "";\r
147 \r
148   line = skipBlankAndComments(in);\r
149   if (line == "") {\r
150     throw(Exception(VHDLFILE_CORRUPTED));\r
151   }\r
152 \r
153   while (! line.contains("architecture",Qt::CaseInsensitive)) {\r
154 \r
155     QRegularExpressionMatch matchGen = rxGen.match(line);\r
156     QRegularExpressionMatch matchPorts = rxPorts.match(line);\r
157 \r
158     if (matchGen.hasMatch()) {\r
159       cout << "matching generics" << endl;\r
160       if (matchGen.captured(1).length() > 0) {\r
161         cerr << "Please, modify VHDL source so that the generic list does not begin at the same line as generic (" << endl;\r
162         throw(Exception(VHDLFILE_CORRUPTED));\r
163       }\r
164       readGenerics(in);\r
165     }\r
166     else if (matchPorts.hasMatch()) {\r
167       cout << "matching ports" << endl;\r
168       if (matchPorts.captured(1).length() > 0) {\r
169         cerr << "Please, modify VHDL source so that the port list does not begin at the same line as port (" << endl;\r
170         throw(Exception(VHDLFILE_CORRUPTED));\r
171       }\r
172       readPorts(in);\r
173     }\r
174 \r
175     line = skipBlankAndComments(in);\r
176     if (line == "") {\r
177       throw(Exception(VHDLFILE_CORRUPTED));\r
178     }\r
179     cout << "read line = " << qPrintable(line) << endl;\r
180   }\r
181 \r
182   return line;\r
183 }\r
184 \r
185 void VHDLConverter::readGenerics(QTextStream &in) throw(Exception) {\r
186 \r
187   QRegularExpression rxGen("^([^:]+):([^:]+)(:=)?([^;]*);?$",QRegularExpression::CaseInsensitiveOption);\r
188 \r
189   QString line = "";\r
190 \r
191   line = skipBlankAndComments(in);\r
192   if (line == "") {\r
193     throw(Exception(VHDLFILE_CORRUPTED));\r
194   }\r
195   line = line.remove(' ');\r
196 \r
197   while (! line.contains(QRegExp("\\);"))) {\r
198 \r
199     QRegularExpressionMatch matchGen = rxGen.match(line);\r
200 \r
201     if (matchGen.hasMatch()) {\r
202       cout << "matching generic value" << endl;\r
203       QString genName = matchGen.captured(1);\r
204       QString genType = matchGen.captured(2);\r
205       QString genValue = matchGen.captured(4);\r
206       cout << qPrintable(genName) << " " << qPrintable(genType) << " " << qPrintable(genValue) << endl;\r
207     }\r
208 \r
209     line = skipBlankAndComments(in);\r
210     if (line == "") {\r
211       throw(Exception(VHDLFILE_CORRUPTED));\r
212     }\r
213     line = line.remove(' ');\r
214      cout << "read line = " << qPrintable(line) << endl;\r
215   }\r
216 }\r
217 \r
218 void VHDLConverter::readPorts(QTextStream &in) throw(Exception) {\r
219 \r
220   QRegularExpression rxPort("^([^:]+):(in|out|inout)([a-zA-Z0-9_]+)(\\([^:)]*\\))?(:=)?([^;]*);?$",QRegularExpression::CaseInsensitiveOption);\r
221 \r
222   QString line = "";\r
223 \r
224   line = skipBlankAndComments(in);\r
225   if (line == "") {\r
226     throw(Exception(VHDLFILE_CORRUPTED));\r
227   }\r
228   line = line.remove(' ');\r
229 \r
230   while (! line.contains(QRegExp("^\\);$"))) {\r
231 \r
232     QRegularExpressionMatch matchPort = rxPort.match(line);\r
233 \r
234     if (matchPort.hasMatch()) {\r
235       cout << "matching port value" << endl;\r
236       QString portName = matchPort.captured(1);\r
237       QString portDir = matchPort.captured(2);\r
238       QString portType = matchPort.captured(3);\r
239       QString portSize = matchPort.captured(4);\r
240       QString portValue = matchPort.captured(6);\r
241       cout << qPrintable(portName) << " " << qPrintable(portDir) << " " << qPrintable(portType) << " " << qPrintable(portSize) << " " << qPrintable(portValue) << endl;\r
242     }\r
243 \r
244     line = skipBlankAndComments(in);\r
245     if (line == "") {\r
246       throw(Exception(VHDLFILE_CORRUPTED));\r
247     }\r
248     line = line.remove(' ');\r
249      cout << "read line = " << qPrintable(line) << endl;\r
250   }\r
251 \r
252 }\r
253 \r
254 void VHDLConverter::readArchitecture(QTextStream &in) throw(Exception) {\r
255   \r
256 }\r
257 \r
258 // This function opens a VHDL file and get the informations about the entity :\r
259 // First the generics, then the signals.\r
260 // You can edit the descriptions in the right, one for the brief description, the other for the detailled.\r
261 void VHDLConverter::loadVHDLFile() {\r
262 \r
263     QString line, portName, portType, portId, genName, genType, genValue;\r
264     QStringList *portNameList, *portTypeList, *portIdList, *genNameList, *genTypeList, *genValueList;\r
265     cpt = 0;\r
266     twDataPort->setColumnCount(3);\r
267     twDataPort->setRowCount(cpt);\r
268     twGenerics->setColumnCount(3);\r
269     twGenerics->setRowCount(cpt);\r
270     portNameList = new QStringList;\r
271     portTypeList = new QStringList;\r
272     portIdList = new QStringList;\r
273     genNameList = new QStringList;\r
274     genTypeList = new QStringList;\r
275     genValueList = new QStringList;\r
276 \r
277 \r
278     fileName = QFileDialog::getOpenFileName(this,\r
279                                             tr("Open File"), QDir::homePath() , tr("Files (*.txt *.vhd)"));\r
280     QFile file(fileName);\r
281 \r
282     if(!file.open(QIODevice::ReadOnly | QIODevice::Text))\r
283         return;\r
284     QTextStream ts(&file);\r
285     \r
286     QString entityLine = "";\r
287     try {\r
288       entityLine = readLibraries(ts);\r
289     }\r
290     catch(Exception e) {\r
291       cerr << "VHDL seems to be malformed" << endl;\r
292       return;\r
293     }\r
294 \r
295     QRegularExpression rxEnt("^entity[\\s\\t]+(.+)[\\s\\t]+is$",QRegularExpression::CaseInsensitiveOption);\r
296     QRegularExpressionMatch matchEnt = rxEnt.match(entityLine);\r
297     if (!matchEnt.hasMatch()) {\r
298       cerr << "VHDL seems to be malformed" << endl;\r
299       return;\r
300     }\r
301     entityName = matchEnt.captured(1);\r
302     cout << "foudn entity " << qPrintable(entityName) << endl;\r
303 \r
304     QString archLine = "";\r
305     try {\r
306       archLine = readEntity(ts);\r
307     }\r
308     catch(Exception e) {\r
309       cerr << "VHDL seems to be malformed" << endl;\r
310       return;\r
311     }\r
312 \r
313     \r
314     /*\r
315     while (!ts.atEnd())\r
316     {\r
317         line = ts.readLine();\r
318         if(rxComment->indexIn(line) != -1) {\r
319             line = rxComment->cap(1);\r
320         }\r
321 \r
322         if(rxEnt->indexIn(line)!= -1) {\r
323 \r
324             entName = rxEnt->cap(1);\r
325             teName->setText(entName);\r
326             QSize size = teName->document()->size().toSize();\r
327             teName->setMaximumSize(size);\r
328 \r
329             while(rxEnd->indexIn(line) == -1) {\r
330                 line = ts.readLine();\r
331                 if(rxComment->indexIn(line) != -1) {\r
332                     line = rxComment->cap(1);\r
333                 }\r
334                 if(rxComma->indexIn(line) != -1) {\r
335                     line = rxComma->cap(1);\r
336                 }\r
337                 if(rxGeneric->indexIn(line) != -1) {\r
338                     while(rxEndGen->indexIn(line) == -1) {\r
339                         line = ts.readLine();\r
340                         if(rxComment->indexIn(line) != -1) {\r
341                             line = rxComment->cap(1);\r
342                         }\r
343                         if(rxComma->indexIn(line) != -1) {\r
344                             line = rxComma->cap(1);\r
345                         }\r
346                         if(rxGen->indexIn(line) != -1) {\r
347                             genName = rxGen->cap(1).simplified();\r
348                             genType = rxGen->cap(2).simplified();\r
349                             genValue = rxGen->cap(3).simplified();\r
350 \r
351                             genNameList->append(genName);\r
352                             genTypeList->append(genType);\r
353                             genValueList->append(genValue);\r
354                         }\r
355                     }\r
356                 }\r
357                 if(rxPort->indexIn(line) != -1) {\r
358                     if(rxComment->indexIn(line) != -1) {\r
359                         line = rxComment->cap(1);\r
360                     }\r
361                     if(rxComma->indexIn(line) != -1) {\r
362                         line = rxComma->cap(1);\r
363                     }\r
364                     portName = rxPort->cap(1).simplified();\r
365                     portId = rxPort->cap(2).simplified();\r
366                     portType = rxPort->cap(3).simplified();\r
367                     portNameList->append(portName);\r
368                     portIdList->append(portId);\r
369                     portTypeList->append(portType);\r
370                 }\r
371             }\r
372         }\r
373     }\r
374     */\r
375 \r
376     twGenerics->setRowCount(genNameList->size());\r
377     for(int i = 0; i < genNameList->size(); i++) {\r
378         twGenerics->setItem(i, 0, new QTableWidgetItem(genNameList->at(i)));\r
379         twGenerics->setItem(i, 1, new QTableWidgetItem(genTypeList->at(i)));\r
380         twGenerics->setItem(i, 2, new QTableWidgetItem(genValueList->at(i)));\r
381     }\r
382     twDataPort->setRowCount(portNameList->size());\r
383     for(int i = 0; i < portNameList->size(); i++) {\r
384         twDataPort->setItem(i, 0, new QTableWidgetItem(portIdList->at(i)));\r
385         twDataPort->setItem(i, 1, new QTableWidgetItem(portNameList->at(i)));\r
386         twDataPort->setItem(i, 2, new QTableWidgetItem(portTypeList->at(i)));\r
387     }\r
388 \r
389     file.close();\r
390     scrollDataPort->setWidget(twDataPort);\r
391     return;\r
392 }\r
393 \r
394 // This function gets the informations in the table and the descriptions, and creates a XML file with this content\r
395 void VHDLConverter::generateXml() {\r
396 /*\r
397     QString portName, portType, portId, genName, genType, genValue;\r
398     QStringList *portNameList, *portTypeList, *portIdList, *genNameList, *genTypeList, *genValueList;\r
399     int x, y, width;\r
400     brief = teBrief->toPlainText();\r
401     desc = teDesc->toPlainText();\r
402     entName = teName->toPlainText();\r
403 \r
404     portNameList = new QStringList;\r
405     portTypeList = new QStringList;\r
406     portIdList = new QStringList;\r
407     genNameList = new QStringList;\r
408     genTypeList = new QStringList;\r
409     genValueList = new QStringList;\r
410     for(int i = 0; i < twGenerics->rowCount(); i++) {\r
411         genNameList->append(twGenerics->item(i,0)->text());\r
412         genTypeList->append(twGenerics->item(i,1)->text());\r
413         genValueList->append(twGenerics->item(i,2)->text());\r
414     }\r
415 \r
416     for(int i = 0; i < twDataPort->rowCount(); i++) {\r
417         portIdList->append(twDataPort->item(i,0)->text());\r
418         portNameList->append(twDataPort->item(i,1)->text());\r
419         portTypeList->append(twDataPort->item(i,2)->text());\r
420     }\r
421 \r
422     QDomDocument doc (entName);\r
423     QDomElement block = doc.createElement("block");\r
424     block.setAttribute("name",entName);\r
425     block.setAttribute("version", "0.1");\r
426     doc.appendChild(block);\r
427 \r
428     QDomElement comments = doc.createElement("comments");\r
429     QDomElement category = doc.createElement("caterory");\r
430     category.setAttribute("ids","");\r
431     comments.appendChild(category);\r
432 \r
433     QDomElement eBrief = doc.createElement("brief");\r
434     if(!brief.isEmpty()) {\r
435         QDomText txtBrief = doc.createTextNode(brief);\r
436         eBrief.appendChild(txtBrief);\r
437         comments.appendChild(eBrief);\r
438     }\r
439     QDomElement eDesc = doc.createElement("description");\r
440     if(!desc.isEmpty()) {\r
441         QDomText txtDesc = doc.createTextNode(desc);\r
442         eDesc.appendChild(txtDesc);\r
443         comments.appendChild(eDesc);\r
444     }\r
445     block.appendChild(comments);\r
446 \r
447     QDomElement parameters = doc.createElement("parameters");\r
448     QDomElement interfaces = doc.createElement("interfaces");\r
449     QDomElement inputs = doc.createElement("inputs");\r
450     QDomElement outputs = doc.createElement("outputs");\r
451     QDomElement bidirs = doc.createElement("bidirs");\r
452     block.appendChild(parameters);\r
453     block.appendChild(interfaces);\r
454     interfaces.appendChild(inputs);\r
455     interfaces.appendChild(outputs);\r
456     interfaces.appendChild(bidirs);\r
457 \r
458     for(int i = 0; i < twGenerics->rowCount(); i++) {\r
459         genName = genNameList->at(i);\r
460         genType = genTypeList->at(i);\r
461         genValue = genValueList->at(i);\r
462         QDomElement parameter = doc.createElement("parameter");\r
463         parameter.setAttribute("name",genName);\r
464         parameter.setAttribute("type",genType);\r
465         parameter.setAttribute("value",genValue);\r
466         parameter.setAttribute("context","generic");\r
467         parameters.appendChild(parameter);\r
468     }\r
469 \r
470     for(int i = 0; i < portIdList->size(); i++) {\r
471         portId = portIdList->at(i);\r
472         portName = portNameList->at(i);\r
473         portType = portTypeList->at(i);\r
474         if(rxWidth->indexIn(portType) != -1) {\r
475             x = rxWidth->cap(1).toInt();\r
476             y = rxWidth->cap(3).toInt();\r
477             if(x < y)\r
478                 width = y - x + 1;\r
479             else if(x > y)\r
480                 width = x - y + 1;\r
481             else\r
482                 width = 1;\r
483         }\r
484 \r
485         if(portId.compare("in", CaseInsensitive) == 0) {\r
486             QDomElement input = doc.createElement("input");\r
487             input.setAttribute("name",portName);\r
488             input.setAttribute("width", width);\r
489             inputs.appendChild(input);\r
490         }\r
491         else if(portId.compare("out", CaseInsensitive) == 0) {\r
492             QDomElement output = doc.createElement("output");\r
493             output.setAttribute("name",portName);\r
494             output.setAttribute("width", width);\r
495             outputs.appendChild(output);\r
496         }\r
497         else if(portId.compare("inout", CaseInsensitive) == 0) {\r
498             QDomElement bidir = doc.createElement("bidir");\r
499             bidir.setAttribute("name",portName);\r
500             bidir.setAttribute("width", width);\r
501             bidirs.appendChild(bidir);\r
502         }\r
503     }\r
504 \r
505     fileName = QFileDialog::getOpenFileName(this, tr("Open File"),\r
506                                             "C:", tr("Files (*.xml)"));\r
507     QFile file(fileName);\r
508     if(!file.open(QIODevice::WriteOnly | QIODevice::Text))\r
509         return;\r
510     QTextStream ts(&file);\r
511     doc.save(ts,QDomNode::EncodingFromTextStream);\r
512     file.close();\r
513 \r
514     QLabel *popup = new QLabel("Votre fichier XML est rempli");\r
515     popup->show();\r
516     */\r
517 }\r