⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfunc.mod

📁 支持数字元件仿真的SPICE插件
💻 MOD
📖 第 1 页 / 共 2 页
字号:
        /* Retrieve H and B values. */               for (i=0; i<size; i++) {            *(H+i) = PARAM(H_array[i]);            *(B+i) = PARAM(B_array[i]);        }                                   /* See if input_domain is absolute...if so, test against   */        /* breakpoint segments for violation of 50% rule...        */        if (PARAM(fraction) == MIF_FALSE) {            for (i=0; i<(size-1); i++) {                 if ( (*(H+i+1) - *(H+i)) < (2.0*input_domain) ) {                    cm_message_send(limit_error);                              return;                 }                }        }        /* Retrieve mmf_input value. */               mmf_input = INPUT(mc);                            /* Calculate H_input value from mmf_input... */        H_input = mmf_input / length;        /* Determine segment boundaries within which H_input resides */        if (H_input <= (*(H+1) + *H)/2.0) {/*** H_input below lowest midpoint ***/            dout_din = (*(B+1) - *B)/(*(H+1) - *H);            B_out = *B + (H_input - *H) * dout_din;        }        else {            if (H_input >= (*(H+size-2) + *(H+size-1))/2.0) {                                        /*** H_input above highest midpoint ***/                dout_din = (*(B+size-1) - *(B+size-2)) /                              (*(H+size-1) - *(H+size-2));                B_out = *(B+size-1) + (H_input - *(H+size-1)) * dout_din;            }            else { /*** H_input within bounds of end midpoints...     ***/                   /*** must determine position progressively & then  ***/                   /*** calculate required output.                    ***/                for (i=1; i<size; i++) {                    if (H_input < (*(H+i) + *(H+i+1))/2.0) {                                        /* approximate position known...          */                                     lower_seg = (*(H+i) - *(H+i-1));                        upper_seg = (*(H+i+1) - *(H+i));                        /* Calculate input_domain about this region's breakpoint.*/                        if (PARAM(fraction) == MIF_TRUE) {  /* Translate input_domain */                                                      /* into an absolute....   */                            if ( lower_seg <= upper_seg )          /* Use lower  */                                                                   /* segment    */                                                                   /* for % calc.*/                                input_domain = input_domain * lower_seg;                            else                                   /* Use upper  */                                                                   /* segment    */                                                                   /* for % calc.*/                                input_domain = input_domain * upper_seg;                        }                             /* Set up threshold values about breakpoint... */                        threshold_lower = *(H+i) - input_domain;                        threshold_upper = *(H+i) + input_domain;                        /* Determine where H_input is within region & determine     */                        /* output and partial values....                            */                        if (H_input < threshold_lower) { /* Lower linear region     */                            dout_din = (*(B+i) - *(B+i-1))/lower_seg;                            B_out = *(B+i) + (H_input - *(H+i)) * dout_din;                        }                        else {                                    if (H_input < threshold_upper) { /* Parabolic region */                                lower_slope = (*(B+i) - *(B+i-1))/lower_seg;                                upper_slope = (*(B+i+1) - *(B+i))/upper_seg;                                cm_smooth_corner(H_input,*(H+i),*(B+i),input_domain,                                            lower_slope,upper_slope,&B_out,&dout_din);                            }                            else {        /* Upper linear region */                                dout_din = (*(B+i+1) - *(B+i))/upper_seg;                                B_out = *(B+i) + (H_input - *(H+i)) * dout_din;                            }                        }                        break;  /* Break search loop...H_input has been found,   */                                /* and B_out and dout_din have been assigned.    */                    }                }            }        }                      /* Calculate value of flux_out... */        flux_out = B_out * area;            /* Adjust dout_din value to reflect area and length multipliers... */        dout_din = dout_din * area / length;        if(ANALYSIS != MIF_AC) {        /* Output DC & Transient Values */            OUTPUT(mc) = flux_out;            PARTIAL(mc,mc) = dout_din;        }        else {                      /* Output AC Gain */            ac_gain.real = dout_din;            ac_gain.imag= 0.0;            AC_GAIN(mc,mc) = ac_gain;        }    }     /******** hysteresis mode ******************/    else {          /** Retrieve frequently used parameters... **/         in_low = PARAM(in_low);        in_high = PARAM(in_high);        hyst = PARAM(hyst);        out_lower_limit = PARAM(out_lower_limit);        out_upper_limit = PARAM(out_upper_limit);                                 input_domain = PARAM(input_domain);                                /** Calculate Hysteresis Linear Region Slopes & Derived Values **/        /* Define slope of rise and fall lines when not being smoothed */        slope = (out_upper_limit - out_lower_limit)/(in_high - in_low);            x_rise_linear = in_low + hyst;    /* Breakpoint - x rising to                                                  linear region */        x_rise_zero = in_high + hyst;     /* Breakpoint - x rising to                                                zero-slope (out_upper_limit) */        x_fall_linear = in_high - hyst;   /* Breakpoint - x falling to                                                  linear region */        x_fall_zero = in_low - hyst;      /* Breakpoint - x falling to                                                zero-slope (out_lower_limit) */                                                    /* Set range to absolute value */        if (PARAM(fraction) == MIF_TRUE)                    input_domain = input_domain * (in_high - in_low);                                                        /** Retrieve frequently used inputs... **/           in = INPUT(mc);        /** Test for INIT; if so, allocate storage, otherwise, retrieve                               previous timepoint value for output...     **/        /* First pass...allocate storage for previous state.   */        /* Also, calculate roughly where the current output    */        /* will be and use this value to define current state. */        if (INIT==1) {                                                                  hyst_state = cm_analog_alloc(TRUE,sizeof(Boolean_t));               old_hyst_state = cm_analog_get_ptr(TRUE,1);                if (in < x_rise_zero + input_domain) { /* Set state to X_RISING */                *old_hyst_state = X_RISING;               }            else {                                         *old_hyst_state = X_FALLING;              }        }        else {   /* Allocation not necessary...retrieve previous values */            hyst_state = cm_analog_get_ptr(TRUE,0);  /* Set out pointer to current                                                          time storage */                old_hyst_state = cm_analog_get_ptr(TRUE,1);  /* Set old-output-state pointer                                                 to previous time storage */            }                           /** Set *hyst_out = *old_hyst_out, unless changed below...              we don't need the last iteration value of *hyst_state.  **/        *hyst_state = *old_hyst_state;        /*** Calculate value of hyst_state, pout_pin.... ***/        if (*old_hyst_state == X_RISING) { /* Assume calculations on lower  */                                           /* hysteresis section (x rising) */            if ( in <= x_rise_linear - input_domain ) { /* Output @ lower limit */                out = out_lower_limit;                pout_pin = 0.0;            }            else {                if ( in <= x_rise_linear + input_domain ) { /* lower smoothing region */                    cm_smooth_corner(in,x_rise_linear,out_lower_limit,input_domain,                                 0.0,slope,&out,&pout_pin);                }                else {                    if (in <= x_rise_zero - input_domain) { /* Rising linear region */                         out = (in - x_rise_linear)*slope + out_lower_limit;                        pout_pin = slope;                    }                    else {                        if (in <= x_rise_zero + input_domain) { /* Upper smoothing region */                             cm_smooth_corner(in,x_rise_zero,out_upper_limit,input_domain,                                        slope,0.0,&out,&pout_pin);                        }                        else { /* input has transitioned to X_FALLING region... */                            out = out_upper_limit;                            pout_pin = 0.0;                            *hyst_state = X_FALLING;                        }                    }                }            }        }        else {    /* Assume calculations on upper hysteresis section (x falling) */            if ( in >= x_fall_linear + input_domain ) { /* Output @ upper limit */                out = out_upper_limit;                pout_pin = 0.0;            }            else {                if ( in >= x_fall_linear - input_domain ) { /* Upper smoothing region */                    cm_smooth_corner(in,x_fall_linear,out_upper_limit,input_domain,                                 slope,0.0,&out,&pout_pin);                }                else {                    if (in >= x_fall_zero + input_domain) { /* Falling linear region */                         out = (in - x_fall_zero)*slope + out_lower_limit;                        pout_pin = slope;                    }                    else {                        if (in >= x_fall_zero - input_domain) { /* Lower smoothing region */                             cm_smooth_corner(in,x_fall_zero,out_lower_limit,input_domain,                                        0.0,slope,&out,&pout_pin);                        }                        else { /* input has transitioned to X_RISING region... */                            out = out_lower_limit;                            pout_pin = 0.0;                            *hyst_state = X_RISING;                        }                    }                }            }        }        if (ANALYSIS != MIF_AC) {     /* DC & Transient Analyses */                OUTPUT(mc) = out;                      PARTIAL(mc,mc) = pout_pin;             }        else {                        /* AC Analysis */            ac_gain.real = pout_pin;            ac_gain.imag= 0.0;            AC_GAIN(mc,mc) = ac_gain;        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -