caching simulation data into "simdata" struct for performance
This commit is contained in:
parent
14ead18ea4
commit
a9d7d93e40
|
|
@ -1470,8 +1470,8 @@ void draw(void)
|
|||
struct instentry *instanceptr;
|
||||
struct wireentry *wireptr;
|
||||
int use_hash;
|
||||
register int c,i;
|
||||
register xSymbol *symptr;
|
||||
int c, i = 0;
|
||||
xSymbol *symptr;
|
||||
int textlayer;
|
||||
|
||||
#if HAS_CAIRO==1
|
||||
|
|
|
|||
116
src/hilight.c
116
src/hilight.c
|
|
@ -24,9 +24,9 @@
|
|||
|
||||
static unsigned int hi_hash(const char *tok)
|
||||
{
|
||||
unsigned int hash = 0;
|
||||
char *str;
|
||||
int c;
|
||||
register int hash = 0;
|
||||
register char *str;
|
||||
register int c;
|
||||
|
||||
str=xctx->sch_path[xctx->currsch];
|
||||
while ( (c = *tok++) )
|
||||
|
|
@ -868,13 +868,12 @@ int get_logic_value(int inst, int n)
|
|||
{
|
||||
int /* mult, */ val;
|
||||
struct hilight_hashentry *entry;
|
||||
char *netname = NULL;
|
||||
/* char *netname = NULL; */
|
||||
|
||||
/* fast option: dont use net_name() (no expandlabel though) */
|
||||
/* THIS MUST BE DONE TO HANDLE VECTOR INSTANCES/BUSES */
|
||||
/* my_strdup(xxxx, &netname, net_name(inst, n, &mult, 1, 0)); */
|
||||
my_strdup(1219, &netname, xctx->inst[inst].node[n]);
|
||||
entry=bus_hilight_lookup(netname, 0, XLOOKUP);
|
||||
entry=hilight_lookup(xctx->inst[inst].node[n], 0, XLOOKUP);
|
||||
if(!entry) {
|
||||
val = 2; /* LOGIC_X */
|
||||
} else {
|
||||
|
|
@ -882,9 +881,10 @@ int get_logic_value(int inst, int n)
|
|||
val = (val == LOGIC_0) ? 0 : (val == LOGIC_1) ? 1 : 2;
|
||||
/* dbg(1, "get_logic_value(): inst=%d pin=%d net=%s val=%d\n", inst, n, netname, val); */
|
||||
}
|
||||
my_free(1221, &netname);
|
||||
/* my_free(xxxx, &netname); */
|
||||
return val;
|
||||
}
|
||||
|
||||
void print_stack(int *stack, int sp)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -904,11 +904,9 @@ int eval_logic_expr(int inst, int output)
|
|||
char *ptr2;
|
||||
char *arg;
|
||||
int res = 0;
|
||||
char function[20];
|
||||
|
||||
my_snprintf(function, S(function), "function%d", output);
|
||||
my_strdup(1218, &saveptr, get_tok_value((xctx->inst[inst].ptr + xctx->sym)->prop_ptr, function, 0));
|
||||
dbg(1, "eval_logic_expr(): function=%s, saveptr=%s\n", function, saveptr ? saveptr : "NULL");
|
||||
my_strdup(827, &saveptr, xctx->simdata.inst[inst].pin[output].function);
|
||||
dbg(1, "eval_logic_expr(): inst=%d pin=%d function=%s\n", inst, output, saveptr ? saveptr : "NULL");
|
||||
if(!saveptr) return 2; /* no logic function defined, return LOGIC_X */
|
||||
ptr2 = saveptr;
|
||||
while( (arg = my_strtok_r(ptr2, " ", &ptr1)) ) {
|
||||
|
|
@ -918,13 +916,13 @@ int eval_logic_expr(int inst, int output)
|
|||
stack[sp] = stack[sp - 1];
|
||||
sp++;
|
||||
}
|
||||
} else if(arg[0] == '~') {
|
||||
} else if(arg[0] == '~') { /* negation operator */
|
||||
if(sp > 0) {
|
||||
sp--;
|
||||
if(stack[sp] != 2) stack[sp] = !stack[sp];
|
||||
++sp;
|
||||
}
|
||||
} else if(arg[0] == '|') {
|
||||
} else if(arg[0] == '|') { /* or operator */
|
||||
if(sp > 1) {
|
||||
res = 0;
|
||||
for(i = sp - 2; i < sp; i++) {
|
||||
|
|
@ -938,7 +936,7 @@ int eval_logic_expr(int inst, int output)
|
|||
stack[sp - 2] = res;
|
||||
sp--;
|
||||
}
|
||||
} else if(arg[0] == '&') {
|
||||
} else if(arg[0] == '&') { /* and operator */
|
||||
if(sp > 1) {
|
||||
res = 1;
|
||||
for(i = sp - 2; i < sp; i++) {
|
||||
|
|
@ -952,7 +950,7 @@ int eval_logic_expr(int inst, int output)
|
|||
stack[sp - 2] = res;
|
||||
sp--;
|
||||
}
|
||||
} else if(arg[0] == '^') {
|
||||
} else if(arg[0] == '^') { /* xor operator */
|
||||
if(sp > 1) {
|
||||
res = 0;
|
||||
for(i = sp - 2; i < sp; i++) {
|
||||
|
|
@ -982,19 +980,63 @@ int eval_logic_expr(int inst, int output)
|
|||
else dbg(0, "eval_logic_expr(): stack overflow!\n");
|
||||
}
|
||||
}
|
||||
my_free(827, &saveptr);
|
||||
my_free(1218, &saveptr);
|
||||
dbg(1, "eval_logic_expr(): inst %d output %d, returning %d\n", inst, output, stack[0]);
|
||||
return stack[0];
|
||||
}
|
||||
|
||||
void create_simdata(void)
|
||||
{
|
||||
int i, j;
|
||||
const char *str;
|
||||
free_simdata();
|
||||
xctx->simdata.inst = NULL;
|
||||
my_realloc(60, &xctx->simdata.inst, xctx->instances * sizeof(struct simdata_inst));
|
||||
xctx->simdata.ninst = xctx->instances;
|
||||
for(i = 0; i < xctx->instances; i++) {
|
||||
xSymbol *symbol = xctx->inst[i].ptr + xctx->sym;
|
||||
int npin = symbol->rects[PINLAYER];
|
||||
xctx->simdata.inst[i].pin = NULL;
|
||||
my_realloc(61, &xctx->simdata.inst[i].pin, npin * sizeof(struct simdata_pin));
|
||||
xctx->simdata.inst[i].npin = npin;
|
||||
for(j = 0; j < npin; j++) {
|
||||
char function[20];
|
||||
xctx->simdata.inst[i].pin[j].function=NULL;
|
||||
xctx->simdata.inst[i].pin[j].go_to=NULL;
|
||||
xctx->simdata.inst[i].pin[j].value=2;
|
||||
my_snprintf(function, S(function), "function%d", j);
|
||||
my_strdup(717, &xctx->simdata.inst[i].pin[j].function, get_tok_value(symbol->prop_ptr, function, 0));
|
||||
my_strdup(963, &xctx->simdata.inst[i].pin[j].go_to, get_tok_value(symbol->rect[PINLAYER][j].prop_ptr, "goto", 0));
|
||||
str = get_tok_value(symbol->rect[PINLAYER][j].prop_ptr, "clock", 0);
|
||||
xctx->simdata.inst[i].pin[j].clock = str[0] ? str[0] - '0' : -1;
|
||||
}
|
||||
}
|
||||
xctx->simdata.valid = 1;
|
||||
}
|
||||
|
||||
void free_simdata(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if(xctx->simdata.inst) {
|
||||
for(i = 0; i < xctx->simdata.ninst; i++) {
|
||||
int npin = xctx->simdata.inst[i].npin;
|
||||
for(j = 0; j < npin; j++) {
|
||||
my_free(1219, &xctx->simdata.inst[i].pin[j].function);
|
||||
my_free(1220, &xctx->simdata.inst[i].pin[j].go_to);
|
||||
}
|
||||
my_free(1221, &xctx->simdata.inst[i].pin);
|
||||
}
|
||||
my_free(1222, &xctx->simdata.inst);
|
||||
}
|
||||
xctx->simdata.valid = 0;
|
||||
}
|
||||
|
||||
void propagate_logic()
|
||||
{
|
||||
char *propagated_net=NULL;
|
||||
/* char *propagated_net=NULL; */
|
||||
int found /* , mult */;
|
||||
xSymbol *symbol;
|
||||
xRect *rct;
|
||||
int i, j, npin;
|
||||
char *propagate_str = NULL;
|
||||
int propagate;
|
||||
struct hilight_hashentry *entry;
|
||||
int val, oldval;
|
||||
|
|
@ -1004,20 +1046,18 @@ void propagate_logic()
|
|||
prepare_netlist_structs(0);
|
||||
while(1) {
|
||||
found=0;
|
||||
for(i=0; i<xctx->instances;i++) {
|
||||
symbol = xctx->inst[i].ptr+xctx->sym;
|
||||
npin = symbol->rects[PINLAYER];
|
||||
rct=symbol->rect[PINLAYER];
|
||||
for(i=0; i<xctx->simdata.ninst; i++) {
|
||||
npin = xctx->simdata.inst[i].npin;
|
||||
for(j=0; j<npin;j++) {
|
||||
my_strdup(1223, &propagate_str, get_tok_value(rct[j].prop_ptr, "goto", 0));
|
||||
if(propagate_str) {
|
||||
if(xctx->simdata.inst && xctx->simdata.inst[i].pin && xctx->simdata.inst[i].pin[j].go_to) {
|
||||
/* if(xctx->simdata.inst[i].pin[j].go_to) { */
|
||||
int n = 1;
|
||||
const char *propag;
|
||||
int clock_pin, clock_val, clock_oldval;
|
||||
const char *clock = get_tok_value(rct[j].prop_ptr, "clock", 0);
|
||||
clock_pin = clock[0] ? clock[0] - '0' : -1;
|
||||
clock_pin = xctx->simdata.inst[i].pin[j].clock;
|
||||
if(clock_pin != -1) {
|
||||
entry = bus_hilight_lookup(xctx->inst[i].node[j], 0, XLOOKUP); /* clock pin */
|
||||
/* no bus_hilight_lookup --> no bus expansion */
|
||||
entry = hilight_lookup(xctx->inst[i].node[j], 0, XLOOKUP); /* clock pin */
|
||||
clock_val = (!entry) ? LOGIC_X : entry->value;
|
||||
clock_oldval = (!entry) ? LOGIC_X : entry->oldvalue;
|
||||
if(entry) {
|
||||
|
|
@ -1036,35 +1076,35 @@ void propagate_logic()
|
|||
}
|
||||
}
|
||||
}
|
||||
dbg(1, "propagate_logic(): inst=%d propagate_str=%s\n", i, propagate_str);
|
||||
dbg(1, "propagate_logic(): inst=%d pin %d, goto=%s\n", i,j, xctx->simdata.inst[i].pin[j].go_to);
|
||||
while(1) {
|
||||
propag = find_nth(propagate_str, ',', n);
|
||||
propag = find_nth(xctx->simdata.inst[i].pin[j].go_to, ',', n);
|
||||
n++;
|
||||
if(!propag[0]) break;
|
||||
propagate = atoi(propag);
|
||||
if(propagate < 0 || propagate >= npin) {
|
||||
dbg(0, "Error: inst: %s, pin %d, goto set to %s <<%d>>\n",
|
||||
xctx->inst[i].instname, j, propagate_str, propagate);
|
||||
xctx->inst[i].instname, j, xctx->simdata.inst[i].pin[j].go_to, propagate);
|
||||
continue;
|
||||
}
|
||||
if(!xctx->inst[i].node[propagate]) {
|
||||
dbg(0, "Error: inst %s, output in %d unconnected\n", xctx->inst[i].instname, propagate);
|
||||
dbg(1, "Error: inst %s, output in %d unconnected\n", xctx->inst[i].instname, propagate);
|
||||
break;
|
||||
}
|
||||
/* get net to propagate hilight to...*/
|
||||
/* fast option: dont use net_name() (no expandlabel though) */
|
||||
/* THIS MUST BE DONE TO HANDLE VECTOR INSTANCES/BUSES */
|
||||
/* my_strdup(xxx, &propagated_net, net_name(i, propagate, &mult, 1, 0)); */
|
||||
my_strdup(1220, &propagated_net, xctx->inst[i].node[propagate]);
|
||||
/* dbg(1, "propagate_logic(): inst %d pin %d propag=%s n=%d\n", i, j, propag, n);
|
||||
* dbg(1, "propagate_logic(): inst %d pin %d propagate=%d\n", i, j, propagate);
|
||||
* dbg(1, "propagate_logic(): propagated_net=%s\n", propagated_net); */
|
||||
/* add net to highlight list */
|
||||
entry = bus_hilight_lookup(propagated_net, 0, XLOOKUP); /* destination pin */
|
||||
/* no bus_hilight_lookup --> no bus expansion */
|
||||
entry = hilight_lookup(xctx->inst[i].node[propagate], 0, XLOOKUP); /* destination pin */
|
||||
oldval = (!entry) ? LOGIC_X : entry->value;
|
||||
val = map[eval_logic_expr(i, propagate)];
|
||||
if(oldval != val) {
|
||||
bus_hilight_lookup(propagated_net, val, XINSERT);
|
||||
hilight_lookup(xctx->inst[i].node[propagate], val, XINSERT);
|
||||
found=1; /* keep looping until no more nets are found. */
|
||||
}
|
||||
}
|
||||
|
|
@ -1077,8 +1117,7 @@ void propagate_logic()
|
|||
Tcl_VarEval(interp, "update; if {$::tclstop == 1} {return 1} else {return 0}", NULL);
|
||||
if( tclresult()[0] == '1') break;
|
||||
} /* while(1) */
|
||||
my_free(1224, &propagate_str);
|
||||
my_free(1222, &propagated_net);
|
||||
/* my_free(1222, &propagated_net); */
|
||||
}
|
||||
|
||||
void logic_set(int value, int num)
|
||||
|
|
@ -1091,6 +1130,7 @@ void logic_set(int value, int num)
|
|||
struct hilight_hashentry *entry;
|
||||
|
||||
prepare_netlist_structs(0);
|
||||
if(!xctx->simdata.valid) create_simdata();
|
||||
rebuild_selected_array();
|
||||
newval = value;
|
||||
if(!no_draw && !big) {
|
||||
|
|
|
|||
|
|
@ -646,6 +646,7 @@ void prepare_netlist_structs(int for_netlist)
|
|||
else if (!for_netlist && xctx->prep_hi_structs) return;
|
||||
/* delete instance pins spatial hash, wires spatial hash, node_hash, wires and inst nodes.*/
|
||||
else delete_netlist_structs();
|
||||
xctx->simdata.valid = 0;
|
||||
dbg(1, "prepare_netlist_structs(): extraction\n");
|
||||
if(netlist_count == 0 ) startlevel = xctx->currsch;
|
||||
print_erc = netlist_count == 0 || startlevel < xctx->currsch;
|
||||
|
|
|
|||
|
|
@ -327,6 +327,7 @@ void free_xschem_data()
|
|||
{
|
||||
int i;
|
||||
delete_undo();
|
||||
free_simdata();
|
||||
my_free(1098, &xctx->wire);
|
||||
my_free(1100, &xctx->text);
|
||||
my_free(1107, &xctx->inst);
|
||||
|
|
@ -405,6 +406,9 @@ void alloc_xschem_data()
|
|||
xctx->maxsel = 0;
|
||||
xctx->prep_net_structs = 0;
|
||||
xctx->prep_hi_structs = 0;
|
||||
xctx->simdata.inst = NULL;
|
||||
xctx->simdata.ninst = 0;
|
||||
xctx->simdata.valid = 0;
|
||||
xctx->prep_hash_inst = 0;
|
||||
xctx->prep_hash_wires = 0;
|
||||
xctx->modified = 0;
|
||||
|
|
|
|||
22
src/xschem.h
22
src/xschem.h
|
|
@ -476,6 +476,24 @@ typedef struct
|
|||
double zoom;
|
||||
} Zoom;
|
||||
|
||||
struct simdata_pin {
|
||||
char *function;
|
||||
char *go_to;
|
||||
short clock;
|
||||
int value;
|
||||
};
|
||||
|
||||
struct simdata_inst {
|
||||
struct simdata_pin *pin;
|
||||
int npin;
|
||||
};
|
||||
|
||||
struct simdata {
|
||||
struct simdata_inst *inst;
|
||||
int ninst;
|
||||
int valid;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
xWire *wire;
|
||||
xText *text;
|
||||
|
|
@ -534,6 +552,7 @@ typedef struct {
|
|||
int prep_hi_structs;
|
||||
int prep_hash_inst;
|
||||
int prep_hash_wires;
|
||||
struct simdata simdata;
|
||||
int modified;
|
||||
int semaphore;
|
||||
int get_tok_size;
|
||||
|
|
@ -822,6 +841,7 @@ extern void saveas(const char *f, int type);
|
|||
extern const char *get_file_path(char *f);
|
||||
extern int save(int confirm);
|
||||
extern struct hilight_hashentry *bus_hilight_lookup(const char *token, int value, int what) ;
|
||||
extern struct hilight_hashentry *hilight_lookup(const char *token, int value, int what);
|
||||
extern int name_strcmp(char *s, char *d) ;
|
||||
extern int search(const char *tok, const char *val, int sub, int sel);
|
||||
extern int process_options(int argc, char **argv);
|
||||
|
|
@ -1121,6 +1141,8 @@ extern void display_hilights(char **str);
|
|||
extern void redraw_hilights(void);
|
||||
extern void override_netlist_type(int type);
|
||||
extern void prepare_netlist_structs(int for_netlist);
|
||||
extern void create_simdata(void);
|
||||
extern void free_simdata(void);
|
||||
extern void delete_netlist_structs(void);
|
||||
extern void delete_inst_node(int i);
|
||||
extern void clear_all_hilights(void);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
v {xschem version=2.9.9 file_version=1.2 }
|
||||
G {}
|
||||
K {type=primitive
|
||||
function2="0 1 & ~"
|
||||
format="@name @@A @@B @VGND @VNB @VPB @VPWR @@Y @prefix\\\\nand2_1"
|
||||
template="name=x1 VGND=VGND VNB=VNB VPB=VPB VPWR=VPWR prefix=sky130_fd_sc_hd__ "
|
||||
extra="VGND VNB VPB VPWR prefix"
|
||||
highlight=true
|
||||
function2="0 1 & ~"}
|
||||
}
|
||||
V {}
|
||||
S {}
|
||||
E {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue