Skip to content

Commit

Permalink
Merge pull request #431 from Radvall/modify_spice_devices
Browse files Browse the repository at this point in the history
Modify SPICE RCD devices; fixes #349
  • Loading branch information
ra3xdh authored Jan 5, 2024
2 parents c36b849 + 0dac9b3 commit f40c93a
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 49 deletions.
20 changes: 15 additions & 5 deletions qucs/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ void Module::intoCategory (Module * m) {

#define REGISTER_COMP_1(cat,val) \
registerComponent (cat, &val::info)
#define REGISTER_SPECIFIC_COMP_1(cat,val,inf1) \
registerComponent (cat, &val::inf1)
#define REGISTER_COMP_2(cat,val,inf1,inf2) \
registerComponent (cat, &val::inf1); \
registerComponent (cat, &val::inf2)
Expand All @@ -204,6 +206,10 @@ void Module::intoCategory (Module * m) {
REGISTER_COMP_2 (QObject::tr("nonlinear components"),val,inf1,inf2)
#define REGISTER_NONLINEAR_3(val,inf1,inf2,inf3) \
REGISTER_COMP_3 (QObject::tr("nonlinear components"),val,inf1,inf2,inf3)
#define REGISTER_PDK_1(val,inf1) \
REGISTER_SPECIFIC_COMP_1 (QObject::tr("PDK devices"),val,inf1)
#define REGISTER_PDK_2(val,inf1,inf2) \
REGISTER_COMP_2 (QObject::tr("PDK devices"),val,inf1,inf2)
#define REGISTER_VERILOGA_1(val) \
REGISTER_COMP_1 (QObject::tr("verilog-a devices"),val)
#define REGISTER_VERILOGA_2(val,inf1,inf2) \
Expand Down Expand Up @@ -405,15 +411,10 @@ void Module::registerModules (void) {
REGISTER_NONLINEAR_1 (DIODE_SPICE);
REGISTER_NONLINEAR_1 (NPN_SPICE);
REGISTER_NONLINEAR_1 (PNP_SPICE);
REGISTER_NONLINEAR_2 (BJT_SPICE,infoNPN4,infoPNP4);
REGISTER_NONLINEAR_2 (BJT_SPICE,infoNPN5,infoPNP5);
REGISTER_NONLINEAR_1 (NJF_SPICE);
REGISTER_NONLINEAR_1 (PJF_SPICE);
REGISTER_NONLINEAR_1 (NMOS_SPICE);
REGISTER_NONLINEAR_1 (PMOS_SPICE);
REGISTER_NONLINEAR_2 (MOS_SPICE,info_NM3pin,info_PM3pin);
REGISTER_NONLINEAR_2 (MOS_SPICE,info_NX3pin,info_PX3pin);
REGISTER_NONLINEAR_2 (MOS_SPICE,info_NX4pin,info_PX4pin);
REGISTER_NONLINEAR_1 (MESFET_SPICE);
REGISTER_NONLINEAR_1 (PMF_MESFET_SPICE);
REGISTER_NONLINEAR_1 (S4Q_Ieqndef);
Expand All @@ -430,6 +431,15 @@ void Module::registerModules (void) {
REGISTER_NONLINEAR_1 (TunnelDiode);
//}

// PDK devices
REGISTER_PDK_1 (R_SPICE, info_R3);
REGISTER_PDK_1 (C_SPICE, info_C3);
REGISTER_PDK_1 (DIODE_SPICE, info_DIODE3);
REGISTER_PDK_2 (MOS_SPICE,info_NM3pin,info_PM3pin);
REGISTER_PDK_2 (MOS_SPICE,info_NX3pin,info_PX3pin);
REGISTER_PDK_2 (MOS_SPICE,info_NX4pin,info_PX4pin);
REGISTER_PDK_2 (BJT_SPICE,infoNPN4,infoPNP4);
REGISTER_PDK_2 (BJT_SPICE,infoNPN5,infoPNP5);

//if (QucsSettings.DefaultSimulator == spicecompat::simQucsator) {
// verilog-a devices
Expand Down
52 changes: 41 additions & 11 deletions qucs/spicecomponents/C_SPICE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,6 @@ C_SPICE::C_SPICE()
Description = QObject::tr("SPICE C:\nMultiple line ngspice or Xyce C specifications allowed using \"+\" continuation lines.\nLeave continuation lines blank when NOT in use.");
Simulator = spicecompat::simSpice;

Lines.append(new qucs::Line( -4,-11, -4, 11,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( 4,-11, 4, 11, QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line(-30, 0, -4, 0, QPen(Qt::darkBlue,2)));
Lines.append(new qucs::Line( 4, 0, 30, 0, QPen(Qt::darkBlue,2)));


Ports.append(new Port( 30, 0));
Ports.append(new Port(-30, 0));

x1 = -30; y1 = -13;
x2 = 30; y2 = 13;

Expand All @@ -52,10 +43,34 @@ C_SPICE::C_SPICE()
Props.append(new Property("C_Line 3", "", false,"+ continuation line 2"));
Props.append(new Property("C_Line 4", "", false,"+ continuation line 3"));
Props.append(new Property("C_Line 5", "", false,"+ continuation line 4"));
Props.append(new Property("Pins", "2", true,"[2,3] Pins count"));
Props.append(new Property("Letter", "C", true,"[C,X,N] SPICE letter"));

createSymbol();

// rotate(); // fix historical flaw
}

void C_SPICE::createSymbol()
{
int Npins = getProperty("Pins")->Value.toInt();
Lines.append(new qucs::Line( -4,-11, -4, 11,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( 4,-11, 4, 11, QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line(-30, 0, -4, 0, QPen(Qt::darkBlue,2)));
Lines.append(new qucs::Line( 4, 0, 30, 0, QPen(Qt::darkBlue,2)));

if (Npins >= 3) {
Lines.append(new qucs::Line( 0, -15, 0, -30,QPen(Qt::darkRed,2)));
}

Ports.append(new Port( 30, 0));
Ports.append(new Port(-30, 0));

if (Npins >= 3) Ports.append(new Port( 0, -30));

rotate(); // fix historical flaw
}


C_SPICE::~C_SPICE()
{
}
Expand All @@ -74,14 +89,29 @@ Element* C_SPICE::info(QString& Name, char* &BitmapFile, bool getNewOne)
return 0;
}

Element* C_SPICE::info_C3(QString& Name, char* &BitmapFile, bool getNewOne)
{
Name = QObject::tr("C Capacitor 3 pin");
BitmapFile = (char *) "C_SPICE";

if(getNewOne) {
auto p = new C_SPICE();
p->Props.at(5)->Value = "3";
p->recreate(0);
return p;
}
return 0;
}

QString C_SPICE::netlist()
{
return QString("");
}

QString C_SPICE::spice_netlist(bool)
{
QString s = spicecompat::check_refdes(Name,SpiceModel);
QString ltr = getProperty("Letter")->Value;
QString s = spicecompat::check_refdes(Name,ltr);
for (Port *p1 : Ports) {
QString nam = p1->Connection->Name;
if (nam=="gnd") nam = "0";
Expand Down
4 changes: 3 additions & 1 deletion qucs/spicecomponents/C_SPICE.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@

#include "components/component.h"

class C_SPICE: public Component {
class C_SPICE: public MultiViewComponent {
public:
C_SPICE();
~C_SPICE();
Component* newOne();
static Element* info(QString&, char* &, bool getNewOne=false);
static Element* info_C3(QString&, char* &, bool getNewOne=false);
protected:
void createSymbol();
QString netlist();
QString spice_netlist(bool isXyce = false);
};
Expand Down
59 changes: 44 additions & 15 deletions qucs/spicecomponents/DIODE_SPICE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,6 @@ DIODE_SPICE::DIODE_SPICE()
Description = QObject::tr("SPICE D:\nMultiple line ngspice or Xyce D model specifications allowed using \"+\" continuation lines.\nLeave continuation lines blank when NOT in use.");
Simulator = spicecompat::simSpice;

Lines.append(new qucs::Line(-30, 0, -20, 0,QPen(Qt::darkBlue,3)));
Lines.append(new qucs::Line( -20, 0, -6, 0,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( 6, 0, 20, 0,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( 20, 0, 30, 0,QPen(Qt::darkBlue,3)));


Lines.append(new qucs::Line( -6, -9, -6, 9,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( 6, -9, 6, 9,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( -6, -9, 6, 0,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( -6, 9, 6, 0,QPen(Qt::darkRed,3)));

Ports.append(new Port(-30, 0));
Ports.append(new Port( 30, 0));

x1 = -30; y1 = -11;
x2 = 30; y2 = 11;

Expand All @@ -58,6 +44,34 @@ DIODE_SPICE::DIODE_SPICE()
Props.append(new Property("D_Line 3", "", false,"+ continuation line 2"));
Props.append(new Property("D_Line 4", "", false,"+ continuation line 3"));
Props.append(new Property("D_Line 5", "", false,"+ continuation line 4"));
Props.append(new Property("Pins", "2", true,"[2,3] Pins count"));
Props.append(new Property("Letter", "D", true,"[D,X,N] SPICE letter"));

createSymbol();
}

void DIODE_SPICE::createSymbol()
{
int Npins = getProperty("Pins")->Value.toInt();
Lines.append(new qucs::Line(-30, 0, -20, 0,QPen(Qt::darkBlue,3)));
Lines.append(new qucs::Line( -20, 0, -6, 0,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( 6, 0, 20, 0,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( 20, 0, 30, 0,QPen(Qt::darkBlue,3)));


Lines.append(new qucs::Line( -6, -9, -6, 9,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( 6, -9, 6, 9,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( -6, -9, 6, 0,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( -6, 9, 6, 0,QPen(Qt::darkRed,3)));

if (Npins >= 3) {
Lines.append(new qucs::Line( 0, -5, 0, -30,QPen(Qt::darkRed,2)));
}

Ports.append(new Port(-30, 0));
Ports.append(new Port( 30, 0));

if (Npins >= 3) Ports.append(new Port( 0, -30));

}

Expand All @@ -79,14 +93,29 @@ Element* DIODE_SPICE::info(QString& Name, char* &BitmapFile, bool getNewOne)
return 0;
}

Element* DIODE_SPICE::info_DIODE3(QString& Name, char* &BitmapFile, bool getNewOne)
{
Name = QObject::tr("D Diode 3 pin");
BitmapFile = (char *) "DIODE_SPICE";

if(getNewOne) {
auto p = new DIODE_SPICE();
p->Props.at(5)->Value = "3";
p->recreate(0);
return p;
}
return 0;
}

QString DIODE_SPICE::netlist()
{
return QString("");
}

QString DIODE_SPICE::spice_netlist(bool)
{
QString s = spicecompat::check_refdes(Name,SpiceModel);
QString ltr = getProperty("Letter")->Value;
QString s = spicecompat::check_refdes(Name,ltr);
for (Port *p1 : Ports) {
QString nam = p1->Connection->Name;
if (nam=="gnd") nam = "0";
Expand Down
4 changes: 3 additions & 1 deletion qucs/spicecomponents/DIODE_SPICE.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@

#include "components/component.h"

class DIODE_SPICE : public Component {
class DIODE_SPICE : public MultiViewComponent {
public:
DIODE_SPICE();
~DIODE_SPICE();
Component* newOne();
static Element* info(QString&, char* &, bool getNewOne=false);
static Element* info_DIODE3(QString&, char* &, bool getNewOne=false);
protected:
void createSymbol();
QString netlist();
QString spice_netlist(bool isXyce = false);
};
Expand Down
58 changes: 43 additions & 15 deletions qucs/spicecomponents/R_SPICE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,11 @@
#include "misc.h"
#include "extsimkernels/spicecompat.h"


R_SPICE::R_SPICE()
{
Description = QObject::tr("SPICE R:\nMultiple line ngspice or Xyce R specifications allowed using \"+\" continuation lines.\nLeave continuation lines blank when NOT in use. ");
Simulator = spicecompat::simSpice;

Lines.append(new qucs::Line(-18, -9, 18, -9,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( 18, -9, 18, 9,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( 18, 9,-18, 9,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line(-18, 9,-18, -9,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line(-30, 0,-18, 0,QPen(Qt::darkBlue,2)));
Lines.append(new qucs::Line( 18, 0, 30, 0,QPen(Qt::darkBlue,2)));

Ports.append(new Port(-30, 0));
Ports.append(new Port( 30, 0));

x1 = -30; y1 = -11;
x2 = 30; y2 = 11;

Expand All @@ -54,10 +43,34 @@ R_SPICE::R_SPICE()
Props.append(new Property("R_Line 3", "", false,"+ continuation line 2"));
Props.append(new Property("R_Line 4", "", false,"+ continuation line 3"));
Props.append(new Property("R_Line 5", "", false,"+ continuation line 4"));
Props.append(new Property("Pins", "2", true,"[2,3] Pins count"));
Props.append(new Property("Letter", "R", true,"[R,X,N] SPICE letter"));

createSymbol();

// rotate(); // fix historical flaw

}

void R_SPICE::createSymbol()
{
int Npins = getProperty("Pins")->Value.toInt();
Lines.append(new qucs::Line(-18, -9, 18, -9,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( 18, -9, 18, 9,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line( 18, 9,-18, 9,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line(-18, 9,-18, -9,QPen(Qt::darkRed,3)));
Lines.append(new qucs::Line(-30, 0,-18, 0,QPen(Qt::darkBlue,2)));
Lines.append(new qucs::Line( 18, 0, 30, 0,QPen(Qt::darkBlue,2)));

if (Npins >= 3) {
Lines.append(new qucs::Line( 0, -10, 0, -30,QPen(Qt::darkRed,2)));
}

Ports.append(new Port(-30, 0));
Ports.append(new Port( 30, 0));

if (Npins >= 3) Ports.append(new Port( 0, -30));

rotate(); // fix historical flaw
}

R_SPICE::~R_SPICE()
Expand All @@ -66,7 +79,7 @@ R_SPICE::~R_SPICE()

Component* R_SPICE::newOne()
{
return new R_SPICE();
return new R_SPICE();
}

Element* R_SPICE::info(QString& Name, char* &BitmapFile, bool getNewOne)
Expand All @@ -78,18 +91,33 @@ Element* R_SPICE::info(QString& Name, char* &BitmapFile, bool getNewOne)
return 0;
}

Element* R_SPICE::info_R3(QString& Name, char* &BitmapFile, bool getNewOne)
{
Name = QObject::tr("R Resistor 3 pin");
BitmapFile = (char *) "R_SPICE";

if(getNewOne) {
auto p = new R_SPICE();
p->Props.at(5)->Value = "3";
p->recreate(0);
return p;
}
return 0;
}

QString R_SPICE::netlist()
{
return QString("");
}

QString R_SPICE::spice_netlist(bool)
{
QString s = spicecompat::check_refdes(Name,SpiceModel);
QString ltr = getProperty("Letter")->Value;
QString s = spicecompat::check_refdes(Name,ltr);
for (Port *p1 : Ports) {
QString nam = p1->Connection->Name;
if (nam=="gnd") nam = "0";
s += " "+ nam+" "; // node names
s += " " + nam + " "; // node names
}

QString R= Props.at(0)->Value;
Expand Down
4 changes: 3 additions & 1 deletion qucs/spicecomponents/R_SPICE.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@

#include "components/component.h"

class R_SPICE : public Component {
class R_SPICE : public MultiViewComponent {
public:
R_SPICE();
~R_SPICE();
Component* newOne();
static Element* info(QString&, char* &, bool getNewOne=false);
static Element* info_R3(QString&, char* &, bool getNewOne=false);
protected:
void createSymbol();
QString netlist();
QString spice_netlist(bool isXyce = false);
};
Expand Down

0 comments on commit f40c93a

Please sign in to comment.