allow "*_ignore" attributes on wires as wella s on instances

This commit is contained in:
stefan schippers 2026-03-28 01:56:24 +01:00
parent 9ebbce0926
commit bdd4338c13
9 changed files with 175 additions and 29 deletions

View File

@ -850,6 +850,42 @@ int set_sym_flags(xSymbol *sym)
return 0;
}
int set_wire_flags(xWire *wire)
{
const char *ptr;
wire->flags = 0;
ptr = get_tok_value(wire->prop_ptr,"spice_ignore",0);
if(!strboolcmp(ptr, "true") || !strcmp(ptr, "open"))
wire->flags |= SPICE_IGNORE;
ptr = get_tok_value(wire->prop_ptr,"spectre_ignore",0);
if(!strboolcmp(ptr, "true") || !strcmp(ptr, "open"))
wire->flags |= SPECTRE_IGNORE;
ptr = get_tok_value(wire->prop_ptr,"verilog_ignore",0);
if(!strboolcmp(ptr, "true") || !strcmp(ptr, "open"))
wire->flags |= VERILOG_IGNORE;
ptr = get_tok_value(wire->prop_ptr,"vhdl_ignore",0);
if(!strboolcmp(ptr, "true") || !strcmp(ptr, "open"))
wire->flags |= VHDL_IGNORE;
ptr = get_tok_value(wire->prop_ptr,"tedax_ignore",0);
if(!strboolcmp(ptr, "true") || !strcmp(ptr, "open"))
wire->flags |= TEDAX_IGNORE;
ptr = get_tok_value(wire->prop_ptr,"lvs_ignore",0);
if(!strboolcmp(ptr, "true") || !strcmp(ptr, "open"))
wire->flags |= LVS_IGNORE_OPEN;
dbg(1, "set_wire_flags: wire flags=%d\n", wire->flags);
return 0;
}
int set_inst_flags(xInstance *inst)
{
const char *ptr;
@ -956,6 +992,9 @@ void reset_caches(void)
{
int i;
dbg(1, "reset_caches()\n");
for(i = 0; i < xctx->wires; i++) {
set_wire_flags(&xctx->wire[i]);
}
for(i = 0; i < xctx->instances; i++) {
set_inst_flags(&xctx->inst[i]);
}
@ -2072,7 +2111,6 @@ void toggle_ignore(void)
else if(flag == 1) flag = 2;
else flag = 0;
if(flag == 1) {
my_strdup(_ALLOC_ID_, &xctx->inst[i].prop_ptr, subst_token(xctx->inst[i].prop_ptr, attr, "true"));
} else if(flag == 2) {
@ -2086,6 +2124,37 @@ void toggle_ignore(void)
xctx->prep_net_structs=0;
xctx->prep_hi_structs=0;
}
if(xctx->sel_array[n].type == WIRE) {
i = xctx->sel_array[n].n;
if(first) {
xctx->push_undo();
first = 0;
}
flag = 0;
ignore_str = get_tok_value(xctx->wire[i].prop_ptr, attr, 0);
if(!strcmp(ignore_str, "short")) flag = 2;
else if(!strboolcmp(ignore_str, "true")) flag = 1;
if(flag == 0) flag = 1;
else if(flag == 1) flag = 2;
else flag = 0;
if(flag == 1) {
my_strdup(_ALLOC_ID_, &xctx->wire[i].prop_ptr, subst_token(xctx->wire[i].prop_ptr, attr, "true"));
} else if(flag == 2) {
my_strdup(_ALLOC_ID_, &xctx->wire[i].prop_ptr, subst_token(xctx->wire[i].prop_ptr, attr, "short"));
} else {
my_strdup(_ALLOC_ID_, &xctx->wire[i].prop_ptr, subst_token(xctx->wire[i].prop_ptr, attr, NULL));
}
set_wire_flags(&xctx->wire[i]);
set_modify(1);
xctx->prep_hash_inst=0;
xctx->prep_net_structs=0;
xctx->prep_hi_structs=0;
}
}
draw();
}

View File

@ -65,6 +65,7 @@ void update_conn_cues(int layer, int draw_cues, int dr_win)
y2 = Y_TO_XSCHEM(xctx->areay2);
for(init_wire_iterator(&ctx, x1, y1, x2, y2); ( wireptr = wire_iterator_next(&ctx) ) ;) {
k=wireptr->n;
if(skip_wire(k)) continue;
/* optimization when editing small areas (detailed zoom) of a huge schematic */
if(LINE_OUTSIDE(wire[k].x1, wire[k].y1, wire[k].x2, wire[k].y2, x1, y1, x2, y2)) continue;
for(l = 0;l < 2; ++l) {
@ -82,6 +83,7 @@ void update_conn_cues(int layer, int draw_cues, int dr_win)
get_square(x0, y0, &sqx, &sqy);
for(wptr = xctx->wire_spatial_table[sqx][sqy] ; wptr ; wptr = wptr->next) {
i = wptr->n;
if(skip_wire(i)) continue;
if(i == k) {
continue; /* no check wire against itself */
}
@ -103,6 +105,7 @@ void update_conn_cues(int layer, int draw_cues, int dr_win)
save_draw = xctx->draw_window; xctx->draw_window = dr_win;
for(init_wire_iterator(&ctx, x1, y1, x2, y2); ( wireptr = wire_iterator_next(&ctx) ) ;) {
i = wireptr->n;
if(skip_wire(i)) continue;
/* optimization when editing small areas (detailed zoom) of a huge schematic */
if(LINE_OUTSIDE(wire[i].x1, wire[i].y1,
wire[i].x2, wire[i].y2, x1, y1, x2, y2)) continue;
@ -170,6 +173,7 @@ void trim_wires(void)
/* break all wires */
for(i=0;i<xctx->wires; ++i) {
int hashloopcnt = 0;
if(skip_wire(i)) continue;
x0 = xctx->wire[i].x1;
y0 = xctx->wire[i].y1;
get_square(x0, y0, &sqx, &sqy);
@ -187,6 +191,7 @@ void trim_wires(void)
}
j = wptr->n;
if(i == j) continue;
if(skip_wire(j)) continue;
++hashloopcnt;
breaks = check_breaks(xctx->wire[j].x1, xctx->wire[j].y1, xctx->wire[j].x2, xctx->wire[j].y2, x0, y0);
if(breaks) { /* wire[i] breaks wire[j] */
@ -241,6 +246,7 @@ void trim_wires(void)
memset(wireflag, 0, xctx->wires*sizeof(unsigned short));
for(i=0;i<xctx->wires; ++i) {
if(wireflag[i]) continue;
if(skip_wire(i)) continue;
x0 = xctx->wire[i].x1;
y0 = xctx->wire[i].y1;
get_square(x0, y0, &sqx, &sqy);
@ -257,6 +263,7 @@ void trim_wires(void)
} else break;
}
j = wptr->n;
if(skip_wire(j)) continue;
if(i == j || wireflag[j]) continue;
includes = check_includes(xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2,
@ -307,6 +314,7 @@ void trim_wires(void)
x0 = xctx->wire[i].x1;
y0 = xctx->wire[i].y1;
xctx->wire[i].end1 = xctx->wire[i].end2 = 0;
if(skip_wire(i)) continue;
get_square(x0, y0, &sqx, &sqy);
k=1;
for(wptr = xctx->wire_spatial_table[sqx][sqy] ; ; wptr = wptr->next) {
@ -321,6 +329,7 @@ void trim_wires(void)
} else break;
}
j = wptr->n;
if(skip_wire(j)) continue;
if(i == j) continue;
if( touch(xctx->wire[j].x1, xctx->wire[j].y1, xctx->wire[j].x2, xctx->wire[j].y2, x0,y0) ) {
/* not parallel */
@ -344,11 +353,13 @@ void trim_wires(void)
/* merge parallel touching (in wire[i].x2, wire[i].y2) wires */
for(i=0;i<xctx->wires; ++i) {
if(wireflag[i]) continue;
if(skip_wire(i)) continue;
x0 = xctx->wire[i].x2;
y0 = xctx->wire[i].y2;
get_square(x0, y0, &sqx, &sqy);
for(wptr = xctx->wire_spatial_table[sqx][sqy] ; wptr ; wptr = wptr->next) {
j = wptr->n;
if(skip_wire(j)) continue;
if(i == j || wireflag[j]) continue;
if( touch(xctx->wire[j].x1, xctx->wire[j].y1, xctx->wire[j].x2, xctx->wire[j].y2, x0,y0) &&
/* parallel */
@ -495,6 +506,7 @@ void break_wires_at_point(double x0, double y0, int align)
xctx->wire[xctx->wires].x2=x0;
xctx->wire[xctx->wires].y2=y0;
xctx->wire[xctx->wires].sel=0;
xctx->wire[xctx->wires].flags = xctx->wire[i].flags;
xctx->wire[xctx->wires].prop_ptr=NULL;
my_strdup(_ALLOC_ID_, &xctx->wire[xctx->wires].prop_ptr, xctx->wire[i].prop_ptr);
xctx->wire[xctx->wires].bus = xctx->wire[i].bus;
@ -566,6 +578,7 @@ void break_wires_at_pins(int remove)
xctx->wire[xctx->wires].y1=xctx->wire[i].y1;
xctx->wire[xctx->wires].end1 = xctx->wire[i].end1;
xctx->wire[xctx->wires].end2 = 1;
xctx->wire[xctx->wires].flags = xctx->wire[i].flags;
xctx->wire[xctx->wires].x2=x0;
xctx->wire[xctx->wires].y2=y0;
xctx->wire[xctx->wires].sel=xctx->wire[i].sel;
@ -660,6 +673,7 @@ void break_wires_at_pins(int remove)
xctx->wire[xctx->wires].y2=y0;
xctx->wire[xctx->wires].end1 = xctx->wire[i].end1;
xctx->wire[xctx->wires].end2 = 1;
xctx->wire[xctx->wires].flags = xctx->wire[i].flags;
xctx->wire[xctx->wires].sel=SELECTED;
set_first_sel(WIRE, xctx->wires, 0);
xctx->wire[xctx->wires].prop_ptr=NULL;

View File

@ -5435,9 +5435,16 @@ void draw(void)
if(i >= xctx->wires) break;
}
if(xctx->wire[i].bus == -1.0) {
drawline(cc, THICK, xctx->wire[i].x1,xctx->wire[i].y1,
xctx->wire[i].x2,xctx->wire[i].y2, xctx->wire[i].bus, 0, NULL);
if(skip_wire(i))
drawline(GRIDLAYER, THICK, xctx->wire[i].x1,xctx->wire[i].y1,
xctx->wire[i].x2,xctx->wire[i].y2, xctx->wire[i].bus, 2, NULL);
else
drawline(cc, THICK, xctx->wire[i].x1,xctx->wire[i].y1,
xctx->wire[i].x2,xctx->wire[i].y2, xctx->wire[i].bus, 0, NULL);
}
else if(skip_wire(i))
drawline(GRIDLAYER, NOW, xctx->wire[i].x1,xctx->wire[i].y1,
xctx->wire[i].x2,xctx->wire[i].y2, xctx->wire[i].bus, 2, NULL);
else
drawline(cc, ADD, xctx->wire[i].x1,xctx->wire[i].y1,
xctx->wire[i].x2,xctx->wire[i].y2, xctx->wire[i].bus, 0, NULL);

View File

@ -1213,7 +1213,7 @@ static int edit_wire_property(void)
my_strdup(_ALLOC_ID_, &xctx->wire[k].prop_ptr,(char *) tclgetvar("tctx::retval"));
}
xctx->wire[k].bus = bus = get_attr_val(get_tok_value(xctx->wire[k].prop_ptr,"bus",0));
set_wire_flags(&xctx->wire[k]);
if(bus > 0.0) width = XLINEWIDTH(bus) / 2.0;
else width = INT_BUS_WIDTH(xctx->lw) / 2.0;
if(oldbus / 2.0 > width) width = XLINEWIDTH(oldbus) / 2.0;

View File

@ -510,7 +510,7 @@ void hash_wire(int what, int n, int incremental)
int x1a, x2a, y1a, y2a;
Wireentry *wptr;
xWire * const wire = xctx->wire;
if(skip_wire(n)) return;
dbg(1, "hash_wire(): what=%d n=%d incremental=%d\n", what, n, incremental);
wire[n].end1 = wire[n].end2=-1;
x1=wire[n].x1;
@ -1011,7 +1011,7 @@ static int wirecheck(int k) /* recursive routine */
double x1, y1, x2, y2;
Wireentry *wptr;
xWire * const wire = xctx->wire;
if(skip_wire(k)) return err;
dbg(1, "wirecheck: %d\n", k);
x1 = wire[k].x1; y1 = wire[k].y1;
x2 = wire[k].x2; y2 = wire[k].y2;
@ -1035,6 +1035,7 @@ static int wirecheck(int k) /* recursive routine */
/*check if wire[k] touches wires in square [tmpi, tmpj] */
for(wptr = xctx->wire_spatial_table[tmpi][tmpj]; wptr; wptr = wptr->next) {
int n = wptr->n;
if(skip_wire(n)) continue;
if(n == k) { /* itself */
err |= name_attached_inst_to_net(k, tmpi, tmpj);
continue;
@ -1067,6 +1068,7 @@ static int name_attached_nets(double x0, double y0, int sqx, int sqy, const char
Wireentry *wptr;
for(wptr = xctx->wire_spatial_table[sqx][sqy]; wptr; wptr = wptr->next) {
int n = wptr->n;
if(skip_wire(n)) continue;
if(touch(wire[n].x1, wire[n].y1, wire[n].x2, wire[n].y2, x0,y0)) {
if(!wire[n].node) {
my_strdup(_ALLOC_ID_, &wire[n].node, node);
@ -1128,6 +1130,33 @@ int shorted_instance(int i, int lvs_ignore)
return shorted;
}
static int skip_wire2(int i, int lvs_ignore, int mask)
{
int skip = 0;
if(xctx->wire[i].flags & mask) skip = 1;
else if(lvs_ignore && (xctx->wire[i].flags & LVS_IGNORE)) skip = 1;
return skip;
}
int skip_wire(int i)
{
int skip = 0;
if(xctx->netlist_type == CAD_SPICE_NETLIST)
skip = skip_wire2(i, netlist_lvs_ignore, SPICE_IGNORE);
else if(xctx->netlist_type == CAD_VERILOG_NETLIST)
skip = skip_wire2(i, netlist_lvs_ignore, VERILOG_IGNORE);
else if(xctx->netlist_type == CAD_SPECTRE_NETLIST)
skip = skip_wire2(i, netlist_lvs_ignore, SPECTRE_IGNORE);
else if(xctx->netlist_type == CAD_VHDL_NETLIST)
skip = skip_wire2(i, netlist_lvs_ignore, VHDL_IGNORE);
else if(xctx->netlist_type == CAD_TEDAX_NETLIST)
skip = skip_wire2(i, netlist_lvs_ignore, TEDAX_IGNORE);
else skip = 0;
dbg(1, "skip_wire(): wire %d skip=%d\n", i, skip);
return skip;
}
static int skip_instance2(int i, int lvs_ignore, int mask)
{
int skip = 0;
@ -1464,6 +1493,7 @@ static int set_unnamed_net(int i)
{
int err = 0;
char tmp_str[30];
if(skip_wire(i)) return err;
my_snprintf(tmp_str, S(tmp_str), "#net%d", get_unnamed_node(1,0,0));
my_strdup(_ALLOC_ID_, &xctx->wire[i].node, tmp_str);
my_strdup(_ALLOC_ID_, &xctx->wire[i].prop_ptr, subst_token(xctx->wire[i].prop_ptr, "lab", tmp_str));
@ -1481,6 +1511,7 @@ static int name_unlabeled_nets()
dbg(2, "name_unlabeled_nets(): naming nets that dont touch labels\n");
for (i = 0; i < xctx->wires; ++i)
{
if(skip_wire(i)) continue;
if(xctx->wire[i].node == NULL)
{
err |= set_unnamed_net(i);

View File

@ -2836,9 +2836,11 @@ static void load_wire(FILE *fd)
ptr[i].prop_ptr = NULL;
ptr[i].end1 = ptr[i].end2 = ptr[i].sel = 0;
ptr[i].bus = 0.0;
ptr[i].flags = 0;
load_ascii_string( &ptr[i].prop_ptr, fd);
ORDER(ptr[i].x1, ptr[i].y1, ptr[i].x2, ptr[i].y2);
ptr[i].bus = get_attr_val(get_tok_value(ptr[i].prop_ptr, "bus", 0));
set_wire_flags(&ptr[i]);
ptr[i].node = NULL;
xctx->wires++;
}

View File

@ -351,6 +351,7 @@ int storeobject(int pos, double x1,double y1,double x2,double y2,
xctx->wire[n].bus = get_attr_val(get_tok_value(prop_ptr,"bus",0));
}
xctx->wire[n].sel=sel;
set_wire_flags(&xctx->wire[n]);
if(sel == SELECTED) set_first_sel(WIRE, n, 0);
xctx->wires++;
modified = 1;

View File

@ -462,6 +462,7 @@ typedef struct
char *node;
char *prop_ptr;
double bus; /* 20171201 cache here wire "bus" property, to avoid too many get_tok_value() calls */
int flags; /* stores the *_ignore flags, see xInstance */
} xWire;
typedef struct
@ -1291,6 +1292,7 @@ extern int new_rawfile(const char *name, const char *type, const char *sweepvar,
extern char *base64_from_file(const char *f, size_t *length);
extern int set_rect_flags(xRect *r);
extern int set_text_flags(xText *t);
extern int set_wire_flags(xWire *wire);
extern int set_inst_flags(xInstance *inst);
extern int set_sym_flags(xSymbol *sym);
extern void reset_caches(void);
@ -1773,6 +1775,7 @@ extern void redraw_hilights(int clear);
extern void set_tcl_netlist_type(void);
extern void show_unconnected_pins(void);
extern int prepare_netlist_structs(int for_netlist);
extern int skip_wire(int i);
extern int skip_instance(int i, int skip_short, int lvs_ignore);
extern int shorted_instance(int i, int lvs_ignore);
extern int compare_schematics(const char *filename);

View File

@ -1,4 +1,4 @@
v {xschem version=3.4.6 file_version=1.2
v {xschem version=3.4.8RC file_version=1.3
*
* This file is part of XSCHEM,
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
@ -23,6 +23,7 @@ G {}
K {}
V {}
S {}
F {}
E {}
L 18 845 -530 880 -530 {}
L 18 845 -530 845 -450 {}
@ -35,8 +36,8 @@ L 18 880 -530 900 -580 {}
L 18 880 -530 880 -450 {}
L 18 900 -580 900 -400 {}
B 2 1200 -500 1880 -310 {flags=graph
y1 = -0.00095
y2 = 12
y1 = -0.0022
y2 = 11
divy = 6
x1=0.0246194
x2=0.0249318
@ -50,7 +51,8 @@ unitx=m
linewidth_mult=2.3
autoload=1
sim_type=tran}
sim_type=tran
hilight_wave=-1}
B 2 1200 -830 1880 -520 {flags=graph
y1 = -50
y2 = 61
@ -121,7 +123,7 @@ T {actual value
T {actual value
50u} 400 -360 0 0 0.4 0.4 {}
T {actual value
50u} 50 -750 0 0 0.4 0.4 {}
50u} 40 -760 0 0 0.4 0.4 {}
T {actual value
50u} 80 -290 0 0 0.4 0.4 {}
T {actual value
@ -166,17 +168,24 @@ N 550 -310 550 -290 {lab=VSS}
N 650 -700 710 -700 {lab=OUTM}
N 650 -240 710 -240 {lab=OUTP}
N 240 -220 260 -220 {lab=INX}
N 260 -680 350 -680 {lab=VSSX}
N 240 -860 240 -840 {lab=VPP}
N 260 -680 260 -650 {lab=VSSX}
N 260 -590 260 -570 {lab=VSS}
N 240 -680 260 -680 {lab=VSSX}
N 180 -680 240 -680 {lab=VSSX}
N 260 -680 350 -680 {lab=VSSX
}
N 240 -860 240 -840 {lab=VPP
}
N 260 -680 260 -650 {lab=VSSX
}
N 260 -590 260 -570 {lab=VSS
}
N 240 -680 260 -680 {lab=VSSX
}
N 180 -680 240 -680 {lab=VSSX
}
N 870 -1200 890 -1200 {lab=IN_INT}
N 870 -1200 870 -1130 {lab=IN_INT}
N 400 -1000 400 -980 {lab=VPP}
N 400 -540 400 -520 {lab=VPP}
N 860 -700 860 -520 {lab=OUTM}
N 860 -700 860 -520 {lab=OUTM
spice_ignore=short}
N 860 -460 860 -240 {lab=OUTP}
N 350 -890 400 -890 {lab=FBN}
N 350 -430 400 -430 {lab=FB}
@ -189,7 +198,8 @@ N 320 -1140 320 -1130 { lab=VSS}
N 320 -1210 320 -1200 { lab=VPP}
N 400 -920 400 -890 { lab=FBN}
N 400 -460 400 -430 { lab=FB}
N 240 -780 240 -680 { lab=VSSX}
N 240 -780 240 -680 { lab=VSSX
}
N 240 -320 240 -220 { lab=INX}
N 220 -1210 230 -1210 {lab=#net1}
N 220 -1050 230 -1050 {lab=#net2}
@ -208,7 +218,8 @@ C {lab_pin.sym} 360 -1130 0 1 {name=p3 lab=VSS}
C {lab_pin.sym} 860 -240 0 1 {name=p14 lab=OUTP
text_size_1=0.7
text_size_0=0.7}
C {res.sym} 860 -490 0 1 {name=R1 m=1 value=8}
C {res.sym} 860 -490 0 1 {name=R1 m=1 value=8
}
C {lab_pin.sym} 500 -1150 0 0 {name=p26 lab=VSS}
C {lab_pin.sym} 540 -1190 0 0 {name=p31 lab=IN}
C {vcvs.sym} 610 -1170 0 0 {name=E3 value=\{gain*0.99\}}
@ -254,16 +265,23 @@ C {vsource.sym} 870 -1100 0 0 {name=V3
xvalue="dc 0 pulse -.1 .1 1m .1u .1u 10.1u 20u"
value="dc 0 sin 0 1 \{frequ\} 1m"
}
C {res.sym} 240 -810 0 1 {name=R4 m=1 value=50k}
C {lab_pin.sym} 240 -860 0 0 {name=p18 lab=VPP}
C {res.sym} 260 -620 0 1 {name=R5 m=1 value=50k}
C {lab_pin.sym} 260 -570 0 0 {name=p10 lab=VSS}
C {res.sym} 240 -810 0 1 {name=R4 m=1 value=50k
}
C {lab_pin.sym} 240 -860 0 0 {name=p18 lab=VPP
}
C {res.sym} 260 -620 0 1 {name=R5 m=1 value=50k
}
C {lab_pin.sym} 260 -570 0 0 {name=p10 lab=VSS
}
C {res.sym} 400 -950 0 1 {name=R8 m=1 value=50k}
C {capa.sym} 170 -220 1 0 {name=C4 m=1 value="100n ; ic=0"}
C {lab_pin.sym} 140 -220 0 0 {name=p0 lab=IN}
C {capa.sym} 150 -680 1 0 {name=C1 m=1 value="100n ; ic=0"}
C {lab_pin.sym} 120 -680 0 0 {name=p17 lab=VSS}
C {lab_pin.sym} 240 -710 0 0 {name=p22 lab=VSSX}
C {capa.sym} 150 -680 1 0 {name=C1 m=1 value="100n ; ic=0"
}
C {lab_pin.sym} 120 -680 0 0 {name=p17 lab=VSS
}
C {lab_pin.sym} 240 -710 0 0 {name=p22 lab=VSSX
}
C {res.sym} 920 -1200 1 1 {name=R10 m=1 value=2}
C {lab_pin.sym} 400 -1000 0 0 {name=p24 lab=VPP}
C {res.sym} 400 -490 0 1 {name=R13 m=1 value=50k}
@ -335,8 +353,9 @@ C {spice_probe.sym} 350 -1210 0 0 {name=p45 analysis=tran }
C {spice_probe.sym} 350 -1050 0 0 {name=p46 analysis=tran }
C {launcher.sym} 1325 -1225 0 0 {name=h5
descr="load ngspice waves"
tclcommand="
xschem raw read $netlist_dir/poweramp.raw tran; xschem redraw
tclcommand=" xschem raw clear $netlist_dir/poweramp.raw tran
xschem raw read $netlist_dir/poweramp.raw tran
xschem redraw
"
}
C {launcher.sym} 1450 -30 0 0 {name=h6