diff --git a/src/hilight.c b/src/hilight.c index 655059c9..22db2276 100644 --- a/src/hilight.c +++ b/src/hilight.c @@ -875,9 +875,10 @@ void propagate_hilights(int set, int clear, int mode) } /* use negative values to bypass the normal hilight color enumeration */ -#define LOGIC_X -1 -#define LOGIC_0 -12 -#define LOGIC_1 -5 +#define LOGIC_0 -12 /* 0 */ +#define LOGIC_1 -5 /* 1 */ +#define LOGIC_X -1 /* 2 */ +#define LOGIC_Z -13 /* 3 */ #define STACKMAX 200 int get_logic_value(int inst, int n) @@ -914,7 +915,7 @@ void print_stack(int *stack, int sp) int eval_logic_expr(int inst, int output) { int stack[STACKMAX]; - int pos = 0, i, sp = 0; + int pos = 0, i, s, sp = 0; char *str; int res = 0; @@ -922,82 +923,113 @@ int eval_logic_expr(int inst, int output) dbg(1, "eval_logic_expr(): inst=%d pin=%d function=%s\n", inst, output, str ? str : "NULL"); if(!str) return 2; /* no logic function defined, return LOGIC_X */ while(str[pos]) { - if(str[pos] == 'd') { /* duplicate top element*/ - if(sp > 0 && sp < STACKMAX) { - stack[sp] = stack[sp - 1]; - sp++; - } - /* rotate down: bottom element goes to top */ - } else if(str[pos] == 'r') { - if(sp > 1) { - int tmp = stack[0]; - for(i = 0 ; i < sp - 1; i++) stack[i] = stack[i + 1]; - stack[sp - 1] = tmp; - } - } else if(str[pos] == 'x') { /* exchange top 2 operands */ - if(sp > 1) { - int tmp = stack[sp - 2]; - stack[sp - 2] = stack[sp - 1]; - stack[sp - 1] = tmp; - } - } else if(str[pos] == '~') { /* negation operator */ - if(sp > 0) { - sp--; - if(stack[sp] != 2) stack[sp] = !stack[sp]; - ++sp; - } - } else if(str[pos] == '|') { /* or operator */ - if(sp > 1) { - res = 0; - for(i = sp - 2; i < sp; i++) { - if(stack[i] == 1) { - res = 1; - break; - } else if(stack[i] == 2) { - res = 2; - } + switch(str[pos]) { + case 'd': /* duplicate top element*/ + if(sp > 0 && sp < STACKMAX) { + stack[sp] = stack[sp - 1]; + sp++; } - stack[sp - 2] = res; - sp--; - } - } else if(str[pos] == '&') { /* and operator */ - if(sp > 1) { - res = 1; - for(i = sp - 2; i < sp; i++) { - if(stack[i] == 0) { - res = 0; - break; - } else if(stack[i] == 2) { - res = 2; - } + break; + case 'r': /* rotate down: bottom element goes to top */ + if(sp > 1) { + s = stack[0]; + for(i = 0 ; i < sp - 1; i++) stack[i] = stack[i + 1]; + stack[sp - 1] = s; } - stack[sp - 2] = res; - sp--; - } - } else if(str[pos] == '^') { /* xor operator */ - if(sp > 1) { - res = 0; - for(i = sp - 2; i < sp; i++) { - if(stack[i] != 2) { - res = res ^ stack[i]; - } - else { - res = 2; - break; - } + break; + case 'x': /* exchange top 2 operands */ + if(sp > 1) { + s = stack[sp - 2]; + stack[sp - 2] = stack[sp - 1]; + stack[sp - 1] = s; } - stack[sp - 2] = res; - sp--; - } - } else if(str[pos] == 'L') { /* logic low (0) */ - if(sp < STACKMAX) { - stack[sp++] = 0; - } - } else if(str[pos] == 'H') { /* logic high (1) */ - if(sp < STACKMAX) { - stack[sp++] = 1; - } - } else if(isdigit(str[pos])) { + break; + case '~': /* negation operator */ + if(sp > 0) { + sp--; + if(!(stack[sp] & 2)) stack[sp] = !stack[sp]; + ++sp; + } + break; + case 'z': /* Tristate driver [signal,enable,'z']-> signal if z==1, Z (3) otherwise */ + if(sp > 1) { + s = stack[sp - 1]; + stack[sp - 2] = (s & 2) ? 2 : (s == 1 ) ? stack[sp - 2] : 3; + sp--; + } + break; + 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]; + sp -=2; + } + break; + case '|': /* or operator */ + if(sp > 1) { + res = 0; + for(i = sp - 2; i < sp; i++) { + if(stack[i] == 1) { + res = 1; + break; + } else if(stack[i] & 2) { + res = 2; + } + } + stack[sp - 2] = res; + sp--; + } + break; + case '&': /* and operator */ + if(sp > 1) { + res = 1; + for(i = sp - 2; i < sp; i++) { + if(stack[i] == 0) { + res = 0; + break; + } else if(stack[i] & 2) { + res = 2; + } + } + stack[sp - 2] = res; + sp--; + } + break; + case '^': /* xor operator */ + if(sp > 1) { + res = 0; + for(i = sp - 2; i < sp; i++) { + if(!(stack[i] & 2)) { + res = res ^ stack[i]; + } + else { + res = 2; + break; + } + } + stack[sp - 2] = res; + sp--; + } + break; + case 'L': /* logic low (0) */ + if(sp < STACKMAX) { + stack[sp++] = 0; + } + break; + case 'H': /* logic high (1) */ + if(sp < STACKMAX) { + stack[sp++] = 1; + } + break; + case 'Z': /* logic Z (3) */ + if(sp < STACKMAX) { + stack[sp++] = 3; + } + break; + default: + break; + } /* switch */ + if(isdigit(str[pos])) { if(sp < STACKMAX) { char *num = str + pos; while(isdigit(str[++pos])) ; @@ -1007,7 +1039,7 @@ int eval_logic_expr(int inst, int output) else dbg(0, "eval_logic_expr(): stack overflow!\n"); } pos++; - } + } /* while */ dbg(1, "eval_logic_expr(): inst %d output %d, returning %d\n", inst, output, stack[0]); return stack[0]; } @@ -1032,7 +1064,8 @@ void create_simdata(void) xctx->simdata.inst[i].pin[j].go_to=NULL; 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)); + 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; } @@ -1065,8 +1098,8 @@ void propagate_logic() int i, j, npin; int propagate; struct hilight_hashentry *entry; - int val, oldval; - static int map[] = {LOGIC_0, LOGIC_1, LOGIC_X}; + int val, oldval, newval; + static int map[] = {LOGIC_0, LOGIC_1, LOGIC_X, LOGIC_Z}; tclsetvar("tclstop", "0"); prepare_netlist_structs(0); @@ -1127,10 +1160,11 @@ void propagate_logic() /* 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) { + newval = eval_logic_expr(i, propagate); + val = map[newval]; + if(newval != 3 && oldval != val) { hilight_lookup(xctx->inst[i].node[propagate], val, XINSERT); - found=1; /* keep looping until no more nets are found. */ + if(newval!=3) found=1; /* keep looping until no more nets are found. */ } } } @@ -1151,7 +1185,7 @@ void logic_set(int value, int num) char *type; xRect boundbox; int big = xctx->wires> 2000 || xctx->instances > 2000 ; - static int map[] = {LOGIC_0, LOGIC_1, LOGIC_X}; + static int map[] = {LOGIC_0, LOGIC_1, LOGIC_X, LOGIC_Z}; struct hilight_hashentry *entry; prepare_netlist_structs(0); diff --git a/src/xschem.h b/src/xschem.h index 5e2f1688..240c1149 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -299,7 +299,7 @@ extern char win_temp_dir[PATH_MAX]; #define LINE_OUTSIDE(xa,ya,xb,yb,x1,y1,x2,y2) \ (xa>=x2 || xb<=x1 || ( (ya=y2 || yb<=y1) : (yb>=y2 || ya<=y1) ) ) -#define CLIP(x,a,b) (xb?b:x) +#define CLIP(x,a,b) ((x) < a ? (a) : (x) > b ? (b) : (x)) #define MINOR(a,b) ( (a) <= (b) ? (a) : (b) ) #define ROUND(a) ((a) > 0.0 ? ceil((a) - 0.5) : floor((a) + 0.5)) diff --git a/src/xschem.tcl b/src/xschem.tcl index 8d75b6dc..fc33888d 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -3218,9 +3218,11 @@ global env has_x ### ### Tk event handling ### - bind . [list raise_dialog $window_path] - bind . [list raise_dialog $window_path] - bind . [list raise_dialog $window_path] + if { $window_path eq {.drw} } { + bind . [list raise_dialog $window_path] + bind . [list raise_dialog $window_path] + bind . [list raise_dialog $window_path] + } bind $window_path {xschem callback -3 %x %y 0 %b 0 %s} bind $window_path {xschem callback -3 %x %y 0 %b 0 %s} bind $window_path {xschem callback -3 %x %y 0 %b 0 %s} diff --git a/xschem_library/devices/gnd.sym b/xschem_library/devices/gnd.sym index ef8b864d..03ecaa35 100644 --- a/xschem_library/devices/gnd.sym +++ b/xschem_library/devices/gnd.sym @@ -1,5 +1,7 @@ -v {xschem version=2.9.5_RC5 file_version=1.1} -G {type=label +v {xschem version=2.9.9 file_version=1.2 } +G {} +K {type=label +function0="L" global=true format="*.alias @lab" template="name=l1 lab=GND"} @@ -10,5 +12,5 @@ L 4 0 0 0 12.5 {} L 4 -5 12.5 5 12.5 {} L 4 0 17.5 5 12.5 {} L 4 -5 12.5 0 17.5 {} -B 5 -2.5 -2.5 2.5 2.5 {name=p dir=inout} +B 5 -2.5 -2.5 2.5 2.5 {name=p dir=inout goto=0} T {@lab} 7.5 5 0 0 0.2 0.2 {} diff --git a/xschem_library/devices/vdd.sym b/xschem_library/devices/vdd.sym index ebee4ecc..e98e95e5 100644 --- a/xschem_library/devices/vdd.sym +++ b/xschem_library/devices/vdd.sym @@ -1,5 +1,7 @@ -v {xschem version=2.9.5_RC5 file_version=1.1} -G {type=label +v {xschem version=2.9.9 file_version=1.2 } +G {} +K {type=label +function0="H" global=true format="*.alias @lab" template="name=l1 lab=VDD"} @@ -8,5 +10,5 @@ S {} E {} L 4 0 -20 0 0 {} L 4 -10 -20 10 -20 {} -B 5 -2.5 -2.5 2.5 2.5 {name=p dir=inout verilog_type=wire} +B 5 -2.5 -2.5 2.5 2.5 {name=p dir=inout verilog_type=wire goto=0} T {@lab} -12.5 -35 0 0 0.2 0.2 {} diff --git a/xschem_library/xschem_simulator/dfrtp_1.sym b/xschem_library/xschem_simulator/dfrtp_1.sym index 4d79b88d..86982927 100644 --- a/xschem_library/xschem_simulator/dfrtp_1.sym +++ b/xschem_library/xschem_simulator/dfrtp_1.sym @@ -1,7 +1,8 @@ v {xschem version=2.9.9 file_version=1.2 } G {} K {type=stdcell -function3="0 d ~ 3 & x 1 & | 2 &" +xfunction3="0 d ~ 3 & x 1 & | 2 &" +function3="3 1 0 m L 2 ~ m" format="@name @@CLK @@D @@RESET_B @VGND @VNB @VPB @VPWR @@Q @prefix\\\\dfrtp_1" template="name=x1 VGND=VGND VNB=VNB VPB=VPB VPWR=VPWR prefix=sky130_fd_sc_hd__ " extra="VGND VNB VPB VPWR prefix" @@ -23,7 +24,7 @@ goto=3 clock=1} B 5 -92.5 -2.5 -87.5 2.5 {name=D dir=in } B 5 -92.5 17.5 -87.5 22.5 {name=RESET_B dir=in goto=3 -clock=2} +clock=0} B 5 87.5 -22.5 92.5 -17.5 {name=Q dir=out } T {@symname} 0 -6 0 0 0.3 0.3 {hcenter=true} T {@name} 75 -42 0 0 0.2 0.2 {} diff --git a/xschem_library/xschem_simulator/dlrtn_1.sym b/xschem_library/xschem_simulator/dlrtn_1.sym index b282b69f..9cc05acd 100644 --- a/xschem_library/xschem_simulator/dlrtn_1.sym +++ b/xschem_library/xschem_simulator/dlrtn_1.sym @@ -5,7 +5,7 @@ format="@name @@D @@GATE_N @@RESET_B @VGND @VNB @VPB @VPWR @@Q @prefix\\\\dlrtn_ template="name=x1 VGND=VGND VNB=VNB VPB=VPB VPWR=VPWR prefix=sky130_fd_sc_hd__ " extra="VGND VNB VPB VPWR prefix" highlight=true -function3="0 1 ~ 2 & & 1 2 3 & & |"} +function3="0 3 1 m L 2 ~ m"} V {} S {} E {} diff --git a/xschem_library/xschem_simulator/dlrtp_1.sym b/xschem_library/xschem_simulator/dlrtp_1.sym index a160eccf..be554474 100644 --- a/xschem_library/xschem_simulator/dlrtp_1.sym +++ b/xschem_library/xschem_simulator/dlrtp_1.sym @@ -5,7 +5,7 @@ format="@name @@D @@GATE @@RESET_B @VGND @VNB @VPB @VPWR @@Q @prefix\\\\dlrtp_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 -function3="0 1 2 & & 1 ~ 2 3 & & |"} +function3="3 0 1 m L 2 ~ m"} V {} S {} E {}