Browse Source

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
pre-master-46
Holger Vogt 8 years ago
parent
commit
faa7ce003c
  1. 1
      src/xspice/icm/xtradev/modpath.lst
  2. 240
      src/xspice/icm/xtradev/sidiode/cfunc.mod
  3. 108
      src/xspice/icm/xtradev/sidiode/ifspec.ifs
  4. 4
      visualc/xspice/xtradev.vcxproj

1
src/xspice/icm/xtradev/modpath.lst

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

240
src/xspice/icm/xtradev/sidiode/cfunc.mod

@ -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;
}
}

108
src/xspice/icm/xtradev/sidiode/ifspec.ifs

@ -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"

4
visualc/xspice/xtradev.vcxproj

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

Loading…
Cancel
Save