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

📄 cfunc.mod

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 MOD
字号:
/* $Id: cfunc.mod,v 1.3 2005/08/23 08:21:02 pnenzi Exp $ *//*.......1.........2.........3.........4.........5.........6.........7.........8================================================================================FILE dac_bridge/cfunc.modCopyright 1991Georgia Tech Research Corporation, Atlanta, Ga. 30332All Rights ReservedPROJECT A-8503-405               AUTHORS                          3 Jun 1991     Jeffrey P. MurrayMODIFICATIONS       16 Aug 1991    Jeffrey P. Murray     2 Oct 1991    Jeffrey P. Murray                                   SUMMARY    This file contains the model-specific routines used to    functionally describe the dac_bridge code model.INTERFACES           FILE                 ROUTINE CALLED         CM.c                 void *cm_analog_alloc()                         void *cm_analog_get_ptr()                         int cm_analog_set_perm_bkpt()    CMevt.c              void *cm_event_alloc()                         void *cm_event_get_ptr()REFERENCED FILES    Inputs from and outputs to ARGS structure.                     NON-STANDARD FEATURES    NONE===============================================================================*//*=== INCLUDE FILES ====================*/#include <stdio.h>#include <ctype.h>#include <math.h>#include <string.h>                                      /*=== CONSTANTS ========================*//*=== MACROS ===========================*/  /*=== LOCAL VARIABLES & TYPEDEFS =======*/                                        /*=== FUNCTION PROTOTYPE DEFINITIONS ===*/                   /*==============================================================================FUNCTION cm_dac_bridge()AUTHORS                          3 Jun 1991     Jeffrey P. MurrayMODIFICATIONS       16 Aug 1991    Jeffrey P. Murray     2 Oct 1991    Jeffrey P. MurraySUMMARY    This function implements the dac_bridge code model.INTERFACES           FILE                 ROUTINE CALLED         CM.c                 void *cm_analog_alloc()                         void *cm_analog_get_ptr()                         int cm_analog_set_perm_bkpt()    CMevt.c              void *cm_event_alloc()                         void *cm_event_get_ptr()RETURNED VALUE        Returns inputs and outputs via ARGS structure.GLOBAL VARIABLES        NONENON-STANDARD FEATURES    NONE==============================================================================*//*=== CM_DAC_BRIDGE ROUTINE ===*//*************************************************      The following is the model for the       **   digital-to-analog nodebridge for the        **   ATESSE Version 2.0 system.                  **                                               **   Created 6/3/91                J.P.Murray    *************************************************/void cm_dac_bridge(ARGS) {    double  out_low,        /* analog output value corresponding to '0'                                digital input 	*/           out_high,        /* analog output value corresponding to '1'                                digital input 	*/          out_undef,        /* analog output value corresponding to 'U'                                digital input 	*/             t_rise,        /* rise time...used to produce d(out)/d(time)                                values for gradual change in analog output.	*/              t_fall,        /* fall time...used to produce d(out)/d(time)                                values for gradual change in analog output.	*/                *out,        /* array holding all output values  */           *out_old,        /* array holding previous output values */                       fraction,        /* fraction of total rise or fall time to add to                               current time value for breakpoint calculation */          level_inc,        /* incremental level value out_high - out_low */         rise_slope,        /* level_inc divided by t_rise */         fall_slope,        /* level_inc divided by t_fall */           time_inc,        /* time increment since last analog call */               test,        /* testing variable */        *breakpoint;        /* holding variable to prevent infinite                               posting of the same breakpoint */    int           i,        /* generic loop counter index */	           size;        /* number of input & output ports */                                     Digital_State_t   *in,       /* base address of array holding all input                                     values  */                  *in_old;       /* array holding previous input values */    /* determine "width" of the node bridge... */    size = PORT_SIZE(in);                               /** Read in remaining model parameters **/                                  out_low = PARAM(out_low);    out_high = PARAM(out_high);    t_rise = PARAM(t_rise);    t_fall = PARAM(t_fall);    /* Test to see if out_low and out_high were specified, but */    /* out_undef was not...                                    */    /* if so, take out_undef as mean of out_high and out_low.  */    if (!PARAM_NULL(out_low) && !PARAM_NULL(out_high) &&          PARAM_NULL(out_undef) ) {       out_undef = out_low + (out_high - out_low) / 2.0;    }    else {       out_undef = PARAM(out_undef);    }                                     if (INIT) {  /*** Test for INIT == TRUE. If so, allocate storage, etc. ***/        /* Allocate storage for inputs */        in = in_old = (Digital_State_t *) cm_event_alloc(0,size * sizeof(Digital_State_t));                              /* Allocate storage for outputs */        /* retrieve previously-allocated discrete input and */        /* allocate storage for analog output values.       */                                            /* allocate output space and obtain adresses */        out = out_old = cm_analog_alloc(0,size * sizeof(double));        breakpoint = cm_analog_alloc(1,sizeof(double));                /* assign discrete addresses */        in = in_old = (Digital_State_t *) cm_event_get_ptr(0,0);        /* assign analog addresses */        out = out_old = cm_analog_get_ptr(0,0);        breakpoint = cm_analog_get_ptr(1,0);        /* read current input values */        for (i=0; i<size; i++) {            in[i] = INPUT_STATE(in[i]);        }                                       /* Output initial analog levels based on input values */        for (i=0; i<size; i++) { /* assign addresses */            switch (in[i]) {                case ZERO: out[i] = out_old[i] = out_low;                        OUTPUT(out[i]) = out_old[i];                        break;                case UNKNOWN: out[i] = out_old[i] = out_undef;                        OUTPUT(out[i]) = out_old[i];                        break;                case ONE: out[i] = out_old[i] = out_high;                        OUTPUT(out[i]) = out_old[i];                        break;            }            LOAD(in[i]) = PARAM(input_load);        }    }    else {    /*** This is not an initialization pass...read in parameters,                   retrieve storage addresses and calculate new outputs,                   if required. ***/        /** Retrieve previous values... **/        /* assign discrete addresses */        in = (Digital_State_t *) cm_event_get_ptr(0,0);        in_old= (Digital_State_t *) cm_event_get_ptr(0,1);        /* assign analog addresses */        out = cm_analog_get_ptr(0,0);        out_old = cm_analog_get_ptr(0,1);        breakpoint = cm_analog_get_ptr(1,0);        /* read current input values */        for (i=0; i<size; i++) {            in[i] = INPUT_STATE(in[i]);        }    }        switch (CALL_TYPE) {    case EVENT:  /** discrete call... **/                          /* Test to see if any change has occurred in an input */        /* since the last digital call...                     */         for (i=0; i<size; i++) {			            if (in[i] != in_old[i]) { /* if there has been a change... */                /* post current time as a breakpoint */                cm_analog_set_perm_bkpt(TIME);            }        }        break;    case ANALOG:    /** analog call... **/                          level_inc = out_high - out_low;        rise_slope = level_inc / t_rise;        fall_slope = level_inc / t_fall;                                          time_inc = TIME - T(1);        for (i=0; i<size; i++) {              if ( 0.0 == TIME ) {  /*** DC analysis ***/                                                                      switch (in[i]) {                             case ONE:                     out[i] = out_high;                    break;                case ZERO:                    out[i] = out_low;                    break;                case UNKNOWN:                    out[i] = out_undef;                    break;                }            }            else          /*** Transient Analysis ***/            if ( in_old[i] == in[i] ) {    /* There has been no change in                                               this digital input since the                                               last analog call...           */                switch (in[i]) {                case ZERO:                     if (out_old[i] > out_low) { /* output still dropping */                        out[i] = out_old[i] - fall_slope*time_inc;                        if ( out_low > out[i]) out[i]=out_low;                     }                    else { /* output at out_low */                                      out[i] = out_low;                    }                    break;                case ONE:                    if (out_old[i] < out_high) { /* output still rising */                        out[i] = out_old[i] + rise_slope*time_inc;                        if ( out_high < out[i]) out[i]=out_high;                     }                    else { /* output at out_high */                                      out[i] = out_high;                    }                    break;                case UNKNOWN:                    if (out_old[i] < out_undef) {     /* output still rising */                        out[i] = out_old[i] + (rise_slope * time_inc);                        if ( out_undef < out[i]) out[i]=out_undef;                     }                    else {                         if (out_old[i] > out_undef) { /* output still falling */                                              out[i] = out_old[i] - fall_slope*time_inc;                            if ( out_undef > out[i]) out[i]=out_undef;                         }                        else {                        /* output at out_undef */                                                                                  out[i] = out_undef;                        }                    }                    break;                }            }            else {     /* There HAS been a change in this digital input                          since the last analog access...need to use the                          old value of input to complete the breakpoint                          slope before changing directions... */                switch (in_old[i]) {                case ZERO:                     if (out_old[i] > out_low) { /* output still dropping */                        out[i] = out_old[i] - fall_slope*time_inc;                        if ( out_low > out[i]) out[i]=out_low;                     }                    else { /* output at out_low */                                      out[i] = out_low;                    }                    break;                case ONE:                    if (out_old[i] < out_high) { /* output still rising */                        out[i] = out_old[i] + rise_slope*time_inc;                        if ( out_high < out[i]) out[i]=out_high;                     }                    else { /* output at out_high */                                      out[i] = out_high;                    }                    break;                case UNKNOWN:                    if (out_old[i] < out_undef) {     /* output still rising */                        out[i] = out_old[i] + (rise_slope * time_inc);                        if ( out_undef < out[i]) out[i]=out_undef;                     }                    else {                         if (out_old[i] > out_undef) { /* output still falling */                                              out[i] = out_old[i] - fall_slope*time_inc;                            if ( out_undef > out[i]) out[i]=out_undef;                         }                        else {                        /* output at out_undef */                                                                                  out[i] = out_undef;                        }                    }                    break;                }                                                             /* determine required new breakpoint for the end of                   the output analog transition & post              */                switch (in[i]) {                     case ONE:        /* rising for all outputs */                        fraction = (out_high - out[i]) / (out_high - out_low);                        test = TIME + (fraction * t_rise);                        cm_analog_set_perm_bkpt(test);                        break;                                case UNKNOWN:    /* may be rising or falling */                        if ( out_undef > out[i] ) { /* rising to U */                            fraction = (out_undef - out[i]) / (out_high - out_low);                            test = TIME + (fraction * t_rise);                            cm_analog_set_perm_bkpt(test);                        }                        else {                       /* falling to U */                            fraction = (out[i] - out_undef) / (out_high - out_low);                            test = TIME + (fraction * t_fall);                            cm_analog_set_perm_bkpt(test);                        }                        break;                case ZERO:    /* falling for all outputs */                        fraction = (out[i] - out_low) / (out_high - out_low);                        test = TIME + (fraction * t_fall);                        cm_analog_set_perm_bkpt(test);                        break;                }            }        }        /* Output values... */                       for (i=0; i<size; i++) {            OUTPUT(out[i]) = out[i];        }        break;    }}

⌨️ 快捷键说明

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