22 #include <qmessagebox.h>
24 #include <qstringlist.h>
27 #include <qtextedit.h>
51 QString Schematic::createClipboardFile()
59 QString
s(
"<Qucs Schematic " PACKAGE_VERSION
">\n");
62 s +=
"<Components>\n";
65 s += pc->
save()+
"\n"; z++; }
66 s +=
"</Components>\n";
69 for(pw =
Wires->first(); pw != 0; pw =
Wires->next())
73 s += pw->
save().section(
'"', 0, 0)+
"\"\" 0 0 0>\n";
79 if(pn->Label)
if(pn->Label->isSelected) {
80 s += pn->Label->save()+
"\n"; z++; }
86 s += pd->
save()+
"\n"; z++; }
92 if(pp->
Name.at(0) !=
'.') {
93 s +=
"<"+pp->
save()+
">\n"; z++; }
94 s +=
"</Paintings>\n";
103 bool Schematic::loadIntoNothing(QTextStream *stream)
106 while(!stream->atEnd()) {
107 Line = stream->readLine();
108 if(Line.at(0) ==
'<')
if(Line.at(1) ==
'/')
return true;
111 QMessageBox::critical(0, QObject::tr(
"Error"),
112 QObject::tr(
"Format Error:\n'Painting' field is not closed!"));
118 bool Schematic::pasteFromClipboard(QTextStream *stream, QPtrList<Element> *pe)
122 Line = stream->readLine();
123 if(Line.left(16) !=
"<Qucs Schematic ")
126 QString
s = PACKAGE_VERSION;
127 Line = Line.mid(16, Line.length()-17);
129 QMessageBox::critical(0, QObject::tr(
"Error"),
130 QObject::tr(
"Wrong document version: ")+Line);
136 while(!stream->atEnd()) {
137 Line = stream->readLine();
138 if(Line ==
"<Components>") {
139 if(!loadIntoNothing(stream))
return false; }
141 if(Line ==
"<Wires>") {
142 if(!loadIntoNothing(stream))
return false; }
144 if(Line ==
"<Diagrams>") {
145 if(!loadIntoNothing(stream))
return false; }
147 if(Line ==
"<Paintings>") {
148 if(!loadPaintings(stream, (QPtrList<Painting>*)pe))
return false; }
150 QMessageBox::critical(0, QObject::tr(
"Error"),
151 QObject::tr(
"Clipboard Format Error:\nUnknown field!"));
160 while(!stream->atEnd()) {
161 Line = stream->readLine();
162 if(Line ==
"<Components>") {
163 if(!loadComponents(stream, (QPtrList<Component>*)pe))
return false; }
165 if(Line ==
"<Wires>") {
166 if(!loadWires(stream, pe))
return false; }
168 if(Line ==
"<Diagrams>") {
169 if(!loadDiagrams(stream, (QPtrList<Diagram>*)pe))
return false; }
171 if(Line ==
"<Paintings>") {
172 if(!loadPaintings(stream, (QPtrList<Painting>*)pe))
return false; }
174 QMessageBox::critical(0, QObject::tr(
"Error"),
175 QObject::tr(
"Clipboard Format Error:\nUnknown field!"));
187 QString cppfile = info.dirPath () + QDir::separator() +
DataSet;
188 QFile file (cppfile);
190 if (!file.open (IO_WriteOnly)) {
191 QMessageBox::critical (0, QObject::tr(
"Error"),
192 QObject::tr(
"Cannot save C++ file \"%1\"!").
arg(cppfile));
196 QTextStream stream (&file);
207 stream <<
" // symbol drawing code\n";
209 if (pp->
Name ==
".ID ")
continue;
210 if (pp->
Name ==
".PortSym ") {
211 if (((
PortSymbol*)pp)->numberStr.toInt() > maxNum)
212 maxNum = ((
PortSymbol*)pp)->numberStr.toInt();
216 if (x1 < xmin) xmin = x1;
217 if (x2 > xmax) xmax = x2;
218 if (y1 < ymin) ymin = y1;
219 if (y2 > ymax) ymax = y2;
220 stream <<
" " << pp->
saveCpp () <<
"\n";
223 stream <<
"\n // terminal definitions\n";
224 for (
int i = 1;
i <= maxNum;
i++) {
226 if (pp->
Name ==
".PortSym ")
228 stream <<
" " << pp->
saveCpp () <<
"\n";
232 stream <<
"\n // symbol boundings\n"
233 <<
" x1 = " << xmin <<
"; " <<
" y1 = " << ymin <<
";\n"
234 <<
" x2 = " << xmax <<
"; " <<
" y2 = " << ymax <<
";\n";
236 stream <<
"\n // property text position\n";
238 if (pp->
Name ==
".ID ")
239 stream <<
" " << pp->
saveCpp () <<
"\n";
247 int Schematic::saveDocument()
250 if(!file.open(IO_WriteOnly)) {
251 QMessageBox::critical(0, QObject::tr(
"Error"),
252 QObject::tr(
"Cannot save document!"));
256 QTextStream stream(&file);
258 stream <<
"<Qucs Schematic " << PACKAGE_VERSION <<
">\n";
260 stream <<
"<Properties>\n";
269 stream <<
Scale <<
","<<contentsX()<<
","<<contentsY() <<
">\n";
273 stream <<
" <DataSet=" <<
DataSet <<
">\n";
274 stream <<
" <DataDisplay=" <<
DataDisplay <<
">\n";
275 stream <<
" <OpenDisplay=" <<
SimOpenDpl <<
">\n";
276 stream <<
" <Script=" <<
Script <<
">\n";
278 stream <<
" <showFrame=" <<
showFrame <<
">\n";
282 stream <<
" <FrameText0=" << t <<
">\n";
284 stream <<
" <FrameText1=" << t <<
">\n";
286 stream <<
" <FrameText2=" << t <<
">\n";
288 stream <<
" <FrameText3=" << t <<
">\n";
289 stream <<
"</Properties>\n";
292 stream <<
"<Symbol>\n";
294 stream <<
" <" << pp->
save() <<
">\n";
295 stream <<
"</Symbol>\n";
297 stream <<
"<Components>\n";
299 stream <<
" " << pc->save() <<
"\n";
300 stream <<
"</Components>\n";
302 stream <<
"<Wires>\n";
304 stream <<
" " << pw->save() <<
"\n";
308 if(pn->Label) stream <<
" " << pn->Label->save() <<
"\n";
309 stream <<
"</Wires>\n";
311 stream <<
"<Diagrams>\n";
313 stream <<
" " << pd->save() <<
"\n";
314 stream <<
"</Diagrams>\n";
316 stream <<
"<Paintings>\n";
318 stream <<
" <" << pp->
save() <<
">\n";
319 stream <<
"</Paintings>\n";
335 bool Schematic::loadProperties(QTextStream *stream)
338 QString Line, cstr, nstr;
339 while(!stream->atEnd()) {
340 Line = stream->readLine();
341 if(Line.at(0) ==
'<')
if(Line.at(1) ==
'/')
return true;
342 Line = Line.stripWhiteSpace();
343 if(Line.isEmpty())
continue;
345 if(Line.at(0) !=
'<') {
346 QMessageBox::critical(0, QObject::tr(
"Error"),
347 QObject::tr(
"Format Error:\nWrong property field limiter!"));
350 if(Line.at(Line.length()-1) !=
'>') {
351 QMessageBox::critical(0, QObject::tr(
"Error"),
352 QObject::tr(
"Format Error:\nWrong property field limiter!"));
355 Line = Line.mid(1, Line.length()-2);
357 cstr = Line.section(
'=',0,0);
358 nstr = Line.section(
'=',1,1);
360 ViewX1 = nstr.section(
',',0,0).toInt(&ok);
if(ok) {
361 ViewY1 = nstr.section(
',',1,1).toInt(&ok);
if(ok) {
362 ViewX2 = nstr.section(
',',2,2).toInt(&ok);
if(ok) {
363 ViewY2 = nstr.section(
',',3,3).toInt(&ok);
if(ok) {
364 Scale = nstr.section(
',',4,4).toDouble(&ok);
if(ok) {
365 tmpViewX1 = nstr.section(
',',5,5).toInt(&ok);
if(ok)
366 tmpViewY1 = nstr.section(
',',6,6).toInt(&ok); }}}}} }
367 else if(cstr ==
"Grid") {
368 GridX = nstr.section(
',',0,0).toInt(&ok);
if(ok) {
369 GridY = nstr.section(
',',1,1).toInt(&ok);
if(ok) {
370 if(nstr.section(
',',2,2).toInt(&ok) == 0) GridOn =
false;
371 else GridOn =
true; }} }
372 else if(cstr ==
"DataSet") DataSet = nstr;
373 else if(cstr ==
"DataDisplay") DataDisplay = nstr;
374 else if(cstr ==
"OpenDisplay")
375 if(nstr.toInt(&ok) == 0) SimOpenDpl =
false;
376 else SimOpenDpl =
true;
377 else if(cstr ==
"Script") Script = nstr;
378 else if(cstr ==
"RunScript")
379 if(nstr.toInt(&ok) == 0) SimRunScript =
false;
380 else SimRunScript =
true;
381 else if(cstr ==
"showFrame")
382 showFrame = nstr.at(0).latin1() -
'0';
388 QMessageBox::critical(0, QObject::tr(
"Error"),
389 QObject::tr(
"Format Error:\nUnknown property: ")+cstr);
393 QMessageBox::critical(0, QObject::tr(
"Error"),
394 QObject::tr(
"Format Error:\nNumber expected in property field!"));
399 QMessageBox::critical(0, QObject::tr(
"Error"),
400 QObject::tr(
"Format Error:\n'Property' field is not closed!"));
406 void Schematic::simpleInsertComponent(
Component *
c)
417 if(pn->
cx == x)
if(pn->
cy == y) {
418 if (!pn->
DType.isEmpty()) {
421 if (!pp->
Type.isEmpty()) {
432 if (!pp->
Type.isEmpty()) {
443 bool Schematic::loadComponents(QTextStream *stream, QPtrList<Component> *List)
447 while(!stream->atEnd()) {
448 Line = stream->readLine();
449 if(Line.at(0) ==
'<')
if(Line.at(1) ==
'/')
return true;
450 Line = Line.stripWhiteSpace();
451 if(Line.isEmpty())
continue;
458 for(z=c->
Name.length()-1; z>=0; z--)
459 if(!c->
Name.at(z).isDigit())
break;
463 else simpleInsertComponent(c);
466 QMessageBox::critical(0, QObject::tr(
"Error"),
467 QObject::tr(
"Format Error:\n'Component' field is not closed!"));
473 void Schematic::simpleInsertWire(
Wire *pw)
478 if(pn->
cx == pw->
x1)
if(pn->
cy == pw->
y1)
break;
485 if(pw->
x1 == pw->
x2)
if(pw->
y1 == pw->
y2) {
499 if(pn->
cx == pw->
x2)
if(pn->
cy == pw->
y2)
break;
512 bool Schematic::loadWires(QTextStream *stream, QPtrList<Element> *List)
516 while(!stream->atEnd()) {
517 Line = stream->readLine();
518 if(Line.at(0) ==
'<')
if(Line.at(1) ==
'/')
return true;
519 Line = Line.stripWhiteSpace();
520 if(Line.isEmpty())
continue;
525 QMessageBox::critical(0, QObject::tr(
"Error"),
526 QObject::tr(
"Format Error:\nWrong 'wire' line format!"));
533 List->append(w->
Label);
540 else simpleInsertWire(w);
543 QMessageBox::critical(0, QObject::tr(
"Error"),
544 QObject::tr(
"Format Error:\n'Wire' field is not closed!"));
549 bool Schematic::loadDiagrams(QTextStream *stream, QPtrList<Diagram> *List)
553 while(!stream->atEnd()) {
554 Line = stream->readLine();
555 if(Line.at(0) ==
'<')
if(Line.at(1) ==
'/')
return true;
556 Line = Line.stripWhiteSpace();
557 if(Line.isEmpty())
continue;
559 cstr = Line.section(
' ',0,0);
564 else if(cstr ==
"<ySmith") d =
new SmithDiagram(0,0,
false);
565 else if(cstr ==
"<PS") d =
new PSDiagram();
566 else if(cstr ==
"<SP") d =
new PSDiagram(0,0,
false);
572 QMessageBox::critical(0, QObject::tr(
"Error"),
573 QObject::tr(
"Format Error:\nUnknown diagram!"));
577 if(!d->
load(Line, stream)) {
578 QMessageBox::critical(0, QObject::tr(
"Error"),
579 QObject::tr(
"Format Error:\nWrong 'diagram' line format!"));
586 QMessageBox::critical(0, QObject::tr(
"Error"),
587 QObject::tr(
"Format Error:\n'Diagram' field is not closed!"));
592 bool Schematic::loadPaintings(QTextStream *stream, QPtrList<Painting> *List)
596 while(!stream->atEnd()) {
597 Line = stream->readLine();
598 if(Line.at(0) ==
'<')
if(Line.at(1) ==
'/')
return true;
600 Line = Line.stripWhiteSpace();
601 if(Line.isEmpty())
continue;
602 if( (Line.at(0) !=
'<') || (Line.at(Line.length()-1) !=
'>')) {
603 QMessageBox::critical(0, QObject::tr(
"Error"),
604 QObject::tr(
"Format Error:\nWrong 'painting' line delimiter!"));
607 Line = Line.mid(1, Line.length()-2);
609 cstr = Line.section(
' ',0,0);
612 else if(cstr ==
".PortSym") p =
new PortSymbol();
613 else if(cstr ==
".ID") p =
new ID_Text();
615 else if(cstr ==
"Rectangle") p =
new Rectangle();
616 else if(cstr ==
"Arrow") p =
new Arrow();
617 else if(cstr ==
"Ellipse") p =
new Ellipse();
619 QMessageBox::critical(0, QObject::tr(
"Error"),
620 QObject::tr(
"Format Error:\nUnknown painting!"));
625 QMessageBox::critical(0, QObject::tr(
"Error"),
626 QObject::tr(
"Format Error:\nWrong 'painting' line format!"));
633 QMessageBox::critical(0, QObject::tr(
"Error"),
634 QObject::tr(
"Format Error:\n'Painting' field is not closed!"));
642 if(!file.open(IO_ReadOnly)) {
643 QMessageBox::critical(0, QObject::tr(
"Error"),
644 QObject::tr(
"Cannot load document: ")+
DocName);
649 QTextStream stream(&file);
658 Line = stream.readLine();
659 }
while(Line.isEmpty());
661 if(Line.left(16) !=
"<Qucs Schematic ") {
663 QMessageBox::critical(0, QObject::tr(
"Error"),
664 QObject::tr(
"Wrong document type: ")+
DocName);
668 Line = Line.mid(16, Line.length()-17);
671 QMessageBox::critical(0, QObject::tr(
"Error"),
672 QObject::tr(
"Wrong document version: ")+Line);
677 while(!stream.atEnd()) {
678 Line = stream.readLine();
679 Line = Line.stripWhiteSpace();
680 if(Line.isEmpty())
continue;
682 if(Line ==
"<Symbol>") {
689 if(Line ==
"<Properties>") {
690 if(!loadProperties(&stream)) { file.close();
return false; } }
692 if(Line ==
"<Components>") {
693 if(!loadComponents(&stream)) { file.close();
return false; } }
695 if(Line ==
"<Wires>") {
696 if(!loadWires(&stream)) { file.close();
return false; } }
698 if(Line ==
"<Diagrams>") {
699 if(!loadDiagrams(&stream, &
DocDiags)) { file.close();
return false; } }
701 if(Line ==
"<Paintings>") {
702 if(!loadPaintings(&stream, &
DocPaints)) { file.close();
return false; } }
704 QMessageBox::critical(0, QObject::tr(
"Error"),
705 QObject::tr(
"File Format Error:\nUnknown field!"));
718 QString Schematic::createUndoString(
char Op)
729 s += pc->
save()+
"\n";
733 s += pw->
save()+
"\n";
740 s += pd->
save()+
"\n";
744 s +=
"<"+pp->
save()+
">\n";
752 QString Schematic::createSymbolUndoString(
char Op)
764 s +=
"<"+pp->
save()+
">\n";
773 bool Schematic::rebuild(QString *s)
782 QTextStream stream(s, IO_ReadOnly);
783 Line = stream.readLine();
786 if(!loadComponents(&stream))
return false;
787 if(!loadWires(&stream))
return false;
788 if(!loadDiagrams(&stream, &
DocDiags))
return false;
789 if(!loadPaintings(&stream, &
DocPaints))
return false;
796 bool Schematic::rebuildSymbol(QString *s)
801 QTextStream stream(s, IO_ReadOnly);
802 Line = stream.readLine();
805 Line = stream.readLine();
806 Line = stream.readLine();
807 Line = stream.readLine();
808 if(!loadPaintings(&stream, &
SymbolPaints))
return false;
820 void Schematic::createNodeSet(QStringList& Collect,
int& countInit,
825 Collect.append(
"NodeSet:NS" + QString::number(countInit++) +
" " +
830 void Schematic::throughAllNodes(
bool User, QStringList& Collect,
837 if(pn->
Name.isEmpty() == User) {
844 pn->
Name =
"net_net";
845 pn->
Name += QString::number(z++);
851 if(
isAnalog) createNodeSet(Collect, countInit, pn, pn);
854 propagateNode(Collect, countInit, pn);
860 void Schematic::collectDigitalSignals(
void)
865 DigMap::Iterator it = Signals.find(pn->
Name);
866 if(it == Signals.end()) {
868 }
else if (!pn->
DType.isEmpty()) {
869 it.data().Type = pn->
DType;
876 void Schematic::propagateNode(QStringList& Collect,
877 int& countInit,
Node *pn)
886 for(p2 = Cons.first(); p2 != 0; p2 = Cons.next())
890 if(p2 != pw->
Port1) {
894 Cons.append(pw->
Port1);
902 Cons.append(pw->
Port2);
908 if (
isAnalog) createNodeSet(Collect, countInit, pw, pn);
919 bool Schematic::throughAllComps(QTextStream *stream,
int& countInit,
920 QStringList& Collect, QTextEdit *ErrText,
int NumPorts)
926 QPtrListIterator<Component> it(
DocComps);
928 while((pc = it.current()) != 0) {
935 ErrText->insert(QObject::tr(
"ERROR: Component \"%1\" has no analog model.").
arg(pc->
Name));
940 ErrText->insert(QObject::tr(
"ERROR: Component \"%1\" has no digital model.").
arg(pc->
Name));
946 if(pc->
Model ==
"GND") {
947 pc->
Ports.getFirst()->Connection->Name =
"gnd";
952 if(pc->
Model ==
"Sub") {
955 SubMap::Iterator it =
FileList.find(f);
957 if (!it.data().PortTypes.isEmpty()) {
960 for(
Port *pp = pc->
Ports.first(); pp; pp = pc->
Ports.next(), i++) {
961 pp->
Type = it.data().PortTypes[
i];
962 pp->Connection->DType = pp->
Type;
971 s = pc->
Props.first()->Value;
975 ErrText->insert(QObject::tr(
"ERROR: Cannot load subcircuit \"%1\".").
arg(s));
986 for(
Port *pp = pc->
Ports.first(); pp; pp = pc->
Ports.next(), i++) {
987 pp->
Type = d->PortTypes[
i];
988 pp->Connection->DType = pp->
Type;
999 if(pc->
Model ==
"Lib") {
1002 QObject::tr(
"WARNING: Skipping library component \"%1\".").
1007 SubMap::Iterator it =
FileList.find(s);
1013 r = ((
LibComp*)pc)->createSubNetlist(stream, Collect, 1);
1016 r = ((
LibComp*)pc)->createSubNetlist(stream, Collect, 4);
1018 r = ((
LibComp*)pc)->createSubNetlist(stream, Collect, 2);
1022 QObject::tr(
"ERROR: Cannot load library component \"%1\".").
1030 if(pc->
Model ==
"SPICE") {
1031 s = pc->
Props.first()->Value;
1033 ErrText->insert(QObject::tr(
"ERROR: No file name in SPICE component \"%1\".").
1038 SubMap::Iterator it =
FileList.find(f);
1046 if(!r)
return false;
1051 if(pc->
Model ==
"VHDL" || pc->
Model ==
"Verilog") {
1056 s = pc->
Props.getFirst()->Value;
1058 ErrText->insert(QObject::tr(
"ERROR: No file name in %1 component \"%2\".").
1064 SubMap::Iterator it =
FileList.find(f);
1067 s = ((pc->
Model ==
"VHDL") ?
"VHD" :
"VER");
1070 if(pc->
Model ==
"VHDL") {
1074 if(!r)
return false;
1076 if(pc->
Model ==
"Verilog") {
1080 if(!r)
return false;
1092 bool Schematic::giveNodeNames(QTextStream *stream,
int& countInit,
1093 QStringList& Collect, QTextEdit *ErrText,
int NumPorts)
1109 if(pw->
Label != 0) {
1117 if(!throughAllComps(stream, countInit, Collect, ErrText, NumPorts))
1121 throughAllNodes(
true, Collect, countInit);
1124 throughAllNodes(
false, Collect, countInit);
1127 collectDigitalSignals();
1137 QStringList Collect;
1144 if(!giveNodeNames(stream, countInit, Collect, ErrText, NumPorts)) {
1159 (*stream) <<
"\n" << c <<
" TOP LEVEL MARK " << c <<
"\n";
1170 #define VHDL_SIGNAL_TYPE "std_logic"
1171 #define VHDL_LIBRARIES "\nlibrary ieee;\nuse ieee.std_logic_1164.all;\n"
1179 QStringList SubcircuitPortNames;
1180 QStringList SubcircuitPortTypes;
1181 QStringList InPorts;
1182 QStringList OutPorts;
1183 QStringList InOutPorts;
1184 QStringList::Iterator it_name;
1185 QStringList::Iterator it_type;
1189 QTextStream * tstream = stream;
1194 if(!ofile.open(IO_WriteOnly)) {
1195 ErrText->insert(tr(
"ERROR: Cannot create library file \"%s\".").
arg(f));
1198 tstream =
new QTextStream(&ofile);
1205 if(pc->
Model.at(0) ==
'.') {
1207 QObject::tr(
"WARNING: Ignore simulation component in subcircuit \"%1\".").
arg(
DocName)+
"\n");
1210 else if(pc->
Model ==
"Port") {
1211 i = pc->
Props.first()->Value.toInt();
1212 for(z=SubcircuitPortNames.size(); z<
i; z++) {
1213 SubcircuitPortNames.append(
" ");
1214 SubcircuitPortTypes.append(
" ");
1216 it_name = SubcircuitPortNames.at(i-1);
1217 it_type = SubcircuitPortTypes.at(i-1);
1218 (*it_name) = pc->
Ports.getFirst()->Connection->Name;
1219 DigMap::Iterator it = Signals.find(*it_name);
1220 (*it_type) = it.data().Type;
1222 pc->
Ports.getFirst()->Connection->DType = *it_type;
1226 Signals.erase(*it_name);
1227 switch(pc->
Props.at(1)->Value.at(0).latin1()) {
1229 InOutPorts.append(*it_name);
1232 OutPorts.append(*it_name);
1235 InPorts.append(*it_name);
1240 Signals.erase(*it_name);
1241 switch(pc->
Props.at(1)->Value.at(0).latin1()) {
1243 (*it_name) +=
" : inout";
1246 Signals.insert(*it_name,
DigSignal(*it_name, *it_type));
1247 (*it_name) =
"net_out" + (*it_name);
1250 (*it_name) +=
" : " + pc->
Props.at(1)->Value;
1252 (*it_name) +=
" " + ((*it_type).isEmpty() ?
1260 for(it_name = SubcircuitPortNames.begin(),
1261 it_type = SubcircuitPortTypes.begin();
1262 it_name != SubcircuitPortNames.end(); ) {
1263 if(*it_name ==
" ") {
1264 it_name = SubcircuitPortNames.remove(it_name);
1265 it_type = SubcircuitPortTypes.remove(it_type);
1267 PortTypes.append(*it_type);
1279 (*tstream) <<
"\n.Def:" << Type <<
" " << SubcircuitPortNames.join(
" ");
1281 if(pi->
Name ==
".ID ") {
1286 (*tstream) <<
" " << s.replace(
"=",
"=\"") <<
'"';
1296 (*tstream) <<
".Def:End\n";
1302 (*tstream) <<
"\nmodule Sub_" << Type <<
" ("
1303 << SubcircuitPortNames.join(
", ") <<
");\n";
1306 if(!InPorts.isEmpty())
1307 (*tstream) <<
" input " << InPorts.join(
", ") <<
";\n";
1308 if(!OutPorts.isEmpty())
1309 (*tstream) <<
" output " << OutPorts.join(
", ") <<
";\n";
1310 if(!InOutPorts.isEmpty())
1311 (*tstream) <<
" inout " << InOutPorts.join(
", ") <<
";\n";
1314 if(!Signals.isEmpty()) {
1315 QValueList<DigSignal> values = Signals.values();
1316 QValueList<DigSignal>::iterator it;
1317 for (it = values.begin(); it != values.end(); ++it) {
1318 (*tstream) <<
" wire " << (*it).Name <<
";\n";
1325 if(pi->
Name ==
".ID ") {
1329 for(pp = pid->
Parameter.first(); pp != 0;) {
1330 s = pp->
Name.section(
'=', 0,0);
1332 (*tstream) <<
" parameter " << s <<
" = " << v <<
";\n";
1342 if(pc->
Model ==
"Eqn") {
1347 if(Signals.find(
"gnd") != Signals.end())
1348 (*tstream) <<
" assign gnd = 0;\n";
1352 if(pc->
Model !=
"Eqn") {
1354 if(s.at(0) ==
'§') {
1355 ErrText->insert(s.mid(1));
1357 else (*tstream) <<
s;
1361 (*tstream) <<
"endmodule\n";
1365 (*tstream) <<
"entity Sub_" << Type <<
" is\n"
1367 << SubcircuitPortNames.join(
";\n ") <<
");\n";
1370 if(pi->
Name ==
".ID ") {
1374 (*tstream) <<
" generic (";
1375 for(pp = pid->
Parameter.first(); pp != 0;) {
1377 QString t = pp->
Type.isEmpty() ?
"real" : pp->
Type;
1378 (*tstream) << s.replace(
"=",
" : "+t+
" := ");
1380 if(pp) (*tstream) <<
";\n ";
1382 (*tstream) <<
");\n";
1387 (*tstream) <<
"end entity;\n"
1388 <<
"use work.all;\n"
1389 <<
"architecture Arch_Sub_" << Type <<
" of Sub_" << Type
1392 if(!Signals.isEmpty()) {
1393 QValueList<DigSignal> values = Signals.values();
1394 QValueList<DigSignal>::iterator it;
1395 for (it = values.begin(); it != values.end(); ++it) {
1396 (*tstream) <<
" signal " << (*it).Name <<
" : "
1397 << ((*it).Type.isEmpty() ?
1404 if(pc->
Model ==
"Eqn") {
1406 QObject::tr(
"WARNING: Equations in \"%1\" are 'time' typed.").
1412 (*tstream) <<
"begin\n";
1414 if(Signals.find(
"gnd") != Signals.end())
1415 (*tstream) <<
" gnd <= '0';\n";
1419 if(pc->
Model !=
"Eqn") {
1421 if(s.at(0) ==
'§') {
1422 ErrText->insert(s.mid(1));
1424 else (*tstream) <<
s;
1428 (*tstream) <<
"end architecture;\n";
1442 QStringList& Collect, QTextEdit *ErrText,
int NumPorts)
1447 if(!giveNodeNames(stream, countInit, Collect, ErrText, NumPorts))
1474 bool isTruthTable =
false;
1475 int allTypes = 0, NumPorts = 0;
1480 if(pc->
Model.at(0) ==
'.') {
1481 if(pc->
Model ==
".Digi") {
1484 QObject::tr(
"ERROR: Only one digital simulation allowed."));
1487 if(pc->
Props.getFirst()->Value !=
"TimeList")
1488 isTruthTable =
true;
1489 if(pc->
Props.getLast()->Value !=
"VHDL")
1498 QObject::tr(
"ERROR: Analog and digital simulations cannot be mixed."));
1502 else if(pc->
Model ==
"DigiSource") NumPorts++;
1515 if(NumPorts < 1 && isTruthTable) {
1517 QObject::tr(
"ERROR: Digital simulation needs at least one digital source."));
1520 if(!isTruthTable) NumPorts = 0;
1529 if(allTypes & isAnalogComponent)
1535 stream <<
" Qucs " << PACKAGE_VERSION <<
" " <<
DocName <<
"\n";
1539 stream <<
"\n`timescale 1ps/100fs\n";
1543 if(!giveNodeNames(&stream, countInit, Collect, ErrText, NumPorts))
1546 if(allTypes & isAnalogComponent)
1551 stream <<
"entity TestBench is\n"
1553 <<
"use work.all;\n";
1560 void Schematic::beginNetlistDigital(QTextStream& stream)
1563 stream <<
"module TestBench ();\n";
1564 QValueList<DigSignal> values = Signals.values();
1565 QValueList<DigSignal>::iterator it;
1566 for (it = values.begin(); it != values.end(); ++it) {
1567 stream <<
" wire " << (*it).Name <<
";\n";
1571 stream <<
"architecture Arch_TestBench of TestBench is\n";
1572 QValueList<DigSignal> values = Signals.values();
1573 QValueList<DigSignal>::iterator it;
1574 for (it = values.begin(); it != values.end(); ++it) {
1575 stream <<
" signal " << (*it).Name <<
" : "
1576 << ((*it).Type.isEmpty() ?
1579 stream <<
"begin\n";
1582 if(Signals.find(
"gnd") != Signals.end()) {
1584 stream <<
" assign gnd = 0;\n";
1586 stream <<
" gnd <= '0';\n";
1593 void Schematic::endNetlistDigital(QTextStream& stream)
1597 stream <<
"end architecture;\n";
1606 beginNetlistDigital(stream);
1621 Time = QString::number((1 << NumPorts));
1623 Time = QString::number((1 << NumPorts) - 1) +
" ns";
1625 Time = pc->
Props.at(1)->Value;
1638 if(s.at(0) ==
'§')
return s;
1644 endNetlistDigital(stream);