📄 cmevt.c
字号:
/* ===========================================================================
FILE CMevt.c
MEMBER OF process XSPICE
Copyright 1991
Georgia Tech Research Corporation
Atlanta, Georgia 30332
All Rights Reserved
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains functions callable from user code models
that are associated with the event-driven algorithm.
INTERFACES
cm_event_alloc()
cm_event_get_ptr()
cm_event_queue()
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
=========================================================================== */
#include "ngspice.h"
#include "cktdefs.h"
//#include "util.h"
#include "cm.h"
#include "mif.h"
#include "evt.h"
#include "evtproto.h"
/*
cm_event_alloc()
This function is called from code model C functions to allocate
state storage for a particular event-driven
instance. It is similar to the
function cm_analog_alloc() used by analog models, but allocates states
that are rotated during event-driven 'timesteps' instead of analog
timesteps.
*/
void *cm_event_alloc(
int tag, /* The user-specified tag for the memory block */
int bytes) /* The number of bytes to be allocated */
{
int inst_index;
int num_tags;
MIFinstance *here;
CKTcircuit *ckt;
void *ptr;
Evt_State_Desc_t **desc_ptr;
Evt_State_Desc_t *desc;
Evt_State_Data_t *state_data;
Evt_State_t *state;
/* Get the address of the ckt and instance structs from g_mif_info */
here = g_mif_info.instance;
ckt = g_mif_info.ckt;
/* If not initialization pass, return error */
if(here->initialized) {
g_mif_info.errmsg =
"ERROR - cm_event_alloc() - Cannot alloc when not initialization pass\n";
return(NULL);
}
/* Get pointers for fast access */
inst_index = here->inst_index;
state_data = ckt->evt->data.state;
/* Scan state descriptor list to determine if tag is present and to */
/* find the end of the list. Report error if duplicate tag */
desc_ptr = &(state_data->desc[inst_index]);
desc = *desc_ptr;
num_tags = 1;
while(desc) {
if(desc->tag == tag) {
g_mif_info.errmsg =
"ERROR - cm_event_alloc() - Duplicate tag\n";
return(NULL);
}
desc_ptr = &(desc->next);
desc = *desc_ptr;
num_tags++;
}
/* Create a new state description structure at end of list */
/* and fill in the data and update the total size */
*desc_ptr = (void *) MALLOC(sizeof(Evt_State_Desc_t));
desc = *desc_ptr;
desc->tag = tag;
desc->size = bytes;
desc->offset = state_data->total_size[inst_index];
state_data->total_size[inst_index] += bytes;
/* Create a new state structure if list starting at head is null */
state = state_data->head[inst_index];
if(state == NULL) {
state = (void *) MALLOC(sizeof(Evt_State_t));
state_data->head[inst_index] = state;
}
/* Create or enlarge the block and set the time */
if(num_tags == 1)
state->block = MALLOC(state_data->total_size[inst_index]);
else
state->block = REALLOC(state->block,
state_data->total_size[inst_index]);
state->step = g_mif_info.circuit.evt_step;
/* Return allocated memory */
ptr = ((char *)state->block) + desc->offset;
return(ptr);
}
/*
cm_event_get_ptr()
This function is called from code model C functions to return a
pointer to state storage allocated with cm_event_alloc(). A tag
specified in its argument list is used to locate the state in
question. A second argument specifies whether the desired state
is for the current timestep or from a preceding timestep. The
location of the state in memory is then computed and returned.
*/
void *cm_event_get_ptr(
int tag, /* The user-specified tag for the memory block */
int timepoint) /* The timepoint - 0=current, 1=previous */
{
int i;
int inst_index;
MIFinstance *here;
CKTcircuit *ckt;
void *ptr;
Evt_State_Desc_t *desc;
Evt_State_Data_t *state_data;
Evt_State_t *state;
/* Get the address of the ckt and instance structs from g_mif_info */
here = g_mif_info.instance;
ckt = g_mif_info.ckt;
/* If initialization pass, return error */
if((! here->initialized) && (timepoint > 0)) {
g_mif_info.errmsg =
"ERROR - cm_event_get_ptr() - Cannot get_ptr(tag,1) during initialization pass\n";
return(NULL);
}
/* Get pointers for fast access */
inst_index = here->inst_index;
state_data = ckt->evt->data.state;
/* Scan state descriptor list to find the descriptor for this tag. */
/* Report error if tag not found */
desc = state_data->desc[inst_index];
while(desc) {
if(desc->tag == tag)
break;
desc = desc->next;
}
if(desc == NULL) {
g_mif_info.errmsg =
"ERROR - cm_event_get_ptr() - Specified tag not found\n";
return(NULL);
}
/* Get the state pointer from the current array */
state = *(state_data->tail[inst_index]);
/* Backup the specified number of timesteps */
for(i = 0; i < timepoint; i++)
if(state->prev)
state = state->prev;
/* Return pointer */
ptr = ((char *) state->block) + desc->offset;
return(ptr);
}
/*
cm_event_queue()
This function queues an event for an instance participating
in the event-driven algorithm.
*/
int cm_event_queue(
double time) /* The time of the event to be queued */
{
MIFinstance *here;
CKTcircuit *ckt;
/* Get the address of the ckt and instance structs from g_mif_info */
here = g_mif_info.instance;
ckt = g_mif_info.ckt;
/* If breakpoint time <= current event time, return error */
if(time <= g_mif_info.circuit.evt_step) {
g_mif_info.errmsg =
"ERROR - cm_event_queue() - Event time cannot be <= current time\n";
return(MIF_ERROR);
}
/* Add the event time to the inst queue */
EVTqueue_inst(ckt, here->inst_index, g_mif_info.circuit.evt_step,
time);
return(MIF_OK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -