Qucs-GUI  0.0.18
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
verilogfile.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  verilogfile.cpp
3  ---------------
4  begin : Sat Mar 31 2007
5  copyright : (C) 2007 by Stefan Jahn
6  email : stefa@lkcc.org
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 #include <QtGui>
18 #include "verilogfile.h"
19 #include "qucs.h"
20 //Added by qt3to4:
21 #include <QTextStream>
22 #include "main.h"
23 #include "schematic.h"
24 
25 #include <QRegExp>
26 #include <QDir>
27 #include <QFileInfo>
28 
29 
31 {
33  Description = QObject::tr("Verilog file");
34 
35  Props.append(new Property("File", "sub.v", false,
36  QObject::tr("Name of Verilog file")));
37 
38  Model = "Verilog";
39  Name = "X";
40 
41  // Do NOT call createSymbol() here. But create port to let it rotate.
42  Ports.append(new Port(0, 0));
43 }
44 
45 // -------------------------------------------------------
47 {
48  Verilog_File *p = new Verilog_File();
49  p->Props.getFirst()->Value = Props.getFirst()->Value;
50  p->recreate(0);
51  return p;
52 }
53 
54 // -------------------------------------------------------
55 Element* Verilog_File::info(QString& Name, char* &BitmapFile, bool getNewOne)
56 {
57  Name = QObject::tr("Verilog file");
58  BitmapFile = (char *) "vhdlfile";
59 
60  if(getNewOne) {
61  Verilog_File *p = new Verilog_File();
62  p->recreate(0); // createSymbol() is NOT called in constructor !!!
63  return p;
64  }
65  return 0;
66 }
67 
68 // -------------------------------------------------------
70 {
71  QString s;
72  Port *pp = Ports.first();
73  if(pp) {
74  s = " " + ModuleName + " " + Name + " (";
75 
76  // output all node names
77  if(pp) s += pp->Connection->Name;
78  for(pp = Ports.next(); pp != 0; pp = Ports.next())
79  s += ", "+pp->Connection->Name; // node names
80 
81  s += ");\n";
82  }
83  return s;
84 }
85 
86 // -------------------------------------------------------
87 // Returns a comma separated list of the port names of the last
88 // entity in this file.
90 {
91  QString s, File(Props.getFirst()->Value);
92  QFileInfo Info(File);
93  if(Info.isRelative())
94  File = QucsSettings.QucsWorkDir.filePath(File);
95 
96  QFile f(File);
97  if(!f.open(QIODevice::ReadOnly))
98  return QString("");
99 
100  QTextStream stream(&f);
101  File = stream.read(); // QString is better for "find" function
102  f.close();
103 
104  // parse ports, i.e. network connections
105  Verilog_File_Info VInfo(File);
106  ModuleName = VInfo.ModuleName;
107  return VInfo.PortNames;
108 }
109 
110 // -------------------------------------------------------
112 {
113  QFontMetrics metrics(QucsSettings.font); // get size of text
114  int fHeight = metrics.lineSpacing();
115 
116  int No = 0;
117  QString tmp, PortNames = loadFile();
118  if(!PortNames.isEmpty())
119  No = PortNames.count(',') + 1;
120 
121 
122  #define HALFWIDTH 24
123  int h = 30*((No-1)/2) + 15;
124  Lines.append(new Line(-HALFWIDTH, -h, HALFWIDTH, -h,QPen(Qt::darkBlue,2)));
125  Lines.append(new Line( HALFWIDTH, -h, HALFWIDTH, h,QPen(Qt::darkBlue,2)));
126  Lines.append(new Line(-HALFWIDTH, h, HALFWIDTH, h,QPen(Qt::darkBlue,2)));
127  Lines.append(new Line(-HALFWIDTH, -h,-HALFWIDTH, h,QPen(Qt::darkBlue,2)));
128 
129  tmp = QObject::tr("verilog");
130  int w = metrics.width(tmp);
131  Texts.append(new Text(w/-2, fHeight/-2, tmp));
132 
133 
134  int y = 15-h, i = 0;
135  while(i<No) {
136  Lines.append(new Line(-30, y,-HALFWIDTH, y,QPen(Qt::darkBlue,2)));
137  Ports.append(new Port(-30, y));
138  tmp = PortNames.section(',', i, i);
139  w = metrics.width(tmp);
140  Texts.append(new Text(-26-w, y-fHeight-2, tmp));
141  i++;
142 
143  if(i == No) break;
144  Lines.append(new Line(HALFWIDTH, y, 30, y,QPen(Qt::darkBlue,2)));
145  Ports.append(new Port( 30, y));
146  tmp = PortNames.section(',', i, i);
147  Texts.append(new Text( 27, y-fHeight-2, tmp));
148  y += 60;
149  i++;
150  }
151 
152  x1 = -30; y1 = -h-2;
153  x2 = 30; y2 = h+2;
154  tx = x1+4;
155  ty = y2+4;
156 }
157 
158 // -------------------------------------------------------
160 {
161  // construct full filename
162  QString FileName = Props.getFirst()->Value;
163  return properAbsFileName(FileName);
164 }
165 
166 // -------------------------------------------------------
167 bool Verilog_File::createSubNetlist(QTextStream *stream)
168 {
169  ErrText = "";
170 
171  // check filename
172  QString FileName = Props.getFirst()->Value;
173  if(FileName.isEmpty()) {
174  ErrText += QObject::tr("ERROR: No file name in %1 component \"%2\".").
175  arg(Model).arg(Name);
176  return false;
177  }
178 
179  // construct full filename
180  FileName = getSubcircuitFile();
181 
182  // open file for reading
183  QFile f(FileName);
184  if(!f.open(QIODevice::ReadOnly)) {
185  ErrText += QObject::tr("ERROR: Cannot open %1 file \"%2\".").
186  arg(Model).arg(FileName);
187  return false;
188  }
189 
190  // write the whole Verilog file into the netlist output
191  QByteArray FileContent = f.readAll();
192  f.close();
193  (*stream) << '\n';
194  //?stream->writeRawBytes(FileContent.data(), FileContent.size());
195  (*stream) << FileContent.data();
196  (*stream) << '\n';
197  return true;
198 }
199 
200 // -------------------------------------------------------
202 {
203  ModuleName = "";
204  PortNames = "";
205 }
206 
207 // -------------------------------------------------------
208 Verilog_File_Info::Verilog_File_Info(QString File, bool isfile)
209 {
210  if (isfile) {
211  QFile f(File);
212  if(!f.open(QIODevice::ReadOnly))
213  File = "";
214  else {
215  QByteArray FileContent = f.readAll();
216  File = QString(FileContent);
217  }
218  f.close();
219  }
220 
221  QString s;
222  int i=0, j, k=0;
223  while((i=File.find("//", i)) >= 0) { // remove all Verilog comments
224  j = File.find('\n', i+2); // (This also finds "//" within a ...
225  if(j < 0) // string, but as no strings are ...
226  File = File.left(i); // allowed in module headers, it ...
227  else // does not matter.)
228  File.remove(i, j-i);
229  }
230 
231  i=0;
232  while((i=File.find("/*", i)) >= 0) { // remove all Verilog comments
233  j = File.find("*/", i+2); // (This also finds "/*" within a ...
234  if(j < 0) // string, but as no strings are ...
235  File = File.left(i); // allowed in module headers, it ...
236  else // does not matter.)
237  File.remove(i, j-i+2);
238  }
239 
240  QRegExp Expr,Expr1;
241  Expr.setCaseSensitive(true);
242  Expr1.setCaseSensitive(true);
243  k--;
244  Expr.setPattern("\\bmodule\\b"); // start of last module
245  k = File.findRev(Expr, k);
246  if(k < 0)
247  return;
248 
249  Expr.setPattern("\\bendmodule\\b"); // end of last module
250  i = File.find(Expr, k+7);
251  if(i < 0)
252  return;
253  s = File.mid(k+7, i-k-7); // cut out module declaration
254 
255  Expr.setPattern("\\b");
256  i = s.find(Expr);
257  if(i < 0)
258  return;
259  j = s.find(Expr, i+1);
260  if(j < 0)
261  return;
262  ModuleName = s.mid(i, j-i); // save module name
263 
264  i = s.find('(', j);
265  if(i < 0)
266  return;
267 
268  j = s.find(')', i);
269  if(j < 0)
270  return;
271  s = s.mid(i+1, j-i-1);
272 
273  // parse ports, i.e. network connections; and generics, i.e. parameters
274  PortNames = parsePorts (s, 0);
275 }
276 
277 // -------------------------------------------------------
278 QString Verilog_File_Info::parsePorts(QString s, int i)
279 {
280  QRegExp Expr,Expr1;
281  Expr.setCaseSensitive(true);
282  Expr1.setCaseSensitive(true);
283 
284  int j;
285  i = 0; // remove all Verilog identifiers (e.g. "input")
286  Expr.setPattern("(\\binput\\b|\\boutput\\b|\\binout\\b)");
287  Expr1.setPattern("(\\b)");
288  while((i=s.find(Expr, i)) >= 0) {
289  j = s.find(Expr1, i+1);
290  if(j < 0)
291  s = s.left(i);
292  else
293  s.remove(i, j-i);
294  }
295 
296  s.remove(' ');
297  s.remove('\n');
298  s.remove('\t');
299  return s;
300 }
Q3PtrList< Line > Lines
Definition: component.h:67
QDir QucsWorkDir
Definition: main.h:65
int Type
Definition: element.h:152
Node * Connection
Definition: element.h:79
int y1
Definition: element.h:153
QFont font
Definition: main.h:46
QString verilogCode(int)
Definition: verilogfile.cpp:69
tQucsSettings QucsSettings
Definition: main.cpp:52
QString ModuleName
Definition: verilogfile.h:54
int tx
Definition: component.h:78
int y2
Definition: element.h:153
Definition: element.h:72
int x1
Definition: element.h:153
void createSymbol()
#define isDigitalComponent
Definition: element.h:113
Definitions and declarations for the main application.
int ty
Definition: component.h:78
QString properAbsFileName(const QString &Name)
Definition: main.cpp:452
Q3PtrList< Property > Props
Definition: component.h:72
QString parsePorts(QString, int)
static Element * info(QString &, char *&, bool getNewOne=false)
Definition: verilogfile.cpp:55
QString loadFile()
Definition: verilogfile.cpp:89
bool createSubNetlist(QTextStream *)
Definition: element.h:82
Definition: element.h:48
Superclass of all schematic drawing elements.
Definition: element.h:142
void recreate(Schematic *)
Definition: component.cpp:1250
QString getSubcircuitFile()
Q3PtrList< Port > Ports
Definition: component.h:70
QString ErrText
Definition: verilogfile.h:43
QString Name
Definition: component.h:80
Q3PtrList< Text > Texts
Definition: component.h:71
QString Model
Definition: component.h:80
QString Name
Definition: node.h:40
QString ModuleName
Definition: verilogfile.h:42
QString Description
Definition: component.h:81
#define HALFWIDTH
Component * newOne()
Definition: verilogfile.cpp:46
int x2
Definition: element.h:153