From 291ba023399d3dc0cb78ce98fcb79da3bea8268d Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Fri, 6 Sep 2024 10:24:12 +0200 Subject: [PATCH] save 4 vars ( node, ph(node), re(node, im(node) ) instead of 2 ( node, ph(node )for ac plots --- src/save.c | 66 +++++++++++++++++------- xschem_library/examples/cmos_example.sch | 25 +++++---- 2 files changed, 62 insertions(+), 29 deletions(-) diff --git a/src/save.c b/src/save.c index 86615bff..a622a94b 100644 --- a/src/save.c +++ b/src/save.c @@ -402,15 +402,17 @@ static void read_binary_block(FILE *fd, Raw *raw, int ac) __int3264 filepos; #endif int npoints; - + int rawvars = raw->nvars; if(!raw) { dbg(0, "read_binary_block() no raw struct allocated\n"); return; } + /* we store 4 variables (mag, phase, real and imag) but raw file has only real and imag */ + if(ac) rawvars >>= 1; /* read buffer */ - tmp = my_calloc(_ALLOC_ID_, raw->nvars, (sizeof(double *) )); + tmp = my_calloc(_ALLOC_ID_, rawvars, (sizeof(double *) )); /* if sweep1 and sweep2 are given calculate actual npoints that will be loaded */ npoints = raw->npoints[raw->datasets]; @@ -419,7 +421,7 @@ static void read_binary_block(FILE *fd, Raw *raw, int ac) npoints = 0; filepos = xftell(fd); /* store file pointer position */ for(p = 0; p < raw->npoints[raw->datasets]; p++) { - if(fread(tmp, sizeof(double), raw->nvars, fd) != raw->nvars) { + if(fread(tmp, sizeof(double), rawvars, fd) != rawvars) { dbg(0, "Warning: binary block is not of correct size\n"); } sweepvar = tmp[0]; @@ -440,7 +442,7 @@ static void read_binary_block(FILE *fd, Raw *raw, int ac) /* read binary block */ p = 0; for(i = 0; i < raw->npoints[raw->datasets]; i++) { - if(fread(tmp, sizeof(double), raw->nvars, fd) != raw->nvars) { + if(fread(tmp, sizeof(double), rawvars, fd) != rawvars) { dbg(0, "Warning: binary block is not of correct size\n"); } @@ -451,18 +453,23 @@ static void read_binary_block(FILE *fd, Raw *raw, int ac) /* assign to xschem struct, memory aligned per variable, for cache locality */ if(ac) { - for(v = 0; v < raw->nvars; v += 2) { /*AC analysis: calculate magnitude */ + int vv = 0; + for(v = 0; v < raw->nvars; v += 4) { /*AC analysis: calculate magnitude */ + vv = v >> 1; if( v == 0 ) /* sweep var */ - raw->values[v][offset + p] = (SPICE_DATA)sqrt( tmp[v] * tmp[v] + tmp[v + 1] * tmp[v + 1]); + raw->values[v][offset + p] = (SPICE_DATA)sqrt( tmp[vv] * tmp[vv] + tmp[vv + 1] * tmp[vv + 1]); else /* magnitude */ /* avoid 0 for dB calculations */ - if(tmp[v] == 0.0 && tmp[v + 1] == 0.0) raw->values[v][offset + p] = 1e-35f; + if(tmp[vv] == 0.0 && tmp[vv + 1] == 0.0) raw->values[v][offset + p] = 1e-35f; else raw->values[v][offset + p] = - (SPICE_DATA)sqrt(tmp[v] * tmp[v] + tmp[v + 1] * tmp[v + 1]); + (SPICE_DATA)sqrt(tmp[vv] * tmp[vv] + tmp[vv + 1] * tmp[vv + 1]); /* AC analysis: calculate phase */ - if(tmp[v] == 0.0 && tmp[v + 1] == 0.0) raw->values[v + 1] [offset + p] = 0.0; + if(tmp[vv] == 0.0 && tmp[vv + 1] == 0.0) raw->values[v + 1] [offset + p] = 0.0; else raw->values[v + 1] [offset + p] = - (SPICE_DATA)(atan2(tmp[v + 1], tmp[v]) * 180.0 / XSCH_PI); + (SPICE_DATA)(atan2(tmp[vv + 1], tmp[vv]) * 180.0 / XSCH_PI); + + raw->values[v + 2] [offset + p] = (SPICE_DATA)tmp[vv]; /* real part */ + raw->values[v + 3] [offset + p] = (SPICE_DATA)tmp[vv + 1]; /* imaginary part */ } } else for(v = 0; v < raw->nvars; v++) { @@ -629,11 +636,15 @@ static int read_dataset(FILE *fd, Raw **rawptr, const char *type) done_points = 1; } else if(!strncmp(line, "No. Variables:", 14)) { + int multiplier = 1; n = sscanf(line, "No. Variables: %d", &nvars); dbg(dbglev, "read_dataset(): nvars=%d\n", nvars); - if(ac) nvars <<= 1; - if(raw->datasets > 0 && raw->nvars != nvars && sim_type) { + if(ac) { + nvars <<= 1; + multiplier = 2; /* we store 4 vars (mag, ph, re, im) for each raw file var (re, im) */ + } + if(raw->datasets > 0 && raw->nvars != nvars * multiplier && sim_type) { dbg(0, "Xschem requires all datasets to be saved with identical and same number of variables\n"); dbg(0, "There is a mismatch, so this and following datasets will not be read\n"); /* exit_status = 1; */ /* do not set, if something useful has been read keep exit status as is */ @@ -649,6 +660,7 @@ static int read_dataset(FILE *fd, Raw **rawptr, const char *type) } if(sim_type) { raw->nvars = nvars; + if(ac) raw->nvars <<= 1; /* we store mag, phase, real and imag from raw real and imag */ } } else if(!done_points && !strncmp(line, "No. Points:", 11)) { @@ -691,13 +703,29 @@ static int read_dataset(FILE *fd, Raw **rawptr, const char *type) ++ptr; } if(ac || (sim_type && !strcmp(sim_type, "ac")) ) { /* AC */ - my_strcat(_ALLOC_ID_, &raw->names[i << 1], varname); - int_hash_lookup(&raw->table, raw->names[i << 1], (i << 1), XINSERT_NOREPLACE); - if(strstr(varname, "v(") == varname || strstr(varname, "i(") == varname) - my_mstrcat(_ALLOC_ID_, &raw->names[(i << 1) + 1], "ph(", varname + 2, NULL); - else - my_mstrcat(_ALLOC_ID_, &raw->names[(i << 1) + 1], "ph(", varname, ")", NULL); - int_hash_lookup(&raw->table, raw->names[(i << 1) + 1], (i << 1) + 1, XINSERT_NOREPLACE); + my_strcat(_ALLOC_ID_, &raw->names[i << 2], varname); + int_hash_lookup(&raw->table, raw->names[i << 2], (i << 2), XINSERT_NOREPLACE); + if(strstr(varname, "v(") == varname /* || strstr(varname, "i(") == varname */) { + my_mstrcat(_ALLOC_ID_, &raw->names[(i << 2) + 1], "ph(", varname + 2, NULL); + } else { + my_mstrcat(_ALLOC_ID_, &raw->names[(i << 2) + 1], "ph(", varname, ")", NULL); + } + int_hash_lookup(&raw->table, raw->names[(i << 2) + 1], (i << 2) + 1, XINSERT_NOREPLACE); + + if(strstr(varname, "v(") == varname /* || strstr(varname, "i(") == varname */) { + my_mstrcat(_ALLOC_ID_, &raw->names[(i << 2) + 2], "re(", varname + 2, NULL); + } else { + my_mstrcat(_ALLOC_ID_, &raw->names[(i << 2) + 2], "re(", varname, ")", NULL); + } + int_hash_lookup(&raw->table, raw->names[(i << 2) + 2], (i << 2) + 2, XINSERT_NOREPLACE); + + if(strstr(varname, "v(") == varname /* || strstr(varname, "i(") == varname */) { + my_mstrcat(_ALLOC_ID_, &raw->names[(i << 2) + 3], "im(", varname + 2, NULL); + } else { + my_mstrcat(_ALLOC_ID_, &raw->names[(i << 2) + 3], "im(", varname, ")", NULL); + } + int_hash_lookup(&raw->table, raw->names[(i << 2) + 3], (i << 2) + 3, XINSERT_NOREPLACE); + } else { my_strcat(_ALLOC_ID_, &raw->names[i], varname); int_hash_lookup(&raw->table, raw->names[i], i, XINSERT_NOREPLACE); diff --git a/xschem_library/examples/cmos_example.sch b/xschem_library/examples/cmos_example.sch index 59bacecf..002403a9 100644 --- a/xschem_library/examples/cmos_example.sch +++ b/xschem_library/examples/cmos_example.sch @@ -39,7 +39,8 @@ node="\\"GAIN @ 2uA;diffout deriv() % 0\\" \\"GAIN @ 10uA;diffout deriv() % 1\\" \\"GAIN @ 100uA;diffout deriv() % 2\\"" color="8 7 6" -dataset=-1} +dataset=-1 +autoload=1} B 2 190 -760 327 -700 {flags=image alpha=0.6 InvertOnExport=true @@ -63,9 +64,9 @@ subdivx=1 node="diffout@2uA;v(diffout)%0 diffout@10uA;v(diffout)%1 diffout@100uA;v(diffout)%2" -color="8 7 6" +color="8 7 6 4 4 4" dataset=-1 -} +autoload=1} B 2 1050 -470 1680 -190 {flags=graph,unlocked rawfile=$netlist_dir/cmos_example_ngspice.raw sim_type=tran @@ -86,7 +87,8 @@ node="\\"diffout 2uA; diffout%0\\" \\"diffout 10uA; diffout%1\\" \\"diffout 100uA; diffout%2\\"" hilight_wave=-1 -xlabmag=1.4} +xlabmag=1.4 +autoload=1} B 2 1050 -740 1680 -530 {flags=graph,unlocked rawfile=$netlist_dir/cmos_example_ngspice.raw sim_type=ac @@ -110,7 +112,8 @@ hilight_wave=-1 logx=1 xlabmag=1.4 divy=5 -ylabmag=1.2} +ylabmag=1.2 +autoload=1} B 2 1050 -960 1680 -750 {flags=graph,unlocked rawfile=$netlist_dir/cmos_example_ngspice.raw sim_type=ac @@ -132,7 +135,8 @@ node="\\"phase 2uA; ph(diffout)%0\\" \\"phase 100uA; ph(diffout)%2\\"" hilight_wave=-1 logx=1 -xlabmag=1.4} +xlabmag=1.4 +autoload=1} B 2 1690 -290 2250 -20 {flags=graph,unlocked rawfile=$netlist_dir/cmos_example_ngspice.raw sim_type=dc @@ -140,15 +144,15 @@ y1=2.3 y2=2.7 divy=4 subdivy=1 -x1=2.3 -x2=2.7 +x1=2.3088075 +x2=2.7088075 divx=6 subdivx=1 node="minus;minus%0 plus;plus%0" color="7 8" dataset=-1 -} +autoload=1} B 2 1050 -180 1680 -60 {flags=graph,unlocked rawfile=$netlist_dir/cmos_example_ngspice.raw sim_type=tran @@ -169,7 +173,8 @@ node="minus;minus%0 plus;plus%0" hilight_wave=-1 ylabmag=1.4 -xlabmag=1.4} +xlabmag=1.4 +autoload=1} T {CMOS DIFFERENTIAL AMPLIFIER EXAMPLE. DC simulation} 30 -680 0 0 0.4 0.4 {} T {tcleval([xschem raw info])} 20 -960 0 0 0.4 0.4 {floater=true layer=16}