add "mux", "tristate" functions to logic expressions
This commit is contained in:
parent
2063b42613
commit
cea1069656
204
src/hilight.c
204
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);
|
||||
|
|
|
|||
|
|
@ -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<yb)? (ya>=y2 || yb<=y1) : (yb>=y2 || ya<=y1) ) )
|
||||
|
||||
#define CLIP(x,a,b) (x<a?a:x>b?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))
|
||||
|
|
|
|||
|
|
@ -3218,9 +3218,11 @@ global env has_x
|
|||
###
|
||||
### Tk event handling
|
||||
###
|
||||
bind . <Expose> [list raise_dialog $window_path]
|
||||
bind . <Visibility> [list raise_dialog $window_path]
|
||||
bind . <FocusIn> [list raise_dialog $window_path]
|
||||
if { $window_path eq {.drw} } {
|
||||
bind . <Expose> [list raise_dialog $window_path]
|
||||
bind . <Visibility> [list raise_dialog $window_path]
|
||||
bind . <FocusIn> [list raise_dialog $window_path]
|
||||
}
|
||||
bind $window_path <Double-Button-1> {xschem callback -3 %x %y 0 %b 0 %s}
|
||||
bind $window_path <Double-Button-2> {xschem callback -3 %x %y 0 %b 0 %s}
|
||||
bind $window_path <Double-Button-3> {xschem callback -3 %x %y 0 %b 0 %s}
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue