Qucs-core
0.0.19
|
00001 /* 00002 * qucs_producer.cpp - the Qucs netlist producer 00003 * 00004 * Copyright (C) 2004-2011 Stefan Jahn <stefan@lkcc.org> 00005 * 00006 * This is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2, or (at your option) 00009 * any later version. 00010 * 00011 * This software is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this package; see the file COPYING. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 * 00021 * $Id$ 00022 * 00023 */ 00024 00025 #if HAVE_CONFIG_H 00026 # include <config.h> 00027 #endif 00028 00029 #include <stdio.h> 00030 #include <stdlib.h> 00031 #include <time.h> 00032 #include <string.h> 00033 #include <ctype.h> 00034 00035 #include "object.h" 00036 #include "complex.h" 00037 #include "vector.h" 00038 #include "dataset.h" 00039 #include "netdefs.h" 00040 #include "check_spice.h" 00041 #include "check_vcd.h" 00042 #include "hash.h" 00043 00044 /* Global variables. */ 00045 FILE * qucs_out = NULL; 00046 int qucs_actions = 1; 00047 const char * qucs_gnd = "gnd"; 00048 00049 qucs::hash<struct node_t> qucs_nodes; 00050 00051 /* Looks through the given list if there is such a node already in the 00052 list and returns non-zero if so, otherwise the function returns 00053 zero. */ 00054 int qucs_find_node (struct node_t * root, char * node) { 00055 for (struct node_t * n = root; n; n = n->next) { 00056 if (!strcmp (node, n->node)) return 1; 00057 } 00058 return 0; 00059 } 00060 00061 /* Adds the given node list to the overall node list without 00062 duplicating the nodes. */ 00063 void qucs_add_nodes (struct node_t * node) { 00064 while (node) { 00065 if (!qucs_nodes.get (node->node)) 00066 qucs_nodes.put (node->node, node); 00067 node = node->next; 00068 } 00069 } 00070 00071 /* Deletes the given node list. */ 00072 void qucs_free_nodes (struct node_t * node) { 00073 struct node_t * n; 00074 for ( ; node; node = n) { 00075 n = node->next; 00076 free (node->node); 00077 free (node); 00078 } 00079 } 00080 00081 /* The function deletes the collected qucs nodes. */ 00082 static void qucs_delete_nodes (void) { 00083 qucs_nodes.clear (); 00084 } 00085 00086 /* Collects all nodes within the given definition root. */ 00087 static void qucs_collect_nodes (struct definition_t * root) { 00088 while (root) { 00089 qucs_add_nodes (root->nodes); 00090 root = root->next; 00091 } 00092 } 00093 00094 /* Prints value representation. */ 00095 static void netlist_list_value (struct value_t * value) { 00096 if (value == NULL) 00097 fprintf (qucs_out, "[]"); 00098 else if (value->ident) 00099 fprintf (qucs_out, "%s", value->ident); 00100 else if (value->next) { 00101 fprintf (qucs_out, "["); 00102 for (; value != NULL; value = value->next) 00103 fprintf (qucs_out, "%g%s", value->value, value->next ? ";" : ""); 00104 fprintf (qucs_out, "]"); 00105 } else { 00106 fprintf (qucs_out, "%g", value->value); 00107 if (value->scale) 00108 fprintf (qucs_out, "%s", value->scale); 00109 if (value->unit) 00110 fprintf (qucs_out, "%s", value->unit); 00111 } 00112 } 00113 00114 /* Returns a static string for an instance identifier usable in 00115 netlists based upon the given identifier. */ 00116 static char * netlist_instance (const char * instance) { 00117 static char ret[256]; 00118 sprintf (ret, "%s%s", isdigit (instance[0]) ? "X" : "", instance); 00119 return ret; 00120 } 00121 00122 /* Prints a single definition on a single line. */ 00123 static void netlist_list_def (struct definition_t * def, const char * prefix) { 00124 struct node_t * node; 00125 struct pair_t * pair; 00126 if (def->define == NULL) { 00127 if (def->text != NULL) 00128 fprintf (qucs_out, "%s# %s\n", prefix, def->text); 00129 } 00130 else { 00131 if (!qucs_actions) { 00132 // skip specific actions if required 00133 if (def->action && strcmp (def->type, "Def")) return; 00134 } 00135 fprintf (qucs_out, "%s%s%s:%s", prefix, def->action ? "." : "", 00136 def->type, netlist_instance (def->instance)); 00137 for (node = def->nodes; node != NULL; node = node->next) 00138 fprintf (qucs_out, " %s", node->node); 00139 for (pair = def->pairs; pair != NULL; pair = pair->next) { 00140 fprintf (qucs_out, " %s=\"", pair->key); 00141 netlist_list_value (pair->value); 00142 fprintf (qucs_out, "\""); 00143 } 00144 fprintf (qucs_out, "\n"); 00145 } 00146 } 00147 00148 /* Prints definition list representation. */ 00149 static void netlist_lister (struct definition_t * root, const char * prefix) { 00150 struct definition_t * def; 00151 for (def = root; def != NULL; def = def->next) { 00152 if (def->sub != NULL) { 00153 netlist_list_def (def, prefix); 00154 netlist_lister (def->sub, " "); 00155 fprintf (qucs_out, ".Def:End\n"); 00156 } 00157 else { 00158 netlist_list_def (def, prefix); 00159 } 00160 } 00161 } 00162 00163 /* Goes recursively through the netlist and applies additional 00164 reference node modifications to subcircuits and their instances. */ 00165 static void netlist_fix_reference (struct definition_t * root) { 00166 struct definition_t * def; 00167 struct node_t * n; 00168 00169 // go through definitions 00170 for (def = root; def != NULL; def = def->next) { 00171 if (!strcmp (def->type, "Sub")) { // subcircuit instances 00172 n = create_node (); 00173 n->node = strdup (qucs_gnd); 00174 n->next = def->nodes; 00175 def->nodes = n; 00176 } 00177 else if (def->sub != NULL) { // subcircuit definitions 00178 n = create_node (); 00179 n->node = strdup (qucs_gnd); 00180 n->next = def->nodes; 00181 def->nodes = n; 00182 netlist_fix_reference (def->sub); 00183 } 00184 } 00185 } 00186 00187 /* Applies reference node modifications if necessary. */ 00188 static void netlist_reference_ground (void) { 00189 struct definition_t * def; 00190 00191 // return if nothing todo 00192 if (qucs_gnd && !strcmp (qucs_gnd, "gnd")) return; 00193 00194 netlist_fix_reference (definition_root); 00195 // go through subcircuits 00196 for (def = subcircuit_root; def != NULL; def = def->next) { 00197 netlist_fix_reference (def->sub); 00198 } 00199 } 00200 00201 /* Look for a single subcircuit definition in a netlist. */ 00202 static struct definition_t * 00203 netlist_get_single_subcircuit (struct definition_t * root) { 00204 int count = 0; 00205 struct definition_t * ret = NULL; 00206 for (struct definition_t * def = root; def != NULL; def = def->next) { 00207 if (!def->action) { 00208 count++; 00209 } else if (def->sub) { 00210 count++; 00211 ret = def; 00212 } 00213 } 00214 return (count == 1) ? ret : NULL; 00215 } 00216 00217 /* Prints the overall netlist representation. */ 00218 static void netlist_list (void) { 00219 struct node_t * n; 00220 struct definition_t * def; 00221 time_t t = time (NULL); 00222 fprintf (qucs_out, "# converted Qucs netlist processed at %s\n", ctime (&t)); 00223 if (spice_title != NULL) { 00224 fprintf (qucs_out, "#\n# %s#\n\n", spice_title); 00225 } 00226 netlist_lister (definition_root, ""); 00227 for (def = subcircuit_root; def != NULL; def = def->next) { 00228 fprintf (qucs_out, ".Def:%s\n", netlist_instance (def->instance)); 00229 netlist_lister (def->sub, " "); 00230 fprintf (qucs_out, ".Def:End\n"); 00231 } 00232 /* Instantiate subcircuit if there is just a single definition. */ 00233 if (definition_root != NULL && subcircuit_root == NULL && 00234 (def = netlist_get_single_subcircuit (definition_root)) != NULL) { 00235 fprintf (qucs_out, "\n# no instance of subcircuit \"%s\" found, " 00236 "creating it\n", netlist_instance (def->instance)); 00237 fprintf (qucs_out, "Sub:X1"); 00238 for (n = def->nodes; n; n = n->next) fprintf (qucs_out, " %s", n->node); 00239 fprintf (qucs_out, " Type=\"%s\"\n", netlist_instance (def->instance)); 00240 } 00241 /* Print overall (toplevel only) node list. */ 00242 qucs_collect_nodes (definition_root); 00243 fprintf (qucs_out, "\n### TOPLEVEL NODELIST BEGIN\n"); 00244 for (qucs::hashiterator<struct node_t> it (qucs_nodes); *it; ++it) { 00245 n = it.currentVal (); 00246 fprintf (qucs_out, "# %s\n", n->node); 00247 } 00248 qucs_delete_nodes (); 00249 fprintf (qucs_out, "### TOPLEVEL NODELIST END\n"); 00250 /* Print potential external node list. */ 00251 fprintf (qucs_out, "\n### SPICE OUTPUT NODELIST BEGIN\n"); 00252 for (n = spice_nodes; n; n = n->next) { 00253 fprintf (qucs_out, "# %s\n", n->node); 00254 } 00255 fprintf (qucs_out, "### SPICE OUTPUT NODELIST END\n"); 00256 } 00257 00258 /* This function is the overall Qucs netlist producer. */ 00259 void qucs_producer (void) { 00260 if (qucs_out != NULL) { 00261 netlist_reference_ground (); 00262 netlist_list (); 00263 } 00264 } 00265 00266 // Structure defining Qucs schematic entries of device models. 00267 struct device_t { 00268 const char * ntype; // netlist type 00269 const char * ltype; // schematic type 00270 const char * stype; // spice type 00271 int nodes; // number of nodes 00272 const char * props[128]; // list of properties in schematic order 00273 const char * symbol; // symbol text 00274 const char * coords; // coordinates and other text 00275 const char * ports; // subcircuit ports 00276 } 00277 qucs_devices[] = { 00278 /* diode */ 00279 { "Diode", "Diode", "D", 2, 00280 {"Is", "N", "Cj0", "M", "Vj", "Fc", "Cp", "Isr", "Nr", "Rs", "Tt", "Ikf", 00281 "Kf", "Af", "Ffe", "Bv", "Ibv", "Temp", "Xti", "Eg", "Tbv", "Trs", 00282 "Ttt1", "Ttt2", "Tm1", "Tm2", "Tnom", "Area", NULL }, 00283 NULL, 00284 "1 0 0 -26 13 0 0", 00285 NULL 00286 }, 00287 /* bipolar transistor */ 00288 { "BJT", "_BJT", "Q", 4, 00289 { "Type", "Is", "Nf", "Nr", "Ikf", "Ikr", "Vaf", "Var", "Ise", "Ne", "Isc", 00290 "Nc", "Bf", "Br", "Rbm", "Irb", "Rc", "Re", "Rb", "Cje", "Vje", "Mje", 00291 "Cjc", "Vjc", "Mjc", "Xcjc", "Cjs", "Vjs", "Mjs", "Fc", "Tf", "Xtf", 00292 "Vtf", "Itf", "Tr", "Temp", "Kf", "Af", "Ffe", "Kb", "Ab", "Fb", "Ptf", 00293 "Xtb", "Xti", "Eg", "Tnom", "Area", NULL }, 00294 NULL, 00295 "1 0 0 8 -26 0 0", 00296 NULL 00297 }, 00298 /* hicum/l0 bipolar transistor */ 00299 { "hic0_full", "hic0_full", "Q", 5, 00300 { "Type", "is", "mcf", "mcr", "vef", "iqf", "iqr", "iqfh", "tfh", "ibes", 00301 "mbe", "ires", "mre", "ibcs", "mbc", "cje0", "vde", "ze", "aje", "t0", 00302 "dt0h", "tbvl", "tef0", "gte", "thcs", "ahc", "tr", "rci0", "vlim", 00303 "vpt", "vces", "cjci0", "vdci", "zci", "vptci", "cjcx0", "vdcx", "zcx", 00304 "vptcx", "fbc", "rbi0", "vr0e", "vr0c", "fgeo", "rbx", "rcx", "re", 00305 "itss", "msf", "iscs", "msc", "cjs0", "vds", "zs", "vpts", "cbcpar", 00306 "cbepar", "eavl", "kavl", "kf", "af", "vgb", "vge", "vgc", "vgs", 00307 "f1vg", "f2vg", "alt0", "kt0", "zetact", "zetabet", "zetaci", "alvs", 00308 "alces", "zetarbi", "zetarbx", "zetarcx", "zetare", "alkav", "aleav", 00309 "flsh", "rth", "cth", "tnom", "dt", "Temp", NULL }, 00310 NULL, 00311 "1 0 0 8 -26 0 0", 00312 NULL 00313 }, 00314 /* hicum/l0 v1.2 bipolar transistor */ 00315 { "hicumL0V1p2", "hicumL0V1p2", "Q", 5, 00316 { "Type", "is", "mcf", "mcr", "vef", "ver", "iqf", "fiqf", "iqr", "iqfh", 00317 "tfh", "ahq", "ibes", "mbe", "ires", "mre", "ibcs", "mbc", "cje0", "vde", 00318 "ze", "aje", "vdedc", "zedc", "ajedc", "t0", "dt0h", "tbvl", "tef0", 00319 "gte", "thcs", "ahc", "tr", "rci0", "vlim", "vpt", "vces", "cjci0", 00320 "vdci", "zci", "vptci", "cjcx0", "vdcx", "zcx", "vptcx", "fbc", "rbi0", 00321 "vr0e", "vr0c", "fgeo", "rbx", "rcx", "re", "itss", "msf", "iscs", "msc", 00322 "cjs0", "vds", "zs", "vpts", "cbcpar", "cbepar", "eavl", "kavl", "kf", 00323 "af", "vgb", "vge", "vgc", "vgs", "f1vg", "f2vg", "alt0", "kt0", 00324 "zetact", "zetabet", "zetaci", "alvs", "alces", "zetarbi", "zetarbx", 00325 "zetarcx", "zetare", "zetaiqf", "alkav", "aleav", "zetarth", "flsh", 00326 "rth", "cth", "tnom", "dt", "Temp", NULL }, 00327 NULL, 00328 "1 0 0 8 -26 0 0", 00329 NULL 00330 }, 00331 /* hicum/l0 v1.2g bipolar transistor */ 00332 { "hicumL0V1p2g", "hicumL0V1p2g", "Q", 5, 00333 { "Type", "is", "mcf", "mcr", "vef", "ver", "iqf", "fiqf", "iqr", "iqfh", 00334 "iqfe", "ahq", "ibes", "mbe", "ires", "mre", "ibcs", "mbc", "cje0", 00335 "vde", "ze", "aje", "vdedc", "zedc", "ajedc", "t0", "dt0h", "tbvl", 00336 "tef0", "gte", "thcs", "ahc", "tr", "rci0", "vlim", "vpt", "vces", 00337 "cjci0", "vdci", "zci", "vptci", "cjcx0", "vdcx", "zcx", "vptcx", "fbc", 00338 "rbi0", "vr0e", "vr0c", "fgeo", "rbx", "rcx", "re", "itss", "msf", 00339 "iscs", "msc", "cjs0", "vds", "zs", "vpts", "cbcpar", "cbepar", "eavl", 00340 "kavl", "kf", "af", "vgb", "vge", "vgc", "vgs", "f1vg", "f2vg", "alt0", 00341 "kt0", "zetact", "zetabet", "zetaci", "alvs", "alces", "zetarbi", 00342 "zetarbx", "zetarcx", "zetare", "zetaiqf", "alkav", "aleav", "flsh", 00343 "rth", "zetarth", "cth", "tnom", "dt", "delte", "deltc", "zetaver", 00344 "zetavef", "ibhrec", "Temp", NULL }, 00345 NULL, 00346 "1 0 0 8 -26 0 0", 00347 NULL 00348 }, 00349 /* hicum/l0 v1.3 bipolar transistor */ 00350 { "hicumL0V1p3", "hicumL0V1p3", "Q", 5, 00351 { "Type", "is", "it_mod", "mcf", "mcr", "vef", "ver", "aver", "iqf", 00352 "fiqf", "iqr", "iqfh", "tfh", "ahq", "ibes", "mbe", "ires", "mre", 00353 "ibcs", "mbc", "cje0", "vde", "ze", "aje", "vdedc", "zedc", "ajedc", 00354 "t0", "dt0h", "tbvl", "tef0", "gte", "thcs", "ahc", "tr", "rci0", 00355 "vlim", "vpt", "vces", "cjci0", "vdci", "zci", "vptci", "cjcx0", "vdcx", 00356 "zcx", "vptcx", "fbc", "rbi0", "vr0e", "vr0c", "fgeo", "rbx", "rcx", 00357 "re", "itss", "msf", "iscs", "msc", "cjs0", "vds", "zs", "vpts", 00358 "cbcpar", "cbepar", "eavl", "kavl", "kf", "af", "vgb", "vge", "vgc", 00359 "vgs", "f1vg", "f2vg", "alt0", "kt0", "zetact", "zetabet", "zetaci", 00360 "alvs", "alces", "zetarbi", "zetarbx", "zetarcx", "zetare", "zetaiqf", 00361 "alkav", "aleav", "zetarth", "tef_temp", "zetaver", "zetavgbe", "dvgbe", 00362 "aliqfh", "kiqfh", "flsh", "rth", "cth", "tnom", "dt", "Temp", NULL }, 00363 NULL, 00364 "1 0 0 8 -26 0 0", 00365 NULL 00366 }, 00367 /* hicum/l2 v2.22 bipolar transistor */ 00368 { "hic2_full", "hic2_full", "Q", 5, 00369 { "c10", "qp0", "ich", "hfe", "hfc", "hjei", "hjci", "ibeis", "mbei", 00370 "ireis", "mrei", "ibeps", "mbep", "ireps", "mrep", "mcf", "tbhrec", 00371 "ibcis", "mbci", "ibcxs", "mbcx", "ibets", "abet", "tunode", "favl", 00372 "qavl", "alfav", "alqav", "rbi0", "rbx", "fgeo", "fdqr0", "fcrbi", 00373 "fqi", "re", "rcx", "itss", "msf", "iscs", "msc", "tsf", "rsu", "csu", 00374 "cjei0", "vdei", "zei", "ajei", "cjep0", "vdep", "zep", "ajep", 00375 "cjci0", "vdci", "zci", "vptci", "cjcx0", "vdcx", "zcx", "vptcx", 00376 "fbcpar", "fbepar", "cjs0", "vds", "zs", "vpts", "t0", "dt0h", "tbvl", 00377 "tef0", "gtfe", "thcs", "ahc", "fthc", "rci0", "vlim", "vces", "vpt", 00378 "tr", "cbepar", "cbcpar", "alqf", "alit", "flnqs", "kf", "af", "cfbe", 00379 "latb", "latl", "vgb", "alt0", "kt0", "zetaci", "alvs", "alces", 00380 "zetarbi", "zetarbx", "zetarcx", "zetare", "zetacx", "vge", "vgc", 00381 "vgs", "f1vg", "f2vg", "zetact", "zetabet", "alb", "flsh", "rth", "cth", 00382 "flcomp", "tnom", "dt", "Temp", NULL }, 00383 NULL, 00384 "1 0 0 8 -26 0 0", 00385 NULL 00386 }, 00387 /* hicum/l2 v2.1 bipolar transistor */ 00388 { "hicumL2V2p1", "hicumL2V2p1", "Q", 5, 00389 { "c10", "qp0", "ich", "hfe", "hfc", "hjei", "hjci", "ibeis", 00390 "mbei", "ireis", "mrei", "ibeps", "mbep", "ireps", "mrep", "mcf", 00391 "ibcis", "mbci", "ibcxs", "mbcx", "ibets", "abet", "favl", "qavl", 00392 "alfav", "alqav", "rbi0", "rbx", "fgeo", "fdqr0", "fcrbi", "fqi", "re", 00393 "rcx", "itss", "msf", "iscs", "msc", "tsf", "rsu", "csu", "cjei0", 00394 "vdei", "zei", "aljei", "cjep0", "vdep", "zep", "aljep", "cjci0", 00395 "vdci", "zci", "vptci", "cjcx0", "vdcx", "zcx", "vptcx", "fbc", "cjs0", 00396 "vds", "zs", "vpts", "t0", "dt0h", "tbvl", "tef0", "gtfe", "thcs", 00397 "alhc", "fthc", "rci0", "vlim", "vces", "vpt", "tr", "ceox", "ccox", 00398 "alqf", "alit", "kf", "af", "krbi", "latb", "latl", "vgb", "alt0", 00399 "kt0", "zetaci", "zetacx", "alvs", "alces", "zetarbi", "zetarbx", 00400 "zetarcx", "zetare", "alb", "rth", "cth", "tnom", "dt", "Temp", NULL }, 00401 NULL, 00402 "1 0 0 8 -26 0 0", 00403 NULL 00404 }, 00405 /* hicum/l2 v2.23 bipolar transistor */ 00406 { "hicumL2V2p23", "hicumL2V2p23", "Q", 5, 00407 { "c10", "qp0", "ich", "hfe", "hfc", "hjei", "hjci", "ibeis", "mbei", 00408 "ireis", "mrei", "ibeps", "mbep", "ireps", "mrep", "mcf", "tbhrec", 00409 "ibcis", "mbci", "ibcxs", "mbcx", "ibets", "abet", "tunode", "favl", 00410 "qavl", "alfav", "alqav", "rbi0", "rbx", "fgeo", "fdqr0", "fcrbi", 00411 "fqi", "re", "rcx", "itss", "msf", "iscs", "msc", "tsf", "rsu", "csu", 00412 "cjei0", "vdei", "zei", "ajei", "cjep0", "vdep", "zep", "ajep", 00413 "cjci0", "vdci", "zci", "vptci", "cjcx0", "vdcx", "zcx", "vptcx", 00414 "fbcpar", "fbepar", "cjs0", "vds", "zs", "vpts", "t0", "dt0h", "tbvl", 00415 "tef0", "gtfe", "thcs", "ahc", "fthc", "rci0", "vlim", "vces", "vpt", 00416 "tr", "cbepar", "cbcpar", "alqf", "alit", "flnqs", "kf", "af", "cfbe", 00417 "latb", "latl", "vgb", "alt0", "kt0", "zetaci", "alvs", "alces", 00418 "zetarbi", "zetarbx", "zetarcx", "zetare", "zetacx", "vge", "vgc", 00419 "vgs", "f1vg", "f2vg", "zetact", "zetabet", "alb", "flsh", "rth", "cth", 00420 "flcomp", "tnom", "dt", "Temp", NULL }, 00421 NULL, 00422 "1 0 0 8 -26 0 0", 00423 NULL 00424 }, 00425 /* hicum/l2 v2.24 bipolar transistor */ 00426 { "hicumL2V2p24", "hicumL2V2p24", "Q", 5, 00427 { "c10", "qp0", "ich", "hfe", "hfc", "hjei", "hjci", "ibeis", "mbei", 00428 "ireis", "mrei", "ibeps", "mbep", "ireps", "mrep", "mcf", "tbhrec", 00429 "ibcis", "mbci", "ibcxs", "mbcx", "ibets", "abet", "tunode", "favl", 00430 "qavl", "alfav", "alqav", "rbi0", "rbx", "fgeo", "fdqr0", "fcrbi", 00431 "fqi", "re", "rcx", "itss", "msf", "iscs", "msc", "tsf", "rsu", "csu", 00432 "cjei0", "vdei", "zei", "ajei", "cjep0", "vdep", "zep", "ajep", 00433 "cjci0", "vdci", "zci", "vptci", "cjcx0", "vdcx", "zcx", "vptcx", 00434 "fbcpar", "fbepar", "cjs0", "vds", "zs", "vpts", "t0", "dt0h", "tbvl", 00435 "tef0", "gtfe", "thcs", "ahc", "fthc", "rci0", "vlim", "vces", "vpt", 00436 "tr", "cbepar", "cbcpar", "alqf", "alit", "flnqs", "kf", "af", "cfbe", 00437 "latb", "latl", "vgb", "alt0", "kt0", "zetaci", "alvs", "alces", 00438 "zetarbi", "zetarbx", "zetarcx", "zetare", "zetacx", "vge", "vgc", 00439 "vgs", "f1vg", "f2vg", "zetact", "zetabet", "alb", "flsh", "rth", "cth", 00440 "flcomp", "tnom", "dt", "Temp", NULL }, 00441 NULL, 00442 "1 0 0 8 -26 0 0", 00443 NULL 00444 }, 00445 /* junction FET */ 00446 { "JFET", "JFET", "J", 3, 00447 { "Type", "Vt0", "Beta", "Lambda", "Rd", "Rs", "Is", "N", "Isr", "Nr", 00448 "Cgs", "Cgd", "Pb", "Fc", "M", "Kf", "Af", "Ffe", "Temp", "Xti", 00449 "Vt0tc", "Betatce", "Tnom", "Area", NULL }, 00450 NULL, 00451 "1 190 140 30 -49 0 0", 00452 NULL 00453 }, 00454 /* MOSFET */ 00455 { "MOSFET", "_MOSFET", "M", 4, 00456 { "Type", "Vt0", "Kp", "Gamma", "Phi", "Lambda", "Rd", "Rs", "Rg", "Is", 00457 "N", "W", "L", "Ld", "Tox", "Cgso", "Cgdo", "Cgbo", "Cbd", "Cbs", "Pb", 00458 "Mj", "Fc", "Cjsw", "Mjsw", "Tt", "Nsub", "Nss", "Tpg", "Uo", "Rsh", 00459 "Nrd", "Nrs", "Cj", "Js", "Ad", "As", "Pd", "Ps", "Kf", "Af", "Ffe", 00460 "Temp", "Tnom", NULL }, 00461 NULL, 00462 "1 0 0 8 -26 0 0", 00463 NULL 00464 }, 00465 { NULL, NULL, NULL, 0, { NULL }, NULL, NULL, NULL } 00466 }; 00467 00468 /* Looks through the list of available Qucs devices. Returns NULL if 00469 there is no such device. */ 00470 static struct device_t * qucslib_find_device (char * type) { 00471 struct device_t * dev; 00472 for (dev = qucs_devices; dev->ntype; dev++) { 00473 if (!strcmp (dev->ntype, type)) 00474 return dev; 00475 } 00476 return NULL; 00477 } 00478 00479 /* This function tries to find the given property in the key/value 00480 pairs of the given netlist entry and returns NULL if there is no 00481 such property. */ 00482 static struct pair_t * 00483 qucslib_find_prop (struct definition_t * def, const char * key) { 00484 struct pair_t * pair; 00485 for (pair = def->pairs; pair; pair = pair->next) { 00486 if (!strcmp (pair->key, key)) 00487 return pair; 00488 } 00489 return NULL; 00490 } 00491 00492 /* The function outputs a device library entry in the Qucs schematic 00493 data format. */ 00494 static void qucslib_list_device (struct definition_t * def) { 00495 struct device_t * dev; 00496 if (!(dev = qucslib_find_device (def->type))) return; 00497 struct pair_t * pair; 00498 char txt[1024]; 00499 00500 sprintf (txt, "\n<Component %s>\n", def->instance[0] == dev->stype[0] ? 00501 &def->instance[1] : def->instance); 00502 fprintf (qucs_out, "%s", txt); 00503 fprintf (qucs_out, " <Description>\n"); 00504 fprintf (qucs_out, " </Description>\n"); 00505 fprintf (qucs_out, " <Model>\n"); 00506 fprintf (qucs_out, " <%s %s_ %s", dev->ltype, 00507 netlist_instance (def->instance), dev->coords); 00508 for (int i = 0; dev->props[i]; i++) { 00509 if ((pair = qucslib_find_prop (def, dev->props[i])) != NULL) { 00510 fprintf (qucs_out, " \""); 00511 netlist_list_value (pair->value); 00512 fprintf (qucs_out, "\" 0"); 00513 } 00514 } 00515 fprintf (qucs_out, ">\n"); 00516 fprintf (qucs_out, " </Model>\n"); 00517 fprintf (qucs_out, "</Component>\n"); 00518 } 00519 00520 /* This function is the overall Qucs library producer. */ 00521 void qucslib_producer (void) { 00522 struct definition_t * def; 00523 fprintf (qucs_out, "<Qucs Library " PACKAGE_VERSION " \"Generic\">\n"); 00524 for (def = device_root; def; def = def->next) { 00525 qucslib_list_device (def); 00526 } 00527 } 00528 00529 /* This function is the Qucs dataset producer for VCD files. */ 00530 void qucsdata_producer_vcd (void) { 00531 struct dataset_variable * ds; 00532 struct dataset_value * dv; 00533 fprintf (qucs_out, "<Qucs Dataset " PACKAGE_VERSION ">\n"); 00534 for (ds = dataset_root; ds; ds = ds->next) { 00535 if (!ds->output || ds->type == DATA_UNKNOWN) 00536 continue; 00537 if (ds->type == DATA_INDEPENDENT) 00538 fprintf (qucs_out, "<indep %s %d>\n", ds->ident, ds->size); 00539 else if (ds->type == DATA_DEPENDENT) 00540 fprintf (qucs_out, "<dep %s.%s %s>\n", ds->ident, ds->isreal ? "R" : "X", 00541 ds->dependencies); 00542 for (dv = ds->values; dv; dv = dv->next) { 00543 fprintf (qucs_out, " %s\n", dv->value); 00544 } 00545 if (ds->type == DATA_INDEPENDENT) 00546 fprintf (qucs_out, "</indep>\n"); 00547 else if (ds->type == DATA_DEPENDENT) 00548 fprintf (qucs_out, "</dep>\n"); 00549 } 00550 } 00551 00552 /* This function is the Qucs dataset producer. */ 00553 void qucsdata_producer (dataset * data) { 00554 data->print (); 00555 }