Add 'esave' command to save only specific event nodes.
Add a prompt for esave/eprint/eprvcd.
This commit is contained in:
parent
738ac4863c
commit
f0e9a35eb6
|
|
@ -18,7 +18,9 @@ Author: 1987 Jeffrey M. Hsu
|
|||
|
||||
|
||||
static void common(const char *string, const struct wordlist *wl,
|
||||
const struct comm *command);
|
||||
const struct comm *command);
|
||||
static void common_list(const char *string, const struct wordlist *wl,
|
||||
const struct comm *command);
|
||||
static int countargs(const wordlist *wl);
|
||||
|
||||
|
||||
|
|
@ -108,6 +110,12 @@ void arg_display(const wordlist *wl, const struct comm *command)
|
|||
}
|
||||
|
||||
|
||||
void arg_enodes(const wordlist *wl, const struct comm *command)
|
||||
{
|
||||
common_list("which event nodes", wl, command);
|
||||
}
|
||||
|
||||
|
||||
/* a common prompt routine */
|
||||
static void common(const char *string, const struct wordlist *wl,
|
||||
const struct comm *command)
|
||||
|
|
@ -129,6 +137,30 @@ static void common(const char *string, const struct wordlist *wl,
|
|||
} /* end of function common */
|
||||
|
||||
|
||||
/* A common prompt routine for commands that take a list. */
|
||||
static void common_list(const char *string, const struct wordlist *wl,
|
||||
const struct comm *command)
|
||||
{
|
||||
struct wordlist *w;
|
||||
char *buf;
|
||||
|
||||
if (!countargs(wl)) {
|
||||
outmenuprompt(string);
|
||||
if ((buf = prompt(cp_in)) == NULL) /* prompt aborted */
|
||||
return; /* don't execute command */
|
||||
/* do something with the wordlist */
|
||||
w = cp_lexer(buf);
|
||||
if (!w)
|
||||
return;
|
||||
if (w->wl_word) {
|
||||
/* O.K. now call fn */
|
||||
command->co_func(w);
|
||||
}
|
||||
wl_free(w);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
outmenuprompt(const char *string)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ void arg_load(const wordlist *wl, const struct comm *command);
|
|||
void arg_let(const wordlist *wl, const struct comm *command);
|
||||
void arg_set(const wordlist *wl, const struct comm *command);
|
||||
void arg_display(const wordlist *wl, const struct comm *command);
|
||||
void arg_enodes(const wordlist *wl, const struct comm *command);
|
||||
void outmenuprompt(const char *string);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -247,13 +247,17 @@ struct comm spcp_coms[] = {
|
|||
arg_print,
|
||||
"[col] expr ... : Print vector values." } ,
|
||||
#ifdef XSPICE
|
||||
{ "esave", EVTsave, FALSE, TRUE,
|
||||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
||||
arg_enodes,
|
||||
"all | none | node node ... : Save event values." } ,
|
||||
{ "eprint", EVTprint, FALSE, TRUE,
|
||||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
||||
NULL,
|
||||
arg_enodes,
|
||||
"node node ... : Print event values." } ,
|
||||
{ "eprvcd", EVTprintvcd, FALSE, TRUE,
|
||||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
||||
NULL,
|
||||
arg_enodes,
|
||||
"node node ... : Print event values into vcd file." },
|
||||
{ "edisplay", EVTdisplay, FALSE, TRUE,
|
||||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 0, 0,
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ struct Evt_Node_Info {
|
|||
char *name; /* Name of node in deck */
|
||||
int udn_index; /* Index of the node type */
|
||||
Mif_Boolean_t invert; /* True if need to make inverted copy */
|
||||
Mif_Boolean_t save; /* Save data for this node */
|
||||
int num_ports; /* Number of ports connected to this node */
|
||||
int num_outputs; /* Number of outputs connected to this node */
|
||||
int num_insts; /* The number of insts receiving node as input */
|
||||
|
|
|
|||
|
|
@ -95,9 +95,8 @@ void EVTdequeue(CKTcircuit *ckt, double time);
|
|||
int EVTload(CKTcircuit *ckt, int inst_index);
|
||||
|
||||
void EVTprint(wordlist *wl);
|
||||
|
||||
void EVTprintvcd(wordlist *wl);
|
||||
|
||||
void EVTsave(wordlist *wl);
|
||||
void EVTdisplay(wordlist *wl);
|
||||
|
||||
int EVTop(
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ void EVTaccept(
|
|||
|
||||
Evt_Inst_Queue_t *inst_queue;
|
||||
Evt_Output_Queue_t *output_queue;
|
||||
|
||||
Evt_Node_Info_t **node_table;
|
||||
Evt_Node_Data_t *node_data;
|
||||
Evt_State_Data_t *state_data;
|
||||
Evt_Msg_Data_t *msg_data;
|
||||
|
|
@ -83,7 +83,7 @@ void EVTaccept(
|
|||
/* Get often used pointers */
|
||||
inst_queue = &(ckt->evt->queue.inst);
|
||||
output_queue = &(ckt->evt->queue.output);
|
||||
|
||||
node_table = ckt->evt->info.node_table;
|
||||
node_data = ckt->evt->data.node;
|
||||
state_data = ckt->evt->data.state;
|
||||
msg_data = ckt->evt->data.msg;
|
||||
|
|
@ -161,10 +161,25 @@ void EVTaccept(
|
|||
for(i = 0; i < num_modified; i++) {
|
||||
/* Get the index of the node modified */
|
||||
index = node_data->modified_index[i];
|
||||
/* Update last_step for this index */
|
||||
node_data->last_step[index] = node_data->tail[index];
|
||||
/* Reset the modified flag */
|
||||
node_data->modified[index] = MIF_FALSE;
|
||||
|
||||
if (node_table[index]->save) {
|
||||
/* Update last_step for this index */
|
||||
node_data->last_step[index] = node_data->tail[index];
|
||||
} else {
|
||||
Evt_Node_t *keep;
|
||||
|
||||
/* If not recording history, discard all but the last item.
|
||||
* It may be needed to restore the previous state on backup.
|
||||
*/
|
||||
keep = *(node_data->tail[index]);
|
||||
*(node_data->tail[index]) = node_data->free[index];
|
||||
node_data->free[index] = node_data->head[index];
|
||||
node_data->head[index] = keep;
|
||||
node_data->last_step[index] = node_data->tail[index] =
|
||||
&node_data->head[index];
|
||||
}
|
||||
}
|
||||
/* Reset number modified to zero */
|
||||
node_data->num_modified = 0;
|
||||
|
|
|
|||
|
|
@ -413,12 +413,15 @@ EVTdisplay(wordlist *wl)
|
|||
out_printf("No event node available!\n");
|
||||
return;
|
||||
}
|
||||
if (!ckt->evt->jobs.job_plot) {
|
||||
out_printf("No event job run, no data available!\n");
|
||||
return;
|
||||
if (ckt->evt->jobs.job_plot) {
|
||||
out_printf("\nList of event nodes in plot %s\n",
|
||||
ckt->evt->jobs.job_plot[ckt->evt->jobs.cur_job]);
|
||||
} else {
|
||||
out_printf("\nList of event nodes\n");
|
||||
}
|
||||
out_printf("\nList of event nodes in plot %s\n", ckt->evt->jobs.job_plot[ckt->evt->jobs.cur_job]);
|
||||
out_printf(" %-20s: %-5s, %s\n\n", "node name", "type", "number of events");
|
||||
out_printf(" %-20s: %-5s, %s\n\n",
|
||||
"node name", "type", "number of events");
|
||||
|
||||
node_index = 0;
|
||||
while (node) {
|
||||
Evt_Node_t *node_data = NULL;
|
||||
|
|
@ -426,11 +429,12 @@ EVTdisplay(wordlist *wl)
|
|||
char *type;
|
||||
|
||||
udn_index = node_table[node_index]->udn_index;
|
||||
if (ckt->evt->data.node)
|
||||
if (ckt->evt->data.node) {
|
||||
node_data = ckt->evt->data.node->head[node_index];
|
||||
while (node_data) {
|
||||
count++;
|
||||
node_data = node_data->next;
|
||||
while (node_data) {
|
||||
count++;
|
||||
node_data = node_data->next;
|
||||
}
|
||||
}
|
||||
type = g_evt_udn_info[udn_index]->name;
|
||||
out_printf(" %-20s: %-5s, %5d\n", node->name, type, count);
|
||||
|
|
@ -710,3 +714,67 @@ EVTprintvcd(wordlist *wl)
|
|||
|
||||
out_printf("\n\n");
|
||||
}
|
||||
|
||||
/* Mark event nodes whose data should be saved for printing.
|
||||
* By default, all nodes are saved, so initial "none" clears.
|
||||
*/
|
||||
|
||||
static void set_all(CKTcircuit *ckt, Mif_Boolean_t val)
|
||||
{
|
||||
int i, count;
|
||||
Evt_Node_Info_t **node_table;
|
||||
|
||||
count = ckt->evt->counts.num_nodes;
|
||||
node_table = ckt->evt->info.node_table;
|
||||
for (i = 0; i < count; i++)
|
||||
node_table[i]->save = val;
|
||||
}
|
||||
|
||||
void
|
||||
EVTsave(wordlist *wl)
|
||||
{
|
||||
int i;
|
||||
Mif_Boolean_t save;
|
||||
wordlist *w;
|
||||
CKTcircuit *ckt;
|
||||
Evt_Node_Info_t **node_table;
|
||||
|
||||
if (wl == NULL) {
|
||||
printf("Usage: esave all | none | <node1> <node2> ...\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get needed pointers. */
|
||||
|
||||
ckt = g_mif_info.ckt;
|
||||
if (!ckt) {
|
||||
fprintf(cp_err, "Error: no circuit loaded.\n");
|
||||
return;
|
||||
}
|
||||
node_table = ckt->evt->info.node_table;
|
||||
|
||||
/* Deal with "all" and "none". */
|
||||
|
||||
save = MIF_FALSE;
|
||||
if (wl->wl_next == NULL &&
|
||||
(!strcmp("none", wl->wl_word) ||
|
||||
(save = !strcmp("all", wl->wl_word)))) {
|
||||
set_all(ckt, save);
|
||||
return;
|
||||
}
|
||||
|
||||
set_all(ckt, MIF_FALSE); /* Clear previous settings. */
|
||||
|
||||
/* Set save flag for each argument */
|
||||
|
||||
for (w = wl; w; w = w->wl_next) {
|
||||
i = get_index(w->wl_word);
|
||||
if (i < 0) {
|
||||
fprintf(cp_err, "ERROR - Node %s is not an event node.\n",
|
||||
w->wl_word);
|
||||
return;
|
||||
}
|
||||
// node_table[i]->save = MIF_FALSE;
|
||||
node_table[i]->save = MIF_TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -329,6 +329,7 @@ static void EVTnode_insert(
|
|||
node->next = NULL;
|
||||
node->name = MIFcopy(node_name);
|
||||
node->udn_index = udn_index;
|
||||
node->save = MIF_TRUE; /* Backward compatible behaviour: save all. */
|
||||
index = ckt->evt->counts.num_nodes;
|
||||
(ckt->evt->counts.num_nodes)++;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue