1 #include "VHDLConverter.h"
\r
6 VHDLConverter::VHDLConverter(QWidget *parent) : QWidget(parent) {
\r
8 rxComment = new QRegExp("(.*)--.*");
\r
9 rxComma = new QRegExp("(.*)[;]");
\r
10 rxPort = new QRegExp("[\\s\\t]*(.*)[\\s\\t]*:[\\s\\t]*(in|out|inout)[\\s\\t]*(.*)",CaseInsensitive,QRegExp::RegExp);
\r
11 rxEnt = new QRegExp("[\\s\\t]*entity[\\s\\t]*(.*)[\\s\\t]*is",CaseInsensitive,QRegExp::RegExp);
\r
12 rxArch = new QRegExp("[\\s\\t]*architecture[\\s\\t]*(.*)[\\s\\t]*of (.*)[\\s\\t]*is",CaseInsensitive,QRegExp::RegExp);
\r
13 rxComp = new QRegExp("[\\s\\t]*component[\\s\\t]*(.*)[\\s\\t]*",CaseInsensitive,QRegExp::RegExp);
\r
14 rxEnd = new QRegExp("[\\s\\t]*end(.*)",CaseInsensitive,QRegExp::RegExp);
\r
15 rxComp = new QRegExp("[\\s\\t]*end component;",CaseInsensitive,QRegExp::RegExp);
\r
16 rxGeneric = new QRegExp("[\\s\\t]*generic[\\s\\t]*[(][\\s\\t]*",CaseInsensitive,QRegExp::RegExp);
\r
17 rxEndGen = new QRegExp("[\\s\\t]*[)]",CaseInsensitive,QRegExp::RegExp);
\r
18 rxGen = new QRegExp("[\\s\\t]*(.*)[\\s\\t]*:[\\s\\t]*(.*)[\\s\\t]*:=[\\s\\t]*(.*)",CaseInsensitive,QRegExp::RegExp);
\r
19 rxConst = new QRegExp("[\\s\\t]*constant[\\s\\t]*(.*)[\\s\\t]*:[\\s\\t]*(.)*[\\s\\t]*:=[\\s\\t]*(.*)",CaseInsensitive,QRegExp::RegExp);
\r
20 rxWidth = new QRegExp(".*[(](.*)(downto|to)(.*)[)]",CaseInsensitive,QRegExp::RegExp);
\r
22 QLabel *labelAppli, *lblBrief, *lblDesc, *lblName, *lblPort, *lblGen;
\r
24 loadBut = new QPushButton("load VHDL");
\r
25 genBut = new QPushButton("generate XML");
\r
26 QHBoxLayout *widgetLayout = new QHBoxLayout;
\r
27 QVBoxLayout *left = new QVBoxLayout;
\r
28 QVBoxLayout *right = new QVBoxLayout;
\r
30 scrollDataPort = new QScrollArea;
\r
31 scrollDataPort->setWidgetResizable(true);
\r
32 twDataPort = new QTableWidget(this);
\r
33 scrollDataPort->setWidget(twDataPort);
\r
34 scrollGenerics = new QScrollArea;
\r
35 scrollGenerics->setWidgetResizable(true);
\r
36 twGenerics = new QTableWidget(this);
\r
37 scrollGenerics->setWidget(twGenerics);
\r
38 teName = new QTextEdit;
\r
39 teBrief = new QTextEdit;
\r
40 teDesc = new QTextEdit;
\r
41 lblName = new QLabel("Block name :");
\r
42 lblBrief = new QLabel("Enter a brief description : ");
\r
43 lblDesc = new QLabel("Enter a detailled description : ");
\r
44 lblPort = new QLabel("Ports :");
\r
45 lblGen = new QLabel("Generics :");
\r
47 connect(loadBut, SIGNAL(clicked()),this, SLOT(loadVHDLFile()));
\r
48 connect(genBut, SIGNAL(clicked()), this, SLOT(generateXml()));
\r
50 left->addWidget(loadBut);
\r
51 left->addWidget(lblPort);
\r
52 left->addWidget(scrollDataPort);
\r
53 left->addWidget(lblGen);
\r
54 left->addWidget(scrollGenerics);
\r
56 right->addWidget(lblName);
\r
57 right->addWidget(teName);
\r
58 right->addWidget(lblBrief);
\r
59 right->addWidget(teBrief);
\r
60 right->addWidget(lblDesc);
\r
61 right->addWidget(teDesc);
\r
62 right->addWidget(genBut);
\r
64 widgetLayout->addLayout(left);
\r
65 widgetLayout->addLayout(right);
\r
66 setLayout(widgetLayout);
\r
70 VHDLConverter::~VHDLConverter() {
\r
74 QString VHDLConverter::skipBlankAndComments(QTextStream &in) {
\r
78 // skipping blank/comment lines
\r
79 while ( (line.isEmpty()) || ((line.at(0) == '-') && (line.at(1) == '-')) ) {
\r
83 line = in.readLine();
\r
84 if (!line.isEmpty()) line = line.trimmed();
\r
89 void VHDLConverter::readLibraries(QTextStream &in) throw(Exception) {
\r
91 QRegularExpression rxLib("^library[\\s\\t]*(.+);$",QRegularExpression::CaseInsensitiveOption);
\r
92 QRegularExpression rxPack("^use[\\s\\t]*([^.]+)[.](.+);$",QRegularExpression::CaseInsensitiveOption);
\r
95 line = skipBlankAndComments(in);
\r
97 throw(Exception(VHDLFILE_CORRUPTED));
\r
100 while (! line.contains("entity",Qt::CaseInsensitive)) {
\r
102 QRegularExpressionMatch matchLib = rxLib.match(line);
\r
103 QRegularExpressionMatch matchPack = rxPack.match(line);
\r
105 if (matchLib.hasMatch()) {
\r
107 QString libName = matchLib.captured(1);
\r
108 libName = libName.toLower();
\r
110 cout << "matching library: " << qPrintable(libName) << endl;
\r
112 if (!packages.contains(libName)) {
\r
113 packages.insert(libName,new QList<QString>());
\r
116 else if (matchPack.hasMatch()) {
\r
117 cout << "matching packages" << endl;
\r
119 QString libName = matchPack.captured(1);
\r
120 QString packName = matchPack.captured(2);
\r
122 libName = libName.toLower();
\r
123 packName = packName.toLower();
\r
125 if (libName == "work") {
\r
126 if (!packages.contains("work")) {
\r
127 packages.insert("work",new QList<QString>());
\r
130 else if (libName == "std") {
\r
131 if (!packages.contains("std")) {
\r
132 packages.insert("std",new QList<QString>());
\r
135 else if (!packages.contains(libName)) throw(Exception(VHDLFILE_CORRUPTED));
\r
137 QList<QString>* lstPack = packages.value(libName);
\r
138 QString s = libName + "." + packName;
\r
139 lstPack->append(s);
\r
140 cout << qPrintable(s) << endl;
\r
144 line = skipBlankAndComments(in);
\r
146 throw(Exception(VHDLFILE_CORRUPTED));
\r
148 cout << "read line = " << qPrintable(line) << endl;
\r
152 void VHDLConverter::readEntity(QTextStream &in) throw(Exception) {
\r
156 void VHDLConverter::readGenerics(QTextStream &in) throw(Exception) {
\r
160 void VHDLConverter::readPorts(QTextStream &in) throw(Exception) {
\r
164 void VHDLConverter::readArchitecture(QTextStream &in) throw(Exception) {
\r
168 // This function opens a VHDL file and get the informations about the entity :
\r
169 // First the generics, then the signals.
\r
170 // You can edit the descriptions in the right, one for the brief description, the other for the detailled.
\r
171 void VHDLConverter::loadVHDLFile() {
\r
173 QString line, portName, portType, portId, genName, genType, genValue;
\r
174 QStringList *portNameList, *portTypeList, *portIdList, *genNameList, *genTypeList, *genValueList;
\r
176 twDataPort->setColumnCount(3);
\r
177 twDataPort->setRowCount(cpt);
\r
178 twGenerics->setColumnCount(3);
\r
179 twGenerics->setRowCount(cpt);
\r
180 portNameList = new QStringList;
\r
181 portTypeList = new QStringList;
\r
182 portIdList = new QStringList;
\r
183 genNameList = new QStringList;
\r
184 genTypeList = new QStringList;
\r
185 genValueList = new QStringList;
\r
187 fileName = QFileDialog::getOpenFileName(this,
\r
188 tr("Open File"), "C:", tr("Files (*.txt *.vhd)"));
\r
189 QFile file(fileName);
\r
191 if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
\r
193 QTextStream ts(&file);
\r
198 while (!ts.atEnd())
\r
200 line = ts.readLine();
\r
201 if(rxComment->indexIn(line) != -1) {
\r
202 line = rxComment->cap(1);
\r
205 if(rxEnt->indexIn(line)!= -1) {
\r
207 entName = rxEnt->cap(1);
\r
208 teName->setText(entName);
\r
209 QSize size = teName->document()->size().toSize();
\r
210 teName->setMaximumSize(size);
\r
212 while(rxEnd->indexIn(line) == -1) {
\r
213 line = ts.readLine();
\r
214 if(rxComment->indexIn(line) != -1) {
\r
215 line = rxComment->cap(1);
\r
217 if(rxComma->indexIn(line) != -1) {
\r
218 line = rxComma->cap(1);
\r
220 if(rxGeneric->indexIn(line) != -1) {
\r
221 while(rxEndGen->indexIn(line) == -1) {
\r
222 line = ts.readLine();
\r
223 if(rxComment->indexIn(line) != -1) {
\r
224 line = rxComment->cap(1);
\r
226 if(rxComma->indexIn(line) != -1) {
\r
227 line = rxComma->cap(1);
\r
229 if(rxGen->indexIn(line) != -1) {
\r
230 genName = rxGen->cap(1).simplified();
\r
231 genType = rxGen->cap(2).simplified();
\r
232 genValue = rxGen->cap(3).simplified();
\r
234 genNameList->append(genName);
\r
235 genTypeList->append(genType);
\r
236 genValueList->append(genValue);
\r
240 if(rxPort->indexIn(line) != -1) {
\r
241 if(rxComment->indexIn(line) != -1) {
\r
242 line = rxComment->cap(1);
\r
244 if(rxComma->indexIn(line) != -1) {
\r
245 line = rxComma->cap(1);
\r
247 portName = rxPort->cap(1).simplified();
\r
248 portId = rxPort->cap(2).simplified();
\r
249 portType = rxPort->cap(3).simplified();
\r
250 portNameList->append(portName);
\r
251 portIdList->append(portId);
\r
252 portTypeList->append(portType);
\r
259 twGenerics->setRowCount(genNameList->size());
\r
260 for(int i = 0; i < genNameList->size(); i++) {
\r
261 twGenerics->setItem(i, 0, new QTableWidgetItem(genNameList->at(i)));
\r
262 twGenerics->setItem(i, 1, new QTableWidgetItem(genTypeList->at(i)));
\r
263 twGenerics->setItem(i, 2, new QTableWidgetItem(genValueList->at(i)));
\r
265 twDataPort->setRowCount(portNameList->size());
\r
266 for(int i = 0; i < portNameList->size(); i++) {
\r
267 twDataPort->setItem(i, 0, new QTableWidgetItem(portIdList->at(i)));
\r
268 twDataPort->setItem(i, 1, new QTableWidgetItem(portNameList->at(i)));
\r
269 twDataPort->setItem(i, 2, new QTableWidgetItem(portTypeList->at(i)));
\r
273 scrollDataPort->setWidget(twDataPort);
\r
277 // This function gets the informations in the table and the descriptions, and creates a XML file with this content
\r
278 void VHDLConverter::generateXml() {
\r
280 QString portName, portType, portId, genName, genType, genValue;
\r
281 QStringList *portNameList, *portTypeList, *portIdList, *genNameList, *genTypeList, *genValueList;
\r
283 brief = teBrief->toPlainText();
\r
284 desc = teDesc->toPlainText();
\r
285 entName = teName->toPlainText();
\r
287 portNameList = new QStringList;
\r
288 portTypeList = new QStringList;
\r
289 portIdList = new QStringList;
\r
290 genNameList = new QStringList;
\r
291 genTypeList = new QStringList;
\r
292 genValueList = new QStringList;
\r
293 for(int i = 0; i < twGenerics->rowCount(); i++) {
\r
294 genNameList->append(twGenerics->item(i,0)->text());
\r
295 genTypeList->append(twGenerics->item(i,1)->text());
\r
296 genValueList->append(twGenerics->item(i,2)->text());
\r
299 for(int i = 0; i < twDataPort->rowCount(); i++) {
\r
300 portIdList->append(twDataPort->item(i,0)->text());
\r
301 portNameList->append(twDataPort->item(i,1)->text());
\r
302 portTypeList->append(twDataPort->item(i,2)->text());
\r
305 QDomDocument doc (entName);
\r
306 QDomElement block = doc.createElement("block");
\r
307 block.setAttribute("name",entName);
\r
308 block.setAttribute("version", "0.1");
\r
309 doc.appendChild(block);
\r
311 QDomElement comments = doc.createElement("comments");
\r
312 QDomElement category = doc.createElement("caterory");
\r
313 category.setAttribute("ids","");
\r
314 comments.appendChild(category);
\r
316 QDomElement eBrief = doc.createElement("brief");
\r
317 if(!brief.isEmpty()) {
\r
318 QDomText txtBrief = doc.createTextNode(brief);
\r
319 eBrief.appendChild(txtBrief);
\r
320 comments.appendChild(eBrief);
\r
322 QDomElement eDesc = doc.createElement("description");
\r
323 if(!desc.isEmpty()) {
\r
324 QDomText txtDesc = doc.createTextNode(desc);
\r
325 eDesc.appendChild(txtDesc);
\r
326 comments.appendChild(eDesc);
\r
328 block.appendChild(comments);
\r
330 QDomElement parameters = doc.createElement("parameters");
\r
331 QDomElement interfaces = doc.createElement("interfaces");
\r
332 QDomElement inputs = doc.createElement("inputs");
\r
333 QDomElement outputs = doc.createElement("outputs");
\r
334 QDomElement bidirs = doc.createElement("bidirs");
\r
335 block.appendChild(parameters);
\r
336 block.appendChild(interfaces);
\r
337 interfaces.appendChild(inputs);
\r
338 interfaces.appendChild(outputs);
\r
339 interfaces.appendChild(bidirs);
\r
341 for(int i = 0; i < twGenerics->rowCount(); i++) {
\r
342 genName = genNameList->at(i);
\r
343 genType = genTypeList->at(i);
\r
344 genValue = genValueList->at(i);
\r
345 QDomElement parameter = doc.createElement("parameter");
\r
346 parameter.setAttribute("name",genName);
\r
347 parameter.setAttribute("type",genType);
\r
348 parameter.setAttribute("value",genValue);
\r
349 parameter.setAttribute("context","generic");
\r
350 parameters.appendChild(parameter);
\r
353 for(int i = 0; i < portIdList->size(); i++) {
\r
354 portId = portIdList->at(i);
\r
355 portName = portNameList->at(i);
\r
356 portType = portTypeList->at(i);
\r
357 if(rxWidth->indexIn(portType) != -1) {
\r
358 x = rxWidth->cap(1).toInt();
\r
359 y = rxWidth->cap(3).toInt();
\r
368 if(portId.compare("in", CaseInsensitive) == 0) {
\r
369 QDomElement input = doc.createElement("input");
\r
370 input.setAttribute("name",portName);
\r
371 input.setAttribute("width", width);
\r
372 inputs.appendChild(input);
\r
374 else if(portId.compare("out", CaseInsensitive) == 0) {
\r
375 QDomElement output = doc.createElement("output");
\r
376 output.setAttribute("name",portName);
\r
377 output.setAttribute("width", width);
\r
378 outputs.appendChild(output);
\r
380 else if(portId.compare("inout", CaseInsensitive) == 0) {
\r
381 QDomElement bidir = doc.createElement("bidir");
\r
382 bidir.setAttribute("name",portName);
\r
383 bidir.setAttribute("width", width);
\r
384 bidirs.appendChild(bidir);
\r
388 fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
\r
389 "C:", tr("Files (*.xml)"));
\r
390 QFile file(fileName);
\r
391 if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
\r
393 QTextStream ts(&file);
\r
394 doc.save(ts,QDomNode::EncodingFromTextStream);
\r
397 QLabel *popup = new QLabel("Votre fichier XML est rempli");
\r