diff --git a/src/xspice/icm/tlines/cpline/cfunc.mod b/src/xspice/icm/tlines/cpline/cfunc.mod index 83f2f3493..7bde30526 100644 --- a/src/xspice/icm/tlines/cpline/cfunc.mod +++ b/src/xspice/icm/tlines/cpline/cfunc.mod @@ -30,8 +30,9 @@ static void copy_complex(double complex s, Complex_t *d) 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) { @@ -49,7 +50,8 @@ void cm_cpline (ARGS) ao = pow(10, 0.05*ao); if(INIT) { - + CALLBACK = cm_cpline_callback; + STATIC_VAR(sim_points_data) = NULL; } /* Compute the output */ @@ -121,9 +123,19 @@ void cm_cpline (ARGS) Ip[2] = INPUT(p3); Ip[3] = INPUT(p4); 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) { - 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) { 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; + } +} diff --git a/src/xspice/icm/tlines/cpline/ifspec.ifs b/src/xspice/icm/tlines/cpline/ifspec.ifs index 136ec0982..03bf014bf 100644 --- a/src/xspice/icm/tlines/cpline/ifspec.ifs +++ b/src/xspice/icm/tlines/cpline/ifspec.ifs @@ -183,3 +183,9 @@ Vector_Bounds: - Null_Allowed: yes +STATIC_VAR_TABLE: + +Static_Var_Name: sim_points_data +Description: "local static data" +Data_Type: pointer + diff --git a/src/xspice/icm/tlines/cpmlin/cfunc.mod b/src/xspice/icm/tlines/cpmlin/cfunc.mod index 6bfde502a..6d6b0939c 100644 --- a/src/xspice/icm/tlines/cpmlin/cfunc.mod +++ b/src/xspice/icm/tlines/cpmlin/cfunc.mod @@ -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, double t, double er, @@ -377,6 +378,7 @@ void cm_cpmline (ARGS) double s = PARAM(s); int SModel = PARAM(model); int DModel = PARAM(disp); + int TModel = PARAM(tranmodel); /* how to get properties of the substrate, e.g. Er, H */ double er = PARAM(er); @@ -386,6 +388,10 @@ void cm_cpmline (ARGS) double rho = PARAM(rho); double D = PARAM(d); + if(INIT) { + CALLBACK = cm_cpmline_callback; + STATIC_VAR(sim_points_data) = NULL; + } /* Compute the output */ @@ -459,9 +465,19 @@ void cm_cpmline (ARGS) Ip[2] = INPUT(p3); Ip[3] = INPUT(p4); double delay = l/(C0); - append_cpline_state(&state, t, Vp, Ip, 1.2*delay); - if (t > delay) { - cpline_state_t *pp = find_cpline_state(state, t - delay); + void **sim_points = &(STATIC_VAR(sim_points_data)); + if (TModel == TRAN_FULL) { + 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) { double J1e = 0.5*(Ip[3] + Ip[0]); @@ -498,8 +514,28 @@ void cm_cpmline (ARGS) } cm_analog_auto_partial(); } 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(); } } } +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; + } +} diff --git a/src/xspice/icm/tlines/cpmlin/ifspec.ifs b/src/xspice/icm/tlines/cpmlin/ifspec.ifs index c8d37ea8b..d4a6367c0 100644 --- a/src/xspice/icm/tlines/cpmlin/ifspec.ifs +++ b/src/xspice/icm/tlines/cpmlin/ifspec.ifs @@ -222,4 +222,20 @@ Vector: no Vector_Bounds: - 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 diff --git a/src/xspice/icm/tlines/mlin/cfunc.mod b/src/xspice/icm/tlines/mlin/cfunc.mod index d21bb7b5b..caa53d2fe 100644 --- a/src/xspice/icm/tlines/mlin/cfunc.mod +++ b/src/xspice/icm/tlines/mlin/cfunc.mod @@ -22,10 +22,12 @@ #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 void cm_mline_callback(ARGS, Mif_Callback_Reason_t reason); + static void calcPropagation (double W, int SModel, int DModel, double er, double h, double t, double tand, double rho, double D, double frequency) { @@ -56,6 +58,7 @@ static void calcPropagation (double W, int SModel, int DModel, void cm_mlin (ARGS) { Complex_t z11, z21; + void **sim_points; /* 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 */ if(INIT) { - + CALLBACK = cm_mline_callback; + STATIC_VAR(sim_points_data) = NULL; } /* Compute the output */ @@ -111,6 +115,7 @@ void cm_mlin (ARGS) } else if(ANALYSIS == TRANSIENT) { calcPropagation(W,SModel,DModel,er,h,t,tand,rho,D,0); + sim_points = &(STATIC_VAR(sim_points_data)); double t = TIME; double V1 = INPUT(V1sens); double V2 = INPUT(V2sens); @@ -118,10 +123,19 @@ void cm_mlin (ARGS) double I2 = INPUT(port2); double delay = l/(C0) * sqrt(ereff); 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) { - 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) { double V2out = pp->V1 + zl*(pp->I1); 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; + } +} + diff --git a/src/xspice/icm/tlines/mlin/ifspec.ifs b/src/xspice/icm/tlines/mlin/ifspec.ifs index 3136f51e3..a0e268116 100644 --- a/src/xspice/icm/tlines/mlin/ifspec.ifs +++ b/src/xspice/icm/tlines/mlin/ifspec.ifs @@ -169,7 +169,7 @@ Null_Allowed: yes PARAMETER_TABLE: Parameter_Name: tranmodel -Description: "RMS Substrate roughness" +Description: "TRAN model DC/FULL" Data_Type: int Default_Value: 0 Limits: - @@ -178,5 +178,9 @@ Vector_Bounds: - Null_Allowed: yes +STATIC_VAR_TABLE: +Static_Var_Name: sim_points_data +Description: "local static data" +Data_Type: pointer diff --git a/src/xspice/icm/tlines/tline/cfunc.mod b/src/xspice/icm/tlines/tline/cfunc.mod index 58f748b3b..207a0ee58 100644 --- a/src/xspice/icm/tlines/tline/cfunc.mod +++ b/src/xspice/icm/tlines/tline/cfunc.mod @@ -21,12 +21,14 @@ #include "msline_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) { Complex_t z11, z21; + void **sim_points; /* 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 */ if(INIT) { - + CALLBACK = cm_tline_callback; + STATIC_VAR(sim_points_data) = NULL; } /* Compute the output */ @@ -72,15 +75,26 @@ void cm_tline (ARGS) AC_GAIN(in,out) = z21; AC_GAIN(out,in) = z21; } else if(ANALYSIS == TRANSIENT) { + sim_points = &(STATIC_VAR(sim_points_data)); double t = TIME; double V1 = INPUT(V1sens); double V2 = INPUT(V2sens); double I1 = INPUT(in); double I2 = INPUT(out); 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) { - 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) { double V2out = pp->V1 + z*(pp->I1); 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; + } +} diff --git a/src/xspice/icm/tlines/tline/ifspec.ifs b/src/xspice/icm/tlines/tline/ifspec.ifs index cfe95aead..5e45685b8 100644 --- a/src/xspice/icm/tlines/tline/ifspec.ifs +++ b/src/xspice/icm/tlines/tline/ifspec.ifs @@ -93,4 +93,8 @@ Vector: no Vector_Bounds: - Null_Allowed: yes +STATIC_VAR_TABLE: +Static_Var_Name: sim_points_data +Description: "local static data" +Data_Type: pointer diff --git a/src/xspice/tlines/tline_common.c b/src/xspice/tlines/tline_common.c index 08e8bb77d..90f652688 100644 --- a/src/xspice/tlines/tline_common.c +++ b/src/xspice/tlines/tline_common.c @@ -61,6 +61,47 @@ tline_state_t *get_state(tline_state_t *first, double time) 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) { @@ -99,3 +140,46 @@ cpline_state_t *find_cpline_state(cpline_state_t *first, double time) 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; +} + + diff --git a/src/xspice/tlines/tline_common.h b/src/xspice/tlines/tline_common.h index 4932ce581..8448d47bb 100644 --- a/src/xspice/tlines/tline_common.h +++ b/src/xspice/tlines/tline_common.h @@ -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); +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 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); +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