Browse Source
Add a new code model 'sidiode' with a simple diode:
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 capacitancepre-master-46
4 changed files with 353 additions and 0 deletions
-
1src/xspice/icm/xtradev/modpath.lst
-
240src/xspice/icm/xtradev/sidiode/cfunc.mod
-
108src/xspice/icm/xtradev/sidiode/ifspec.ifs
-
4visualc/xspice/xtradev.vcxproj
@ -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; |
|||
} |
|||
} |
|||
@ -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" |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue