Skip to content

Commit

Permalink
Introduce optional netlisting to console
Browse files Browse the repository at this point in the history
-Introduced cli parameter --cdl for netlisting CDL
-Implemented netlisting to console for ngspice and xyce
-Increased readability and introduced smart-pointer semantics for some
 qucs-s main.cpp functions
-Increased readability and introduced c++ cast's for casting to
 Schematic* for affected QucsApp::slotSimulateWithSpice and QucsApp::slotSaveNetlist

Signed-off-by: ThomasZecha <[email protected]>
  • Loading branch information
ThomasZecha committed Jan 16, 2025
1 parent b4034d1 commit e706187
Show file tree
Hide file tree
Showing 9 changed files with 456 additions and 226 deletions.
44 changes: 29 additions & 15 deletions qucs/extsimkernels/externsimdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include "main.h"
#include "qucs.h"

ExternSimDialog::ExternSimDialog(Schematic *sch, bool netlist_mode) :
ExternSimDialog::ExternSimDialog(Schematic* sch, bool netlist2Console, bool netlist_mode) :
QDialog(sch),
a_schematic(sch),
a_buttonStopSim(new QPushButton(tr("Stop"),this)),
Expand All @@ -37,7 +37,8 @@ ExternSimDialog::ExternSimDialog(Schematic *sch, bool netlist_mode) :
a_ngspice(new Ngspice(sch,this)),
a_xyce(new Xyce(sch,this)),
a_wasSimulated(true),
a_hasError(false)
a_hasError(false),
a_netlist2Console(netlist2Console)
{
const QString workdir(QucsSettings.S4Qworkdir);

Expand Down Expand Up @@ -296,27 +297,40 @@ void ExternSimDialog::slotStop()
void ExternSimDialog::slotSaveNetlist()
{
QFileInfo inf(a_schematic->getDocName());
QString filename = QFileDialog::getSaveFileName(this,tr("Save netlist"),inf.path()+QDir::separator()+"netlist.cir",
"All files (*)");
if (filename.isEmpty()) return;
QString filename;

if (!a_netlist2Console)
{
filename = QFileDialog::getSaveFileName(
this,
tr("Save netlist"),
inf.path() + QDir::separator() + "netlist.cir",
"All files (*)");
if (filename.isEmpty())
{
return;
}
}

switch (QucsSettings.DefaultSimulator) {
switch (QucsSettings.DefaultSimulator)
{
case spicecompat::simNgspice:
case spicecompat::simSpiceOpus: {
a_ngspice->SaveNetlist(filename);
}
case spicecompat::simSpiceOpus:
a_ngspice->SaveNetlist(filename, a_netlist2Console);
break;
case spicecompat::simXyce: {
a_xyce->SaveNetlist(filename);
}
case spicecompat::simXyce:
a_xyce->SaveNetlist(filename, a_netlist2Console);
break;
default:
break;
}

if (!QFile::exists(filename)) {
QMessageBox::critical(0, QObject::tr("Save netlist"),
QObject::tr("Disk write error!"), QMessageBox::Ok);
if (!a_netlist2Console && !QFile::exists(filename))
{
QMessageBox::critical(
nullptr,
QObject::tr("Save netlist"),
QObject::tr("Disk write error!"), QMessageBox::Ok);
}
}

Expand Down
9 changes: 6 additions & 3 deletions qucs/extsimkernels/externsimdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ExternSimDialog : public QDialog
Q_OBJECT

private:
Schematic *a_schematic;
Schematic* a_schematic;

QPushButton *a_buttonStopSim;
QPushButton *a_buttonSaveNetlist;
Expand All @@ -46,10 +46,13 @@ class ExternSimDialog : public QDialog

bool a_wasSimulated;
bool a_hasError;
bool a_netlist2Console;

public:
explicit ExternSimDialog(Schematic *sch,
bool netlist_mode = false);
explicit ExternSimDialog(
Schematic* sch,
bool netlist2Console,
bool netlist_mode = false);
~ExternSimDialog();

bool wasSimulated() const { return a_wasSimulated; }
Expand Down
54 changes: 40 additions & 14 deletions qucs/extsimkernels/ngspice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
#include "config.h"
#endif

#include <QScopedPointer>

#include <iostream>

/*!
\file ngspice.cpp
\brief Implementation of the Ngspice class
Expand All @@ -43,7 +47,7 @@
* \param schematic Schematic that need to be simulated with Ngspice.
* \param parent Parent object
*/
Ngspice::Ngspice(Schematic *schematic, QObject *parent) :
Ngspice::Ngspice(Schematic* schematic, QObject *parent) :
AbstractSpiceKernel(schematic, parent),
a_spinit_name()
{
Expand All @@ -67,8 +71,11 @@ Ngspice::Ngspice(Schematic *schematic, QObject *parent) :
* \param[out] vars The list of output variables and node names.
* \param[out] outputs The list of spice output raw text files.
*/
void Ngspice::createNetlist(QTextStream &stream, int ,
QStringList &simulations, QStringList &vars, QStringList &outputs)
void Ngspice::createNetlist(
QTextStream& stream,
QStringList& simulations,
QStringList& vars,
QStringList& outputs)
{
Q_UNUSED(simulations);

Expand Down Expand Up @@ -464,7 +471,7 @@ void Ngspice::slotSimulate()

QString netfile = "spice4qucs.cir";
QString tmp_path = QDir::toNativeSeparators(a_workdir+QDir::separator()+netfile);
SaveNetlist(tmp_path);
SaveNetlist(tmp_path, false);

removeAllSimulatorOutputs();

Expand Down Expand Up @@ -583,24 +590,43 @@ void Ngspice::slotProcessOutput()
* \brief Ngspice::SaveNetlist Create netlist and save it to file without execution
* of simulator.
* \param[in] filename Absolute path to netlist
* \param[in] netlist2Console Whether netlist to console instead to file
*/
void Ngspice::SaveNetlist(QString filename)
void Ngspice::SaveNetlist(QString filename, bool netlist2Console)
{
int num=0;
a_sims.clear();
a_vars.clear();

QFile spice_file(filename);
if (spice_file.open(QFile::WriteOnly)) {
QTextStream stream(&spice_file);
createNetlist(stream,num,a_sims,a_vars,a_output_files);
spice_file.close();
QScopedPointer<QString> netlistString;
QScopedPointer<QTextStream> netlistStream;
QScopedPointer<QFile> netlistFile;

if (netlist2Console)
{
netlistString.reset(new QString);
netlistStream.reset(new QTextStream(netlistString.get()));
}
else
{
QString msg=QStringLiteral("Tried to save netlist \nin %1\n(could not open for writing!)").arg(filename);
QString final_msg=QStringLiteral("%1\n This could be an error in the QSettings settings file\n(usually in ~/.config/qucs/qucs_s.conf)\nThe value for S4Q_workdir (default:/spice4qucs) needs to be writeable!\nFor a Simulation Simulation will raise error! (most likely S4Q_workdir does not exists)").arg(msg);
QMessageBox::critical(nullptr,tr("Problem with SaveNetlist"),final_msg,QMessageBox::Ok);
netlistFile.reset(new QFile(filename));
if (netlistFile->open(QFile::WriteOnly))
{
netlistStream.reset(new QTextStream(netlistFile.get()));
}
else
{
QString msg = QStringLiteral("Tried to save netlist \nin %1\n(could not open for writing!)").arg(filename);
QString final_msg = QStringLiteral("%1\n This could be an error in the QSettings settings file\n(usually in ~/.config/qucs/qucs_s.conf)\nThe value for S4Q_workdir (default:/spice4qucs) needs to be writeable!\nFor a Simulation Simulation will raise error! (most likely S4Q_workdir does not exists)").arg(msg);
QMessageBox::critical(nullptr,tr("Problem with SaveNetlist"), final_msg, QMessageBox::Ok);
return;
}
}

createNetlist(*netlistStream, a_sims, a_vars, a_output_files);

if (netlist2Console)
{
std::cout << netlistString->toUtf8().constData() << std::endl;
}
}

Expand Down
13 changes: 8 additions & 5 deletions qucs/extsimkernels/ngspice.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,25 @@ class Ngspice : public AbstractSpiceKernel
QString a_spinit_name;

bool checkNodeNames(QStringList &incompat);
static QString collectSpiceinit(Schematic *sch);
static QString collectSpiceinit(Schematic* sch);
bool findMathFuncInc(QString &mathf_inc);
QString getParentSWPscript(Component *pc_swp, QString sim, bool before, bool &hasDblSWP);
QString getParentSWPCntVar(Component *pc_swp, QString sim);
void cleanSpiceinit();
void createSpiceinit(const QString &initial_spiceinit);

public:
explicit Ngspice(Schematic *schematic, QObject *parent = 0);
void SaveNetlist(QString filename);
explicit Ngspice(Schematic* schematic, QObject *parent = 0);
void SaveNetlist(QString filename, bool netlist2Console);
void setSimulatorCmd(QString cmd);
void setSimulatorParameters(QString parameters);

protected:
void createNetlist(QTextStream &stream, int NumPorts, QStringList &simulations,
QStringList &vars, QStringList &outputs);
void createNetlist(
QTextStream& stream,
QStringList& simulations,
QStringList& vars,
QStringList& outputs);

public slots:
void slotSimulate();
Expand Down
50 changes: 38 additions & 12 deletions qucs/extsimkernels/xyce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
#include "config.h"
#endif

#include <QScopedPointer>

#include <iostream>

/*!
\file xyce.cpp
\brief Implementation of the Xyce class
Expand All @@ -35,7 +39,7 @@
* \param schematic Schematic that need to be simulated with Ngspice.
* \param parent Parent object
*/
Xyce::Xyce(Schematic *schematic, QObject *parent) :
Xyce::Xyce(Schematic* schematic, QObject *parent) :
AbstractSpiceKernel(schematic, parent),
a_Noisesim(false),
a_simulationsQueue(),
Expand Down Expand Up @@ -79,8 +83,11 @@ void Xyce::determineUsedSimulations(QStringList *sim_lst)
* \param[out] vars The list of output variables and node names.
* \param[out] outputs The list of spice output raw text files.
*/
void Xyce::createNetlist(QTextStream &stream, int , QStringList &simulations,
QStringList &vars, QStringList &outputs)
void Xyce::createNetlist(
QTextStream& stream,
QStringList& simulations,
QStringList& vars,
QStringList& outputs)
{
QString s;
bool hasParSweep = false;
Expand Down Expand Up @@ -312,7 +319,6 @@ void Xyce::slotSimulate()
return;
}

int num=0;
a_netlistQueue.clear();
a_output_files.clear();

Expand All @@ -332,7 +338,7 @@ void Xyce::slotSimulate()
QFile spice_file(tmp_path);
if (spice_file.open(QFile::WriteOnly)) {
QTextStream stream(&spice_file);
createNetlist(stream,num,sim_lst,a_vars,a_output_files);
createNetlist(stream,sim_lst,a_vars,a_output_files);
spice_file.close();
}
}
Expand All @@ -347,16 +353,36 @@ void Xyce::slotSimulate()
* \brief Xyce::SaveNetlist Save netlist into specified file without
* execution of simulator.
* \param[in] filename The name of file in which netlist is saved
* \param[in] netlist2Console Whether netlist to console instead to file
*/
void Xyce::SaveNetlist(QString filename)
void Xyce::SaveNetlist(QString filename, bool netlist2Console)
{
determineUsedSimulations();
int num = 0;
QFile spice_file(filename);
if (spice_file.open(QFile::WriteOnly)) {
QTextStream stream(&spice_file);
createNetlist(stream,num,a_simulationsQueue,a_vars,a_output_files);
spice_file.close();

QScopedPointer<QString> netlistString;
QScopedPointer<QTextStream> netlistStream;
QScopedPointer<QFile> netlistFile;

if (netlist2Console)
{
netlistString.reset(new QString);
netlistStream.reset(new QTextStream(netlistString.get()));
}
else
{
netlistFile.reset(new QFile(filename));

if (netlistFile->open(QFile::WriteOnly))
{
netlistStream.reset(new QTextStream(netlistFile.get()));
}
}

createNetlist(*netlistStream, a_simulationsQueue, a_vars, a_output_files);

if (netlist2Console)
{
std::cout << netlistString->toUtf8().constData() << std::endl;
}
}

Expand Down
12 changes: 8 additions & 4 deletions qucs/extsimkernels/xyce.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,19 @@ class Xyce : public AbstractSpiceKernel

public:
void determineUsedSimulations(QStringList *sim_lst = NULL);
explicit Xyce(Schematic *schematic, QObject *parent = 0);
explicit Xyce(Schematic* schematic, QObject *parent = 0);

void SaveNetlist(QString filename);
void SaveNetlist(QString filename, bool netlist2Console);
void setParallel(bool par);
bool waitEndOfSimulation();

protected:
void createNetlist(QTextStream &stream, int NumPorts, QStringList &simulations,
QStringList &vars, QStringList &outputs);
void createNetlist(
QTextStream& stream,
QStringList& simulations,
QStringList& vars,
QStringList& outputs);

protected slots:
void slotFinished();
void slotProcessOutput();
Expand Down
Loading

0 comments on commit e706187

Please sign in to comment.