Skip to content

Commit

Permalink
prototype for Verilog-A integration using OSDI and OpenVAF
Browse files Browse the repository at this point in the history
This initial prototype is capable of performing DC, transient and AC
analysis. Not all features of OSDI are supported yet and there are still
some open questions regarding ngspice integration. However many usecase
already work very well and a large amount of CMC models are supported.
The biggest missing feature right now is noise analysis.

test: test case for diode DC working with SH

test: add transient analysis to osdi_diode test

test: added docu text to osdi_diode test

test: added test case directories

fix: bug in osdi_load

test: small change to netlist

fix: implement DEVunsetup

fix: correct behaviour for MODEINITSMSIG

test: osdi diode enable all analysis modes

removed netlist

ignoring test results

added the build of the diode shared object to the python test script

deleting old stuff and always rebuilding the shared object

added diode_va.c to the repo

preparing CI

Create .gitlab-ci.yml file

(testing) add res, cap and multiple devices test

feat: use osdi command to load files

Previously OSDI shared object files were loaded from fixed directories.
This was unreliable, inconvenient and caused conflicts with XSPICE.

This commit remove the old loading mechanism and instead introduces the
`osdi` command that can load (a list of) osdi object files (like the
codemodel command for XSPICE). A typical usecase will use this as a
precommand in the netlist:

.control
pre_osdi foo.osdi
.endc

If the specified file is a relative path it is first resolved relative
to the parent directory of the netlist. If the osdi command is invoked
from the interactive prompt the file is resolved relative to the current
working directory instead.

This commit also moves osdi from the devices folder to the root src
folder like xspice. This better reflects the role of the code as users
may otherthwise (mistakenly) assume that osdi is just another
handwritten model.

test: update tests to new command

fix: do not ignore first parameter

feat: implement log message callback

fix: don't generate ddt matrix/rhs in DC sweep

fix: missing linker script

update to osdi 0.3

(testing) simplify test cases, fix bug

(testing) multiple devices test improvement

(testig) node collapsing bugfix

test: increase tolerance in tests

feat: update to newest OSDI header

fix: temperature update dt behaviour

fix: ignored models

fix: compilation script

fix: allow hicum/l2 to compile with older c++ compilers

fix: set required compiler flags for osdi

fix: disable x by default

fix: add missing SPICE functions

fix: update diode to latest ngspice version

feat: implement python CMC test runner

doc: Add README_OSDI.md

fix: make testing script work with python version before 3.9

fix: free of undefined local variable

fix: do not calculate time derivative during tran op

update osdi version

fixes for compilation on windows
  • Loading branch information
pascalkuthe authored and holvo committed Dec 27, 2022
1 parent d7bdfe1 commit acfaf02
Show file tree
Hide file tree
Showing 65 changed files with 7,635 additions and 34 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,7 @@ src/spicelib/parser/inpptree-parser.c
src/spicelib/parser/inpptree-parser.h
# Visual Studio Code user options files
.vscode/

test_cases/diode/__pycache__/*
test_cases/diode/test_osdi/*
test_cases/diode/test_built_in/*
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ Dietmar Warning,
Michael Widlok,
Charles D.H. Williams,
Antony Wilson,
Pascal Kuthe,
and many others...

If someone helped in the development and has not been inserted in this list
Expand Down
380 changes: 380 additions & 0 deletions COPYING

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM python:3.10.4-bullseye

# python installation
RUN apt-get update && apt-get -y install bc bison flex libxaw7 libxaw7-dev libx11-6 libx11-dev libreadline8 libxmu6
RUN apt-get update && apt-get -y install build-essential libtool gperf libxml2 libxml2-dev libxml-libxml-perl libgd-perl
RUN apt-get update && apt-get -y install g++ gfortran make cmake libfl-dev libfftw3-dev

RUN pip install pytest numpy pandas
33 changes: 33 additions & 0 deletions README_OSDI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# OSDI implementation for NGSPICE

OSDI (Open Source Device Interface) is a simulator independent device interface, that is used by the OpenVAF compiler.
Implementing this interface in NGSPICE allows loading Verilog-A models compiled by OpenVAF.
The interface is fixed and does not require the compiler to know about NGSPICE during compilation.
NGSPICE also doesn't need to know anything about the compiled models at compilation.
Therefore, these models can be loaded dynamically at runtime.

To that end the `osdi` command is provided.
It allows loading a dynamic library conforming to OSDI.
Example usage: `osdi diode.osdi`.

If used within a netlist the command requires the `pre_` prefix.
This ensures that the devices are loaded before the netlist is parsed.

Example usage: `pre_osdi diode.osdi`

If a relative path is provided to the `osdi` command in a netlist, it will resolve that path **relative to the netlist**, not relative to current working directory.
This ensures that netlists can be simulated from any directory

## Build Instructions

To compile NGSPICE with OSDI support ensure that the `--enable-predictor` and `--enable-osdi` flags are used.
The `compile_linus.sh` file enables these flags by default.


## Example/Test Case

A simple handwritten diode can be found in `test_cases/diode/diode.c`.
In the same directory a script named `test_diode.py` is provided that will compile this model and run some example simulations.
After the script has finished the compilation result `diode.osdi` and the netlist can then be found in `test_cases/diode/test_osdi`.


4 changes: 2 additions & 2 deletions compile_linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ if test "$1" = "d"; then
echo "configuring for 64 bit debug"
echo
# You may add --enable-adms to the following command for adding adms generated devices
../configure --with-x --enable-xspice --enable-cider --with-readline=yes --enable-openmp CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-m64 -g"
../configure --with-x --enable-xspice --enable-cider --enable-predictor --enable-osdi --with-readline=yes --enable-openmp CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-m64 -g"
else
cd release
if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi
echo "configuring for 64 bit release"
echo
# You may add --enable-adms to the following command for adding adms generated devices
../configure --with-x --enable-xspice --enable-cider --with-readline=yes --enable-openmp --disable-debug CFLAGS="-m64 -O2" LDFLAGS="-m64 -s"
../configure --with-x --enable-xspice --enable-cider --enable-predictor --enable-osdi --with-readline=yes --enable-openmp --disable-debug CFLAGS="-m64 -O2" LDFLAGS="-m64 -s"
fi
if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi

Expand Down
46 changes: 46 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ AC_ARG_ENABLE([oldapps],
AC_ARG_ENABLE([xspice],
[AS_HELP_STRING([--enable-xspice], [Enable XSPICE enhancements])])

# --enable-osdi: define OSDI in the code. This is for osdi support
AC_ARG_ENABLE([osdi],
[AS_HELP_STRING([--enable-osdi], [Enable OSDI integration])])

# --enable-cider: define CIDER in the code. This is for CIDER support
AC_ARG_ENABLE([cider],
[AS_HELP_STRING([--enable-cider], [Enable CIDER enhancements])])
Expand Down Expand Up @@ -1156,7 +1160,18 @@ if test "x$enable_xspice" = xyes; then
AC_SUBST([VIS_CFLAGS])
else
XSPICEINIT="*"
if test "x$enable_osdi" = xyes; then\
case $host_os in
*mingw* | *msys* | *cygwin* | *solaris* )
XSPICEDLLIBS=""
;;
* )
XSPICEDLLIBS="-ldl"
;;
esac
fi
fi

AC_SUBST([XSPICEINIT])
AC_SUBST([XSPICEDLLIBS])

Expand All @@ -1165,6 +1180,36 @@ AM_CONDITIONAL([XSPICE_WANTED], [test "x$enable_xspice" = xyes])
AM_CONDITIONAL([SHORT_CHECK_WANTED], [test "x$enable_shortcheck" = xyes])


if test "x$enable_osdi" = xyes; then
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
AS_VAR_IF(CACHEVAR,yes,
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_COMPILE_FLAGS

AX_CHECK_COMPILE_FLAG([-std=c11], [
CFLAGS="$CFLAGS -std=c11"
LDLAGS="$LDLAGS -std=c11"
], [
echo "C compiler cannot compile C11 code"
exit -1
])
AC_MSG_RESULT([OSDI features included])
AC_DEFINE([OSDI], [1], [The OSDI enhancements])
fi

AM_CONDITIONAL([OSDI_WANTED], [test "x$enable_osdi" = xyes])

# Add CIDER enhancements to ngspice.
if test "x$enable_cider" = xyes; then
AC_MSG_RESULT([CIDER features enabled])
Expand Down Expand Up @@ -1444,6 +1489,7 @@ AC_CONFIG_FILES([Makefile
src/xspice/enh/Makefile
src/xspice/ipc/Makefile
src/xspice/idn/Makefile
src/osdi/Makefile
tests/Makefile
tests/bsim1/Makefile
tests/bsim2/Makefile
Expand Down
32 changes: 26 additions & 6 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ if XSPICE_WANTED
SUBDIRS += xspice
endif

if OSDI_WANTED
SUBDIRS += osdi
endif

if CIDER_WANTED
SUBDIRS += ciderlib
endif
Expand Down Expand Up @@ -97,6 +101,8 @@ DYNAMIC_DEVICELIBS = \
@VLADEV@




## Build ngspice first:

## compile the icon:
Expand All @@ -116,6 +122,8 @@ ngspice_CPPFLAGS = $(AM_CPPFLAGS) -DSIMULATOR
if WINGUI
ngspice_LDFLAGS = -municode $(AM_LDFLAGS)
ngspice_SOURCES += winmain.c hist_info.c
else
ngspice_LDFLAGS =
endif

ngspice_LDADD = \
Expand Down Expand Up @@ -157,9 +165,9 @@ ngspice_LDADD += \
xspice/evt/libevtxsp.la \
xspice/enh/libenhxsp.la \
xspice/ipc/libipcxsp.la \
xspice/idn/libidnxsp.la \
@XSPICEDLLIBS@
xspice/idn/libidnxsp.la
endif
ngspice_LDADD += @XSPICEDLLIBS@

ngspice_LDADD += \
frontend/parser/libparser.la \
Expand All @@ -175,6 +183,10 @@ ngspice_LDADD += \
ciderlib/support/libcidersuprt.la
endif

if OSDI_WANTED
ngspice_LDADD += osdi/libosdi.la
endif

ngspice_LDADD += \
maths/deriv/libderiv.la \
maths/cmaths/libcmaths.la \
Expand Down Expand Up @@ -439,9 +451,9 @@ libspice_la_LIBADD += \
xspice/evt/libevtxsp.la \
xspice/enh/libenhxsp.la \
xspice/ipc/libipcxsp.la \
xspice/idn/libidnxsp.la \
@XSPICEDLLIBS@
xspice/idn/libidnxsp.la
endif
libspice_la_LIBADD += @XSPICEDLLIBS@

libspice_la_LIBADD += \
frontend/parser/libparser.la \
Expand All @@ -457,6 +469,11 @@ libspice_la_LIBADD += \
ciderlib/support/libcidersuprt.la
endif


if OSDI_WANTED
libspice_la_LIBADD += osdi/libosdi.la
endif

libspice_la_LIBADD += \
maths/deriv/libderiv.la \
maths/cmaths/libcmaths.la \
Expand Down Expand Up @@ -558,9 +575,9 @@ libngspice_la_LIBADD += \
xspice/evt/libevtxsp.la \
xspice/enh/libenhxsp.la \
xspice/ipc/libipcxsp.la \
xspice/idn/libidnxsp.la \
@XSPICEDLLIBS@
xspice/idn/libidnxsp.la
endif
libngspice_la_LIBADD += @XSPICEDLLIBS@

libngspice_la_LIBADD += \
frontend/parser/libparser.la \
Expand All @@ -576,6 +593,9 @@ libngspice_la_LIBADD += \
ciderlib/support/libcidersuprt.la
endif


libngspice_la_LIBADD += osdi/libosdi.la

libngspice_la_LIBADD += \
maths/deriv/libderiv.la \
maths/cmaths/libcmaths.la \
Expand Down
15 changes: 15 additions & 0 deletions src/frontend/com_dl.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ void com_codemodel(wordlist *wl)
}
#endif

#ifdef OSDI
void com_osdi(wordlist *wl)
{
wordlist *ww;
for (ww = wl; ww; ww = ww->wl_next)
if (load_osdi(ww->wl_word)) {
fprintf(cp_err, "Error: Library %s couldn't be loaded!\n", ww->wl_word);
if (ft_stricterror)
controlled_exit(EXIT_BAD);
}
}
#endif




#ifdef DEVLIB
void com_use(wordlist *wl)
Expand Down
4 changes: 4 additions & 0 deletions src/frontend/com_dl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
void com_codemodel(wordlist *wl);
#endif

#ifdef OSDI
void com_osdi(wordlist *wl);
#endif

#ifdef DEVLIB
void com_use(wordlist *wl);
#endif
Expand Down
6 changes: 6 additions & 0 deletions src/frontend/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ struct comm spcp_coms[] = {
NULL,
"library library ... : Loads the code model libraries." } ,
#endif
#ifdef OSDI
{ "osdi", com_osdi, FALSE, TRUE,
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
NULL,
"library library ... : Loads a osdi library." } ,
#endif
#ifdef DEVLIB
{ "use", com_use, FALSE, TRUE,
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
Expand Down
30 changes: 26 additions & 4 deletions src/frontend/inp.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Author: 1985 Wayne A. Christopher
#include "ngspice/fteinp.h"
#include "inp.h"

#include "ngspice/osdiitf.h"
#include "runcoms.h"
#include "inpcom.h"
#include "circuits.h"
Expand Down Expand Up @@ -565,7 +566,6 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
if (fp) {
cp_vset("inputdir", CP_STRING, dir_name);
}
tfree(dir_name);

/* if nothing came back from inp_readall, e.g. after calling ngspice without parameters,
just close fp and return to caller */
Expand Down Expand Up @@ -740,8 +740,16 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
before the circuit structure is set up */
if (pre_controls) {
pre_controls = wl_reverse(pre_controls);
for (wl = pre_controls; wl; wl = wl->wl_next)
for (wl = pre_controls; wl; wl = wl->wl_next){
#ifdef OSDI
inputdir = dir_name;
#endif
cp_evloop(wl->wl_word);
}

#ifdef OSDI
inputdir = NULL;
#endif
wl_free(pre_controls);
}

Expand Down Expand Up @@ -1108,18 +1116,29 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
of commands. Thus this is delegated to a function using a third thread, that
only starts when the background thread has finished (sharedspice.c).*/
#ifdef SHARED_MODULE
for (wl = controls; wl; wl = wl->wl_next)
for (wl = controls; wl; wl = wl->wl_next){
#ifdef OSDI
inputdir = dir_name;
#endif
if (cp_getvar("controlswait", CP_BOOL, NULL, 0)) {
exec_controls(wl_copy(wl));
break;
}
else
cp_evloop(wl->wl_word);
}
#else
for (wl = controls; wl; wl = wl->wl_next)
for (wl = controls; wl; wl = wl->wl_next){
#ifdef OSDI
inputdir = dir_name;
#endif
cp_evloop(wl->wl_word);
}
#endif
wl_free(controls);
#ifdef OSDI
inputdir = NULL;
#endif
}

/* Now reset everything. Pop the control stack, and fix up the IO
Expand All @@ -1131,6 +1150,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile)
cp_curerr = lasterr;

tfree(tt);
tfree(dir_name);



return 0;
}
Expand Down
Loading

0 comments on commit acfaf02

Please sign in to comment.