Skip to content

Commit

Permalink
New Feature: CDL netlist export
Browse files Browse the repository at this point in the history
Introduced very basic c++ coding style for the extsimkernels subsystem
based on https://google.github.io/styleguide/cppguide.html:
-Prefix class attributes with a_ (much more better readability!)
-Class member initialization via constructor member initialization list
-No public class attributes

Signed-off-by: ThomasZecha <[email protected]>
  • Loading branch information
ThomasZecha committed Nov 15, 2024
1 parent 6abdf70 commit 9d55075
Show file tree
Hide file tree
Showing 18 changed files with 883 additions and 853 deletions.
162 changes: 84 additions & 78 deletions qucs/extsimkernels/abstractspicekernel.cpp

Large diffs are not rendered by default.

33 changes: 19 additions & 14 deletions qucs/extsimkernels/abstractspicekernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class QPlainTextEdit;
class AbstractSpiceKernel : public QObject
{
Q_OBJECT

private:
enum outType {xyceSTD, spiceRaw, spiceRawSwp, xyceSTDswp, spicePrn, Unknown};

Expand All @@ -56,19 +57,23 @@ class AbstractSpiceKernel : public QObject
int NumVars, bool isComplex);

protected:
QString netlist,workdir, simulator_cmd,
simulator_parameters, output;
QProcess *SimProcess;
QString a_workdir;
QString a_simulator_cmd;
QString a_simulator_parameters;
QString a_output;
QProcess *a_simProcess;

QPlainTextEdit *console;
QStringList sims,vars,output_files;
QPlainTextEdit *a_console;
QStringList a_sims;
QStringList a_vars;
QStringList a_output_files;

bool DC_OP_only; // only calculate operating point to show DC bias
bool needsPrefix;
Schematic *Sch;
bool a_DC_OP_only; // only calculate operating point to show DC bias
bool a_needsPrefix;
Schematic *a_schematic;

bool parseFourTHD = false; // Fourier output is parsed twice, first freqencies, then THD
bool parsePZzeros = false; // PZ output is parsed twice, first poles, then zeros
bool a_parseFourTHD; // Fourier output is parsed twice, first freqencies, then THD
bool a_parsePZzeros; // PZ output is parsed twice, first poles, then zeros

bool prepareSpiceNetlist(QTextStream &stream, bool isSubckt = false);
virtual void startNetlist(QTextStream& stream, bool xyce = false);
Expand All @@ -82,7 +87,7 @@ class AbstractSpiceKernel : public QObject

public:

explicit AbstractSpiceKernel(Schematic *sch_, QObject *parent = 0);
explicit AbstractSpiceKernel(Schematic *schematic, QObject *parent = 0);
~AbstractSpiceKernel();

bool checkSchematic(QStringList &incompat);
Expand Down Expand Up @@ -124,8 +129,8 @@ class AbstractSpiceKernel : public QObject
void setWorkdir(QString path);
virtual void SaveNetlist(QString filename);
virtual bool waitEndOfSimulation();
void setConsole(QPlainTextEdit *console_) { console = console_; }
void setConsole(QPlainTextEdit *console) { a_console = console; }

signals:
void started();
void finished();
Expand All @@ -140,7 +145,7 @@ public slots:
virtual void slotSimulate();
void killThemAll();
void slotErrors(QProcess::ProcessError err);

};

#endif // ABSTRACTSPICEKERNEL_H
139 changes: 70 additions & 69 deletions qucs/extsimkernels/customsimdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,112 +29,113 @@
/*!
* \brief CustomSimDialog::CustomSimDialog class constructor
* \param pc[in] Component that need to be edit.
* \param sch[in] Schematic on which component presents.
* \param sch[in] Schematic on which a_component presents.
*/
CustomSimDialog::CustomSimDialog(SpiceCustomSim *pc, Schematic *sch) :
QDialog(sch)
QDialog(sch),
a_isXyceScr(false),
a_isChanged(false),
a_comp(pc),
a_schematic(sch),
a_edtCode(new QTextEdit(this)),
a_checkCode(new QCheckBox(tr("display in schematic"), this)),
a_btnOK(new QPushButton(tr("OK"))),
a_btnApply(new QPushButton(tr("Apply"))),
a_btnCancel(new QPushButton(tr("Cancel"))),
a_btnPlotAll(new QPushButton(tr("Find all variables"))),
a_btnFindOutputs(new QPushButton(tr("Find all outputs"))),
a_edtVars(new QLineEdit(a_comp->Props.at(1)->Value)),
a_edtOutputs(new QLineEdit(a_comp->Props.at(2)->Value))
{
comp = pc;
Sch = sch;

resize(640, 480);

setWindowTitle(tr("Edit SPICE code"));
QLabel* lblName = new QLabel(tr("Component: ")+comp->Description);
QLabel* lblName = new QLabel(tr("Component: ")+a_comp->Description);

edtCode = new QTextEdit(this);
edtCode->document()->setDefaultFont(QucsSettings.textFont);
edtCode->setWordWrapMode(QTextOption::NoWrap);
edtCode->insertPlainText(comp->Props.at(0)->Value);
connect(edtCode, SIGNAL(textChanged()), this, SLOT(slotChanged()));
a_edtCode->document()->setDefaultFont(QucsSettings.textFont);
a_edtCode->setWordWrapMode(QTextOption::NoWrap);
a_edtCode->insertPlainText(a_comp->Props.at(0)->Value);
connect(a_edtCode, SIGNAL(textChanged()), this, SLOT(slotChanged()));

checkCode = new QCheckBox(tr("display in schematic"), this);
checkCode->setChecked(comp->Props.at(0)->display);
connect(checkCode, SIGNAL(stateChanged(int)), this, SLOT(slotChanged()));
a_checkCode->setChecked(a_comp->Props.at(0)->display);
connect(a_checkCode, SIGNAL(stateChanged(int)), this, SLOT(slotChanged()));

QLabel* lblVars = new QLabel(tr("Variables to plot (semicolon separated)"));
edtVars = new QLineEdit(comp->Props.at(1)->Value);
connect(edtVars, SIGNAL(textChanged(const QString&)), this, SLOT(slotChanged()));
connect(a_edtVars, SIGNAL(textChanged(const QString&)), this, SLOT(slotChanged()));

QLabel* lblOut = new QLabel(tr("Extra outputs (semicolon separated; raw-SPICE or XYCE-STD or scalars print format)"));
edtOutputs = new QLineEdit(comp->Props.at(2)->Value);
connect(edtOutputs, SIGNAL(textChanged(const QString&)), this, SLOT(slotChanged()));

btnApply = new QPushButton(tr("Apply"));
connect(btnApply,SIGNAL(clicked()),this,SLOT(slotApply()));
btnCancel = new QPushButton(tr("Cancel"));
connect(btnCancel,SIGNAL(clicked()),this,SLOT(slotCancel()));
btnOK = new QPushButton(tr("OK"));
connect(btnOK,SIGNAL(clicked()),this,SLOT(slotOK()));
btnPlotAll = new QPushButton(tr("Find all variables"));
connect(btnPlotAll,SIGNAL(clicked()),this,SLOT(slotFindVars()));
btnFindOutputs = new QPushButton(tr("Find all outputs"));
connect(btnFindOutputs,SIGNAL(clicked()),this,SLOT(slotFindOutputs()));
connect(a_edtOutputs, SIGNAL(textChanged(const QString&)), this, SLOT(slotChanged()));

connect(a_btnApply,SIGNAL(clicked()),this,SLOT(slotApply()));
connect(a_btnCancel,SIGNAL(clicked()),this,SLOT(slotCancel()));
connect(a_btnOK,SIGNAL(clicked()),this,SLOT(slotOK()));
connect(a_btnPlotAll,SIGNAL(clicked()),this,SLOT(slotFindVars()));
connect(a_btnFindOutputs,SIGNAL(clicked()),this,SLOT(slotFindOutputs()));

QVBoxLayout *vl1 = new QVBoxLayout;
QVBoxLayout *vl2 = new QVBoxLayout;
QHBoxLayout *hl1 = new QHBoxLayout;

vl1->addWidget(lblName);
QGroupBox *gpb1 = new QGroupBox(tr("SPICE code editor"));
vl2->addWidget(edtCode);
vl2->addWidget(checkCode);
vl2->addWidget(a_edtCode);
vl2->addWidget(a_checkCode);
gpb1->setLayout(vl2);
vl1->addWidget(gpb1);
vl1->addWidget(lblVars);
vl1->addWidget(edtVars);
vl1->addWidget(btnPlotAll);
vl1->addWidget(a_edtVars);
vl1->addWidget(a_btnPlotAll);
vl1->addWidget(lblOut);
vl1->addWidget(edtOutputs);
vl1->addWidget(btnFindOutputs);
vl1->addWidget(a_edtOutputs);
vl1->addWidget(a_btnFindOutputs);

hl1->addWidget(btnOK);
hl1->addWidget(btnApply);
hl1->addWidget(btnCancel);
hl1->addWidget(a_btnOK);
hl1->addWidget(a_btnApply);
hl1->addWidget(a_btnCancel);
vl1->addLayout(hl1);

this->setLayout(vl1);
this->setWindowTitle(tr("Edit SPICE code"));

if (comp->Model == ".XYCESCR") {
if (a_comp->Model == ".XYCESCR") {
lblVars->setEnabled(false);
edtVars->setEnabled(false);
btnPlotAll->setEnabled(false);
isXyceScr = true;
} else if (comp->Model == "INCLSCR") {
a_edtVars->setEnabled(false);
a_btnPlotAll->setEnabled(false);
a_isXyceScr = true;
} else if (a_comp->Model == "INCLSCR") {
lblVars->setEnabled(false);
edtVars->setEnabled(false);
btnPlotAll->setEnabled(false);
btnFindOutputs->setEnabled(false);
a_edtVars->setEnabled(false);
a_btnPlotAll->setEnabled(false);
a_btnFindOutputs->setEnabled(false);
lblOut->setEnabled(false);
} else isXyceScr = false;
} else a_isXyceScr = false;
}

/*!
* \brief CustomSimDialog::slotChanged Set isChanged state.
* \brief CustomSimDialog::slotChanged Set a_isChanged state.
*/
void CustomSimDialog::slotChanged()
{
isChanged = true;
a_isChanged = true;
}
/*!
* \brief CustomSimDialog::slotApply Apply changes of component properties.
* \brief CustomSimDialog::slotApply Apply changes of a_component properties.
*/
void CustomSimDialog::slotApply()
{
if ( isChanged ) {
edtVars->setText(edtVars->text().remove(' '));
edtOutputs->setText(edtOutputs->text().remove(' '));
if ( a_isChanged ) {
a_edtVars->setText(a_edtVars->text().remove(' '));
a_edtOutputs->setText(a_edtOutputs->text().remove(' '));

comp->Props.at(0)->Value = edtCode->document()->toPlainText();
comp->Props.at(0)->display = checkCode->isChecked();
comp->Props.at(1)->Value = edtVars->text();
comp->Props.at(2)->Value = edtOutputs->text();
a_comp->Props.at(0)->Value = a_edtCode->document()->toPlainText();
a_comp->Props.at(0)->display = a_checkCode->isChecked();
a_comp->Props.at(1)->Value = a_edtVars->text();
a_comp->Props.at(2)->Value = a_edtOutputs->text();

Sch->recreateComponent(comp);
Sch->viewport()->repaint();
a_schematic->recreateComponent(a_comp);
a_schematic->viewport()->repaint();

isChanged = false;
a_isChanged = false;
}
}

Expand All @@ -157,27 +158,27 @@ void CustomSimDialog::slotCancel()

/*!
* \brief CustomSimDialog::slotFindVars Auto-find used variables and nodes
* in simulation script and place them into edtVars line edit.
* in simulation script and place them into a_edtVars line edit.
*/
void CustomSimDialog::slotFindVars()
{
QStringList vars;
for(Node *pn = Sch->DocNodes.first(); pn != 0; pn = Sch->DocNodes.next()) {
for(Node *pn = a_schematic->DocNodes.first(); pn != 0; pn = a_schematic->DocNodes.next()) {
if(pn->Label != 0) {
if (!vars.contains(pn->Label->Name)) {
vars.append(pn->Label->Name);
}
}
}
for(Wire *pw = Sch->DocWires.first(); pw != 0; pw = Sch->DocWires.next()) {
for(Wire *pw = a_schematic->DocWires.first(); pw != 0; pw = a_schematic->DocWires.next()) {
if(pw->Label != 0) {
if (!vars.contains(pw->Label->Name)) {
vars.append(pw->Label->Name);
}
}
}

for(Component *pc=Sch->DocComps.first();pc!=0;pc=Sch->DocComps.next()) {
for(Component *pc=a_schematic->DocComps.first();pc!=0;pc=a_schematic->DocComps.next()) {
if(pc->isProbe) {
if (!vars.contains(pc->getProbeVariable())) {
vars.append(pc->getProbeVariable());
Expand All @@ -191,7 +192,7 @@ void CustomSimDialog::slotFindVars()



QStringList strings = edtCode->toPlainText().split('\n');
QStringList strings = a_edtCode->toPlainText().split('\n');
QRegularExpression let_pattern("^\\s*let\\s+[A-Za-z].*=.+");

for (const QString& line : strings) {
Expand All @@ -203,15 +204,15 @@ void CustomSimDialog::slotFindVars()
}
}

edtVars->setText(vars.join(";"));
a_edtVars->setText(vars.join(";"));
}

void CustomSimDialog::slotFindOutputs()
{
QStringList outps;
QString outp;
QStringList strings = edtCode->toPlainText().split('\n');
if (isXyceScr) {
QStringList strings = a_edtCode->toPlainText().split('\n');
if (a_isXyceScr) {
QRegularExpression print_ex("^\\s*\\.print\\s.*", QRegularExpression::CaseInsensitiveOption);
QRegularExpression file_ex("\\s*file\\s*=\\s*", QRegularExpression::CaseInsensitiveOption);
for (const QString& line : strings) {
Expand Down Expand Up @@ -242,5 +243,5 @@ void CustomSimDialog::slotFindOutputs()
}
}

edtOutputs->setText(outps.join(";"));
a_edtOutputs->setText(outps.join(";"));
}
32 changes: 16 additions & 16 deletions qucs/extsimkernels/customsimdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,26 @@ class CustomSimDialog : public QDialog

private:

bool isXyceScr;
bool isChanged = false;
bool a_isXyceScr;
bool a_isChanged = false;

SpiceCustomSim* comp;
Schematic *Sch;
SpiceCustomSim* a_comp;
Schematic *a_schematic;

QTextEdit* edtCode;
QCheckBox *checkCode;
QPushButton *btnOK;
QPushButton *btnApply;
QPushButton *btnCancel;
QPushButton *btnPlotAll;
QPushButton *btnFindOutputs;
QTextEdit* a_edtCode;
QCheckBox *a_checkCode;
QPushButton *a_btnOK;
QPushButton *a_btnApply;
QPushButton *a_btnCancel;
QPushButton *a_btnPlotAll;
QPushButton *a_btnFindOutputs;

QLineEdit *edtVars;
QLineEdit *edtOutputs;
QLineEdit *a_edtVars;
QLineEdit *a_edtOutputs;

public:
explicit CustomSimDialog(SpiceCustomSim *pc, Schematic *sch);

signals:

private slots:
Expand All @@ -71,9 +71,9 @@ private slots:
void slotFindVars();
void slotFindOutputs();
void slotChanged();

public slots:

};

#endif // CUSTOMSIMDIALOG_H
Loading

0 comments on commit 9d55075

Please sign in to comment.