added Hi-Z in logic values

This commit is contained in:
Stefan Frederik 2021-01-11 19:31:47 +01:00
parent 990647f4fa
commit 50028baa9f
5 changed files with 44 additions and 15 deletions

View File

@ -1102,9 +1102,9 @@ int callback(int event, int mx, int my, KeySym key,
place_net_label(1);
break;
}
if(key >= '0' && key <= '3' && state == 0) { /* Toggle pin logic level */
if(key >= '0' && key <= '4' && state == 0) { /* Toggle pin logic level */
if(xctx->semaphore >= 2) break;
if(key == '3') logic_set(-1, 1);
if(key == '4') logic_set(-1, 1);
else logic_set(key - '0', 1);
break;
}

View File

@ -895,7 +895,7 @@ int get_logic_value(int inst, int n)
val = 2; /* LOGIC_X */
} else {
val = entry->value;
val = (val == LOGIC_0) ? 0 : (val == LOGIC_1) ? 1 : 2;
val = (val == LOGIC_0) ? 0 : (val == LOGIC_1) ? 1 : (val == LOGIC_Z) ? 3 : 2;
/* dbg(1, "get_logic_value(): inst=%d pin=%d net=%s val=%d\n", inst, n, netname, val); */
}
/* my_free(xxxx, &netname); */
@ -948,6 +948,7 @@ int eval_logic_expr(int inst, int output)
if(sp > 0) {
sp--;
if(!(stack[sp] & 2)) stack[sp] = !stack[sp];
else stack[sp] = 2;
++sp;
}
break;
@ -961,7 +962,10 @@ int eval_logic_expr(int inst, int output)
case 'm': /* mux operator */
s = stack[sp - 1];
if(sp > 2) {
stack[sp - 3] = (s & 2) ? 2 : (s == 0) ? stack[sp - 3] : stack[sp - 2];
if(!(s & 2) ) { /* reduce pessimism, avoid infinite loops */
stack[sp - 3] = (s == 0) ? stack[sp - 3] : stack[sp - 2];
}
else stack[sp - 3] = 3;
sp -=2;
}
break;
@ -1091,15 +1095,20 @@ void free_simdata(void)
xctx->simdata.valid = 0;
}
#undef DELAYED_ASSIGN
void propagate_logic()
{
/* char *propagated_net=NULL; */
int found /* , mult */;
int found, iter = 0 /* , mult */;
int i, j, npin;
int propagate;
int min_iter = 0; /* set to 3 to simulate up to 3 series bidirectional pass-devices */
struct hilight_hashentry *entry;
int val, oldval, newval;
static int map[] = {LOGIC_0, LOGIC_1, LOGIC_X, LOGIC_Z};
#ifdef DELAYED_ASSIGN
int *newval_arr = NULL;
#endif
tclsetvar("tclstop", "0");
prepare_netlist_structs(0);
@ -1107,6 +1116,10 @@ void propagate_logic()
found=0;
for(i=0; i<xctx->simdata.ninst; i++) {
npin = xctx->simdata.inst[i].npin;
#ifdef DELAYED_ASSIGN
my_realloc(778, &newval_arr, npin * sizeof(int));
for(j=0; j<npin;j++) newval_arr[j] = -10000;
#endif
for(j=0; j<npin;j++) {
if(xctx->simdata.inst && xctx->simdata.inst[i].pin && xctx->simdata.inst[i].pin[j].go_to) {
int n = 1;
@ -1162,20 +1175,36 @@ void propagate_logic()
oldval = (!entry) ? LOGIC_X : entry->value;
newval = eval_logic_expr(i, propagate);
val = map[newval];
if(newval != 3 && oldval != val) {
hilight_lookup(xctx->inst[i].node[propagate], val, XINSERT);
if(newval!=3) found=1; /* keep looping until no more nets are found. */
if(iter < min_iter || (newval != 3 && oldval != val) ) {
dbg(1, "propagate_logic(): inst %d pin %d oldval %d newval %d to pin %s\n",
i, j, oldval, val, xctx->inst[i].node[propagate]);
#ifdef DELAYED_ASSIGN
newval_arr[propagate] = val;
#else
hilight_lookup(xctx->inst[i].node[propagate], val, XINSERT);
#endif
found=1; /* keep looping until no more nets are found. */
}
}
}
} /* for(j...) */
#ifdef DELAYED_ASSIGN
for(j=0;j<npin;j++) {
if(newval_arr[j] != -10000) hilight_lookup(xctx->inst[i].node[j], newval_arr[j], XINSERT);
}
#endif
} /* for(i...) */
xctx->hilight_time++;
if(!found) break;
/* get out from infinite loops (circuit is oscillating) */
Tcl_VarEval(interp, "update; if {$::tclstop == 1} {return 1} else {return 0}", NULL);
if( tclresult()[0] == '1') break;
iter++;
} /* while(1) */
#ifdef DELAYED_ASSIGN
my_free(779, &newval_arr);
#endif
/* my_free(1222, &propagated_net); */
}

View File

@ -182,9 +182,9 @@ void merge_polygon(FILE *fd)
for(j=0;j<points;j++) {
if(fscanf(fd, "%lf %lf ",&(ptr[i].x[j]), &(ptr[i].y[j]))<2) {
fprintf(errfp,"merge_polygon(): WARNING: missing fields for POLYGON points, ignoring.\n");
my_free(886, &ptr[i].x);
my_free(887, &ptr[i].y);
my_free(888, &ptr[i].selected_point);
my_free(827, &ptr[i].x);
my_free(1218, &ptr[i].y);
my_free(1223, &ptr[i].selected_point);
read_line(fd, 0);
return;
}
@ -244,10 +244,10 @@ void merge_inst(int k,FILE *fd)
load_ascii_string(&tmp, fd);
/* avoid as much as possible calls to rel_sym_path (slow) */
#ifdef __unix__
if(tmp[0] == '/') my_strdup(755, &ptr[i].name, rel_sym_path(tmp));
if(tmp[0] == '/') my_strdup(763, &ptr[i].name, rel_sym_path(tmp));
else my_strdup(755, &ptr[i].name,tmp);
#else
my_strdup(755, &ptr[i].name, rel_sym_path(tmp));
my_strdup(780, &ptr[i].name, rel_sym_path(tmp));
#endif
my_free(756, &tmp);
if(fscanf(fd, "%lf %lf %hd %hd",&ptr[i].x0, &ptr[i].y0,&ptr[i].rot, &ptr[i].flip) < 4) {

View File

@ -543,7 +543,7 @@ static void load_inst(int k, FILE *fd)
if(name[0] == '/') my_strdup2(56, &xctx->inst[i].name, rel_sym_path(name));
else my_strdup2(762, &xctx->inst[i].name, name);
#else
my_strdup2(56, &xctx->inst[i].name, rel_sym_path(name));
my_strdup2(777, &xctx->inst[i].name, rel_sym_path(name));
#endif
if(fscanf(fd, "%lf %lf %hd %hd", &xctx->inst[i].x0, &xctx->inst[i].y0,
&xctx->inst[i].rot, &xctx->inst[i].flip) < 4) {

View File

@ -1451,7 +1451,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
if(argc > 3 ) num = atoi(argv[3]);
if(argc > 2) {
int n = atoi(argv[2]);
if(n == 3) n = -1;
if(n == 4) n = -1;
logic_set(n, num);
}
Tcl_ResetResult(interp);