Add 'esave' command to save only specific event nodes.

Add a prompt for esave/eprint/eprvcd.
This commit is contained in:
Holger Vogt 2022-01-07 11:53:32 +01:00
parent 738ac4863c
commit f0e9a35eb6
8 changed files with 139 additions and 18 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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,

View File

@ -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 */

View File

@ -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(

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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)++;
}