Implement rollback; fix memory management

This commit is contained in:
Vadim Kuznetsov 2025-06-11 20:58:43 +03:00
parent fe20d8a340
commit f90f5172ac
10 changed files with 243 additions and 17 deletions

View File

@ -30,8 +30,9 @@ static void copy_complex(double complex s, Complex_t *d)
d->imag = cimag(s); d->imag = cimag(s);
} }
cpline_state_t *sim_points = NULL; //cpline_state_t *sim_points = NULL;
static void cm_cpline_callback(ARGS, Mif_Callback_Reason_t reason);
void cm_cpline (ARGS) void cm_cpline (ARGS)
{ {
@ -49,7 +50,8 @@ void cm_cpline (ARGS)
ao = pow(10, 0.05*ao); ao = pow(10, 0.05*ao);
if(INIT) { if(INIT) {
CALLBACK = cm_cpline_callback;
STATIC_VAR(sim_points_data) = NULL;
} }
/* Compute the output */ /* Compute the output */
@ -121,9 +123,19 @@ void cm_cpline (ARGS)
Ip[2] = INPUT(p3); Ip[2] = INPUT(p3);
Ip[3] = INPUT(p4); Ip[3] = INPUT(p4);
double delay = l/(C0); double delay = l/(C0);
append_cpline_state(&sim_points, t, Vp, Ip, 1.2*delay);
void **sim_points = &(STATIC_VAR(sim_points_data));
cpline_state_t *last = get_cpline_last_state(*(cpline_state_t **)sim_points);
double last_time = 0;
if (last != NULL) last_time = last->time;
if (TIME < last_time) {
delete_cpline_last_state((cpline_state_t **)sim_points);
}
append_cpline_state((cpline_state_t **)sim_points, t, Vp, Ip, 1.2*delay);
if (t > delay) { if (t > delay) {
cpline_state_t *pp = find_cpline_state(sim_points, t - delay); cpline_state_t *pp = find_cpline_state(*(cpline_state_t **)sim_points, t - delay);
if (pp != NULL) { if (pp != NULL) {
double J1e = 0.5*(Ip[3] + Ip[0]); double J1e = 0.5*(Ip[3] + Ip[0]);
@ -165,3 +177,12 @@ void cm_cpline (ARGS)
} }
} }
static void cm_cpline_callback(ARGS, Mif_Callback_Reason_t reason)
{
switch (reason) {
case MIF_CB_DESTROY:
delete_cpline_states((cpline_state_t **)&(STATIC_VAR(sim_points_data)));
break;
default: break;
}
}

View File

@ -183,3 +183,9 @@ Vector_Bounds: -
Null_Allowed: yes Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: sim_points_data
Description: "local static data"
Data_Type: pointer

View File

@ -33,7 +33,8 @@ static void copy_complex(double complex s, Complex_t *d)
} }
static cpline_state_t *state = NULL; //static cpline_state_t *state = NULL;
static void cm_cpmline_callback(ARGS, Mif_Callback_Reason_t reason);
static void analyseQuasiStatic (double W, double h, double s, static void analyseQuasiStatic (double W, double h, double s,
double t, double er, double t, double er,
@ -377,6 +378,7 @@ void cm_cpmline (ARGS)
double s = PARAM(s); double s = PARAM(s);
int SModel = PARAM(model); int SModel = PARAM(model);
int DModel = PARAM(disp); int DModel = PARAM(disp);
int TModel = PARAM(tranmodel);
/* how to get properties of the substrate, e.g. Er, H */ /* how to get properties of the substrate, e.g. Er, H */
double er = PARAM(er); double er = PARAM(er);
@ -386,6 +388,10 @@ void cm_cpmline (ARGS)
double rho = PARAM(rho); double rho = PARAM(rho);
double D = PARAM(d); double D = PARAM(d);
if(INIT) {
CALLBACK = cm_cpmline_callback;
STATIC_VAR(sim_points_data) = NULL;
}
/* Compute the output */ /* Compute the output */
@ -459,9 +465,19 @@ void cm_cpmline (ARGS)
Ip[2] = INPUT(p3); Ip[2] = INPUT(p3);
Ip[3] = INPUT(p4); Ip[3] = INPUT(p4);
double delay = l/(C0); double delay = l/(C0);
append_cpline_state(&state, t, Vp, Ip, 1.2*delay); void **sim_points = &(STATIC_VAR(sim_points_data));
if (t > delay) { if (TModel == TRAN_FULL) {
cpline_state_t *pp = find_cpline_state(state, t - delay); cpline_state_t *last = get_cpline_last_state(*(cpline_state_t **)sim_points);
double last_time = 0;
if (last != NULL) last_time = last->time;
if (TIME < last_time) {
delete_cpline_last_state((cpline_state_t **)sim_points);
}
append_cpline_state((cpline_state_t **)sim_points, t, Vp, Ip, 1.2*delay);
}
if (t > delay && TModel == TRAN_FULL) {
cpline_state_t *pp = find_cpline_state(*(cpline_state_t **)sim_points, t - delay);
if (pp != NULL) { if (pp != NULL) {
double J1e = 0.5*(Ip[3] + Ip[0]); double J1e = 0.5*(Ip[3] + Ip[0]);
@ -498,8 +514,28 @@ void cm_cpmline (ARGS)
} }
cm_analog_auto_partial(); cm_analog_auto_partial();
} else { } else {
double z = sqrt(ze*zo);
double V2out = Vp[0] + z*Ip[0];
double V1out = Vp[1] + z*Ip[1];
OUTPUT(p1) = V1out + Ip[0]*z;
OUTPUT(p2) = V2out + Ip[1]*z;
double V3out = Vp[3] + z*Ip[3];
double V4out = Vp[2] + z*Ip[2];
OUTPUT(p3) = V3out + Ip[2]*z;
OUTPUT(p4) = V4out + Ip[3]*z;
cm_analog_auto_partial(); cm_analog_auto_partial();
} }
} }
} }
static void cm_cpmline_callback(ARGS, Mif_Callback_Reason_t reason)
{
switch (reason) {
case MIF_CB_DESTROY:
delete_cpline_states((cpline_state_t **)&(STATIC_VAR(sim_points_data)));
break;
default: break;
}
}

View File

@ -222,4 +222,20 @@ Vector: no
Vector_Bounds: - Vector_Bounds: -
Null_Allowed: yes Null_Allowed: yes
PARAMETER_TABLE:
Parameter_Name: tranmodel
Description: "TRAN model DC/FULL"
Data_Type: int
Default_Value: 0
Limits: -
Vector: no
Vector_Bounds: -
Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: sim_points_data
Description: "local static data"
Data_Type: pointer

View File

@ -22,10 +22,12 @@
#include "msline_common.h" #include "msline_common.h"
static tline_state_t *sim_points = NULL; //static tline_state_t *sim_points = NULL;
static double zl, alpha, beta, ereff; static double zl, alpha, beta, ereff;
static void cm_mline_callback(ARGS, Mif_Callback_Reason_t reason);
static void calcPropagation (double W, int SModel, int DModel, static void calcPropagation (double W, int SModel, int DModel,
double er, double h, double t, double tand, double rho, double D, double er, double h, double t, double tand, double rho, double D,
double frequency) { double frequency) {
@ -56,6 +58,7 @@ static void calcPropagation (double W, int SModel, int DModel,
void cm_mlin (ARGS) void cm_mlin (ARGS)
{ {
Complex_t z11, z21; Complex_t z11, z21;
void **sim_points;
/* how to get properties of this component, e.g. L, W */ /* how to get properties of this component, e.g. L, W */
@ -77,7 +80,8 @@ void cm_mlin (ARGS)
/* Initialize/access instance specific storage for capacitor voltage */ /* Initialize/access instance specific storage for capacitor voltage */
if(INIT) { if(INIT) {
CALLBACK = cm_mline_callback;
STATIC_VAR(sim_points_data) = NULL;
} }
/* Compute the output */ /* Compute the output */
@ -111,6 +115,7 @@ void cm_mlin (ARGS)
} }
else if(ANALYSIS == TRANSIENT) { else if(ANALYSIS == TRANSIENT) {
calcPropagation(W,SModel,DModel,er,h,t,tand,rho,D,0); calcPropagation(W,SModel,DModel,er,h,t,tand,rho,D,0);
sim_points = &(STATIC_VAR(sim_points_data));
double t = TIME; double t = TIME;
double V1 = INPUT(V1sens); double V1 = INPUT(V1sens);
double V2 = INPUT(V2sens); double V2 = INPUT(V2sens);
@ -118,10 +123,19 @@ void cm_mlin (ARGS)
double I2 = INPUT(port2); double I2 = INPUT(port2);
double delay = l/(C0) * sqrt(ereff); double delay = l/(C0) * sqrt(ereff);
if (TModel == TRAN_FULL) { if (TModel == TRAN_FULL) {
append_state(&sim_points, t, V1, V2, I1, I2, 1.2*delay);
tline_state_t *last = get_tline_last_state(*(tline_state_t **)sim_points);
double last_time = 0;
if (last != NULL) last_time = last->time;
if (TIME < last_time) {
//fprintf(stderr,"Rollbacki time=%g\n",TIME);
delete_tline_last_state((tline_state_t **)sim_points);
}
append_state((tline_state_t **)sim_points, t, V1, V2, I1, I2, 1.2*delay);
} }
if (t > delay && TModel == TRAN_FULL) { if (t > delay && TModel == TRAN_FULL) {
tline_state_t *pp = get_state(sim_points, t - delay); tline_state_t *pp = get_state(*(tline_state_t **)sim_points, t - delay);
if (pp != NULL) { if (pp != NULL) {
double V2out = pp->V1 + zl*(pp->I1); double V2out = pp->V1 + zl*(pp->I1);
double V1out = pp->V2 + zl*(pp->I2); double V1out = pp->V2 + zl*(pp->I2);
@ -140,3 +154,13 @@ void cm_mlin (ARGS)
} }
} }
static void cm_mline_callback(ARGS, Mif_Callback_Reason_t reason)
{
switch (reason) {
case MIF_CB_DESTROY:
delete_tline_states((tline_state_t **)&(STATIC_VAR(sim_points_data)));
break;
default: break;
}
}

View File

@ -169,7 +169,7 @@ Null_Allowed: yes
PARAMETER_TABLE: PARAMETER_TABLE:
Parameter_Name: tranmodel Parameter_Name: tranmodel
Description: "RMS Substrate roughness" Description: "TRAN model DC/FULL"
Data_Type: int Data_Type: int
Default_Value: 0 Default_Value: 0
Limits: - Limits: -
@ -178,5 +178,9 @@ Vector_Bounds: -
Null_Allowed: yes Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: sim_points_data
Description: "local static data"
Data_Type: pointer

View File

@ -21,12 +21,14 @@
#include "msline_common.h" #include "msline_common.h"
#include "tline_common.h" #include "tline_common.h"
static tline_state_t *sim_points = NULL; //static tline_state_t *sim_points = NULL;
static void cm_tline_callback(ARGS, Mif_Callback_Reason_t reason);
void cm_tline (ARGS) void cm_tline (ARGS)
{ {
Complex_t z11, z21; Complex_t z11, z21;
void **sim_points;
/* how to get properties of this component, e.g. L, W */ /* how to get properties of this component, e.g. L, W */
@ -39,7 +41,8 @@ void cm_tline (ARGS)
/* Initialize/access instance specific storage for capacitor voltage */ /* Initialize/access instance specific storage for capacitor voltage */
if(INIT) { if(INIT) {
CALLBACK = cm_tline_callback;
STATIC_VAR(sim_points_data) = NULL;
} }
/* Compute the output */ /* Compute the output */
@ -72,15 +75,26 @@ void cm_tline (ARGS)
AC_GAIN(in,out) = z21; AC_GAIN(out,in) = z21; AC_GAIN(in,out) = z21; AC_GAIN(out,in) = z21;
} }
else if(ANALYSIS == TRANSIENT) { else if(ANALYSIS == TRANSIENT) {
sim_points = &(STATIC_VAR(sim_points_data));
double t = TIME; double t = TIME;
double V1 = INPUT(V1sens); double V1 = INPUT(V1sens);
double V2 = INPUT(V2sens); double V2 = INPUT(V2sens);
double I1 = INPUT(in); double I1 = INPUT(in);
double I2 = INPUT(out); double I2 = INPUT(out);
double delay = l/(C0); double delay = l/(C0);
append_state(&sim_points, t, V1, V2, I1, I2, 1.2*delay);
tline_state_t *last = get_tline_last_state(*(tline_state_t **)sim_points);
double last_time = 0;
if (last != NULL) last_time = last->time;
if (TIME < last_time) {
//fprintf(stderr,"Rollback time=%g\n",TIME);
delete_tline_last_state((tline_state_t **)sim_points);
}
append_state((tline_state_t **)sim_points, t, V1, V2, I1, I2, 1.2*delay);
if (t > delay) { if (t > delay) {
tline_state_t *pp = get_state(sim_points, t - delay); tline_state_t *pp = get_state(*(tline_state_t **)sim_points, t - delay);
if (pp != NULL) { if (pp != NULL) {
double V2out = pp->V1 + z*(pp->I1); double V2out = pp->V1 + z*(pp->I1);
double V1out = pp->V2 + z*(pp->I2); double V1out = pp->V2 + z*(pp->I2);
@ -98,3 +112,13 @@ void cm_tline (ARGS)
} }
} }
static void cm_tline_callback(ARGS, Mif_Callback_Reason_t reason)
{
switch (reason) {
case MIF_CB_DESTROY:
delete_tline_states((tline_state_t **)&(STATIC_VAR(sim_points_data)));
break;
default: break;
}
}

View File

@ -93,4 +93,8 @@ Vector: no
Vector_Bounds: - Vector_Bounds: -
Null_Allowed: yes Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: sim_points_data
Description: "local static data"
Data_Type: pointer

View File

@ -61,6 +61,47 @@ tline_state_t *get_state(tline_state_t *first, double time)
return pp; return pp;
} }
tline_state_t *get_tline_last_state(tline_state_t *first)
{
tline_state_t *pp = first;
if (first == NULL) return NULL;
while (pp->next != NULL) {
pp = pp->next;
}
return pp;
}
void delete_tline_last_state(tline_state_t **first)
{
tline_state_t *pn = *first;
if (*first == NULL) return;
if ((*first)->next == NULL) {
free (*first);
*first = NULL;
return;
}
while (pn->next->next != NULL) {
pn = pn->next;
}
free(pn->next);
pn->next = NULL;
}
void delete_tline_states(tline_state_t **first)
{
if (*first == NULL) return;
tline_state_t *pn;
tline_state_t *pc = *first;
while (pc != NULL) {
pn = pc->next;
free (pc);
pc = pn;
}
*first = NULL;
}
void append_cpline_state(cpline_state_t **first, double time, double *Vp, double *Ip, double tmax) void append_cpline_state(cpline_state_t **first, double time, double *Vp, double *Ip, double tmax)
{ {
@ -99,3 +140,46 @@ cpline_state_t *find_cpline_state(cpline_state_t *first, double time)
return pp; return pp;
} }
cpline_state_t *get_cpline_last_state(cpline_state_t *first)
{
cpline_state_t *pp = first;
if (first == NULL) return NULL;
while (pp->next != NULL) {
pp = pp->next;
}
return pp;
}
void delete_cpline_last_state(cpline_state_t **first)
{
cpline_state_t *pn = *first;
if (*first == NULL) return;
if ((*first)->next == NULL) {
free (*first);
*first = NULL;
return;
}
while (pn->next->next != NULL) {
pn = pn->next;
}
free(pn->next);
pn->next = NULL;
}
void delete_cpline_states(cpline_state_t **first)
{
if (*first == NULL) return;
cpline_state_t *pn;
cpline_state_t *pc = *first;
while (pc != NULL) {
pn = pc->next;
free (pc);
pc = pn;
}
*first = NULL;
}

View File

@ -59,6 +59,10 @@ void append_state(tline_state_t **first, double time, double V1, double V2,
tline_state_t *get_state(tline_state_t *first, double time); tline_state_t *get_state(tline_state_t *first, double time);
void delete_tline_states(tline_state_t **first);
void delete_tline_last_state(tline_state_t **first);
tline_state_t *get_tline_last_state(tline_state_t *first);
#define PORT_NUM 4 #define PORT_NUM 4
typedef struct cpline_state { typedef struct cpline_state {
@ -74,5 +78,8 @@ void append_cpline_state(cpline_state_t **first, double time, double *Vp, double
cpline_state_t *find_cpline_state(cpline_state_t *first, double time); cpline_state_t *find_cpline_state(cpline_state_t *first, double time);
void delete_cpline_states(cpline_state_t **first);
void delete_cpline_last_state(cpline_state_t **first);
cpline_state_t *get_cpline_last_state(cpline_state_t *first);
#endif #endif