some fixes for gcc-15 (-std=c23), smaller threshold for click & move that will abort move, added smaller verilog cosim example (tb_counter_wrapper.sch), arbitrary top level names allowed in create_new_window() and switch_window() (no tabbed interface)

This commit is contained in:
stefan schippers 2025-09-19 14:18:06 +02:00
parent 1f52d630f5
commit 92bc9cad34
11 changed files with 162 additions and 24 deletions

View File

@ -87,8 +87,8 @@ void arg_auto_print_options(FILE *fout, const char *line_prefix, const char *pad
continue;
if (*t->help_txt == '$') {
int kl = strlen(t->arg_key);
if (kl > pl)
kl = pl;
if (kl >= pl)
kl = pl-1;
fprintf(fout, "%s--%s%s%s\n", line_prefix, t->arg_key, padding+kl, t->help_txt+1);
}
else

View File

@ -2437,7 +2437,7 @@ static void handle_motion_notify(int event, KeySym key, int state, int rstate, i
!(state & ShiftMask) && !(xctx->ui_state & (PLACE_SYMBOL | PLACE_TEXT)))
{
/* make motion a bit sticky. require 10 pixels (screen units, not xschem units) */
if(abs(mx - xctx->mx_save) > tk_scaling * 10 || abs(my - xctx->my_save) > tk_scaling * 10) {
if(abs(mx - xctx->mx_save) > tk_scaling * 5 || abs(my - xctx->my_save) > tk_scaling * 5) {
xctx->mouse_moved = 1;
if(!xctx->drag_elements) {
int stretch = (state & ControlMask) ? !enable_stretch : enable_stretch;
@ -4382,7 +4382,7 @@ static void handle_button_release(int event, KeySym key, int state, int button,
xctx->drag_elements = 0;
}
else if(xctx->ui_state & STARTMOVE && xctx->drag_elements) {
/* motion was below 10 screen units so no motion was set, abort */
/* motion was below 5 screen units so no motion was set, abort */
if(!(state & ShiftMask) && !xctx->mouse_moved) {
move_objects(ABORT,0,0,0);
} else {

View File

@ -799,8 +799,8 @@ void my_realloc(int id, void *ptr,size_t size)
char *my_free(int id, void *ptr)
{
if(*(void **)ptr) {
free(*(void **)ptr);
dbg(3, "\nmy_free(%d,): freeing %p\n", id, *(void **)ptr);
free(*(void **)ptr);
*(void **)ptr=NULL;
} else {
dbg(3, "\n--> my_free(%d,): trying to free NULL pointer\n", id);

View File

@ -80,7 +80,7 @@ static char ps_font_family[80] = "Helvetica"; /* Courier Times Helvetica Symbol
static int ps_embedded_image(xRect* r, double x1, double y1, double x2, double y2, int rot, int flip)
{
#if defined(HAS_LIBJPEG) && HAS_CAIRO==1
int i, jpg;
int i, jpg = -1;
int size_x, size_y;
unsigned char *ptr = NULL;
int invertImage;

View File

@ -3569,7 +3569,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
* Open/destroy a new tab or window
* create: create new empty window or with 'file' loaded if 'file' given.
* The win_path must be given (even {} is ok).
* non empty win_path ({1}) will avoid warnings if opening the
* '1' win_path ({1}) will avoid warnings if opening the
* same file multiple times.
* destroy: destroy tab/window identified by win_path. Example:
* xschem new_schematic destroy .x1.drw
@ -3855,7 +3855,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
int fullzoom = 0;
int w = 0, h = 0;
int eps = 0;
double x1, y1, x2, y2;
double x1 = 0., y1 = 0., x2 = 0., y2 = 0.;
if(!strcmp(argv[2],"eps")) eps = 1;
if(eps && xctx->lastsel == 0) {
@ -3930,7 +3930,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[2], "png")) {
double save_lw = xctx->lw;
int w = 0, h = 0;
double x1, y1, x2, y2;
double x1 = 0., y1 = 0., x2 = 0., y2 = 0.;
if(argc == 6) {
if(xctx->lastsel) {
xRect boundbox;
@ -3993,7 +3993,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[2], "svg")) {
double save_lw = xctx->lw;
int w = 0, h = 0;
double x1, y1, x2, y2;
double x1 = 0., y1 = 0., x2 = 0., y2 = 0.;
if(argc == 6) {
if(xctx->lastsel) {
xRect boundbox;

View File

@ -1533,12 +1533,13 @@ static int switch_window(int *window_count, const char *win_path, int tcl_ctx)
}
if(!strcmp(win_path, xctx->current_win_path)) return 0; /* already there */
n = get_tab_or_window_number(win_path);
if(n == 0) my_snprintf(my_win_path, S(my_win_path), ".drw");
else my_snprintf(my_win_path, S(my_win_path), ".x%d.drw", n);
if(n == -1) {
dbg(0, "new_schematic(\"switch\"...): no window to switch to found: %s\n", win_path);
return 1;
}
if(n == 0) my_snprintf(my_win_path, S(my_win_path), ".drw");
/* else my_snprintf(my_win_path, S(my_win_path), ".x%d.drw", n); */
else my_snprintf(my_win_path, S(my_win_path), "%s", window_path[n]);
if(*window_count) {
/* build my_win_path since win_path can also be a filename */
dbg(1, "new_schematic(\"switch\"...): %s\n", my_win_path);
@ -1615,8 +1616,8 @@ static int switch_tab(int *window_count, const char *win_path, int dr)
return 0;
}
/* non NULL and not empty noconfirm is used to avoid warning for duplicated filenames */
static void create_new_window(int *window_count, const char *noconfirm, const char *fname, int dr)
/* non NULL and not empty win_path is used to avoid warning for duplicated filenames */
static void create_new_window(int *window_count, const char *win_path, const char *fname, int dr)
{
double save_lw = xctx->lw;
Window win_id = 0LU;
@ -1626,7 +1627,7 @@ static void create_new_window(int *window_count, const char *noconfirm, const ch
dbg(1, "new_schematic() create: fname=%s *window_count = %d\n", fname, *window_count);
if(noconfirm && noconfirm[0]) confirm = 0;
if(win_path && win_path[0]) confirm = 0;
my_strncpy(prev_window, xctx->current_win_path, S(prev_window));
if(confirm && fname && fname[0] && check_loaded(fname, toppath)) {
char msg[PATH_MAX+100];
@ -1672,8 +1673,13 @@ static void create_new_window(int *window_count, const char *noconfirm, const ch
dbg(0, "new_schematic(\"create\"...): no more free slots\n");
return;
}
my_snprintf(window_path[n], S(window_path[n]), ".x%d.drw", n);
my_snprintf(toppath, S(toppath), ".x%d", n);
if(win_path && win_path[0] == '.') {
my_snprintf(window_path[n], S(window_path[n]), "%s.drw", win_path);
my_snprintf(toppath, S(toppath), "%s", win_path);
} else {
my_snprintf(window_path[n], S(window_path[n]), ".x%d.drw", n);
my_snprintf(toppath, S(toppath), ".x%d", n);
}
if(has_x) {
tclvareval("toplevel ", toppath, " -bg {} -width 400 -height 400", NULL);
tclvareval("build_widgets ", toppath, NULL);

View File

@ -1,4 +1,4 @@
v {xschem version=3.4.7RC 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 3 860 -680 910 -660 {}
L 3 830 -800 1150 -800 {}
@ -66,12 +67,12 @@ A 7 884.1666666666666 -210 39.58991173406564 210.3432488842396 198.9246444160511
P 1 10 880 -480 870 -540 950 -520 910 -500 940 -470 920 -470 910 -450 890 -490 880 -470 880 -480 {dash=3}
P 4 6 830 -460 830 -550 820 -500 780 -560 770 -520 810 -480 {bezier=1}
P 15 11 870 -510 880 -550 900 -520 910 -540 920 -510 940 -520 920 -480 890 -490 860 -470 840 -520 870 -510 {fill=true}
T {Welcome to XSCHEM!} 110 -1130 0 0 1 1 {layer=5}
T {Welcome to XSCHEM!} 100 -1150 0 0 1 1 {layer=5}
T {This is a test schematic window
On the left you see some sample circuits. You may descend into any of these by selecting one with a left mouse button click and
pressing the 'e' key, or by menu 'Edit -> Push Schematic'. You can return here after descending into a schematic by hitting
'<Ctrl>-e' or by menu 'Edit -> Pop'.} 60 -1060 0 0 0.4 0.4 {}
'<Ctrl>-e' or by menu 'Edit -> Pop'.} 60 -1070 0 0 0.4 0.4 {}
T {Lines} 960 -680 0 0 0.6 0.6 {layer=4}
T {Rectangles /
Ellipses} 960 -640 0 0 0.6 0.6 {layer=4}
@ -99,8 +100,8 @@ T {Simulation
Graphs
} 1530 -550 0 0 0.6 0.6 {layer=4}
T {Bus rippers} 580 -380 0 0 0.6 0.6 {layer=4}
T {Verilog-A example} 800 -940 0 0 0.4 0.4 {}
T {Ngspice + Verilog Cosimulation example} 1190 -940 0 0 0.4 0.4 {}
T {Verilog-A example} 800 -950 0 0 0.4 0.4 {}
T {Ngspice + Verilog Cosimulation example} 1190 -950 0 0 0.4 0.4 {}
N 910 -410 940 -410 {lab=#net1}
N 860 -380 860 -360 {lab=#net2}
N 860 -380 920 -380 {lab=#net2}
@ -1501,5 +1502,6 @@ C {autozero_comp.sym} 480 -500 0 0 {name=x29}
C {tb_symbol_include.sym} 480 -780 0 0 {name=x30}
C {intuitive_interface_cheatsheet.sym} 1060 -100 0 0 {name=x31}
C {test_nyquist.sym} 480 -460 0 0 {name=x32}
C {tb_diff_amp.sym} 890 -890 0 0 {name=x33}
C {tb_sar_adc.sym} 1360 -890 0 0 {name=x34}
C {tb_diff_amp.sym} 890 -900 0 0 {name=x33}
C {tb_sar_adc.sym} 1360 -870 0 0 {name=x34}
C {tb_counter_wrapper.sym} 1360 -900 0 0 {name=x35}

View File

@ -0,0 +1,21 @@
v {xschem version=3.4.8RC file_version=1.3}
G {}
K {type=primitive
format="@name [ @@clk ] [ @@count[3..0] ] @model"
template="name=a1 model=counter"
}
V {}
S {}
F {}
E {}
L 4 50 0 70 0 {}
L 4 -70 0 -50 0 {}
B 5 67.5 -2.5 72.5 2.5 {name=count[3..0] dir=out}
B 5 -72.5 -2.5 -67.5 2.5 {name=clk dir=in}
P 4 5 50 -10 -50 -10 -50 10 50 10 50 -10 {}
P 4 8 -10 20 -10 40 -20 40 -5 60 10 40 -0 40 -0 20 -10 20 {}
T {@symname} -68 -31 0 0 0.3 0.3 {}
T {@name} 30 -27 0 0 0.2 0.2 {}
T {count[3..0]} 45 -4 0 1 0.2 0.2 {}
T {clk} -45 -4 0 0 0.2 0.2 {}
T {tcleval([read_data [abs_sym_path counter.v]])} -145 65 0 0 0.2 0.2 {layer=4 font="courier new" weight=bold}

View File

@ -0,0 +1,18 @@
`timescale 1ns/1ns // needed for Icarus
module counter (
input clk,
output reg [3:0] count
);
initial begin
$display("initial");
count = 0;
end
always @(posedge clk) begin
count <= count + 1;
$display("clock event: count=%d", count);
end
endmodule

View File

@ -0,0 +1,83 @@
v {xschem version=3.4.8RC file_version=1.3}
G {}
K {}
V {}
S {}
F {}
E {}
B 2 20 -770 1060 -430 {flags=graph
y1=0
y2=2
ypos1=0.12703394
ypos2=1.7910429
divy=5
subdivy=1
unity=1
x1=-3.9199067e-07
x2=1.9268808e-05
divx=5
subdivx=1
xlabmag=1.0
ylabmag=1.0
node="clk
----
count_out; count_out3,count_out2,count_out1,count_out0
---
count_out3
count_out2
count_out1
count_out0"
color="8 9 11 9 11 11 11 11"
dataset=-1
unitx=1
logx=0
logy=0
digital=1}
T {These capacitors are used to force
auto-creation of dac bridges
(digital count_out --> analog count_out).
Analog nodes can be plotted and saved
in raw file.} 800 -230 0 0 0.3 0.3 {layer=7}
N 50 -110 50 -90 {lab=CLK}
N 440 -310 570 -310 {lab=CLK}
N 710 -310 840 -310 {bus=1 lab=count_out[3..0]}
N 800 -310 800 -270 {lab=count_out[3..0]}
C {vsource.sym} 50 -60 0 0 {name=VCLOCK value="pulse 0 'VCC' 500n 10n 10n 490n 1u"}
C {lab_pin.sym} 50 -30 0 0 {name=p6 lab=0}
C {lab_pin.sym} 50 -110 0 0 {name=p13 lab=CLK}
C {code_shown.sym} 20 -370 0 0 {name=COMMANDS only_toplevel=false value="
.param VCC=1.8
.control
save all
tran 10n 50u
remzerovec
write tb_counter_wrapper.raw
.endc
"}
C {launcher.sym} 460 -390 0 0 {name=h5
descr="load waves"
tclcommand="xschem raw_read $netlist_dir/[file tail [file rootname [xschem get current_name]]].raw tran"
}
C {lab_pin.sym} 440 -310 0 0 {name=p3 lab=CLK}
C {lab_pin.sym} 840 -310 0 1 {name=p4 lab=count_out[3..0]}
C {counter.sym} 640 -310 0 0 {name=a1 model=counter
**** put an asteric or any other character before (and no spaces in between)
**** the model you DON'T want to use:
***Verilator***
*device_model=".model counter d_cosim simulation=\\"./counter.so\\""
***Icarus_verilog***
device_model=".model counter d_cosim simulation=\\"ivlng\\" sim_args=[\\"counter\\"]"
tclcommand="edit_file counter.v"}
C {parax_cap.sym} 800 -260 0 0 {name=C2[3..0] gnd=0 value=1f m=1}
C {launcher.sym} 870 -400 0 0 {name=h3
descr="Verilate Design"
tclcommand="execute 1 sh -c \\"cd $netlist_dir; ngspice vlnggen [abs_sym_path counter.v]\\""}
C {launcher.sym} 870 -360 0 0 {name=h1
descr="Icarusate Design"
tclcommand="execute 1 sh -c \\"cd $netlist_dir; iverilog -o counter [abs_sym_path counter.v]\\""
}

View File

@ -0,0 +1,8 @@
v {xschem version=3.4.8RC file_version=1.3}
K {type=subcircuit
format="@name @pinlist @symname"
template="name=x1"
}
T {@symname} -99 -6 0 0 0.3 0.3 {}
T {@name} 135 -22 0 0 0.2 0.2 {}
P 4 5 130 -10 -130 -10 -130 10 130 10 130 -10 {}