From ebf0f0cf95d9ee6b304dec3c626e295731ad5139 Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Sat, 30 Oct 2021 03:12:06 +0200 Subject: [PATCH] fixed simulation engine, no more bidirectional devices allowed --- src/hilight.c | 102 +++++++++++------- src/xschem.h | 1 + xschem_library/devices/gnd.sym | 2 +- xschem_library/devices/vdd.sym | 2 +- xschem_library/xschem_simulator/dev-1.sym | 5 +- xschem_library/xschem_simulator/dev-2.sym | 25 +++++ xschem_library/xschem_simulator/dlrtp_1.sym | 4 +- xschem_library/xschem_simulator/invert-1.sym | 8 +- xschem_library/xschem_simulator/n.sym | 9 +- xschem_library/xschem_simulator/p.sym | 9 +- xschem_library/xschem_simulator/switch-1.sym | 5 +- .../xschem_simulator/switch_level_sim.sch | 10 +- 12 files changed, 117 insertions(+), 65 deletions(-) create mode 100644 xschem_library/xschem_simulator/dev-2.sym diff --git a/src/hilight.c b/src/hilight.c index a98dd4c7..d95860f2 100644 --- a/src/hilight.c +++ b/src/hilight.c @@ -1083,10 +1083,12 @@ void propagate_hilights(int set, int clear, int mode) } /* use negative values to bypass the normal hilight color enumeration */ -#define LOGIC_0 -12 /* 0 */ -#define LOGIC_1 -5 /* 1 */ -#define LOGIC_X -1 /* 2 */ -#define LOGIC_Z -13 /* 3 */ +#define LOGIC_0 -12 /* 0 */ +#define LOGIC_1 -5 /* 1 */ +#define LOGIC_X -1 /* 2 */ +#define LOGIC_Z -13 /* 3 */ +#define LOGIC_NOUP 0 /* 4 don't update */ + #define STACKMAX 200 int get_logic_value(int inst, int n) @@ -1127,6 +1129,7 @@ int eval_logic_expr(int inst, int output) char *str; int res = 0; + stack[0] = 2; /* default if nothing is calculated: LOGIC_X */ str = xctx->simdata[inst].pin[output].function; 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 */ @@ -1167,6 +1170,19 @@ int eval_logic_expr(int inst, int output) sp--; } break; + case 'R': /* resolution operator, resolve output based on 2 inputs */ + if(sp > 1) { + s = stack[sp - 1]; + i = stack[sp - 2]; + if(s == 2 || i == 2) res = 2; /* s 0 1 X Z */ + else if(s == 3) res = i; /* i ------- */ + else if(i == 3) res = s; /* 0 | 0 X X 0 */ + else if(i == s) res = i; /* 1 | X 1 X 1 */ + else res = 2; /* X | X X X X */ + stack[sp - 2] = res; /* Z | 0 1 X Z */ + sp--; + } + break; case 'M': /* mux operator */ if(sp > 2) { s = stack[sp - 1]; @@ -1180,6 +1196,8 @@ int eval_logic_expr(int inst, int output) case 'm': /* mux operator , lower priority*/ if(sp > 2) { s = stack[sp - 1]; + stack[sp - 3] = (stack[sp - 3] == 2) ? 4 : stack[sp - 3]; /* if LOGIC_X set to don't update */ + stack[sp - 2] = (stack[sp - 2] == 2) ? 4 : stack[sp - 2]; /* if LOGIC_X set to don't update */ if(s < 2) { stack[sp - 3] = (s == 0) ? stack[sp - 3] : stack[sp - 2]; } @@ -1321,31 +1339,28 @@ void free_simdata(void) xctx->simdata_ninst = 0; } -#define DELAYED_ASSIGN /* fixes bidirectional devices (avoid infinite loops) */ void propagate_logic() { /* char *propagated_net=NULL; */ int found, iter = 0 /* , mult */; int i, j, npin; int propagate; - int min_iter = 3; /* 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 + int val, newval; + static int map[] = {LOGIC_0, LOGIC_1, LOGIC_X, LOGIC_Z, LOGIC_NOUP}; prepare_netlist_structs(0); if(!xctx->simdata) create_simdata(); + + for(i=0; iinstances; i++) + for(j=0;j < xctx->simdata[i].npin; j++) + xctx->simdata[i].pin[j].value=-10000; + while(1) { + dbg(0, "propagate_logic(): main loop iteration\n"); found=0; for(i=0; iinstances; i++) { npin = xctx->simdata[i].npin; - #ifdef DELAYED_ASSIGN - my_realloc(778, &newval_arr, npin * sizeof(int)); - for(j=0; jsimdata && xctx->simdata[i].pin && xctx->simdata[i].pin[j].go_to) { int n = 1; @@ -1361,11 +1376,11 @@ void propagate_logic() if(clock_pin == 0) { /* clock falling edge */ if( clock_val == clock_oldval) continue; if( clock_val != LOGIC_0) continue; - if(entry && entry->time != xctx->hilight_time) continue; + if(entry && (entry->time < xctx->hilight_time)) continue; } else if(clock_pin == 1) { /* clock rising edge */ if( clock_val == clock_oldval) continue; if( clock_val != LOGIC_1) continue; - if(entry && entry->time != xctx->hilight_time) continue; + if(entry && (entry->time < xctx->hilight_time)) continue; } else if(clock_pin == 2) { /* set/clear active low */ if( clock_val != LOGIC_0) continue; } else if(clock_pin == 3) { /* set/clear active high */ @@ -1397,40 +1412,49 @@ void propagate_logic() * dbg(1, "propagate_logic(): propagated_net=%s\n", propagated_net); */ /* add net to highlight list */ /* 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; newval = eval_logic_expr(i, propagate); val = map[newval]; - if( newval !=4 && (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 + if(newval != 4 && xctx->simdata[i].pin[propagate].value != val ) { found=1; /* keep looping until no more nets are found. */ - } + xctx->simdata[i].pin[propagate].value = val; + dbg(0, "propagate_logic(): DRIVERS inst %s pin %d, net %s --> value %d\n", + xctx->inst[i].instname, j, xctx->inst[i].node[propagate], val); + } + } /* while( ith-goto ) */ + } /* if((xctx->simdata && xctx->simdata[i].pin && xctx->simdata[i].pin[j].go_to) */ + } /* for(j...) */ + } /* for(i...) */ + + xctx->hilight_time++; + + /* update all values */ + for(i=0; iinstances; i++) { + for(j=0;j < xctx->simdata[i].npin; j++) { + if(xctx->simdata[i].pin[j].value != -10000) { + entry = hilight_lookup(xctx->inst[i].node[j], 0, XLOOKUP); + if(!entry || xctx->hilight_time != entry->time) { + hilight_lookup(xctx->inst[i].node[j], xctx->simdata[i].pin[j].value, XINSERT); + dbg(0, "propagate_logic(): UPDATE1 inst %s pin %d, net %s --> value %d\n", + xctx->inst[i].instname, j, xctx->inst[i].node[j], xctx->simdata[i].pin[j].value); + } else if(entry->value != xctx->simdata[i].pin[j].value && + xctx->simdata[i].pin[j].value != LOGIC_Z) { + hilight_lookup(xctx->inst[i].node[j], xctx->simdata[i].pin[j].value, XINSERT); + dbg(0, "propagate_logic(): UPDATE2 inst %s pin %d, net %s --> value %d\n", + xctx->inst[i].instname, j, xctx->inst[i].node[j], xctx->simdata[i].pin[j].value); + } else { + dbg(0, "propagate_logic(): UPDATE3 inst %s pin %d, net %s --> value %d NOT assigned\n", + xctx->inst[i].instname, j, xctx->inst[i].node[j], xctx->simdata[i].pin[j].value); } } - } /* for(j...) */ - #ifdef DELAYED_ASSIGN - for(j=0;jinst[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); */ } @@ -1440,7 +1464,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, LOGIC_Z}; + static int map[] = {LOGIC_0, LOGIC_1, LOGIC_X, LOGIC_Z, LOGIC_NOUP}; struct hilight_hashentry *entry; tclsetvar("tclstop", "0"); diff --git a/src/xschem.h b/src/xschem.h index edd18cce..99087bbd 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -492,6 +492,7 @@ struct iterator_ctx { struct simdata_pin { char *function; char *go_to; + int value; short clock; }; diff --git a/xschem_library/devices/gnd.sym b/xschem_library/devices/gnd.sym index 03ecaa35..00a0c984 100644 --- a/xschem_library/devices/gnd.sym +++ b/xschem_library/devices/gnd.sym @@ -1,4 +1,4 @@ -v {xschem version=2.9.9 file_version=1.2 } +v {xschem version=3.0.0 file_version=1.2 } G {} K {type=label function0="L" diff --git a/xschem_library/devices/vdd.sym b/xschem_library/devices/vdd.sym index e98e95e5..4a4f79b5 100644 --- a/xschem_library/devices/vdd.sym +++ b/xschem_library/devices/vdd.sym @@ -1,4 +1,4 @@ -v {xschem version=2.9.9 file_version=1.2 } +v {xschem version=3.0.0 file_version=1.2 } G {} K {type=label function0="H" diff --git a/xschem_library/xschem_simulator/dev-1.sym b/xschem_library/xschem_simulator/dev-1.sym index 738074fb..4a1c822e 100644 --- a/xschem_library/xschem_simulator/dev-1.sym +++ b/xschem_library/xschem_simulator/dev-1.sym @@ -1,7 +1,6 @@ v {xschem version=3.0.0 file_version=1.2 } G {} K {type=switch -function0="1 2 3 m" function1="0 Z 3 m" function2="Z 0 3 m" template="name=s1" @@ -14,10 +13,12 @@ L 4 -30 0 -10 0 {} L 4 0 -40 0 0 {} L 4 10 10 30 10 {} L 4 -10 0 10 0 {} +L 4 -20 -5 -10 0 {} +L 4 -20 5 -10 0 {} B 5 -32.5 -2.5 -27.5 2.5 {name=t0 dir=inout} B 5 27.5 7.5 32.5 12.5 {name=t1 dir=inout } B 5 27.5 -12.5 32.5 -7.5 {name=t2 dir=inout } -B 5 -2.5 -42.5 2.5 -37.5 {name=g dir=inout goto=0,1,2} +B 5 -2.5 -42.5 2.5 -37.5 {name=g dir=inout goto=1,2} A 4 -8.75 0 1.25 360 360 {fill=true} A 4 10 -10 1.25 0 360 {fill=true} A 4 10 10 1.25 0 360 {fill=true} diff --git a/xschem_library/xschem_simulator/dev-2.sym b/xschem_library/xschem_simulator/dev-2.sym new file mode 100644 index 00000000..bc52254a --- /dev/null +++ b/xschem_library/xschem_simulator/dev-2.sym @@ -0,0 +1,25 @@ +v {xschem version=3.0.0 file_version=1.2 } +G {} +K {type=switch +function0="1 2 3 m" +template="name=s1" +} +V {} +S {} +E {} +L 4 10 -10 30 -10 {} +L 4 -30 0 -10 0 {} +L 4 0 -40 0 0 {} +L 4 10 10 30 10 {} +L 4 -10 0 10 0 {} +L 4 -20 0 -10 -5 {} +L 4 -20 0 -10 5 {} +B 5 -32.5 -2.5 -27.5 2.5 {name=t0 dir=inout} +B 5 27.5 7.5 32.5 12.5 {name=t1 dir=inout } +B 5 27.5 -12.5 32.5 -7.5 {name=t2 dir=inout } +B 5 -2.5 -42.5 2.5 -37.5 {name=g dir=inout goto=0} +A 4 -8.75 0 1.25 360 360 {fill=true} +A 4 10 -10 1.25 0 360 {fill=true} +A 4 10 10 1.25 0 360 {fill=true} +T {1} 20 -17.5 0 0 0.1 0.1 {} +T {0} 20 2.5 0 0 0.1 0.1 {} diff --git a/xschem_library/xschem_simulator/dlrtp_1.sym b/xschem_library/xschem_simulator/dlrtp_1.sym index 17a6069a..86af0b41 100644 --- a/xschem_library/xschem_simulator/dlrtp_1.sym +++ b/xschem_library/xschem_simulator/dlrtp_1.sym @@ -1,4 +1,4 @@ -v {xschem version=2.9.9 file_version=1.2 } +v {xschem version=3.0.0 file_version=1.2 } G {} K {type=primitive format="@name @@D @@GATE @@RESET_B @VGND @VNB @VPB @VPWR @@Q @prefix\\\\dlrtp_1" @@ -21,7 +21,7 @@ B 5 -92.5 -22.5 -87.5 -17.5 {name=D dir=in goto=3} B 5 -92.5 -2.5 -87.5 2.5 {name=GATE dir=in goto=3} -B 5 -92.5 17.5 -87.5 22.5 {name=RESET_B dir=in } +B 5 -92.5 17.5 -87.5 22.5 {name=RESET_B dir=in goto=3} 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/invert-1.sym b/xschem_library/xschem_simulator/invert-1.sym index 277bf23a..3549c1d8 100644 --- a/xschem_library/xschem_simulator/invert-1.sym +++ b/xschem_library/xschem_simulator/invert-1.sym @@ -1,8 +1,6 @@ v {xschem version=3.0.0 file_version=1.2 } G {} K {type=switch -function0="3 2 4 m" -function1="2 3 4 m" function2="1 0 4 m" function3="0 1 4 m" template="name=s1" @@ -19,11 +17,15 @@ L 4 -5 5 5 -5 {} L 4 -5 -5 5 5 {} L 4 -5 -10 5 -10 {} L 4 -5 10 5 10 {} +L 4 -20 5 -10 10 {} +L 4 -20 15 -10 10 {} +L 4 -20 -15 -10 -10 {} +L 4 -20 -5 -10 -10 {} B 5 -32.5 -12.5 -27.5 -7.5 {name=t0 dir=inout} B 5 -32.5 7.5 -27.5 12.5 {name=t1 dir=inout} B 5 27.5 7.5 32.5 12.5 {name=t2 dir=inout } B 5 27.5 -12.5 32.5 -7.5 {name=t3 dir=inout } -B 5 -2.5 -42.5 2.5 -37.5 {name=g dir=inout goto=0,1,2,3} +B 5 -2.5 -42.5 2.5 -37.5 {name=g dir=inout goto=2,3} A 4 -10 -10 1.25 0 360 {fill=true} A 4 10 -10 1.25 0 360 {fill=true} A 4 10 10 1.25 0 360 {fill=true} diff --git a/xschem_library/xschem_simulator/n.sym b/xschem_library/xschem_simulator/n.sym index a81635a0..87dfae36 100644 --- a/xschem_library/xschem_simulator/n.sym +++ b/xschem_library/xschem_simulator/n.sym @@ -1,8 +1,7 @@ -v {xschem version=2.9.9 file_version=1.2 } +v {xschem version=3.0.0 file_version=1.2 } G {} K {type=nmos -function0="Z 2 1 m" -function2="Z 0 1 m" +function0="Z 2 1 M" verilog_format="nmos #(@risedel , @falldel , @offdel ) @name ( @@d , @@s , @@g );" format="@name @pinlist @model w=@w l=@l + ad='@w *4.3u' as='@w *4.3u' @@ -42,8 +41,8 @@ L 4 10 0 20 0 {} L 4 5 -5 10 0 {} L 4 5 5 10 0 {} B 5 17.5 -32.5 22.5 -27.5 {name=d dir=inout} -B 5 -22.5 -2.5 -17.5 2.5 {name=g dir=in goto=0,2} -B 5 17.5 27.5 22.5 32.5 {name=s dir=inout } +B 5 -22.5 -2.5 -17.5 2.5 {name=g dir=in goto=0} +B 5 17.5 27.5 22.5 32.5 {name=s dir=inout} B 5 17.5 -2.5 22.5 2.5 {name=b dir=in} T {@w\\/@l\\/@m} 7.5 -17.5 0 0 0.2 0.2 {} T {@name} 7.5 5 0 0 0.2 0.2 {} diff --git a/xschem_library/xschem_simulator/p.sym b/xschem_library/xschem_simulator/p.sym index f632a6c1..0a48c305 100644 --- a/xschem_library/xschem_simulator/p.sym +++ b/xschem_library/xschem_simulator/p.sym @@ -1,8 +1,7 @@ -v {xschem version=2.9.9 file_version=1.2 } +v {xschem version=3.0.0 file_version=1.2 } G {} K {type=pmos -function0="2 Z 1 m" -function2="0 Z 1 m" +function0="2 Z 1 M" verilog_format="pmos #(@risedel , @falldel , @offdel ) @name ( @@d , @@s , @@g );" format="@name @pinlist @model w=@w l=@l + ad='@w *4.6u' as='@w *4.6u' @@ -39,8 +38,8 @@ L 4 5 -5 10 0 {} L 4 5 5 10 0 {} L 4 10 0 20 0 {} B 5 17.5 27.5 22.5 32.5 {name=d dir=inout} -B 5 -22.5 -2.5 -17.5 2.5 {name=g dir=in goto=0,2} -B 5 17.5 -32.5 22.5 -27.5 {name=s dir=inout } +B 5 -22.5 -2.5 -17.5 2.5 {name=g dir=in goto=0} +B 5 17.5 -32.5 22.5 -27.5 {name=s dir=inout} B 5 17.5 -2.5 22.5 2.5 {name=b dir=in} T {@w\\/@l\\/@m} 7.5 -17.5 0 0 0.2 0.2 {} T {@name} 7.5 5 0 0 0.2 0.2 {999} diff --git a/xschem_library/xschem_simulator/switch-1.sym b/xschem_library/xschem_simulator/switch-1.sym index 0eb6fe07..ce2afa34 100644 --- a/xschem_library/xschem_simulator/switch-1.sym +++ b/xschem_library/xschem_simulator/switch-1.sym @@ -1,7 +1,6 @@ v {xschem version=3.0.0 file_version=1.2 } G {} K {type=switch -function0="Z 1 2 M" function1="Z 0 2 M" template="name=s1" } @@ -12,9 +11,11 @@ L 4 10 0 30 0 {} L 4 -30 0 -10 0 {} L 4 -10 0 10 -10 {} L 4 0 -40 0 -5 {} +L 4 -25 -5 -15 0 {} +L 4 -25 5 -15 0 {} B 5 -32.5 -2.5 -27.5 2.5 {name=t0 dir=inout} B 5 27.5 -2.5 32.5 2.5 {name=t1 dir=inout } -B 5 -2.5 -43.75 2.5 -38.75 {name=g dir=inout goto=0,1} +B 5 -2.5 -43.75 2.5 -38.75 {name=g dir=inout goto=1} A 4 10 0 1.25 0 360 {fill=true} A 4 -10 0 1.25 0 360 {fill=true} T {1} 20 -7.5 0 0 0.1 0.1 {} diff --git a/xschem_library/xschem_simulator/switch_level_sim.sch b/xschem_library/xschem_simulator/switch_level_sim.sch index 7b2a2684..0996f78c 100644 --- a/xschem_library/xschem_simulator/switch_level_sim.sch +++ b/xschem_library/xschem_simulator/switch_level_sim.sch @@ -296,14 +296,14 @@ C {p.sym} 300 -1210 3 0 {name=m12 model=cmosp w=wp l=lp m=1 } C {lab_pin.sym} 300 -1230 3 1 {name=p34 lab=VCC} C {vdd.sym} 100 -1290 0 0 {name=l5 lab=VCC} C {gnd.sym} 100 -1030 0 0 {name=l6 lab=GND} -C {n.sym} 650 -1110 1 0 {name=m13 model=cmosn w=wn l=lln m=1} +C {n.sym} 650 -1110 3 1 {name=m13 model=cmosn w=wn l=lln m=1} C {lab_pin.sym} 650 -1090 1 1 {name=p35 lab=GND} -C {p.sym} 650 -950 3 0 {name=m14 model=cmosp w=wp l=lp m=1 } +C {p.sym} 650 -950 1 1 {name=m14 model=cmosp w=wp l=lp m=1 } C {lab_pin.sym} 650 -970 3 1 {name=p36 lab=VCC} C {inv_2.sym} 740 -1160 0 1 {name=x19 VGND=VGND VNB=VNB VPB=VPB VPWR=VPWR prefix=sky130_fd_sc_hd__ } -C {n.sym} 650 -1370 1 0 {name=m15 model=cmosn w=wn l=lln m=1} +C {n.sym} 650 -1370 3 1 {name=m15 model=cmosn w=wn l=lln m=1} C {lab_pin.sym} 650 -1350 1 1 {name=p37 lab=GND} -C {p.sym} 650 -1210 3 0 {name=m16 model=cmosp w=wp l=lp m=1 } +C {p.sym} 650 -1210 1 1 {name=m16 model=cmosp w=wp l=lp m=1 } C {lab_pin.sym} 650 -1230 3 1 {name=p38 lab=VCC} C {vdd.sym} 850 -1290 0 1 {name=l7 lab=VCC} C {gnd.sym} 850 -1030 0 1 {name=l8 lab=GND} @@ -312,7 +312,7 @@ C {switch-1.sym} 1370 -1260 0 0 {name=s4} C {inv_2.sym} 1370 -1190 0 0 {name=x20 VGND=VGND VNB=VNB VPB=VPB VPWR=VPWR prefix=sky130_fd_sc_hd__ } C {diode_3.sym} 1270 -1280 0 0 {name=x12 VTH=0.6 RON=10 ROFF=1G} C {ipin.sym} 70 -170 0 0 { name=p19 lab=B } -C {dev-1.sym} 1530 -620 0 1 {name=s3} +C {dev-2.sym} 1530 -620 0 1 {name=s3} C {invert-1.sym} 1370 -620 0 0 {name=s1} C {dev-1.sym} 1210 -620 0 0 {name=s2} C {vdd.sym} 1080 -620 0 0 {name=l9 lab=VCC}