Add a new code model 'sidiode' with a simple diode:

Linear reverse, off, and on regions
Smooth parabolic transition between the regions
Maximum current settings possible with tanh transistion
Current versus voltage continuously differentiable
No diode capacitance
This commit is contained in:
Holger Vogt 2018-10-05 21:12:16 +02:00
parent 76c43ab512
commit faa7ce003c
4 changed files with 353 additions and 0 deletions

View File

@ -8,3 +8,4 @@ lmeter
potentiometer
zener
memristor
sidiode

View File

@ -0,0 +1,240 @@
/*.......1.........2.........3.........4.........5.........6.........7.........8
================================================================================
FILE diodes/cfunc.mod
Copyright 2018
GHolger Vogt
All Rights Reserved
AUTHORS
2 October 2018 Holger Vogt
MODIFICATIONS
SUMMARY
This file contains the model-specific routines used to
functionally describe a simplified diode code model.
INTERFACES
FILE ROUTINE CALLED
REFERENCED FILES
Inputs from and outputs to ARGS structure.
NON-STANDARD FEATURES
NONE
===============================================================================*/
/*=== INCLUDE FILES ====================*/
#include <stdlib.h>
#include <math.h>
/*=== CONSTANTS ========================*/
/*=== MACROS ===========================*/
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
typedef struct {
double a1; /* parameter of first quadratic equation */
double a2; /* parameter of first tanh equation */
double b1; /* parameter of second quadratic equation */
double b2; /* parameter of second tanh equation */
double hRevepsilon; /* half delta between Va and Vb */
double hEpsilon; /* half delta between Vc and Vd */
double Va; /* voltage limits of the quadratic regions */
double Vb;
double Vc;
double Vd;
double grev; /* conductance in all three regions */
double goff;
double gon;
Boolean_t Ili; /* TRUE, if current limits are given */
Boolean_t Revili;
Boolean_t epsi; /* TRUE, if quadratic overlap */
Boolean_t revepsi;
} Local_Data_t;
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
/*==============================================================================
FUNCTION void cm_diodes()
==============================================================================*/
static void
cm_sidiode_callback(ARGS, Mif_Callback_Reason_t reason)
{
switch (reason) {
case MIF_CB_DESTROY: {
Local_Data_t *loc = STATIC_VAR (locdata);
free(loc);
break;
}
}
}
/*=== CM_DIODES ROUTINE ===*/
void cm_sidiode(ARGS) /* structure holding parms,
inputs, outputs, etc. */
{
Local_Data_t *loc; /* Pointer to local static data, not to be included
in the state vector */
Mif_Complex_t ac_gain; /* AC gain */
double Vrev, Vfwd, Vin, Id, deriv, Ilimit, Revilimit;
Vrev = -PARAM(vrev);
Vfwd = PARAM(vfwd);
Ilimit = PARAM(ilimit);
Revilimit = -PARAM(revilimit);
if (INIT==1) { /* First pass...allocate memory and calculate some constants... */
double grev, goff, gon, Va, Vb, Vc, Vd, hEpsilon, hRevepsilon;
CALLBACK = cm_sidiode_callback;
/* allocate static storage for *loc */
STATIC_VAR(locdata) = calloc (1, sizeof(Local_Data_t));
loc = STATIC_VAR(locdata);
goff = 1./PARAM(roff);
gon = 1./PARAM(ron);
if (PARAM(rrev) == 0.)
grev = gon;
else
grev = 1./PARAM(rrev);
hRevepsilon = 0.5 * PARAM(revepsilon);
loc->Va = Va = Vrev - hRevepsilon;
loc->Vb = Vb = Vrev + hRevepsilon;
if(hRevepsilon > 0.0) {
loc->a1 = (goff - grev)/PARAM(revepsilon);
loc->a2 = grev/Revilimit;
loc->revepsi = MIF_TRUE;
}
else
loc->revepsi = MIF_FALSE;
hEpsilon = 0.5 * PARAM(epsilon);
loc->Vc = Vc = Vfwd - hEpsilon;
loc->Vd = Vd = Vfwd + hEpsilon;
if(hEpsilon > 0.0) {
loc->b1 = (gon - goff)/PARAM(epsilon);
loc->b2 = gon/Ilimit;
loc->epsi = MIF_TRUE;
}
else
loc->epsi = MIF_FALSE;
if (Ilimit < 1e29)
loc->Ili = MIF_TRUE;
else
loc->Ili = MIF_FALSE;
if (Revilimit > -1e29)
loc->Revili = MIF_TRUE;
else
loc->Revili = MIF_FALSE;
loc->grev = grev;
loc->goff = goff;
loc->gon = gon;
}
else
loc = STATIC_VAR(locdata);
/* Calculate diode current Id and its derivative deriv=dId/dVin */
Vin = INPUT(ds);
if (Vin < loc->Va) {
if(loc->Revili) {
double tmp = tanh(loc->a2 * (loc->Va - Vin));
Id = Ilimit * tmp + loc->goff * loc->Va
+ 0.5 * (loc->Va - loc->Vb) * (loc->Va - loc->Vb) * loc->a1;
deriv = loc->grev * (1. - tmp * tmp);
}
else {
Id = Vrev * loc->goff + (Vin - Vrev) * loc->grev;
deriv = loc->grev;
}
}
else if (loc->revepsi && Vin >= loc->Va && Vin < loc->Vb) {
Id = 0.5 * (Vin -loc->Vb) * (Vin - loc->Vb) * loc->a1 + Vin * loc->goff;
deriv = (Vin - loc->Vb) * loc->a1 + loc->goff;
}
else if (Vin >= loc->Vb && Vin < loc->Vc) {
Id = Vin * loc->goff;
deriv = loc->goff;
}
else if (loc->epsi && Vin >= loc->Vc && Vin < loc->Vd) {
Id = 0.5 * (Vin -loc->Vc) * (Vin - loc->Vc) * loc->b1 + Vin * loc->goff;
deriv = (Vin - loc->Vc) * loc->b1 + loc->goff;
}
else {
if(loc->Ili) {
double tmp = tanh(loc->b2 * (Vin - loc->Vd));
Id = Ilimit * tmp + loc->goff * loc->Vd
+ 0.5 * (loc->Vd - loc->Vc) * (loc->Vd - loc->Vc) * loc->b1;
deriv = loc->gon * (1. - tmp * tmp);
}
else {
Id = Vfwd * loc->goff + (Vin - Vfwd) * loc->gon;
deriv = loc->gon;
}
}
if(ANALYSIS != MIF_AC) { /* Output DC & Transient Values */
OUTPUT(ds) = Id;
PARTIAL(ds,ds) = deriv;
}
else { /* Output AC Gain */
ac_gain.real = deriv;
ac_gain.imag= 0.0;
AC_GAIN(ds,ds) = ac_gain;
}
}

View File

@ -0,0 +1,108 @@
/*.......1.........2.........3.........4.........5.........6.........7.........8
================================================================================
Copyright 2018
Holger Vogt
All Rights Reserved
AUTHORS
2 October 2018 Holger Vogt
SUMMARY
This file contains the interface specification file for the
analog simple diode code model.
===============================================================================*/
NAME_TABLE:
C_Function_Name: cm_sidiode
Spice_Model_Name: sidiode
Description: "simple diode"
PORT_TABLE:
Port_Name: ds
Description: "diode port"
Direction: inout
Default_Type: gd
Allowed_Types: [gd]
Vector: no
Vector_Bounds: -
Null_Allowed: no
PARAMETER_TABLE:
Parameter_Name: ron roff
Description: "resistance on-state" "resistance off-state"
Data_Type: real real
Default_Value: 1 1
Limits: [1e-6 - ] [1e-12 -]
Vector: no no
Vector_Bounds: - -
Null_Allowed: no no
PARAMETER_TABLE:
Parameter_Name: vfwd vrev
Description: "forward voltage" "reverse breakdown voltage"
Data_Type: real real
Default_Value: 0. 1e30
Limits: [0. -] [0. -]
Vector: no no
Vector_Bounds: - -
Null_Allowed: yes yes
PARAMETER_TABLE:
Parameter_Name: ilimit revilimit
Description: "limit of on-current" "limit of breakdown current"
Data_Type: real real
Default_Value: 1e30 1e30
Limits: [1e-15 -] [1e-15 -]
Vector: no no
Vector_Bounds: - -
Null_Allowed: yes yes
PARAMETER_TABLE:
Parameter_Name: epsilon revepsilon
Description: "width quadrat. r 1" "width quadratic region 2"
Data_Type: real real
Default_Value: 0. 0.
Limits: [0. -] [0. -]
Vector: no no
Vector_Bounds: - -
Null_Allowed: yes yes
PARAMETER_TABLE:
Parameter_Name: rrev
Description: "resistance in breakdown"
Data_Type: real
Default_Value: 0.
Limits: -
Vector: no
Vector_Bounds: -
Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: locdata
Data_Type: pointer
Description: "table with constants"

View File

@ -219,6 +219,8 @@
<AdditionalIncludeDirectories>..\..\src\xspice\%(RelativeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<ClCompile Include="icm\xtradev\core\core-ifspec.c" />
<ClCompile Include="icm\xtradev\sidiode\sidiode-cfunc.c" />
<ClCompile Include="icm\xtradev\sidiode\sidiode-ifspec.c" />
<ClCompile Include="icm\xtradev\inductor\inductor-cfunc.c">
<AdditionalIncludeDirectories>..\..\src\xspice\%(RelativeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
@ -254,6 +256,8 @@
<None Include="..\..\src\xspice\icm\xtradev\cmeter\ifspec.ifs" />
<None Include="..\..\src\xspice\icm\xtradev\core\cfunc.mod" />
<None Include="..\..\src\xspice\icm\xtradev\core\ifspec.ifs" />
<None Include="..\..\src\xspice\icm\xtradev\sidiode\cfunc.mod" />
<None Include="..\..\src\xspice\icm\xtradev\sidiode\ifspec.ifs" />
<None Include="..\..\src\xspice\icm\xtradev\inductor\cfunc.mod" />
<None Include="..\..\src\xspice\icm\xtradev\inductor\ifspec.ifs" />
<None Include="..\..\src\xspice\icm\xtradev\lcouple\cfunc.mod" />