diff --git a/README-old.adms b/README-old.adms deleted file mode 100644 index 2c70c9397..000000000 --- a/README-old.adms +++ /dev/null @@ -1,453 +0,0 @@ -*************************************************************************** -* DISCLAIMER * -* * -* The admst code generators, part of adms and this document are released * -* under LGPL license terms. * -* * -* Copyright (C) 2006 Freescale Inc. * -* * -* This library is free software; you can redistribute it and/or * -* modify it under the terms of the GNU Lesser General Public * -* License as published by the Free Software Foundation; either * -* version 2.1 of the License, or (at your option) any later version. * -* * -* This library is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * -* Lesser General Public License for more details. * -* * -* You should have received a copy of the GNU Lesser General Public * -* License along with this library; if not, write to the Free Software * -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * -* 02110-1301 USA * -*************************************************************************** - -WARNING! - -The text in this document has been prepared in 2006 and is outdated. It is -provided here only for reference and may provide some (historical) -information. - -Please refer to the ngspice adms web page at -http://ngspice.sourceforge.net/admshowto.html -for actual information on how to integrate Verilog A device models into -ngspice. - -Holger Vogt, May 2013 - - - -INTRODUCTION - -In this document we will provide a guideline on how to auto-generate the -ready-to compile C code for the ngspice API of a compact device model -defined in the Verilog-AMS language. - -Condition: - To compile Verilog-AMS compact models into ngspice-ready C models with - admsXml a copy of the latest adms distribution is needed. You get it from - the adms Download page http://mot-adms.sourceforge.net as a source code - package. (Also use of cvs version is possible, but needs some more effort.) - -Version: - This guideline has been tested on Windows-XP under cygwin using: - $ admsXml -v - [usage] - [info] elapsed time: 0 - [info] admst iterations: 0 (0 freed) - -Goal: - In this guideline we will add device model hicum0 to ngspice - using the Verilog-AMS source code available at: - http://www.iee.et.tu-dresden.de/~schroter/Hicum_PD/Hicumna/hicumL0V1p11.va - -Limitations: - The adms ngspice interface supports a limited set of Verilog-AMS language - constructs. See the home page of adms (http://mot-adms.sourceforge.net/) - for more info. - Feel free to contribute to the adms ngspice interface so that more - constructs can be supported. - - -01- ngspice Files - - Ngspice does not (yet) have support for loading models at run time, every - model must be included at compile time. Then, adding a new model into - ngspice is a process that cannot be completely automated. Some files need - to be edited by hand. - - 01.01 What ngspice need to know of a new model ? - - First you have to assign your new model a "device type". As you probably - know, ngspice recognizes the type of a device by the first letter in - device's name in the netlists ("r" for resistors, "q" for BJT, "m" for - mosfets and so on). Then the first thing you have to find is the correct - type for your new device (let's call this device_type). - - Since there can be more than one model for each device type, another - parameter you have to set is the device_level, which must be unique - for each device type. - - Once you have found the (device_type, device_level) couple you have - identified the files you have to edit: - - /configure.ac - Here you have to add the entries in adms section for your new directory - and library. - - /src/spicelib/parser/inp2.c - Substitute with the letter corresponding to the - type of you new model. Here you have to add the interface code for your - new device. In the case of hicum (a BJT model and thus a "q" device type) - you have to edit inp2q.c - - /src/spicelib/parser/inpdomod.c - Here you have to add a switch for the level of your new device. - - /src/spicelib/devices/dev.c - Follow the structure of the files and add information on your new - model. In dev.c you have to adjust some macro. - - See existing examples to make the modifications for your own implementation. - is the path to the ngspice source installation. - For instance can be /tools/ng-spice-rework-17 - - Please see appendix 01 about spice3-flavoured flags. - -02- adms Files - - List of files that adms needs to create the ready-to-compile C code: - /src/spicelib/devices/adms/admst/ngspice*.xml - adms creates the ready-to-compile C code from a set of admst code - generators. admst is a subset of the XML language which has been created - specifically for the purpose of C code generation. The syntax of admst is - very close to the XSLT language (it includes some extensions.) - -03- Create the data file structure - - Create the following directories if they do not already exist: - -a /src/spicelib/devices/adms/hicum0 - -b /src/spicelib/devices/adms/hicum0/admsva - - There is no convention on the way to choice the last directory name in -a. - However in -b 'admsva' is mandatory. - -04- Save the Verilog-AMS source code - - Save the source code of hicum0 from - http://www.iee.et.tu-dresden.de/~schroter/Hicum_PD/Hicumna/hicumL0V1p11.va - to: - /src/spicelib/devices/adms/hicum0/admsva/hic0_full.va - - NOTE: the name of the Verilog-AMS file that contains the 'module' declaration - should match the name of the module in the file. - For instance in file hic0_full.va you will find the following declaration: - ... - module hic0_full (c,b,e,s); - ... - -05- Create file 'Makefile.am' - - In directory ..../hicum0 run the following command in order to create file 'Makefile.am': - $ admsXml admsva/hic0_full.va -Iadmsva -e ../admst/ngspiceMakefile.am.xml - [info] admsXml-2.1.3 Feb 2 2006 19:01:39 - [warning] [admsva\hic0_full.va:30]: standard vams file created (not found in -I path) ... 'constants.h' - [warning] [admsva\hic0_full.va:31]: standard vams file created (not found in -I path) ... 'discipline.h' - [info] Makefile.am: file created - [info] elapsed time: 1.0624 - [info] admst iterations: 185425 (185425 freed) - After this step file 'Makefile.am' is created: - $ head Makefile.am - ## - ## Interface: - ## created by: admsXml-2.1.3 - Monday, 01/30/06 - ## Process this file with automake to produce Makefile.in - ADMSXMLINTERFACE:=../admst - adms: - admsXml.exe -Iadmsva admsva/hic0_full.va \ - -06- Update/Create the auto-tools files (configure, Makefile.in, Makefile) - - 06.01 Manual changes - In directory edit file configure.ac, add new device 'hicum0' - (use the name of the directory - not the name of the module): - $ grep hicum0 configure.ac - src/spicelib/devices/adms/hicum0/Makefile \ - In directory /src/spicelib/devices edit file Makefile.am, add new device 'hicum0': - $ grep hicum0 Makefile.am - adms/hicum0 \ - adms/hicum0 \ - - 06.02 Makefile.in - In directory run the shell command 'automake': - File 'Makefile.in' is created in directory /src/spicelib/devices/hicum0. - In directory /src/spicelib/devices/hicum0 you should have: - $ ls - Makefile.am Makefile.in admsva constants.h discipline.h - - 06.03 Update file 'configure' - In directory run the shell command 'autoconf': - File 'configure' is updated. - Edit the file to make sure that "adms/hicum0/Makefile" is present in the file. - - 06.04 Makefile - In directory run shell command 'configure': - $ configure - ... - config.status: creating src/spicelib/devices/adms/hicum0/Makefile - ... - File 'Makefile' is created in directory /src/spicelib/devices/hicum0. - In directory /src/spicelib/devices/hicum0 you should have: - $ ls - Makefile Makefile.am Makefile.in admsva constants.h discipline.h - -07- Create the ready-to-compile auto-generated C code of device hicum0 - - In directory ..../hicum0 run the following command in order to create the auto-generated C code: - $ make adms - admsXml.exe -Iadmsva admsva/hic0_full.va \ - -e ../admst/ngspiceVersion.xml \ - -e ../admst/ngspiceMakefile.am.xml \ - -e ../admst/ngspiceMODULEitf.h.xml \ - -e ../admst/ngspiceMODULEinit.c.xml \ - -e ../admst/ngspiceMODULEinit.h.xml \ - -e ../admst/ngspiceMODULEext.h.xml \ - -e ../admst/ngspiceMODULEdefs.h.xml \ - -e ../admst/ngspiceMODULEask.c.xml \ - -e ../admst/ngspiceMODULEmask.c.xml \ - -e ../admst/ngspiceMODULEpar.c.xml \ - -e ../admst/ngspiceMODULEmpar.c.xml \ - -e ../admst/ngspiceMODULEload.c.xml \ - -e ../admst/ngspiceMODULEacld.c.xml \ - -e ../admst/ngspiceMODULEtemp.c.xml \ - -e ../admst/ngspiceMODULEsetup.c.xml \ - -e ../admst/ngspiceMODULEguesstopology.c.xml \ - -e ../admst/ngspiceMODULE.c.xml - [info] admsXml-2.1.3 Feb 2 2006 19:01:39 - [info] Makefile.am: file created - [info] hic0_fullitf.h: file created - [info] hic0_fullinit.c: file created - [info] hic0_fullinit.h: file created - [info] hic0_fullext.h: file created - [info] hic0_fulldefs.h: file created - [info] hic0_fullask.c: file created - [info] hic0_fullmask.c: file created - [info] hic0_fullpar.c: file created - [info] hic0_fullmpar.c: file created - [info] noise contribution not implemented - ignored! - [info] noise contribution not implemented - ignored! - [info] noise contribution not implemented - ignored! - [info] noise contribution not implemented - ignored! - [info] noise contribution not implemented - ignored! - [info] noise contribution not implemented - ignored! - [info] hic0_fullload.c: file created - [info] hic0_fullacld.c: file created - [info] hic0_fulltemp.c: file created - [info] hic0_fullsetup.c: file created - [info] hic0_fullguesstopology.c: file created - [info] hic0_full.c: file created - [info] elapsed time: 5.43757 - [info] admst iterations: 1099640 (1099640 freed) - perl -p -i -e 's/IOP\("(\w+)"/IOP("\L\1"/' hic0_full.c - - In directory /src/spicelib/devices/hicum0 you should have: - $ ls - Makefile constants.h hic0_fullacld.c hic0_fullguesstopology.c hic0_fullload.c hic0_fullsetup.c - Makefile.am discipline.h hic0_fullask.c hic0_fullinit.c hic0_fullmask.c hic0_fulltemp.c - Makefile.in hic0_full.c hic0_fulldefs.h hic0_fullinit.h hic0_fullmpar.c - admsva hic0_fullext.h hic0_fullitf.h hic0_fullpar.c - -08- Compile the ready-to-compile auto-generated C code - - In directory ..../hicum0 run the following command in order to create the object files*.o and libhic0_full.a: - $ make CFLAGS="-g" - if gcc -DHAVE_CONFIG_H -I. -I. -I../../../../.. -I../../../../../src/include -g -MT hic0_full.o - -MD -MP -MF ".ds/hic0_full.Tpo" -c -o hic0_full.o hic0_full.c; \ - then mv -f ".deps/hic0_full.Tpo" ".deps/hic0_full.Po"; else rm -f ".deps/hic0_full.Tpo"; exit 1; fi - ... - ar cru libhic0_full.a hic0_full.o hic0_fullacld.o hic0_fullask.o hic0_fullguesstopology.o hic0_fullinit.o - hic0_fullload.o hic0_fullmask.o hic0_fullmpar.o hic0_fullpar.o hic0_fullsetup.o hic0_fulltemp.o - ranlib libhic0_full.a - - WARNING: at the compilation step some messages about '#warning conflict' will be printed. - They mean that some ngspice reserved keywords have been used in the Verilog-AMS. - Just ignore them in the case of hicum0. - - In directory /src/spicelib/devices/hicum0 you should have: - $ ls - Makefile hic0_full.c hic0_fullask.o hic0_fullinit.h hic0_fullmask.o hic0_fullsetup.o - Makefile.am hic0_fulldefs.h hic0_fullinit.o hic0_fullmpar.c hic0_fulltemp.c - Makefile.in hic0_full.o hic0_fullext.h hic0_fullitf.h hic0_fullmpar.o hic0_fulltemp.o - admsva hic0_fullacld.c hic0_fullguesstopology.c hic0_fullload.c hic0_fullpar.c libhic0_full.a - constants.h hic0_fullacld.o hic0_fullguesstopology.o hic0_fullload.o hic0_fullpar.o - discipline.h hic0_fullask.c hic0_fullinit.c hic0_fullmask.c hic0_fullsetup.c - - NOTE: CFLAGS is redefined to "-g" is order to speed up the compilation process. - It is better NOT to redefine CFLAGS for official releases. - (the compilation will take a lot longer to complete) - - -09- Update manually the ngspice parser files - Modify the following files: - /src/spicelib/parser/inp2q.c ----> depends on the type of the device, here 'q' device - /src/spicelib/parser/inpdomod.c - /src/spicelib/devices/dev.c - ... -10- Update executable 'ngspice' - - 10-01 Update ngspice - In directory run shell command 'make': - $ make - File 'src/ngspice.exe' is updated and contains the new device 'hicum0'. - - 10-02 Install ngspice - In directory run shell command 'make': - $ make install - ngspice executables are installed in /usr/local/bin. - -11- Test the Implementation of hicum0 into ngspice - 11-01 Create a simple ngspice netlist - Create file 'hicum0.sp'. Its contents is given below: - $ cat hicum0.sp - .title Netlist - .option - + temp=25.0 - + reltol=1e-5 - + abstol=1e-15 - .model mybjtmodel npn - + npn=1 - + level=5 - qN1 - + c b 0 0 - + mybjtmodel - rcc cc c 100.0 - rbb bb b 1k - vcc - + cc 0 - + 1.0 - vbb - + bb 0 - + 0.0 - + ac=0.0 - .dc vbb 0.0 1.0 0.02 - .print - + dc - + v(c) - + i(vbb) - + i(vcc) - .end - - 11-02 run 'ngspice': - $ ngspice -b hicum0.sp - Circuit: .title Netlist - Doing analysis at TEMP = 298.150000 and TNOM = 300.150000 - No. of Data Rows : 51 - .title Netlist - DC transfer characteristic Mon Jan 30 10:22:01 2006 - -------------------------------------------------------------------------------- - Index v-sweep v(c) vbb#branch vcc#branch - -------------------------------------------------------------------------------- - 0 0.000000e+00 1.000000e+00 0.000000e+00 -7.105421e-17 - 1 2.000000e-02 1.000000e+00 -5.593842e-19 -1.265654e-16 - 2 4.000000e-02 1.000000e+00 -2.076336e-18 -2.775558e-16 - 3 6.000000e-02 1.000000e+00 -5.366258e-18 -6.061817e-16 - 4 8.000000e-02 1.000000e+00 -1.254873e-17 -1.320055e-15 - 5 1.000000e-01 1.000000e+00 -2.812744e-17 -2.874367e-15 - 6 1.200000e-01 1.000000e+00 -7.629085e-17 -7.666090e-15 - 7 1.400000e-01 1.000000e+00 -1.669761e-16 -1.669553e-14 - 8 1.600000e-01 1.000000e+00 -3.645759e-16 -3.636425e-14 - 9 1.800000e-01 1.000000e+00 -7.948513e-16 -7.920553e-14 - 10 2.000000e-01 1.000000e+00 -1.732082e-15 -1.725142e-13 - 11 2.200000e-01 1.000000e+00 -3.773484e-15 -3.757461e-13 - 12 2.400000e-01 1.000000e+00 -8.219658e-15 -8.183998e-13 - 13 2.600000e-01 1.000000e+00 -1.790375e-14 -1.782522e-12 - 14 2.800000e-01 1.000000e+00 -3.899630e-14 -3.882434e-12 - 15 3.000000e-01 1.000000e+00 -8.493698e-14 -8.456170e-12 - 16 3.200000e-01 1.000000e+00 -1.849987e-13 -1.841804e-11 - 17 3.400000e-01 1.000000e+00 -4.029389e-13 -4.011557e-11 - 18 3.600000e-01 1.000000e+00 -8.776254e-13 -8.737407e-11 - 19 3.800000e-01 1.000000e+00 -1.911521e-12 -1.903059e-10 - 20 4.000000e-01 1.000000e+00 -4.163405e-12 -4.144973e-10 - 21 4.200000e-01 9.999999e-01 -9.068141e-12 -9.027994e-10 - 22 4.400000e-01 9.999998e-01 -1.975094e-11 -1.966349e-09 - 23 4.600000e-01 9.999996e-01 -4.301867e-11 -4.282821e-09 - 24 4.800000e-01 9.999991e-01 -9.369701e-11 -9.328218e-09 - 25 5.000000e-01 9.999980e-01 -2.040767e-10 -2.031732e-08 - 26 5.200000e-01 9.999956e-01 -4.444870e-10 -4.425191e-08 - 27 5.400000e-01 9.999904e-01 -9.680991e-10 -9.638130e-08 - 28 5.600000e-01 9.999790e-01 -2.108483e-09 -2.099148e-07 - 29 5.800000e-01 9.999543e-01 -4.591957e-09 -4.571626e-07 - 30 6.000000e-01 9.999004e-01 -9.999448e-09 -9.955176e-07 - 31 6.200000e-01 9.997833e-01 -2.176941e-08 -2.167303e-06 - 32 6.400000e-01 9.995284e-01 -4.736784e-08 -4.715812e-06 - 33 6.600000e-01 9.989751e-01 -1.029470e-07 -1.024912e-05 - 34 6.800000e-01 9.977781e-01 -2.231776e-07 -2.221894e-05 - 35 7.000000e-01 9.952090e-01 -4.812339e-07 -4.791028e-05 - 36 7.200000e-01 9.897838e-01 -1.026165e-06 -1.021618e-04 - 37 7.400000e-01 9.786930e-01 -2.140206e-06 -2.130697e-04 - 38 7.600000e-01 9.573154e-01 -4.287705e-06 -4.268455e-04 - 39 7.800000e-01 9.197474e-01 -8.062749e-06 -8.025264e-04 - 40 8.000000e-01 8.611162e-01 -1.395965e-05 -1.388838e-03 - 41 8.200000e-01 7.801099e-01 -2.212604e-05 -2.198901e-03 - 42 8.400000e-01 6.791392e-01 -3.235919e-05 -3.208608e-03 - 43 8.600000e-01 5.627227e-01 -4.429334e-05 -4.372773e-03 - 44 8.800000e-01 4.367031e-01 -5.756142e-05 -5.632969e-03 - 45 9.000000e-01 3.111929e-01 -7.186079e-05 -6.888071e-03 - 46 9.200000e-01 2.120521e-01 -8.696058e-05 -7.879479e-03 - 47 9.400000e-01 1.637984e-01 -1.026891e-04 -8.362016e-03 - 48 9.600000e-01 1.443326e-01 -1.189191e-04 -8.556674e-03 - 49 9.800000e-01 1.353683e-01 -1.355550e-04 -8.646317e-03 - 50 1.000000e+00 1.312181e-01 -1.525242e-04 -8.687819e-03 - Total elapsed time: 0.625 seconds. - Current dynamic memory usage = 1.515520 MB, - Dynamic memory limit = 1241.702400 MB. - -12- How to update ngspice when the Verilog-AMS source code changes - - If you modify the Verilog-AMS source code of 'hicum0' - just complete the following steps in order to update - 'ngspice': - - 12-01 Update the auto-generated C code - In directory ..../hicum0 run: - - make clean - - make adms - - make - 12-02 Update 'ngspice' and re-install - In directory run: - - make - - make install - -Appendix 01: Comments on spice3-flavoured flags like npn, pnp, nmos, pmos and so on - - In the adms-based implementation of hicum0 the value of the device type flag (either npn or pnp) - in the model card is just ignored. - The selection of the type of the device is actually done using model parameters. - In the Verilog-AMS code of hicum0 there are two special model parameters called 'npn' and 'pnp' - which decide what the type of the device will be (either a npn bipolar model or pnp bipolar model). - The Verilog-AMS piece of code that triggers the decision is as follows: - if (`PGIVEN(npn)) - HICUMtype = `NPN; - else if (`PGIVEN(pnp)) - HICUMtype = `PNP; - else - HICUMtype = `NPN; - end - `PGIVEN(npn) is a macro that returns 1 is model parameter 'npn' occurs in the .model card - of the ngspice netlist. Otherwise it returns 0. - For instance: - 1- the following model card will select a NPN type device: - .model mybjtmodel npn - + npn=1 - + level=5 - 2- the following model card will select a PNP type device: - .model mybjtmodel npn - + pnp=1 - + level=5 - - In both cases flag 'npn' is just ignored. - In section 'Update manually the ngspice parser files' it is recommended - to use flag 'adms' instead. - This limitation results from the LRM of VerilogAMS that does not support flags. - - diff --git a/README.adms b/README.adms index cbda7a84e..86d861466 100644 --- a/README.adms +++ b/README.adms @@ -1,5 +1,12 @@ This document is covered by the Creative Commons Attribution Share-Alike (CC-BY-SA) v4.0. . +As of Jan. 23 ADMS is deprectated and replaced by OpenVAF/OSDI. +See README_OSDI.md and README_OSDI_howto. +All references to ADMS will be removed in a future ngspice release. + + + + *************** Verilog A Device models in ngspice ****************************************** diff --git a/README_OSDI_howto b/README_OSDI_howto new file mode 100644 index 000000000..3d2c85b11 --- /dev/null +++ b/README_OSDI_howto @@ -0,0 +1,60 @@ +A 'quick and dirty' howto for OpenVAF and OSDI: + +Example BSIMBULK +Tested under MS Windows 10 and OpenSUSE 15.4 + +Have OpenVAF compiler available. + Executables for download are available at https://openvaf.semimod.de/download/ + for Linux and MS Windows. +Download BSIMBULK model from http://www.bsim.berkeley.edu/models/bsimbulk/ +Open bsimbulk.va in a text editor +Search for the module name, here: + module bsimbulk(d, g, s, b, t); +The module name 'bsimbulk' will become the new model type in the .model statement + .model mname type ( pname1 = pval1 pname2 = pval2 ... ). +Compile bsimbulk.va with OpenVAF to obtain bsimbulk.osdi +Put bsimbulk.osdi into directory bsimbulk/test_osdi_libs +Search for suitable model parameters + BSIMBULK107 distro does not contain any parameters + BSIMBULK106 does contain a model parameter file model.l among the benchmark tests + Put model.l into directory bsimbulk/Modelcards + Edit model.l: + Check if model type is 'bsimbulk' (it is already) + Choose a model name for mname (nch or pch may be o.k., or BSIMBULK_osdi_N or ...) + There are NMOS and PMOS parameters in the same file here. + +Create a ngspice netlist in directory bsimbulk, e.g. bb_IDvsVG.cir. + +*** BSIMBULK107 Id versus Vgs *** +* the voltage sources +Vd dd 0 50m +Vg gg 0 1 +Vs ss 0 0 +Vb bb 0 0 + +* load the model parameter sets +.include Modelcards/model.l + +* the call to the transistor (OSDI devices always start with N !) +NMN1 dd gg ss bb BSIMBULK_osdi_N W=500n L=90n + +* the .control section +.control +* load the model dynamically +pre_osdi test_osdi_libs/bsimbulk.osdi +* the dc simulation +dc Vg 0 1.5 0.01 Vb 0 -1.6 -0.4 +* plotting +set xbrushwidth=3 +plot I(Vs) +.endc +.end +********************************* + +So we have two OSDI specific actions in the netlist: +load the model by + pre_osdi test_osdi_libs/bsimbulk.osdi +instantiate the transistor by + NMN1 dd gg ss bb BSIMBULK_osdi_N W=500n L=90n + + diff --git a/examples/digital/compare/adder_common.inc b/examples/digital/adder_common.inc similarity index 100% rename from examples/digital/compare/adder_common.inc rename to examples/digital/adder_common.inc diff --git a/examples/digital/compare/adder_behav.cir b/examples/digital/compare/adder_behav.cir index 2ccadd76a..f00a4f99a 100644 --- a/examples/digital/compare/adder_behav.cir +++ b/examples/digital/compare/adder_behav.cir @@ -5,6 +5,6 @@ .include 74HCng_short_2.lib .param vcc=3 tripdt=6n -.include adder_common.inc +.include ../adder_common.inc .END diff --git a/examples/osdi/EKV2.6/ekv26_inverter.sp b/examples/osdi/EKV2.6/ekv26_inverter.sp index 0a8a379b2..cf5887a92 100644 --- a/examples/osdi/EKV2.6/ekv26_inverter.sp +++ b/examples/osdi/EKV2.6/ekv26_inverter.sp @@ -28,7 +28,7 @@ c2 z vss 0.576f .dc V1 0 'vcc' 'vcc/100' .control -pre_osdi test_osdi_win/ekv26_mod.osdi +pre_osdi osdi_libs/ekv26_mod.osdi run *set nolegend set xbrushwidth=3 diff --git a/examples/osdi/EKV2.6/netlist_mod_nmos.sp b/examples/osdi/EKV2.6/netlist_mod_nmos.sp index 13e5cb15b..b5561fec2 100644 --- a/examples/osdi/EKV2.6/netlist_mod_nmos.sp +++ b/examples/osdi/EKV2.6/netlist_mod_nmos.sp @@ -15,7 +15,7 @@ VB bb 0 0 N1 dd gg ss bb nch W=5e-6 L=0.5e-6 .control -pre_osdi test_osdi_win/ekv26_mod.osdi +pre_osdi osdi_libs/ekv26_mod.osdi set xbrushwidth=3 * a DC sweep: drain, gate dc Vd 0 1.6 0.01 VG 0 1.6 0.2 diff --git a/examples/osdi/EKV2.6/netlist_mod_pmos.sp b/examples/osdi/EKV2.6/netlist_mod_pmos.sp index b20a26cee..25331a923 100644 --- a/examples/osdi/EKV2.6/netlist_mod_pmos.sp +++ b/examples/osdi/EKV2.6/netlist_mod_pmos.sp @@ -15,7 +15,7 @@ VB bb 0 0 N1 dd gg ss bb pch W=5e-6 L=5e-7 .control -pre_osdi test_osdi_win/ekv26_mod.osdi +pre_osdi osdi_libs/ekv26_mod.osdi set xbrushwidth=3 * a DC sweep: drain, gate *op diff --git a/examples/osdi/EKV2.6/test_osdi_win/README b/examples/osdi/EKV2.6/osdi_libs/README similarity index 100% rename from examples/osdi/EKV2.6/test_osdi_win/README rename to examples/osdi/EKV2.6/osdi_libs/README diff --git a/examples/osdi/README b/examples/osdi/README index 6475f9d9e..9f03839e1 100644 --- a/examples/osdi/README +++ b/examples/osdi/README @@ -1,10 +1,11 @@ A 'quick and dirty' howto for OpenVAF and OSDI: Example BSIMBULK -Tested under MS Windows 10 +Tested under MS Windows 10 and OpenSUSE 15.4 Have OpenVAF compiler available. - Sources will be available soon. + Executables for download are available at https://openvaf.semimod.de/download/ + for Linux and MS Windows. Download BSIMBULK model from http://www.bsim.berkeley.edu/models/bsimbulk/ Open bsimbulk.va in a text editor Search for the module name, here: @@ -12,7 +13,7 @@ Search for the module name, here: The module name 'bsimbulk' will become the new model type in the .model statement .model mname type ( pname1 = pval1 pname2 = pval2 ... ). Compile bsimbulk.va with OpenVAF to obtain bsimbulk.osdi -Put bsimbulk.osdi into directory bsimbulk/test_osdi_win +Put bsimbulk.osdi into directory bsimbulk/osdi_libs Search for suitable model parameters BSIMBULK107 distro does not contain any parameters BSIMBULK106 does contain a model parameter file model.l among the benchmark tests @@ -40,7 +41,7 @@ NMN1 dd gg ss bb BSIMBULK_osdi_N W=500n L=90n * the .control section .control * load the model dynamically -pre_osdi test_osdi_win/bsimbulk107.osdi +pre_osdi osdi_libs/bsimbulk.osdi * the dc simulation dc Vg 0 1.5 0.01 Vb 0 -1.6 -0.4 * plotting @@ -52,7 +53,7 @@ plot I(Vs) So we have two OSDI specific actions in the netlist: load the model by - pre_osdi test_osdi_win/bsimbulk107.osdi + pre_osdi osdi_libs/bsimbulk.osdi instantiate the transistor by NMN1 dd gg ss bb BSIMBULK_osdi_N W=500n L=90n diff --git a/examples/osdi/bsimbulk/bsimbulk_inverter.sp b/examples/osdi/bsimbulk/bsimbulk_inverter.sp index 78f3163c0..bc62233f1 100644 --- a/examples/osdi/bsimbulk/bsimbulk_inverter.sp +++ b/examples/osdi/bsimbulk/bsimbulk_inverter.sp @@ -27,7 +27,7 @@ c2 z vss 0.576f .dc V1 0 'vcc' 'vcc/100' .control -pre_osdi test_osdi_win/bsimbulk107.osdi +pre_osdi osdi_libs/bsimbulk107.osdi run *set nolegend set xbrushwidth=3 diff --git a/examples/osdi/bsimbulk/bsimbulk_ro.sp b/examples/osdi/bsimbulk/bsimbulk_ro.sp index b691f340f..93712e38f 100644 --- a/examples/osdi/bsimbulk/bsimbulk_ro.sp +++ b/examples/osdi/bsimbulk/bsimbulk_ro.sp @@ -31,7 +31,7 @@ c2 z vss 0.576f .tran 10p 10n uic .control -pre_osdi test_osdi_win/bsimbulk107.osdi +pre_osdi osdi_libs/bsimbulk107.osdi run set xbrushwidth=3 plot in diff --git a/examples/osdi/bsimbulk/c7552_ann_bsimbulk.net b/examples/osdi/bsimbulk/c7552_ann_bsimbulk.net index 6886915aa..f036bab31 100644 --- a/examples/osdi/bsimbulk/c7552_ann_bsimbulk.net +++ b/examples/osdi/bsimbulk/c7552_ann_bsimbulk.net @@ -89225,7 +89225,7 @@ c2 z vss 0.834f *.print tran V(g7529_1) V(g7509_0) V(g7484_1) V(g7477_1) V(g7460_0) V(g7503_1) V(g7522_0) V(g7485_1) V(g7453_0) V(g7474_0) V(g7500_0) V(g7514_0) V(g7546_1) V(g7549_0) V(g7467_0) V(g7491_0) V(g7456_0) V(g7495_1) V(g7545_0) V(g7473_0) V(g7541_0) V(g7448_1) V(g7525_1) V(g7550_1) V(g165_1) V(g7510_1) V(g7535_1) V(g7534_1) V(g7469_1) V(g7476_0) V(g7517_1) V(g7537_0) V(g7489_1) V(g7521_1) V(g7486_0) V(g7533_1) V(g7449_0) V(g7447_0) V(g7528_0) V(g7513_1) V(g7548_0) V(g7544_1) V(g7552_0) V(g7540_1) V(g7507_0) V(g7481_0) V(g7455_0) V(g7502_1) V(g7446_1) V(g7478_1) V(g7470_0) V(g7526_0) V(g7494_1) V(g7452_1) V(g7463_0) V(g7532_1) V(g7512_0) V(g7527_0) V(g7451_0) V(g7472_0) V(g7498_1) V(g7475_0) V(g7536_0) V(g7488_1) V(g7493_1) V(g7551_1) V(g7482_0) V(g7487_1) V(g7501_1) V(g7520_1) V(g7516_1) V(g7450_1) V(g7508_0) V(g7458_1) V(g7479_1) V(g7506_1) V(g7499_0) V(g7471_0) V(g7465_1) V(g7464_1) V(g7543_1) V(g7524_0) V(g7539_1) V(g7468_1) V(g7459_0) V(g7504_1) V(g7515_1) V(g7492_1) V(g7511_0) V(g7462_1) V(g7530_0) V(g7497_1) V(g7454_1) V(g7519_1) V(g7531_0) V(g7547_0) V(g7483_1) V(g7466_1) V(g7480_1) V(g7523_1) V(g7496_0) V(g7538_0) V(g7490_1) V(g7518_1) V(g7461_0) V(g7542_0) V(g7457_0) V(g7505_1) .control -pre_osdi test_osdi_win/bsimbulk107.osdi +pre_osdi osdi_libs/bsimbulk107.osdi unset ngdebug save V(g7529_1) V(g7509_0) V(g7484_1) V(g7477_1) V(g7460_0) V(g7503_1) V(g7522_0) V(g7485_1) V(g7453_0) V(g7474_0) V(g7500_0) V(g7514_0) V(g7546_1) V(g7549_0) V(g7467_0) V(g7491_0) V(g7456_0) V(g7495_1) V(g7545_0) V(g7473_0) V(g7541_0) V(g7448_1) V(g7525_1) V(g7550_1) V(g165_1) V(g7510_1) V(g7535_1) V(g7534_1) V(g7469_1) V(g7476_0) V(g7517_1) V(g7537_0) V(g7489_1) V(g7521_1) V(g7486_0) V(g7533_1) V(g7449_0) V(g7447_0) V(g7528_0) V(g7513_1) V(g7548_0) V(g7544_1) V(g7552_0) V(g7540_1) V(g7507_0) V(g7481_0) V(g7455_0) V(g7502_1) V(g7446_1) V(g7478_1) V(g7470_0) V(g7526_0) V(g7494_1) V(g7452_1) V(g7463_0) V(g7532_1) V(g7512_0) V(g7527_0) V(g7451_0) V(g7472_0) V(g7498_1) V(g7475_0) V(g7536_0) V(g7488_1) V(g7493_1) V(g7551_1) V(g7482_0) V(g7487_1) V(g7501_1) V(g7520_1) V(g7516_1) V(g7450_1) V(g7508_0) V(g7458_1) V(g7479_1) V(g7506_1) V(g7499_0) V(g7471_0) V(g7465_1) V(g7464_1) V(g7543_1) V(g7524_0) V(g7539_1) V(g7468_1) V(g7459_0) V(g7504_1) V(g7515_1) V(g7492_1) V(g7511_0) V(g7462_1) V(g7530_0) V(g7497_1) V(g7454_1) V(g7519_1) V(g7531_0) V(g7547_0) V(g7483_1) V(g7466_1) V(g7480_1) V(g7523_1) V(g7496_0) V(g7538_0) V(g7490_1) V(g7518_1) V(g7461_0) V(g7542_0) V(g7457_0) V(g7505_1) diff --git a/examples/osdi/bsimbulk/netlist_mod_nmos.sp b/examples/osdi/bsimbulk/netlist_mod_nmos.sp index ae1e32165..fd9392e27 100644 --- a/examples/osdi/bsimbulk/netlist_mod_nmos.sp +++ b/examples/osdi/bsimbulk/netlist_mod_nmos.sp @@ -15,7 +15,7 @@ VB bb 0 0 N1 dd gg ss bb BSIMBULK_osdi_N W=500n L=90n .control -pre_osdi test_osdi_win/bsimbulk107.osdi +pre_osdi osdi_libs/bsimbulk107.osdi set xbrushwidth=3 * a DC sweep: drain, gate dc Vd 0 1.6 0.01 VG 0 1.6 0.2 diff --git a/examples/osdi/bsimbulk/netlist_mod_pmos.sp b/examples/osdi/bsimbulk/netlist_mod_pmos.sp index 29c8d31e5..0637ee59b 100644 --- a/examples/osdi/bsimbulk/netlist_mod_pmos.sp +++ b/examples/osdi/bsimbulk/netlist_mod_pmos.sp @@ -16,7 +16,7 @@ VB bb 0 0 N1 dd gg ss bb BSIMBULK_osdi_P W=500n L=90n .control -pre_osdi test_osdi_win/bsimbulk107.osdi +pre_osdi osdi_libs/bsimbulk107.osdi set xbrushwidth=3 * a DC sweep: drain, gate *op diff --git a/examples/osdi/bsimbulk/nmos_pmos_BSIMBULK.sp b/examples/osdi/bsimbulk/nmos_pmos_BSIMBULK.sp index 27f40c01a..7e9588060 100644 --- a/examples/osdi/bsimbulk/nmos_pmos_BSIMBULK.sp +++ b/examples/osdi/bsimbulk/nmos_pmos_BSIMBULK.sp @@ -17,7 +17,7 @@ vbsp 44 0 0 .control * Load the models dynamically -pre_osdi test_osdi_win/bsimbulk107.osdi +pre_osdi osdi_libs/bsimbulk107.osdi set xgridwidth=2 set xbrushwidth=3 diff --git a/examples/osdi/bsimbulk/test_osdi_win/README b/examples/osdi/bsimbulk/osdi_libs/README similarity index 100% rename from examples/osdi/bsimbulk/test_osdi_win/README rename to examples/osdi/bsimbulk/osdi_libs/README diff --git a/examples/osdi/bsimcmg/inverter_ro.sp b/examples/osdi/bsimcmg/inverter_ro.sp index 816ed6839..721b0dbc7 100644 --- a/examples/osdi/bsimcmg/inverter_ro.sp +++ b/examples/osdi/bsimcmg/inverter_ro.sp @@ -28,7 +28,7 @@ Xinv6 vi vo supply 0 mg_inv .tran 0.1p 1n .control -pre_osdi test_osdi_win/bsimcmg.osdi +pre_osdi osdi_libs/bsimcmg.osdi set xbrushwidth=3 run plot i(vss) diff --git a/examples/osdi/bsimcmg/inverter_transient.sp b/examples/osdi/bsimcmg/inverter_transient.sp index e943b9dca..57dc03262 100644 --- a/examples/osdi/bsimcmg/inverter_transient.sp +++ b/examples/osdi/bsimcmg/inverter_transient.sp @@ -27,7 +27,7 @@ Xinv5 4 vo supply 0 mg_inv .print tran v(vi) v(vo) .control -pre_osdi test_osdi_win/bsimcmg.osdi +pre_osdi osdi_libs/bsimcmg.osdi set xbrushwidth=3 run plot v(vi) v(vo) diff --git a/examples/osdi/bsimcmg/netlist_nmos.sp b/examples/osdi/bsimcmg/netlist_nmos.sp index bc0d7c02d..ef521c8f8 100644 --- a/examples/osdi/bsimcmg/netlist_nmos.sp +++ b/examples/osdi/bsimcmg/netlist_nmos.sp @@ -16,7 +16,7 @@ VB bb 0 0 N1 dd gg ss bb BSIMCMG_osdi_N ; W=5u L=0.2u .control -pre_osdi test_osdi_win/bsimcmg.osdi +pre_osdi osdi_libs/bsimcmg.osdi set xbrushwidth=3 * a DC sweep: drain, gate dc Vd 0 2.5 0.01 VG 0 2.5 0.5 diff --git a/examples/osdi/bsimcmg/netlist_pmos.sp b/examples/osdi/bsimcmg/netlist_pmos.sp index b56010fa8..419299773 100644 --- a/examples/osdi/bsimcmg/netlist_pmos.sp +++ b/examples/osdi/bsimcmg/netlist_pmos.sp @@ -16,7 +16,7 @@ VB bb 0 0 N1 dd gg ss bb BSIMCMG_osdi_P .control -pre_osdi test_osdi_win/bsimcmg.osdi +pre_osdi osdi_libs/bsimcmg.osdi set xbrushwidth=3 * a DC sweep: drain, gate dc Vd 0 -1.8 -0.01 VG 0 -1.8 -0.3 diff --git a/examples/osdi/bsimcmg/test_osdi_win/README b/examples/osdi/bsimcmg/osdi_libs/README similarity index 100% rename from examples/osdi/bsimcmg/test_osdi_win/README rename to examples/osdi/bsimcmg/osdi_libs/README diff --git a/examples/osdi/bsimcmg/ringosc_17stg.sp b/examples/osdi/bsimcmg/ringosc_17stg.sp index 4677d8292..650ac805b 100644 --- a/examples/osdi/bsimcmg/ringosc_17stg.sp +++ b/examples/osdi/bsimcmg/ringosc_17stg.sp @@ -45,7 +45,7 @@ Xinv17 17 1 supply 0 mg_inv .measure tran delay_per_stage param='period/34' .control -pre_osdi test_osdi_win/bsimcmg.osdi +pre_osdi osdi_libs/bsimcmg.osdi set xbrushwidth=3 run plot v(1) diff --git a/examples/osdi/bsimcmg/simple_inverter_dc.sp b/examples/osdi/bsimcmg/simple_inverter_dc.sp index b47b7514f..d7eac639d 100644 --- a/examples/osdi/bsimcmg/simple_inverter_dc.sp +++ b/examples/osdi/bsimcmg/simple_inverter_dc.sp @@ -18,7 +18,7 @@ NN1 vout vin 0 0 BSIMCMG_osdi_N .tran 10n 2u .control -pre_osdi test_osdi_win/bsimcmg.osdi +pre_osdi osdi_libs/bsimcmg.osdi set xbrushwidth=3 run plot v(vout) v(vin) diff --git a/examples/osdi/hicuml0/DFF_Y_ECL_HICUM.sp b/examples/osdi/hicuml0/DFF_Y_ECL_HICUM.sp index ff22111b0..984c186be 100644 --- a/examples/osdi/hicuml0/DFF_Y_ECL_HICUM.sp +++ b/examples/osdi/hicuml0/DFF_Y_ECL_HICUM.sp @@ -32,7 +32,7 @@ Rdt dt 0 1G .include Modelcards/model-card-hicumL0V1p11_mod.lib .SAVE V(D) V(CLK) V(Q) .control -pre_osdi test_osdi_win/HICUML0-2.osdi +pre_osdi osdi_libs/HICUML0-2.osdi TRAN 0.25p 5n rusage set color0=white diff --git a/examples/osdi/hicuml0/ECL-RO-5.cir b/examples/osdi/hicuml0/ECL-RO-5.cir index f6e764f89..b4ed886fe 100644 --- a/examples/osdi/hicuml0/ECL-RO-5.cir +++ b/examples/osdi/hicuml0/ECL-RO-5.cir @@ -35,7 +35,7 @@ V1 VEE GND -5.2 .tran 0.02n 200n .control -pre_osdi test_osdi_win/HICUML0-2.osdi +pre_osdi osdi_libs/HICUML0-2.osdi run rusage plot out9 xlimit 100n 110n diff --git a/examples/osdi/hicuml0/ECL-RO.cir b/examples/osdi/hicuml0/ECL-RO.cir index 45ff75c33..1b378cd4c 100644 --- a/examples/osdi/hicuml0/ECL-RO.cir +++ b/examples/osdi/hicuml0/ECL-RO.cir @@ -18,7 +18,7 @@ V3 In2 GND dc -1.75 pulse(-1.75 -0.9 0 1n 1n 2.5u 5u) Rt1 DT GND 1G .tran 0.1n 100u .control -pre_osdi test_osdi_win/HICUML0-2.osdi +pre_osdi osdi_libs/HICUML0-2.osdi run plot a1 a2+2 in1+4 in2+6 .endc diff --git a/examples/osdi/hicuml0/hic0_gum.sp b/examples/osdi/hicuml0/hic0_gum.sp index ef4a48adf..c16c84e00 100644 --- a/examples/osdi/hicuml0/hic0_gum.sp +++ b/examples/osdi/hicuml0/hic0_gum.sp @@ -8,7 +8,7 @@ XQ1 C B 0 S DT hicumL0V1p1_c_sbt Rdt dt 0 1G .control -pre_osdi test_osdi_win/HICUML0-2.osdi +pre_osdi osdi_libs/HICUML0-2.osdi dc vb 0.2 1.4 0.01 set xbrushwidth=2 plot abs(i(vc)) abs(i(vb)) abs(i(vs)) ylimit 0.1p 100m ylog diff --git a/examples/osdi/hicuml0/hic0_out.sp b/examples/osdi/hicuml0/hic0_out.sp index 399478137..01dbba72e 100644 --- a/examples/osdi/hicuml0/hic0_out.sp +++ b/examples/osdi/hicuml0/hic0_out.sp @@ -8,7 +8,7 @@ X1 C B 0 S DT hicumL0V1p1_c_sbt Rdt dt 0 1G .control -pre_osdi test_osdi_win/HICUML0-2.osdi +pre_osdi osdi_libs/HICUML0-2.osdi dc vc 0.0 3.0 0.05 ib 10u 100u 10u set xbrushwidth=2 plot abs(i(vc)) diff --git a/examples/osdi/hicuml0/test_osdi_win/README b/examples/osdi/hicuml0/osdi_libs/README similarity index 100% rename from examples/osdi/hicuml0/test_osdi_win/README rename to examples/osdi/hicuml0/osdi_libs/README diff --git a/examples/osdi/mextram/mex_gum.sp b/examples/osdi/mextram/mex_gum.sp index dd3cd014d..0bff206bd 100644 --- a/examples/osdi/mextram/mex_gum.sp +++ b/examples/osdi/mextram/mex_gum.sp @@ -5,11 +5,12 @@ MEXTRAM Gummel Test Ic,b,s=f(Vc,Ib) VB B 0 0.5 VC C 0 2.0 VS S 0 0.0 -NQ1 C B 0 S DT BJTRF1 +NQ1 C B 0 S dt BJTRF1 .control -pre_osdi test_osdi_win/bjt504t.osdi +pre_osdi osdi_libs/bjt504t.osdi dc vb 0.2 1.4 0.01 +set xbrushwidth=2 plot abs(i(vc)) abs(i(vb)) abs(i(vs)) ylog xlimit 0.3 1.4 ylimit 1e-12 100e-3 plot abs(i(vc))/abs(i(vb)) vs abs(-i(vc)) xlog xlimit 1e-09 10e-3 ylimit 0 150 .endc diff --git a/examples/osdi/mextram/mex_out.sp b/examples/osdi/mextram/mex_out.sp index 9ffc46480..cbc6f86c1 100644 --- a/examples/osdi/mextram/mex_out.sp +++ b/examples/osdi/mextram/mex_out.sp @@ -8,8 +8,9 @@ VS S 0 0.0 NQ1 C B 0 S T BJTRF1 .control -pre_osdi test_osdi_win/bjt504t.osdi -dc vc 0 6.0 0.05 ib 1u 8u 1u +pre_osdi osdi_libs/bjt504t.osdi +dc vc 0 6.0 0.05 ib 0 8u 1u +set xbrushwidth=2 plot abs(i(vc)) xlabel Vce title Output-Characteristic .endc diff --git a/examples/osdi/mextram/test_osdi_win/README b/examples/osdi/mextram/osdi_libs/README similarity index 100% rename from examples/osdi/mextram/test_osdi_win/README rename to examples/osdi/mextram/osdi_libs/README diff --git a/examples/osdi/mixed-models/bb-psp_ro.sp b/examples/osdi/mixed-models/bb-psp_ro.sp index 9d6f2ac43..94bca776d 100644 --- a/examples/osdi/mixed-models/bb-psp_ro.sp +++ b/examples/osdi/mixed-models/bb-psp_ro.sp @@ -67,7 +67,7 @@ c2 z vss 0.576f .control * Load the models dynamically -pre_osdi test_osdi_win/bsimbulk107.osdi test_osdi_win/psp103.osdi +pre_osdi osdi_libs/bsimbulk107.osdi osdi_libs/psp103.osdi * Run the simulation run * Plotting diff --git a/examples/osdi/mixed-models/bsimbulk_inverter.sp b/examples/osdi/mixed-models/bsimbulk_inverter.sp index 78f3163c0..bc62233f1 100644 --- a/examples/osdi/mixed-models/bsimbulk_inverter.sp +++ b/examples/osdi/mixed-models/bsimbulk_inverter.sp @@ -27,7 +27,7 @@ c2 z vss 0.576f .dc V1 0 'vcc' 'vcc/100' .control -pre_osdi test_osdi_win/bsimbulk107.osdi +pre_osdi osdi_libs/bsimbulk107.osdi run *set nolegend set xbrushwidth=3 diff --git a/examples/osdi/mixed-models/test_osdi_win/README b/examples/osdi/mixed-models/osdi_libs/README similarity index 100% rename from examples/osdi/mixed-models/test_osdi_win/README rename to examples/osdi/mixed-models/osdi_libs/README diff --git a/examples/osdi/mixed-models/psp_inverter.sp b/examples/osdi/mixed-models/psp_inverter.sp index 084c0f74c..160cbae5e 100644 --- a/examples/osdi/mixed-models/psp_inverter.sp +++ b/examples/osdi/mixed-models/psp_inverter.sp @@ -53,7 +53,7 @@ c2 z vss 0.576f .dc V1 0 'vcc' 'vcc/100' .control -pre_osdi test_osdi_win/psp103.osdi +pre_osdi osdi_libs/psp103.osdi run *set nolegend set xbrushwidth=2 diff --git a/examples/osdi/psp103/c7552_ann_psp.net b/examples/osdi/psp103/c7552_ann_psp.net index f125e07ee..2ddfd61ee 100644 --- a/examples/osdi/psp103/c7552_ann_psp.net +++ b/examples/osdi/psp103/c7552_ann_psp.net @@ -89225,7 +89225,7 @@ c2 z vss 0.834f *.print tran V(g7529_1) V(g7509_0) V(g7484_1) V(g7477_1) V(g7460_0) V(g7503_1) V(g7522_0) V(g7485_1) V(g7453_0) V(g7474_0) V(g7500_0) V(g7514_0) V(g7546_1) V(g7549_0) V(g7467_0) V(g7491_0) V(g7456_0) V(g7495_1) V(g7545_0) V(g7473_0) V(g7541_0) V(g7448_1) V(g7525_1) V(g7550_1) V(g165_1) V(g7510_1) V(g7535_1) V(g7534_1) V(g7469_1) V(g7476_0) V(g7517_1) V(g7537_0) V(g7489_1) V(g7521_1) V(g7486_0) V(g7533_1) V(g7449_0) V(g7447_0) V(g7528_0) V(g7513_1) V(g7548_0) V(g7544_1) V(g7552_0) V(g7540_1) V(g7507_0) V(g7481_0) V(g7455_0) V(g7502_1) V(g7446_1) V(g7478_1) V(g7470_0) V(g7526_0) V(g7494_1) V(g7452_1) V(g7463_0) V(g7532_1) V(g7512_0) V(g7527_0) V(g7451_0) V(g7472_0) V(g7498_1) V(g7475_0) V(g7536_0) V(g7488_1) V(g7493_1) V(g7551_1) V(g7482_0) V(g7487_1) V(g7501_1) V(g7520_1) V(g7516_1) V(g7450_1) V(g7508_0) V(g7458_1) V(g7479_1) V(g7506_1) V(g7499_0) V(g7471_0) V(g7465_1) V(g7464_1) V(g7543_1) V(g7524_0) V(g7539_1) V(g7468_1) V(g7459_0) V(g7504_1) V(g7515_1) V(g7492_1) V(g7511_0) V(g7462_1) V(g7530_0) V(g7497_1) V(g7454_1) V(g7519_1) V(g7531_0) V(g7547_0) V(g7483_1) V(g7466_1) V(g7480_1) V(g7523_1) V(g7496_0) V(g7538_0) V(g7490_1) V(g7518_1) V(g7461_0) V(g7542_0) V(g7457_0) V(g7505_1) .control -pre_osdi test_osdi_win/psp103.osdi +pre_osdi osdi_libs/psp103.osdi unset ngdebug save V(g7529_1) V(g7509_0) V(g7484_1) V(g7477_1) V(g7460_0) V(g7503_1) V(g7522_0) V(g7485_1) V(g7453_0) V(g7474_0) V(g7500_0) V(g7514_0) V(g7546_1) V(g7549_0) V(g7467_0) V(g7491_0) V(g7456_0) V(g7495_1) V(g7545_0) V(g7473_0) V(g7541_0) V(g7448_1) V(g7525_1) V(g7550_1) V(g165_1) V(g7510_1) V(g7535_1) V(g7534_1) V(g7469_1) V(g7476_0) V(g7517_1) V(g7537_0) V(g7489_1) V(g7521_1) V(g7486_0) V(g7533_1) V(g7449_0) V(g7447_0) V(g7528_0) V(g7513_1) V(g7548_0) V(g7544_1) V(g7552_0) V(g7540_1) V(g7507_0) V(g7481_0) V(g7455_0) V(g7502_1) V(g7446_1) V(g7478_1) V(g7470_0) V(g7526_0) V(g7494_1) V(g7452_1) V(g7463_0) V(g7532_1) V(g7512_0) V(g7527_0) V(g7451_0) V(g7472_0) V(g7498_1) V(g7475_0) V(g7536_0) V(g7488_1) V(g7493_1) V(g7551_1) V(g7482_0) V(g7487_1) V(g7501_1) V(g7520_1) V(g7516_1) V(g7450_1) V(g7508_0) V(g7458_1) V(g7479_1) V(g7506_1) V(g7499_0) V(g7471_0) V(g7465_1) V(g7464_1) V(g7543_1) V(g7524_0) V(g7539_1) V(g7468_1) V(g7459_0) V(g7504_1) V(g7515_1) V(g7492_1) V(g7511_0) V(g7462_1) V(g7530_0) V(g7497_1) V(g7454_1) V(g7519_1) V(g7531_0) V(g7547_0) V(g7483_1) V(g7466_1) V(g7480_1) V(g7523_1) V(g7496_0) V(g7538_0) V(g7490_1) V(g7518_1) V(g7461_0) V(g7542_0) V(g7457_0) V(g7505_1) diff --git a/examples/osdi/psp103/nmos_pmos_PSP.sp b/examples/osdi/psp103/nmos_pmos_PSP.sp index 71578b7eb..68769e218 100644 --- a/examples/osdi/psp103/nmos_pmos_PSP.sp +++ b/examples/osdi/psp103/nmos_pmos_PSP.sp @@ -42,7 +42,7 @@ vbsp 44 0 0 .control * Load the models dynamically -pre_osdi test_osdi_win/psp103.osdi +pre_osdi osdi_libs/psp103.osdi set xgridwidth=2 set xbrushwidth=3 diff --git a/examples/osdi/psp103/test_osdi_win/README b/examples/osdi/psp103/osdi_libs/README similarity index 100% rename from examples/osdi/psp103/test_osdi_win/README rename to examples/osdi/psp103/osdi_libs/README diff --git a/examples/osdi/psp103/psp_inverter.sp b/examples/osdi/psp103/psp_inverter.sp index 084c0f74c..160cbae5e 100644 --- a/examples/osdi/psp103/psp_inverter.sp +++ b/examples/osdi/psp103/psp_inverter.sp @@ -53,7 +53,7 @@ c2 z vss 0.576f .dc V1 0 'vcc' 'vcc/100' .control -pre_osdi test_osdi_win/psp103.osdi +pre_osdi osdi_libs/psp103.osdi run *set nolegend set xbrushwidth=2 diff --git a/examples/osdi/psp103/psp_out_nmos_nm.sp b/examples/osdi/psp103/psp_out_nmos_nm.sp index 65713e0f3..e11b1fa7f 100644 --- a/examples/osdi/psp103/psp_out_nmos_nm.sp +++ b/examples/osdi/psp103/psp_out_nmos_nm.sp @@ -23,7 +23,7 @@ nm1 d g s b nch *.include Modelcards/psp103_nmos.mod .control -pre_osdi test_osdi_win/psp103.osdi +pre_osdi osdi_libs/psp103.osdi dc vd 0 2.0 0.05 vg 0 1.5 0.25 plot i(vs) dc vg 0 1.5 0.05 vb 0 -3.0 -1 diff --git a/examples/osdi/psp103/psp_out_pmos_nm.sp b/examples/osdi/psp103/psp_out_pmos_nm.sp index 52d5b2906..1977eb539 100644 --- a/examples/osdi/psp103/psp_out_pmos_nm.sp +++ b/examples/osdi/psp103/psp_out_pmos_nm.sp @@ -19,7 +19,7 @@ nm1 d g s b pch * .option temp=21 .control -pre_osdi test_osdi_win/psp103.osdi +pre_osdi osdi_libs/psp103.osdi dc vd 0 -2.0 -0.05 vg 0 -1.5 -0.25 ; saturation plot i(vs) dc vg 0 -1.5 -0.05 vb 0 3.0 1 diff --git a/examples/osdi/psp103/psp_ro.sp b/examples/osdi/psp103/psp_ro.sp index 0bdada044..789c6ddf2 100644 --- a/examples/osdi/psp103/psp_ro.sp +++ b/examples/osdi/psp103/psp_ro.sp @@ -56,7 +56,7 @@ c2 z vss 0.576f .tran 10p 10n uic .control -pre_osdi test_osdi_win/psp103.osdi +pre_osdi osdi_libs/psp103.osdi run set xbrushwidth=3 plot in diff --git a/examples/osdi/psp103/psp_transfer.sp b/examples/osdi/psp103/psp_transfer.sp index 9feab6feb..09fb6fa96 100644 --- a/examples/osdi/psp103/psp_transfer.sp +++ b/examples/osdi/psp103/psp_transfer.sp @@ -19,7 +19,7 @@ nm1 d g s b nch * .option temp=21 .control -pre_osdi test_osdi_win/psp103.osdi +pre_osdi osdi_libs/psp103.osdi set xbrushwidth=2 dc vg 0 1.5 0.02 vb -3 0 0.5 plot abs(i(vd)) diff --git a/examples/osdi/r2_cmc/test_osdi_win/README b/examples/osdi/r2_cmc/osdi_win/README similarity index 100% rename from examples/osdi/r2_cmc/test_osdi_win/README rename to examples/osdi/r2_cmc/osdi_win/README diff --git a/examples/osdi/r2_cmc/res_r2_cmc.cir b/examples/osdi/r2_cmc/res_r2_cmc.cir index f03c06b66..dc45f6f90 100644 --- a/examples/osdi/r2_cmc/res_r2_cmc.cir +++ b/examples/osdi/r2_cmc/res_r2_cmc.cir @@ -7,7 +7,7 @@ NRr2_cmc 1 0 rmodel w=1u l=20u isnoisy=1 .model rmodel r2_cmc(level=2 rsh=200 xl=0.2u xw=-0.05u p3=0.12 q3=1.6 p2=0.015 q2=3.8 tc1=1.5e-4 tc2=7e-7) .control -pre_osdi test_osdi_win/r2_cmc.osdi +pre_osdi osdi_libs/r2_cmc.osdi op let res = v(1) / -v1#branch print res diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index ccfa6ea64..413cccff5 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -2869,8 +2869,10 @@ static char *inp_spawn_brace(char *s) removes " " quotes, returns lower case letters, replaces non-printable characters with '_', however if non-printable character is the only character in a line, - replace it by '*'. If there is a XSPICE code model .model - line with file input, keep quotes and case for the file path. + replace it by '*'. Leave quotes in .param, .subckt and x + (subcircuit instance) cards to allow string-valued parameters. + If there is a XSPICE code model .model line with file input, + keep quotes and case for the file path. *-------------------------------------------------------------------------*/ void inp_casefix(char *string) @@ -2883,20 +2885,23 @@ void inp_casefix(char *string) return; } if (string) { + bool keepquotes; + #ifdef XSPICE - /* special treatment of code model file input */ char* tmpstr = NULL; - bool keepquotes = ciprefix(".model", string); - if (keepquotes){ + + /* Special treatment of code model file input. */ + + if (ciprefix(".model", string)) tmpstr = strstr(string, "file="); - keepquotes = keepquotes && tmpstr; - } #endif + keepquotes = ciprefix(".param", string); // Allow string params + while (*string) { #ifdef XSPICE /* exclude file name inside of quotes from getting lower case, keep quotes to enable spaces in file path */ - if (keepquotes && string == tmpstr) { + if (string == tmpstr) { string = string + 6; // past first quote while (*string && *string != '"') string++; @@ -2907,12 +2912,13 @@ void inp_casefix(char *string) } #endif if (*string == '"') { - *string++ = ' '; + if (!keepquotes) + *string++ = ' '; while (*string && *string != '"') string++; if (*string == '\0') continue; /* needed if string is "something ! */ - if (*string == '"') + if (*string == '"' && !keepquotes) *string = ' '; } if (*string && !isspace_c(*string) && !isprint_c(*string)) @@ -5054,24 +5060,40 @@ static int inp_split_multi_param_lines(struct card *card, int line_num) char *beg_param, *end_param; - bool get_expression = FALSE; - bool get_paren_expression = FALSE; + int expression_depth = 0; + int paren_depth = 0; beg_param = skip_back_ws(equal_ptr, curr_line); beg_param = skip_back_non_ws(beg_param, curr_line); end_param = skip_ws(equal_ptr + 1); - while (*end_param != '\0' && - (!isspace_c(*end_param) || get_expression || - get_paren_expression)) { - if (*end_param == '{') - get_expression = TRUE; - if (*end_param == '(') - get_paren_expression = TRUE; - if (*end_param == '}') - get_expression = FALSE; - if (*end_param == ')') - get_paren_expression = FALSE; - end_param++; + while (*end_param && !isspace_c(*end_param)) { + /* Advance over numeric or string expression. */ + + if (*end_param == '"') { + /* RHS is quoted string. */ + + end_param++; + while (*end_param != '\0' && *end_param != '"') + end_param++; + if (*end_param == '"') + end_param++; + } else { + while (*end_param != '\0' && *end_param != '"' && + (!isspace_c(*end_param) || + expression_depth || paren_depth)) { + if (*end_param == ',' && paren_depth == 0) + break; + if (*end_param == '{') + ++expression_depth; + if (*end_param == '(') + ++paren_depth; + if (*end_param == '}' && expression_depth > 0) + --expression_depth; + if (*end_param == ')' && paren_depth > 0) + --paren_depth; + end_param++; + } + } } if (end_param[-1] == ',') diff --git a/src/frontend/numparam/general.h b/src/frontend/numparam/general.h index a17c26d9a..a0bf7aeaf 100644 --- a/src/frontend/numparam/general.h +++ b/src/frontend/numparam/general.h @@ -9,6 +9,7 @@ #include "ngspice/bool.h" +void pscat(DSTRINGPTR s, const char *str, const char *stop); void pscopy(DSTRINGPTR s, const char *str, const char *stop); void scopyd(DSTRINGPTR dst, const DSTRINGPTR src); void scopys(DSTRINGPTR a, const char *b); diff --git a/src/frontend/numparam/mystring.c b/src/frontend/numparam/mystring.c index fe58576e1..c16043877 100644 --- a/src/frontend/numparam/mystring.c +++ b/src/frontend/numparam/mystring.c @@ -123,21 +123,26 @@ scopys(DSTRINGPTR s, const char *t) /* returns success flag */ } -/* Copy until stop char (exclusive) or end of string if none given */ +/* Concatentate until stop char (exclusive) or end of string if none given */ + void -pscopy(DSTRINGPTR dstr_p, const char *t, const char *stop) +pscat(DSTRINGPTR dstr_p, const char *t, const char *stop) { if (!stop) { /* locate end of string if no stop char given */ stop = strchr(t, '\0'); } - - ds_clear(dstr_p); if (ds_cat_mem(dstr_p, t, (size_t) (stop - t)) != DS_E_OK) { fprintf(stderr, "Error: DS could not copy partially string %s\n", t); controlled_exit(-1); } +} /* end of function pscat */ - return; +/* Copy until stop char (exclusive) or end of string if none given */ +void +pscopy(DSTRINGPTR dstr_p, const char *t, const char *stop) +{ + ds_clear(dstr_p); + pscat(dstr_p, t, stop); } /* end of function pscopy */ diff --git a/src/frontend/numparam/numpaif.h b/src/frontend/numparam/numpaif.h index 800f4c701..560a70da2 100644 --- a/src/frontend/numparam/numpaif.h +++ b/src/frontend/numparam/numpaif.h @@ -18,9 +18,9 @@ extern int nupa_eval(struct card *card); extern void nupa_signal(int sig); extern void nupa_scan(const struct card *card); extern void nupa_list_params(FILE *cp_out); -extern double nupa_get_param(char *param_name, int *found); +extern double nupa_get_param(const char *param_name, int *found); +extern const char *nupa_get_string_param(const char *param_name); extern void nupa_add_param(char *param_name, double value); -extern void nupa_add_inst_param(char *param_name, double value); extern void nupa_copy_inst_dico(void); extern void nupa_del_dicoS(void); extern int nupa_add_dicoslist(void); diff --git a/src/frontend/numparam/numparam.h b/src/frontend/numparam/numparam.h index e5076a4c2..a294e2a2e 100644 --- a/src/frontend/numparam/numparam.h +++ b/src/frontend/numparam/numparam.h @@ -68,3 +68,4 @@ void nupa_subcktexit(dico_t *); entry_t *entrynb(dico_t *dico, char *s); entry_t *attrib(dico_t *, NGHASHPTR htable, char *t, char op); void del_attrib(void *); +void nupa_copy_inst_entry(char *param_name, entry_t *proto); diff --git a/src/frontend/numparam/spicenum.c b/src/frontend/numparam/spicenum.c index 338e83464..ce1af5153 100644 --- a/src/frontend/numparam/spicenum.c +++ b/src/frontend/numparam/spicenum.c @@ -415,6 +415,9 @@ dump_symbol_table(NGHASHPTR htable_p, FILE *fp) { if (entry->tp == NUPA_REAL) fprintf(fp, " ---> %s = %g\n", entry->symbol, entry->vl); + else if (entry->tp == NUPA_STRING) + fprintf(fp, " ---> %s = \"%s\"\n", + entry->symbol, entry->sbbase); } } @@ -456,8 +459,7 @@ nupa_list_params(FILE *fp) * Otherwise, we have to exhaust all of the tables including the global * table. * ----------------------------------------------------------------- */ -double -nupa_get_param(char *param_name, int *found) +static entry_t *nupa_get_entry(const char *param_name) { dico_t *dico = dicoS; /* local copy for speed */ int depth; /* nested subcircit depth */ @@ -465,21 +467,40 @@ nupa_get_param(char *param_name, int *found) for (depth = dico->stack_depth; depth >= 0; depth--) { NGHASHPTR htable_p = dico->symbols[depth]; if (htable_p) { - entry_t *entry = (entry_t *) nghash_find(htable_p, param_name); - if (entry) { - *found = 1; - return entry->vl; - } + entry_t *entry; + + entry = (entry_t *)nghash_find(htable_p, (void *)param_name); + if (entry) + return entry; } } + return NULL; +} +double +nupa_get_param(const char *param_name, int *found) +{ + entry_t *entry = nupa_get_entry(param_name); + if (entry && entry->tp == NUPA_REAL) { + *found = 1; + return entry->vl; + } *found = 0; return 0; } +const char * +nupa_get_string_param(const char *param_name) +{ + entry_t *entry = nupa_get_entry(param_name); + if (entry && entry->tp == NUPA_STRING) + return entry->sbbase; + return NULL; +} -void -nupa_add_param(char *param_name, double value) + +static void +nupa_copy_entry(entry_t *proto) { dico_t *dico = dicoS; /* local copy for speed */ entry_t *entry; /* current entry */ @@ -491,18 +512,32 @@ nupa_add_param(char *param_name, double value) htable_p = dico->symbols[dico->stack_depth]; - entry = attrib(dico, htable_p, param_name, 'N'); + entry = attrib(dico, htable_p, proto->symbol, 'N'); if (entry) { - entry->vl = value; - entry->tp = NUPA_REAL; - entry->ivl = 0; - entry->sbbase = NULL; + entry->vl = proto->vl; + entry->tp = proto->tp; + entry->ivl = proto->ivl; + entry->sbbase = proto->sbbase; } } void -nupa_add_inst_param(char *param_name, double value) +nupa_add_param(char *param_name, double value) +{ + entry_t entry; + + entry.symbol = param_name; + entry.vl = value; + entry.tp = NUPA_REAL; + entry.ivl = 0; + entry.sbbase = NULL; + nupa_copy_entry(&entry); +} + + +void +nupa_copy_inst_entry(char *param_name, entry_t *proto) { dico_t *dico = dicoS; /* local copy for speed */ entry_t *entry; /* current entry */ @@ -512,10 +547,10 @@ nupa_add_inst_param(char *param_name, double value) entry = attrib(dico, dico->inst_symbols, param_name, 'N'); if (entry) { - entry->vl = value; - entry->tp = NUPA_REAL; - entry->ivl = 0; - entry->sbbase = NULL; + entry->vl = proto->vl; + entry->tp = proto->tp; + entry->ivl = proto->ivl; + entry->sbbase = proto->sbbase; } } @@ -542,7 +577,7 @@ nupa_copy_inst_dico(void) entry; entry = (entry_t *) nghash_enumerateRE(dico->inst_symbols, &iter)) { - nupa_add_param(entry->symbol, entry->vl); + nupa_copy_entry(entry); dico_free_entry(entry); } diff --git a/src/frontend/numparam/xpressn.c b/src/frontend/numparam/xpressn.c index 1f523f66c..fd0749bc3 100644 --- a/src/frontend/numparam/xpressn.c +++ b/src/frontend/numparam/xpressn.c @@ -232,7 +232,6 @@ message(dico_t *dico, const char *fmt, ...) dico->oldline); } } - va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); @@ -275,7 +274,6 @@ dico_free_entry(entry_t *entry) { if (entry->symbol) txfree(entry->symbol); - txfree(entry); } @@ -339,7 +337,7 @@ dicostack_pop(dico_t *dico) fprintf(stderr, "Error: DS could not add string %s\n", inst_name); controlled_exit(-1); } - nupa_add_inst_param(ds_get_buf(¶m_name), entry->vl); + nupa_copy_inst_entry(ds_get_buf(¶m_name), entry); dico_free_entry(entry); } nghash_free(htable_p, NULL, NULL); @@ -440,6 +438,8 @@ del_attrib(void *entry_p) entry_t *entry = (entry_t*) entry_p; if(entry) { tfree(entry->symbol); + if (entry->sbbase) + tfree(entry->sbbase); tfree(entry); } } @@ -1085,6 +1085,79 @@ formula(dico_t *dico, const char *s, const char *s_end, bool *perror) } +/* Check for a string expression, return end pointer or NULL. + * A string expression is a sequence of quoted strings and string + * variables, optionally enclosed by '{}' with no interventing space. + * If successful return pointer to next char, otherwise NULL. + * Evaluated string is returned in *qstr_p (may be NULL). + */ + +static char *string_expr(dico_t *dico, DSTRINGPTR qstr_p, + const char *t, const char *t_end) +{ + const char *tie; + bool ok = FALSE; + + while (isblank(*t) && t < t_end) + ++t; + if (qstr_p) + ds_clear(qstr_p); + for (; t < t_end; ) { + if (*t == '"') { + /* String constant. */ + + tie = ++t; + while (*t != '"' && t < t_end) + ++t; + if (qstr_p) + pscat(qstr_p, tie, t); + if (*t == '"') + ++t; + ok = TRUE; + continue; + } + if (*t == '{') { + /* Isolate and check wrapped identifier. */ + + tie = ++t; + while (t < t_end) { + if (*t == '}') + break; + ++t; + } + } else { + /* Last option: naked string-valued param. */ + + tie = t; + t = fetchid(t, t_end); + if (t == tie ) + return NULL; + } + /* Now pointers tie, t should bracket an identifier. */ + + { + DS_CREATE(lcl_str, 200); + entry_t *entry; + + /* Formula is a single identifier. */ + + pscopy(&lcl_str, tie, t); + entry = entrynb(dico, ds_get_buf(&lcl_str)); + ds_free(&lcl_str); + if (entry && (entry->tp == NUPA_STRING)) { + if (qstr_p) + pscat(qstr_p, entry->sbbase, NULL); + ok = TRUE; + } else { + return NULL; + } + } + if (*t == '}') + ++t; + } + return ok ? (char *)t : NULL; +} + /* stupid, produce a string representation of a given double * to be spliced back into the circuit deck * we want *exactly* 25 chars, we have @@ -1113,7 +1186,8 @@ evaluate_expr(dico_t *dico, DSTRINGPTR qstr_p, const char *t, const char * const double u; ds_clear(qstr_p); - + if (string_expr(dico, qstr_p, t, t_end)) + return 0; u = formula(dico, t, t_end, &err); if (err) return err; @@ -1247,38 +1321,31 @@ getword(const char *s, DSTRINGPTR tstr_p) static char * -getexpress(nupa_type *type, DSTRINGPTR tstr_p, const char *s) +getexpress(dico_t *dico, nupa_type *type, DSTRINGPTR tstr_p, const char *s) /* returns expression-like string until next separator Input i=position before expr, output i=just after expr, on separator. returns tpe=='R' if (numeric, 'S' if (string only */ { - const char * const s_end = s + strlen(s); + const char *s_end = s + strlen(s); const char *p; nupa_type tpe; while ((s < s_end - 1) && ((unsigned char)(* s) <= ' ')) s++; /*white space ? */ - if (*s == '"') { /* string constant */ - - s++; - p = s; - - while ((p < s_end - 1) && (*p != '"')) - p++; - - do - p++; - while ((p < s_end) && ((unsigned char)(*p) <= ' ')); + /* Check for injected semicolon separator in assignment list. */ + p = strchr(s, ';'); + if (p) + s_end = p; + p = string_expr(dico, NULL, s, s_end); + if (p) { tpe = NUPA_STRING; - } else { if (*s == '{') s++; - p = s; for (; p < s_end; p++) { @@ -1304,7 +1371,6 @@ getexpress(nupa_type *type, DSTRINGPTR tstr_p, const char *s) } } } - tpe = NUPA_REAL; } @@ -1313,9 +1379,6 @@ getexpress(nupa_type *type, DSTRINGPTR tstr_p, const char *s) if (*p == '}') p++; - if (tpe == NUPA_STRING) - p++; /* beyond quote */ - if (type) *type = tpe; @@ -1334,7 +1397,8 @@ nupa_assignment(dico_t *dico, const char *s, char mode) /* s has the format: ident = expression; ident= expression ... */ const char * const s_end = s + strlen(s); const char *p = s; - + const char *tmp; + char *sval = NULL; bool error = 0; nupa_type dtype; int wval = 0; @@ -1369,23 +1433,26 @@ nupa_assignment(dico_t *dico, const char *s, char mode) break; } - p = getexpress(&dtype, &ustr, p + 1) + 1; + p = getexpress(dico, &dtype, &ustr, p + 1) + 1; + tmp = ds_get_buf(&ustr); if (dtype == NUPA_REAL) { - const char *tmp = ds_get_buf(&ustr); rval = formula(dico, tmp, tmp + strlen(tmp), &error); if (error) { message(dico, " Formula() error.\n" - " %s\n", s); + " |%s| : |%s|=|%s|\n", s, ds_get_buf(&tstr), ds_get_buf(&ustr)); break; } } else if (dtype == NUPA_STRING) { - wval = (int) (p - s); + DS_CREATE(sstr, 200); + string_expr(dico, &sstr, tmp, tmp + strlen(tmp)); + sval = copy(ds_get_buf(&sstr)); + ds_free(&sstr); } error = nupa_define(dico, ds_get_buf(&tstr), mode /* was ' ' */ , - dtype, rval, wval, NULL); + dtype, rval, wval, sval); if (error) break; @@ -1445,9 +1512,10 @@ nupa_subcktcall(dico_t *dico, const char *s, const char *x, /***** first, analyze the subckt definition line */ n = 0; /* number of parameters if any */ - scopys(&tstr, s); + /* Get the subcircuit name in subname. */ + const char *j2 = strstr(ds_get_buf(&tstr), "subckt"); if (j2) { j2 = skip_ws(j2 + 6); /* skip subckt and whitespace */ @@ -1456,6 +1524,8 @@ nupa_subcktcall(dico_t *dico, const char *s, const char *x, err = message(dico, " ! a subckt line!\n"); } + /* Scan the .subckt line for assignments, copying templates to idlist. */ + const char *i2 = strstr(ds_get_buf(&tstr), "params:"); if (i2) { @@ -1510,7 +1580,7 @@ nupa_subcktcall(dico_t *dico, const char *s, const char *x, char * const t_p = ds_get_buf(&tstr); char *jp = NULL; - /* search for the last occurence of `subname' in the given line */ + /* Search for the last occurence of `subname' in the call line. */ for (;;) { char *next_p = search_isolated_identifier(jp ? jp + 1 : t_p, ds_get_buf(&subname)); @@ -1528,7 +1598,6 @@ nupa_subcktcall(dico_t *dico, const char *s, const char *x, /* jp is pointing to the 1st position of arglist now */ while (*jp) { - /* try to fetch valid arguments */ char *kp = jp; ds_clear(&ustr); @@ -1538,13 +1607,16 @@ nupa_subcktcall(dico_t *dico, const char *s, const char *x, jp = skip_non_ws(kp); pscopy(&ustr, kp, jp); } else if (*kp == '{') { - jp = getexpress(NULL, &ustr, jp); + jp = getexpress(dico, NULL, &ustr, jp); } else { jp++; if ((unsigned char) (*kp) > ' ') message(dico, "Subckt call, symbol %c not understood\n", *kp); } + /* Substitute the parameter for one of the '$' characters + * in idlist. + */ char * const u_p = ds_get_buf(&ustr); if (*u_p) { char * const idlist_p = ds_get_buf(&idlist);