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

📄 evtdeque.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
字号:
/*============================================================================FILE    EVTdequeue.cMEMBER OF process XSPICECopyright 1991Georgia Tech Research CorporationAtlanta, Georgia 30332All Rights ReservedPROJECT A-8503AUTHORS    9/12/91  Bill KuhnMODIFICATIONS    <date> <person name> <nature of modifications>SUMMARY    This file contains function EVTdequeue which removes any items on the    output and instance queues with event times matching the specified    simulation time.INTERFACES    void EVTdequeue(CKTcircuit *ckt, double time)REFERENCED FILES    None.NON-STANDARD FEATURES    None.============================================================================*/#include <stdio.h>#include "ngspice.h"#include "cktdefs.h"//#include "util.h"#include "mif.h"#include "evt.h"#include "evtudn.h"#include "evtproto.h"static void EVTdequeue_output(CKTcircuit *ckt, double time);static void EVTdequeue_inst(CKTcircuit *ckt, double time);static void EVTprocess_output(    CKTcircuit  *ckt,    int         output_index,    void        *value);/*EVTdequeueThis function removes any items on the output and instance queueswith event times matching the specified simulation time.  EVTiteris then called to determine which instances need to be called.*/void EVTdequeue(    CKTcircuit  *ckt,      /* The circuit structure */    double      time)      /* The event time of the events to dequeue */{    /* Take all items on output queue with matching time */    /* and set changed flags in output queue */    EVTdequeue_output(ckt, time);    /* Take all items on inst queue with matching time */    /* and set to_call flags in inst queue */    EVTdequeue_inst(ckt, time);}/*EVTdequeue_outputThis function de-queues output events with times matching thespecified time.*/static void EVTdequeue_output(    CKTcircuit  *ckt,          /* The circuit structure */    double      time)          /* The event time of the events to dequeue */{    int         i;    int         j;    int         num_pending;    int         index;    int         output_index;    double      next_time;    double      event_time;    Evt_Output_Queue_t  *output_queue;    Evt_Output_Event_t  *output;    Evt_Output_Event_t  **output_ptr;    /* Get pointers for fast access */    output_queue = &(ckt->evt->queue.output);    /* Exit if nothing pending on output queue or if next_time */    /* != specified time */    if(output_queue->num_pending == 0)        return;    if(output_queue->next_time != time)        return;    /* Scan the list of outputs pending */    num_pending = output_queue->num_pending;    for(i = 0; i < num_pending; i++) {        /* Get the index of the output */        index = output_queue->pending_index[i];        /* Get pointer to next event in queue at this index */        output = *(output_queue->current[index]);        /* If event time does not match current time, skip */        if(output->event_time != time)            continue;        /* It must match, so pull the event from the queue and process it */        EVTprocess_output(ckt, index, output->value);        /* Move current to point to next non-removed item in list */        output_ptr = &(output->next);        output = *output_ptr;        while(output) {            if(! output->removed)                break;            output_ptr = &(output->next);            output = *output_ptr;        }        output_queue->current[index] = output_ptr;        /* Mark that this index in the queue has been modified */        if(! output_queue->modified[index]) {            output_queue->modified[index] = MIF_TRUE;            output_queue->modified_index[(output_queue->num_modified)++] = index;        }    }    /* Update/compact the pending list and update the next_time */    next_time = 1e30;    for(i = 0, j = 0; i < num_pending; i++) {        output_index = output_queue->pending_index[i];        output = *(output_queue->current[output_index]);        /* If nothing in queue at last_step, remove this index from the pending list */        if(! output) {            output_queue->pending[output_index] = MIF_FALSE;            (output_queue->num_pending)--;        }        /* else, keep the index and update the next time */        else {            output_queue->pending_index[j] = output_queue->pending_index[i];            j++;            event_time = output->event_time;            if(event_time < next_time)                next_time = event_time;        }    }    output_queue->next_time = next_time;}/*EVTdequeue_instThis function de-queues instance events with times matching thespecified time.*/void EVTdequeue_inst(    CKTcircuit  *ckt,    /* The circuit structure */    double      time)    /* The event time of the events to dequeue */{    int         i;    int         j;    int         num_pending;    int         index;    int         inst_index;    double      next_time;    double      event_time;    Evt_Inst_Queue_t  *inst_queue;    Evt_Inst_Event_t  *inst;    /* Get pointers for fast access */    inst_queue = &(ckt->evt->queue.inst);    /* Exit if nothing pending on inst queue or if next_time */    /* != specified time */    if(inst_queue->num_pending == 0)        return;    if(inst_queue->next_time != time)        return;    /* Scan the list of insts pending */    num_pending = inst_queue->num_pending;    for(i = 0; i < num_pending; i++) {        /* Get the index of the inst */        index = inst_queue->pending_index[i];        /* Get pointer to next event in queue at this index */        inst = *(inst_queue->current[index]);        /* If event time does not match current time, skip */        if(inst->event_time != time)            continue;        /* It must match, so pull the event from the queue and process it */        if(! inst_queue->to_call[index]) {            inst_queue->to_call[index] = MIF_TRUE;            inst_queue->to_call_index[(inst_queue->num_to_call)++] =                    index;        }        /* Move current to point to next item in list */        inst_queue->current[index] = &(inst->next);        /* Mark that this index in the queue has been modified */        if(! inst_queue->modified[index]) {            inst_queue->modified[index] = MIF_TRUE;            inst_queue->modified_index[(inst_queue->num_modified)++] = index;        }    }    /* Update/compact the pending list and update the next_time */    next_time = 1e30;    for(i = 0, j = 0; i < num_pending; i++) {        inst_index = inst_queue->pending_index[i];        inst = *(inst_queue->current[inst_index]);        /* If nothing in queue at last_step, remove this index from the pending list */        if(! inst) {            inst_queue->pending[inst_index] = MIF_FALSE;            (inst_queue->num_pending)--;        }        /* else, keep the index and update the next time */        else {            inst_queue->pending_index[j] = inst_queue->pending_index[i];            j++;            event_time = inst->event_time;            if(event_time < next_time)                next_time = event_time;        }    }    inst_queue->next_time = next_time;}/*EVTprocess_outputThis function processes a specified output after it is pulledfrom the queue.*/static void EVTprocess_output(    CKTcircuit  *ckt,          /* The circuit structure */    int         output_index,  /* The index of the output to process */    void        *value)        /* The output value */{    int                 num_outputs;    int                 node_index;    int                 udn_index;    int                 output_subindex;    Evt_Output_Info_t   **output_table;    Evt_Node_Info_t     **node_table;    Evt_Node_t          *rhs;    Evt_Node_t          *rhsold;    Evt_Output_Queue_t  *output_queue;    Mif_Boolean_t       equal;    output_table = ckt->evt->info.output_table;    node_table = ckt->evt->info.node_table;    node_index = output_table[output_index]->node_index;    num_outputs = node_table[node_index]->num_outputs;    udn_index = node_table[node_index]->udn_index;    rhs = ckt->evt->data.node->rhs;    rhsold = ckt->evt->data.node->rhsold;    /* Determine if output is different from rhsold value */    /* and copy it to rhs AND rhsold if so */    /* This is somewhat inefficient, but that's the way */    /* we have setup the structures (rhs and rhsold must match)... */    if(num_outputs > 1) {        output_subindex = output_table[output_index]->output_subindex;        (*(g_evt_udn_info[udn_index]->compare))                (value,                rhsold[node_index].output_value[output_subindex],                &equal);        if(! equal) {            (*(g_evt_udn_info[udn_index]->copy))                    (value, rhs[node_index].output_value[output_subindex]);            (*(g_evt_udn_info[udn_index]->copy))                    (value, rhsold[node_index].output_value[output_subindex]);        }    }    else {        (*(g_evt_udn_info[udn_index]->compare))                (value,                rhsold[node_index].node_value,                &equal);        if(! equal) {            (*(g_evt_udn_info[udn_index]->copy))                    (value, rhs[node_index].node_value);            (*(g_evt_udn_info[udn_index]->copy))                    (value, rhsold[node_index].node_value);        }    }    /* If different, put in changed list of output queue */    if(! equal) {        output_queue = &(ckt->evt->queue.output);        if(! output_queue->changed[output_index]) {            output_queue->changed[output_index] = MIF_TRUE;            output_queue->changed_index[(output_queue->num_changed)++] =                    output_index;        }    }}

⌨️ 快捷键说明

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