From 3b0589d2d1b08f21e0e33d62a2797267f9f80dfd Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Wed, 3 Aug 2022 17:44:53 +0200 Subject: [PATCH] store just magnitude and phase of AC vectors instead of dB and phase. Add db20() function to get dB values from magnitude in graph RPN expressions. --- src/draw.c | 2 +- src/save.c | 27 +++++++++++++++++++++++++-- xschem_library/examples/test_ac.sch | 6 +++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/draw.c b/src/draw.c index 36b2cbc6..3bdaff9b 100644 --- a/src/draw.c +++ b/src/draw.c @@ -2173,7 +2173,7 @@ static void draw_graph_variables(int wcnt, int wave_color, int n_nodes, int swee if(strstr(ntok_ptr, "ph(") == ntok_ptr || strstr(ntok_ptr, "_ph")) my_snprintf(tmpstr, S(tmpstr), "%s[Phase]", alias_ptr); else - my_snprintf(tmpstr, S(tmpstr), "%s[dB]", alias_ptr); + my_snprintf(tmpstr, S(tmpstr), "%s[Mag]", alias_ptr); } else if(gr->unity != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", alias_ptr, gr->unity_suffix); else my_snprintf(tmpstr, S(tmpstr), "%s", alias_ptr); diff --git a/src/save.c b/src/save.c index 4db909f2..034cae41 100644 --- a/src/save.c +++ b/src/save.c @@ -255,9 +255,14 @@ static void read_binary_block(FILE *fd) if( v == 0 ) /* log scale x */ xctx->graph_values[v][offset + p] = (float)log10(sqrt( tmp[v] * tmp[v] + tmp[v + 1] * tmp[v + 1])); else /* dB */ - xctx->graph_values[v][offset + p] = 20 * (float)log10(sqrt(tmp[v] * tmp[v] + tmp[v + 1] * tmp[v + 1])); + /* avoid 0 for dB calculations */ + if(tmp[v] == 0.0 && tmp[v + 1] == 0.0) xctx->graph_values[v][offset + p] = 1e-35f; + else xctx->graph_values[v][offset + p] = + (float)sqrt(tmp[v] * tmp[v] + tmp[v + 1] * tmp[v + 1]); /* AC analysis: calculate phase */ - xctx->graph_values[v + 1] [offset + p] = (float)(atan2(tmp[v + 1], tmp[v]) * 180.0 / XSCH_PI); + if(tmp[v] == 0.0 && tmp[v + 1] == 0.0) xctx->graph_values[v + 1] [offset + p] = 0.0; + else xctx->graph_values[v + 1] [offset + p] = + (float)(atan2(tmp[v + 1], tmp[v]) * 180.0 / XSCH_PI); } } else for(v = 0; v < xctx->graph_nvars; v++) { @@ -331,6 +336,10 @@ static int read_dataset(FILE *fd) if(xctx->graph_sim_type && xctx->graph_sim_type != 2) xctx->graph_sim_type = 0; else xctx->graph_sim_type = 2; } + else if(!strncmp(line, "Plotname: Operating Point", 25)) { + if(xctx->graph_sim_type && xctx->graph_sim_type != 4) xctx->graph_sim_type = 0; + else xctx->graph_sim_type = 4; + } else if(!strncmp(line, "Plotname: AC Analysis", 21)) { if(xctx->graph_sim_type && xctx->graph_sim_type != 3) xctx->graph_sim_type = 0; else xctx->graph_sim_type = 3; @@ -344,15 +353,24 @@ static int read_dataset(FILE *fd) /* array of number of points of datasets (they are of varialbe length) */ my_realloc(1414, &xctx->graph_npoints, (xctx->graph_datasets+1) * sizeof(int)); sscanf(line, "No. of Data Rows : %d", &xctx->graph_npoints[xctx->graph_datasets]); + /* multi-point OP is equivalent to a DC sweep. Change xctx->graph_sim_type */ + if(xctx->graph_npoints[xctx->graph_datasets] > 1 && xctx->graph_sim_type == 4 ) { + xctx->graph_sim_type = 2; + } done_points = 1; } else if(!strncmp(line, "No. Variables:", 14)) { sscanf(line, "No. Variables: %d", &xctx->graph_nvars); if(xctx->graph_sim_type == 3) xctx->graph_nvars <<= 1; /* mag and phase */ + } else if(!done_points && !strncmp(line, "No. Points:", 11)) { my_realloc(1415, &xctx->graph_npoints, (xctx->graph_datasets+1) * sizeof(int)); sscanf(line, "No. Points: %d", &xctx->graph_npoints[xctx->graph_datasets]); + /* multi-point OP is equivalent to a DC sweep. Change xctx->graph_sim_type */ + if(xctx->graph_npoints[xctx->graph_datasets] > 1 && xctx->graph_sim_type == 4 ) { + xctx->graph_sim_type = 2; + } } if(!done_header && variables) { /* get the list of lines with index and node name */ @@ -572,6 +590,7 @@ static double ravg_store(int what , int i, int p, int last, double integ) #define EXCH -37 #define DUP -38 #define RAVG -39 /* running average */ +#define DB20 -40 #define NUMBER -60 typedef struct { @@ -621,6 +640,7 @@ int plot_raw_custom_data(int sweep_idx, int first, int last, const char *expr) else if(!strcmp(n, "integ()")) stack1[stackptr1++].i = INTEG; else if(!strcmp(n, "avg()")) stack1[stackptr1++].i = AVG; else if(!strcmp(n, "ravg()")) stack1[stackptr1++].i = RAVG; + else if(!strcmp(n, "db20()")) stack1[stackptr1++].i = DB20; else if(!strcmp(n, "deriv()")) stack1[stackptr1++].i = DERIV; else if(!strcmp(n, "exch()")) stack1[stackptr1++].i = EXCH; else if(!strcmp(n, "dup()")) stack1[stackptr1++].i = DUP; @@ -782,6 +802,9 @@ int plot_raw_custom_data(int sweep_idx, int first, int last, const char *expr) case LOG10: stack2[stackptr2 - 1] = log10(stack2[stackptr2 - 1]); break; + case DB20: + stack2[stackptr2 - 1] = 20 * log10(stack2[stackptr2 - 1]); + break; case SGN: stack2[stackptr2 - 1] = stack2[stackptr2 - 1] > 0.0 ? 1 : stack2[stackptr2 - 1] < 0.0 ? -1 : 0; diff --git a/xschem_library/examples/test_ac.sch b/xschem_library/examples/test_ac.sch index b4af2461..2b34f7b4 100644 --- a/xschem_library/examples/test_ac.sch +++ b/xschem_library/examples/test_ac.sch @@ -1,11 +1,11 @@ -v {xschem version=3.0.0 file_version=1.2 } +v {xschem version=3.1.0 file_version=1.2 } G {} K {} V {} S {} E {} B 2 1030 -330 1570 -130 {flags=graph -y1=-5.7 +y1=-4.6 y2=44 ypos1=0 ypos2=2 @@ -16,7 +16,7 @@ x1=3 x2=10 subdivx=8 -node=diffout +node="\\"diffout db20()\\"" color=4 unitx=M