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,
|
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);
|
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 */
|
/* a common prompt routine */
|
||||||
static void common(const char *string, const struct wordlist *wl,
|
static void common(const char *string, const struct wordlist *wl,
|
||||||
const struct comm *command)
|
const struct comm *command)
|
||||||
|
|
@ -129,6 +137,30 @@ static void common(const char *string, const struct wordlist *wl,
|
||||||
} /* end of function common */
|
} /* 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
|
void
|
||||||
outmenuprompt(const char *string)
|
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_let(const wordlist *wl, const struct comm *command);
|
||||||
void arg_set(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_display(const wordlist *wl, const struct comm *command);
|
||||||
|
void arg_enodes(const wordlist *wl, const struct comm *command);
|
||||||
void outmenuprompt(const char *string);
|
void outmenuprompt(const char *string);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -247,13 +247,17 @@ struct comm spcp_coms[] = {
|
||||||
arg_print,
|
arg_print,
|
||||||
"[col] expr ... : Print vector values." } ,
|
"[col] expr ... : Print vector values." } ,
|
||||||
#ifdef XSPICE
|
#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,
|
{ "eprint", EVTprint, FALSE, TRUE,
|
||||||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
||||||
NULL,
|
arg_enodes,
|
||||||
"node node ... : Print event values." } ,
|
"node node ... : Print event values." } ,
|
||||||
{ "eprvcd", EVTprintvcd, FALSE, TRUE,
|
{ "eprvcd", EVTprintvcd, FALSE, TRUE,
|
||||||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
||||||
NULL,
|
arg_enodes,
|
||||||
"node node ... : Print event values into vcd file." },
|
"node node ... : Print event values into vcd file." },
|
||||||
{ "edisplay", EVTdisplay, FALSE, TRUE,
|
{ "edisplay", EVTdisplay, FALSE, TRUE,
|
||||||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 0, 0,
|
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 0, 0,
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ struct Evt_Node_Info {
|
||||||
char *name; /* Name of node in deck */
|
char *name; /* Name of node in deck */
|
||||||
int udn_index; /* Index of the node type */
|
int udn_index; /* Index of the node type */
|
||||||
Mif_Boolean_t invert; /* True if need to make inverted copy */
|
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_ports; /* Number of ports connected to this node */
|
||||||
int num_outputs; /* Number of outputs 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 */
|
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);
|
int EVTload(CKTcircuit *ckt, int inst_index);
|
||||||
|
|
||||||
void EVTprint(wordlist *wl);
|
void EVTprint(wordlist *wl);
|
||||||
|
|
||||||
void EVTprintvcd(wordlist *wl);
|
void EVTprintvcd(wordlist *wl);
|
||||||
|
void EVTsave(wordlist *wl);
|
||||||
void EVTdisplay(wordlist *wl);
|
void EVTdisplay(wordlist *wl);
|
||||||
|
|
||||||
int EVTop(
|
int EVTop(
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ void EVTaccept(
|
||||||
|
|
||||||
Evt_Inst_Queue_t *inst_queue;
|
Evt_Inst_Queue_t *inst_queue;
|
||||||
Evt_Output_Queue_t *output_queue;
|
Evt_Output_Queue_t *output_queue;
|
||||||
|
Evt_Node_Info_t **node_table;
|
||||||
Evt_Node_Data_t *node_data;
|
Evt_Node_Data_t *node_data;
|
||||||
Evt_State_Data_t *state_data;
|
Evt_State_Data_t *state_data;
|
||||||
Evt_Msg_Data_t *msg_data;
|
Evt_Msg_Data_t *msg_data;
|
||||||
|
|
@ -83,7 +83,7 @@ void EVTaccept(
|
||||||
/* Get often used pointers */
|
/* Get often used pointers */
|
||||||
inst_queue = &(ckt->evt->queue.inst);
|
inst_queue = &(ckt->evt->queue.inst);
|
||||||
output_queue = &(ckt->evt->queue.output);
|
output_queue = &(ckt->evt->queue.output);
|
||||||
|
node_table = ckt->evt->info.node_table;
|
||||||
node_data = ckt->evt->data.node;
|
node_data = ckt->evt->data.node;
|
||||||
state_data = ckt->evt->data.state;
|
state_data = ckt->evt->data.state;
|
||||||
msg_data = ckt->evt->data.msg;
|
msg_data = ckt->evt->data.msg;
|
||||||
|
|
@ -161,10 +161,25 @@ void EVTaccept(
|
||||||
for(i = 0; i < num_modified; i++) {
|
for(i = 0; i < num_modified; i++) {
|
||||||
/* Get the index of the node modified */
|
/* Get the index of the node modified */
|
||||||
index = node_data->modified_index[i];
|
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 */
|
/* Reset the modified flag */
|
||||||
node_data->modified[index] = MIF_FALSE;
|
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 */
|
/* Reset number modified to zero */
|
||||||
node_data->num_modified = 0;
|
node_data->num_modified = 0;
|
||||||
|
|
|
||||||
|
|
@ -413,12 +413,15 @@ EVTdisplay(wordlist *wl)
|
||||||
out_printf("No event node available!\n");
|
out_printf("No event node available!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!ckt->evt->jobs.job_plot) {
|
if (ckt->evt->jobs.job_plot) {
|
||||||
out_printf("No event job run, no data available!\n");
|
out_printf("\nList of event nodes in plot %s\n",
|
||||||
return;
|
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",
|
||||||
out_printf(" %-20s: %-5s, %s\n\n", "node name", "type", "number of events");
|
"node name", "type", "number of events");
|
||||||
|
|
||||||
node_index = 0;
|
node_index = 0;
|
||||||
while (node) {
|
while (node) {
|
||||||
Evt_Node_t *node_data = NULL;
|
Evt_Node_t *node_data = NULL;
|
||||||
|
|
@ -426,11 +429,12 @@ EVTdisplay(wordlist *wl)
|
||||||
char *type;
|
char *type;
|
||||||
|
|
||||||
udn_index = node_table[node_index]->udn_index;
|
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];
|
node_data = ckt->evt->data.node->head[node_index];
|
||||||
while (node_data) {
|
while (node_data) {
|
||||||
count++;
|
count++;
|
||||||
node_data = node_data->next;
|
node_data = node_data->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
type = g_evt_udn_info[udn_index]->name;
|
type = g_evt_udn_info[udn_index]->name;
|
||||||
out_printf(" %-20s: %-5s, %5d\n", node->name, type, count);
|
out_printf(" %-20s: %-5s, %5d\n", node->name, type, count);
|
||||||
|
|
@ -710,3 +714,67 @@ EVTprintvcd(wordlist *wl)
|
||||||
|
|
||||||
out_printf("\n\n");
|
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->next = NULL;
|
||||||
node->name = MIFcopy(node_name);
|
node->name = MIFcopy(node_name);
|
||||||
node->udn_index = udn_index;
|
node->udn_index = udn_index;
|
||||||
|
node->save = MIF_TRUE; /* Backward compatible behaviour: save all. */
|
||||||
index = ckt->evt->counts.num_nodes;
|
index = ckt->evt->counts.num_nodes;
|
||||||
(ckt->evt->counts.num_nodes)++;
|
(ckt->evt->counts.num_nodes)++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue