Browse Source

example for using shared ngspice.dll with XSPICE

pre-master-46
h_vogt 9 years ago
committed by Holger Vogt
parent
commit
3958783010
  1. 66
      visualc/ng_shared_xspice_v/examples/adder_mos.cir
  2. 81
      visualc/ng_shared_xspice_v/examples/count-latch-dac.cir
  3. 45
      visualc/ng_shared_xspice_v/examples/counter-test.cir
  4. 2
      visualc/ng_shared_xspice_v/ng_shared_start.bat
  5. 22
      visualc/ng_shared_xspice_v/ng_shared_test_v.sln
  6. 109
      visualc/ng_shared_xspice_v/ng_shared_test_v/ng_shared_test_v.vcxproj
  7. 581
      visualc/ng_shared_xspice_v/src/main_xspice.c

66
visualc/ng_shared_xspice_v/examples/adder_mos.cir

@ -0,0 +1,66 @@
ADDER - 4 BIT ALL-NAND-GATE BINARY ADDER
*** SUBCIRCUIT DEFINITIONS
.SUBCKT NAND in1 in2 out VDD
* NODES: INPUT(2), OUTPUT, VCC
M1 out in2 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p
M2 net.1 in2 0 0 n1 W=3u L=0.35u pd=9u ad=9p ps=9u as=9p
M3 out in1 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p
M4 out in1 net.1 0 n1 W=3u L=0.35u pd=9u ad=9p ps=9u as=9p
.ENDS NAND
.SUBCKT ONEBIT 1 2 3 4 5 6
* NODES: INPUT(2), CARRY-IN, OUTPUT, CARRY-OUT, VCC
X1 1 2 7 6 NAND
X2 1 7 8 6 NAND
X3 2 7 9 6 NAND
X4 8 9 10 6 NAND
X5 3 10 11 6 NAND
X6 3 11 12 6 NAND
X7 10 11 13 6 NAND
X8 12 13 4 6 NAND
X9 11 7 5 6 NAND
.ENDS ONEBIT
.SUBCKT TWOBIT 1 2 3 4 5 6 7 8 9
* NODES: INPUT - BIT0(2) / BIT1(2), OUTPUT - BIT0 / BIT1,
* CARRY-IN, CARRY-OUT, VCC
X1 1 2 7 5 10 9 ONEBIT
X2 3 4 10 6 8 9 ONEBIT
.ENDS TWOBIT
.SUBCKT FOURBIT 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
* NODES: INPUT - BIT0(2) / BIT1(2) / BIT2(2) / BIT3(2),
* OUTPUT - BIT0 / BIT1 / BIT2 / BIT3, CARRY-IN, CARRY-OUT, VCC
X1 1 2 3 4 9 10 13 16 15 TWOBIT
X2 5 6 7 8 11 12 16 14 15 TWOBIT
.ENDS FOURBIT
*** POWER
VCC 99 0 DC 3.3V
*** ALL INPUTS
VIN1A 1 0 DC 0 PULSE(0 3 0 5NS 5NS 20NS 50NS)
VIN1B 2 0 DC 0 PULSE(0 3 0 5NS 5NS 30NS 100NS)
VIN2A 3 0 DC 0 PULSE(0 3 0 5NS 5NS 50NS 200NS)
VIN2B 4 0 DC 0 PULSE(0 3 0 5NS 5NS 90NS 400NS)
VIN3A 5 0 DC 0 PULSE(0 3 0 5NS 5NS 170NS 800NS)
VIN3B 6 0 DC 0 PULSE(0 3 0 5NS 5NS 330NS 1600NS)
VIN4A 7 0 DC 0 PULSE(0 3 0 5NS 5NS 650NS 3200NS)
VIN4B 8 0 DC 0 PULSE(0 3 0 5NS 5NS 1290NS 6400NS)
*** DEFINE NOMINAL CIRCUIT
X1 1 2 3 4 5 6 7 8 9 10 11 12 0 13 99 FOURBIT
.option noinit acct
.TRAN 500p 6400NS
* save inputs
.save V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8)
* use BSIM3 model with default parameters
.model n1 nmos level=49 version=3.3.0
.model p1 pmos level=49 version=3.3.0
*.include ./Modelcards/modelcard32.nmos
*.include ./Modelcards/modelcard32.pmos
.END

81
visualc/ng_shared_xspice_v/examples/count-latch-dac.cir

@ -0,0 +1,81 @@
* counter, latch DAC
* 10 bit synchronous digital counter
* inhibit at overflow, no revolving
.subckt count10 din dinb dclk drs dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9 dout10
* j k clk set reset out nout
ajk1 din dinb diclk ds1 drs dout1 dnout1 jkflop
ajk2 dout1 dout1 diclk ds2 drs dout2 dnout2 jkflop
ajk3 djk3 djk3 diclk ds3 drs dout3 dnout3 jkflop
ajk4 djk4 djk4 diclk ds4 drs dout4 dnout4 jkflop
ajk5 djk5 djk5 diclk ds1 drs dout5 dnout5 jkflop
ajk6 djk6 djk6 diclk ds2 drs dout6 dnout6 jkflop
ajk7 djk7 djk7 diclk ds3 drs dout7 dnout8 jkflop
ajk8 djk8 djk8 diclk ds4 drs dout8 dnout8 jkflop
ajk9 djk9 djk9 diclk ds3 drs dout9 dnout9 jkflop
ajk10 djk10 djk10 diclk ds4 drs dout10 dnout10 jkflop
aand1 [dout1 dout2] djk3 and1
aand2 [dout1 dout2 dout3] djk4 and1
aand3 [dout1 dout2 dout3 dout4] djk5 and1
aand4 [dout1 dout2 dout3 dout4 dout5] djk6 and1
aand5 [dout1 dout2 dout3 dout4 dout5 dout6] djk7 and1
aand6 [dout1 dout2 dout3 dout4 dout5 dout6 dout7] djk8 and1
aand7 [dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8] djk9 and1
aand8 [dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9] djk10 and1
* inhibit revolving of counter, just let it saturate
* (footnote p. 57)
aand_all [dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9 dout10] dinhibit nand1
aandclk [dclk dinhibit] diclk and1
.model nand1 d_nand(rise_delay = 1e-9 fall_delay = 1e-9
+ input_load = 0.5e-12)
.model and1 d_and(rise_delay = 1e-9 fall_delay = 1e-9
+ input_load = 0.5e-12)
.model jkflop d_jkff(clk_delay = 1.0e-9 set_delay = 1e-9
+ reset_delay = 1e-9 ic = 0 rise_delay = 1.0e-9
+ fall_delay = 1e-9)
.ends count 10
** 10 bit edge triggered latch
.subckt latch10 din1 din2 din3 din4 din5 din6 din7 din8 din9 din10
+ dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9 dout10 dclk
*data clk set reset out nout
aff1 din1 dclk dzero dzero dout1 dnout1 flop1
aff2 din2 dclk dzero dzero dout2 dnout2 flop1
aff3 din3 dclk dzero dzero dout3 dnout3 flop1
aff4 din4 dclk dzero dzero dout4 dnout4 flop1
aff5 din5 dclk dzero dzero dout5 dnout5 flop1
aff6 din6 dclk dzero dzero dout6 dnout6 flop1
aff7 din7 dclk dzero dzero dout7 dnout7 flop1
aff8 din8 dclk dzero dzero dout8 dnout8 flop1
aff9 din9 dclk dzero dzero dout9 dnout9 flop1
aff10 din10 dclk dzero dzero dout10 dnout10 flop1
.model flop1 d_dff(clk_delay = 1e-9 set_delay = 0
+ reset_delay = 0 ic = 0 rise_delay = 1e-9
+ fall_delay = 1e-9)
.ends latch10
** emulation of 10 bit DAC
.subckt dac10 din1 din2 din3 din4 din5 din6 din7 din8 din9 din10 aout
.param vref=1
abridge1 [din1 din2 din3 din4 din5 din6 din7 din8 din9 din10]
+ [ain1 ain2 ain3 ain4 ain5 ain6 ain7 ain8 ain9 ain10] dac1
BVout aout 0 V = 'vref'*(v(ain10)/2 + v(ain9)/4 + v(ain8)/8 + v(ain7)/16 + v(ain6)/32 +
+ v(ain5)/64 + v(ain4)/128 + v(ain3)/256 + v(ain2)/512 + v(ain1)/1024)
.model dac1 dac_bridge(out_low = 0 out_high = 1 out_undef = 0.5
+ input_load = 5.0e-12 t_rise = 1e-9
+ t_fall = 1e-9)
.ends dac10

45
visualc/ng_shared_xspice_v/examples/counter-test.cir

@ -0,0 +1,45 @@
* 10 bit synchronous digital counter
* inhibit at overflow, no revolving
* according to Schreier, Temes: Understanding Delta-Sigma Data Converters, 2005
* Fig. 2.27, p. 58
.options noinit noacct
* clock generation
* PULSE(V1 V2 TD TR TF PW PER)
vclk aclk 0 dc 0 pulse(0 1 1u 2n 2n 1u 2u)
* reset generation
* single pulse, actual value stored in latch and read by DAC
vres ars 0 dc 0 pulse(0 1 1.1m 2n 2n 1u 2.2m)
vone aone 0 dc 1
vzero azero 0 dc 0
* digital one
* digital zero
abridge1 [aone azero] [done dzero] adc_buff
.model adc_buff adc_bridge(in_low = 0.5 in_high = 0.5)
* digital clock
* digital reset
abridge2 [aclk ars] [dclk dreset] adc_buff
.model adc_buff adc_bridge(in_low = 0.5 in_high = 0.5)
XCounter done done dclk dreset dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9 dout10 count10
Xlatch dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9 dout10
+ dlout1 dlout2 dlout3 dlout4 dlout5 dlout6 dlout7 dlout8 dlout9 dlout10 dreset
+ latch10
Xdac dlout1 dlout2 dlout3 dlout4 dlout5 dlout6 dlout7 dlout8 dlout9 dlout10 adacout dac10
.include count-latch-dac.cir
.tran 1u 2.5m
* no .control section if to be started with bg_run
*.control
*eprint dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9 dout10 > digi4b.txt
*eprint dlout1 dlout2 dlout3 dlout4 dlout5 dlout6 dlout7 dlout8 dlout9 dlout10 >> digi4b.txt
*plot adacout
*.endc
.end

2
visualc/ng_shared_xspice_v/ng_shared_start.bat

@ -0,0 +1,2 @@
start /B .\Debug\ng_shared_test_v.exe
PAUSE

22
visualc/ng_shared_xspice_v/ng_shared_test_v.sln

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25029.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ng_shared_test_v", "ng_shared_test_v\ng_shared_test_v.vcxproj", "{01B94AD4-AF8F-4173-9BF8-120638B8BC6C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{01B94AD4-AF8F-4173-9BF8-120638B8BC6C}.Debug|Win32.ActiveCfg = Debug|Win32
{01B94AD4-AF8F-4173-9BF8-120638B8BC6C}.Debug|Win32.Build.0 = Debug|Win32
{01B94AD4-AF8F-4173-9BF8-120638B8BC6C}.Release|Win32.ActiveCfg = Release|Win32
{01B94AD4-AF8F-4173-9BF8-120638B8BC6C}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

109
visualc/ng_shared_xspice_v/ng_shared_test_v/ng_shared_test_v.vcxproj

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{01B94AD4-AF8F-4173-9BF8-120638B8BC6C}</ProjectGuid>
<RootNamespace>ng_shared_test_v</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>14.0.25029.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;XSPICE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<ExceptionHandling />
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention />
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>Full</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<ExceptionHandling />
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>false</FunctionLevelLinking>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat />
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress />
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\main_xspice.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\src\include\ngspice\sharedspice.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

581
visualc/ng_shared_xspice_v/src/main_xspice.c

@ -0,0 +1,581 @@
/*
Test file for shared ngspice
Copyright Holger Vogt 2013
ngspice library loaded dynamically
Test 1
Load and initialize ngspice
Source an input file adder_mos.cir
Run the simulation for 5 seconds in a background thread
Stop the simulation for 3 seconds
Resume the simulation in the background thread
Write rawfile
Unload ngspice
*/
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#ifndef _MSC_VER
#include <stdbool.h>
#include <pthread.h>
#else
#define bool int
#define true 1
#define false 0
#define strdup _strdup
#endif
#include "../../../src/include/ngspice/sharedspice.h"
#if defined(__MINGW32__) || defined(_MSC_VER)
#undef BOOLEAN
#include <windows.h>
typedef FARPROC funptr_t;
void *dlopen (const char *, int);
funptr_t dlsym (void *, const char *);
int dlclose (void *);
char *dlerror (void);
#define RTLD_LAZY 1 /* lazy function call binding */
#define RTLD_NOW 2 /* immediate function call binding */
#define RTLD_GLOBAL 4 /* symbols in this dlopen'ed obj are visible to other dlopen'ed objs */
static char errstr[128];
#else
#include <dlfcn.h> /* to load libraries*/
#include <unistd.h>
#include <ctype.h>
typedef void * funptr_t;
#endif
bool no_bg = true;
bool not_yet = true;
bool will_unload = false;
bool error_ngspice = false;
int cieq(register char *p, register char *s);
int ciprefix(const char *p, const char *s);
/* callback functions used by ngspice */
int
ng_getchar(char* outputreturn, int ident, void* userdata);
int
ng_getstat(char* outputreturn, int ident, void* userdata);
int
ng_thread_runs(bool noruns, int ident, void* userdata);
/* callback functions used by XSPICE for event data */
int
ng_getevtdata(int index, double step, double dvalue, char *svalue,
void *pvalue, int plen, int mode, int ident, void *userdata);
int
ng_getinitevtdata(int index, int max_index, char * name, char *type, int ident, void *userdata);
ControlledExit ng_exit;
SendData ng_data;
SendInitData ng_initdata;
int vecgetnumber = 0;
double v2dat;
static bool has_break = false;
int testnumber = 0;
void alterp(int sig);
/* functions exported by ngspice */
funptr_t ngSpice_Init_handle = NULL;
funptr_t ngSpice_Command_handle = NULL;
funptr_t ngSpice_Circ_handle = NULL;
funptr_t ngSpice_CurPlot_handle = NULL;
funptr_t ngSpice_AllVecs_handle = NULL;
funptr_t ngSpice_GVI_handle = NULL;
funptr_t ngSpice_AllNodes_handle = NULL;
funptr_t ngSpice_EVT_handle = NULL;
funptr_t ngSpice_Init_Evt_handle = NULL;
void * ngdllhandle = NULL;
#ifndef _MSC_VER
pthread_t mainthread;
#endif // _MSC_VER
int main()
{
char *errmsg = NULL, *loadstring, *curplot, *vecname;
int *ret, i;
char **vecarray;
printf("****************************\n");
printf("** ngspice shared start **\n");
printf("****************************\n");
#ifndef _MSC_VER
mainthread = pthread_self();
#endif // _MSC_VER
printf("Load ngspice.dll\n");
#ifdef __CYGWIN__
loadstring = "/cygdrive/c/cygwin/usr/local/bin/cygngspice-0.dll";
#elif _MSC_VER
// loadstring = "ngspice.dll";
// loadstring = "..\\..\\..\\ngspice\\visualc\\sharedspice\\Debug.Win32\\ngspice.dll";
// loadstring = "..\\..\\..\\ngspice\\visualc\\sharedspice\\ReleaseOMP.Win32\\ngspice.dll";
loadstring = "D:\\Spice_general\\ngspice\\visualc\\sharedspice\\Debug.Win32\\ngspice.dll";
#elif __MINGW32__
loadstring = "D:\\Spice_general\\ngspice\\visualc-shared\\Debug\\bin\\ngspice.dll";
#else
loadstring = "libngspice.so";
#endif
ngdllhandle = dlopen(loadstring, RTLD_NOW);
errmsg = dlerror();
if (errmsg)
printf("%s\n", errmsg);
if (ngdllhandle)
printf("ngspice.dll loaded\n");
else {
printf("ngspice.dll not loaded !\n");
// exit(1);
}
ngSpice_Init_handle = dlsym(ngdllhandle, "ngSpice_Init");
errmsg = dlerror();
if (errmsg)
printf(errmsg);
ngSpice_Command_handle = dlsym(ngdllhandle, "ngSpice_Command");
errmsg = dlerror();
if (errmsg)
printf(errmsg);
ngSpice_CurPlot_handle = dlsym(ngdllhandle, "ngSpice_CurPlot");
errmsg = dlerror();
if (errmsg)
printf(errmsg);
ngSpice_AllVecs_handle = dlsym(ngdllhandle, "ngSpice_AllVecs");
errmsg = dlerror();
if (errmsg)
printf(errmsg);
ngSpice_GVI_handle = dlsym(ngdllhandle, "ngGet_Vec_Info");
errmsg = dlerror();
if (errmsg)
printf(errmsg);
ngSpice_AllNodes_handle = dlsym(ngdllhandle, "ngSpice_AllEvtNodes");
errmsg = dlerror();
if (errmsg)
printf(errmsg);
ngSpice_EVT_handle = dlsym(ngdllhandle, "ngGet_Evt_NodeInfo");
errmsg = dlerror();
if (errmsg)
printf(errmsg);
ngSpice_Init_Evt_handle = dlsym(ngdllhandle, "ngSpice_Init_Evt");
errmsg = dlerror();
if (errmsg)
printf(errmsg);
/* general callback initialization */
ret = ((int * (*)(SendChar*, SendStat*, ControlledExit*, SendData*, SendInitData*,
BGThreadRunning*, void*)) ngSpice_Init_handle)(ng_getchar, ng_getstat,
ng_exit, NULL, ng_initdata, ng_thread_runs, NULL);
/* event data initialization */
ret = ((int * (*)(SendEvtData*, SendInitEvtData*, void*)) ngSpice_Init_Evt_handle)(ng_getevtdata,
ng_getinitevtdata, NULL);
testnumber = 1;
printf("\n** Test no. %d with sourcing input file **\n\n", testnumber);
error_ngspice = false;
will_unload = false;
#if defined(__CYGWIN__)
ret = ((int * (*)(char*)) ngSpice_Command_handle)("source /cygdrive/d/Spice_general/ngspice_sh/examples/shared-ngspice/counter-test.cir");
#elif __MINGW32__
ret = ((int * (*)(char*)) ngSpice_Command_handle)("source D:\\Spice_general\\ngspice_sh\\examples\\shared-ngspice\\counter-test.cir");
#elif _MSC_VER
ret = ((int * (*)(char*)) ngSpice_Command_handle)("source ./examples/counter-test.cir");
#else
ret = ((int * (*)(char*)) ngSpice_Command_handle)("source ../examples/counter-test.cir");
// ret = ((int * (*)(char*)) ngSpice_Command_handle)("source adder_mos.cir");
#endif
ret = ((int * (*)(char*)) ngSpice_Command_handle)("bg_run");
printf("We are back again\n");
/* wait to catch error signal, if available */
#if defined(__MINGW32__) || defined(_MSC_VER)
Sleep(100);
#else
usleep(100000);
#endif
/* Upon error: unload ngspice and skip rest of test code */
if (error_ngspice) {
printf("Error detected, let's unload\n");
ret = ((int * (*)(char*)) ngSpice_Command_handle)("quit");
dlclose(ngdllhandle);
printf("ngspice.dll unloaded\n\n");
ngdllhandle = NULL;
return 0;
}
/* simulate for 500 milli seconds or until simulation has finished */
for (i = 0; i < 5; i++) {
#if defined(__MINGW32__) || defined(_MSC_VER)
Sleep(100);
#else
usleep(100000);
#endif
/* we are faster than anticipated */
if (no_bg)
goto endsim;
}
ret = ((int * (*)(char*)) ngSpice_Command_handle)("bg_halt");
for (i = 3; i > 0; i--) {
printf("Pause for %d seconds\n", i);
#if defined(__MINGW32__) || defined(_MSC_VER)
Sleep(1000);
#else
usleep(1000000);
#endif
}
ret = ((int * (*)(char*)) ngSpice_Command_handle)("bg_resume");
/* wait for 1s while simulation continues */
#if defined(__MINGW32__) || defined(_MSC_VER)
Sleep(1000);
#else
usleep(1000000);
#endif
/* read current plot while simulation continues */
curplot = ((char * (*)()) ngSpice_CurPlot_handle)();
printf("\nCurrent plot is %s\n\n", curplot);
vecarray = ((char ** (*)(char*)) ngSpice_AllVecs_handle)(curplot);
/* get length of first vector */
if (vecarray) {
char plotvec[256];
pvector_info myvec;
int veclength;
vecname = vecarray[0];
sprintf(plotvec, "%s.%s", curplot, vecname);
myvec = ((pvector_info(*)(char*)) ngSpice_GVI_handle)(plotvec);
veclength = myvec->v_length;
printf("\nActual length of vector %s is %d\n\n", plotvec, veclength);
}
/* wait until simulation finishes */
for (;;) {
#if defined(__MINGW32__) || defined(_MSC_VER)
Sleep(100);
#else
usleep(100000);
#endif
if (no_bg)
break;
}
endsim:
/* Print all event nodes to stdout */
vecarray = ((char ** (*)()) ngSpice_AllNodes_handle)();
i = 0;
if (vecarray) {
char* node;
printf("\nWe print all event node names:\n");
for (i = 0; ; i++) {
node = vecarray[i];
if (!vecarray[i])
break;
fprintf(stdout, "%s\n", vecarray[i]);
}
}
printf("We have %d event nodes\n\n", i);
/* just to select some nodes */
int j = (int)(i / 2);
char * nodename;
if (j > 0) {
nodename = vecarray[j];
printf("We analyse event node %s\n", nodename);
pevt_shared_data evtnode;
/* Get data from ngspice.dll */
evtnode = ((pevt_shared_data(*)(char*)) ngSpice_EVT_handle)(nodename);
pevt_data *nodevals = evtnode->evt_dect;
int count = evtnode->num_steps;
for (i = 0; i < count; i++) {
char *nodeval = nodevals[i]->node_value;
double step = nodevals[i]->step;
fprintf(stdout, "%e %s\n", step, nodeval);
}
/* Delete data */
((pevt_shared_data(*)(char*)) ngSpice_EVT_handle)(NULL);
/* just watch another node */
nodename = vecarray[j - 1];
printf("We analyse event node %s\n", nodename);
evtnode = ((pevt_shared_data(*)(char*)) ngSpice_EVT_handle)(nodename);
nodevals = evtnode->evt_dect;
count = evtnode->num_steps;
for (i = 0; i < count; i++) {
char *nodeval = nodevals[i]->node_value;
double step = nodevals[i]->step;
fprintf(stdout, "%e %s\n", step, nodeval);
}
/* Delete data */
((pevt_shared_data(*)(char*)) ngSpice_EVT_handle)(NULL);
}
else
printf("Not enough nodes for selection\n");
ret = ((int * (*)(char*)) ngSpice_Command_handle)("quit");
#if 0
/* unload now */
dlclose(ngdllhandle);
ngdllhandle = NULL;
printf("Unloaded\n\n");
#endif
if (will_unload) {
printf("Unload now\n");
dlclose(ngdllhandle);
ngdllhandle = NULL;
printf("Unloaded\n\n");
}
return 0;
}
/* Callback function called from bg thread in ngspice to transfer
any string created by printf or puts. Output to stdout in ngspice is
preceded by token stdout, same with stderr.*/
int
ng_getchar(char* outputreturn, int ident, void* userdata)
{
printf("%s\n", outputreturn);
/* setting a flag if an error message occurred */
if (ciprefix("stderr Error:", outputreturn))
error_ngspice = true;
return 0;
}
/* Callback function called from bg thread in ngspice to transfer
simulation status (type and progress in percent. */
int
ng_getstat(char* outputreturn, int ident, void* userdata)
{
printf("%s\n", outputreturn);
return 0;
}
/* Callback function called from ngspice upon starting (returns true) or
leaving (returns false) the bg thread. */
int
ng_thread_runs(bool noruns, int ident, void* userdata)
{
no_bg = noruns;
if (noruns)
printf("bg not running\n");
else
printf("bg running\n");
return 0;
}
/* Callback function called from bg thread in ngspice if fcn controlled_exit()
is hit. Do not exit, but unload ngspice. */
int
ng_exit(int exitstatus, bool immediate, bool quitexit, int ident, void* userdata)
{
if(quitexit) {
printf("DNote: Returned from quit with exit status %d\n", exitstatus);
}
if(immediate) {
printf("DNote: Unload ngspice\n");
((int * (*)(char*)) ngSpice_Command_handle)("quit");
dlclose(ngdllhandle);
}
else {
printf("DNote: Prepare unloading ngspice\n");
will_unload = true;
}
return exitstatus;
}
/* Callback function called from bg thread in ngspice once per accepted data point */
int
ng_data(pvecvaluesall vdata, int numvecs, int ident, void* userdata)
{
int *ret;
v2dat = vdata->vecsa[vecgetnumber]->creal;
if (!has_break && (v2dat > 0.5)) {
/* using signal SIGTERM by sending to main thread, alterp() then is run from the main thread,
(not on Windows though!) */
#ifndef _MSC_VER
if (testnumber == 4)
pthread_kill(mainthread, SIGTERM);
#endif
has_break = true;
/* leave bg thread for a while to allow halting it from main */
#if defined(__MINGW32__) || defined(_MSC_VER)
Sleep (100);
#else
usleep (100000);
#endif
// ret = ((int * (*)(char*)) ngSpice_Command_handle)("bg_halt");
}
return 0;
}
/* Callback function called from bg thread in ngspice once upon intialization
of the analog simulation vectors)*/
int
ng_initdata(pvecinfoall intdata, int ident, void* userdata)
{
int i;
/* suppress second printing (after bg_resume) */
static bool printonce = TRUE;
int vn = intdata->veccount;
if (printonce) {
for (i = 0; i < vn; i++) {
printf("Vector: %s\n", intdata->vecs[i]->vecname);
/* find the location of a vector */
char *myvec = "adacout";
if (cieq(intdata->vecs[i]->vecname, myvec)) {
vecgetnumber = i;
printf("Vector %s has index %d\n", myvec, i);
}
}
printonce = FALSE;
}
return 0;
}
int mindex = -1;
char* mynode = "dout8";
/* callback functions used by XSPICE for event data. */
/* Function is executed each time EVTdump() in ngspice is called and output
data for the node indexed by index have changed. */
int
ng_getevtdata(int index, double step, double dvalue, char *svalue,
void *pvalue, int plen, int mode, int ident, void *userdata)
{
static bool once = TRUE;
if (mindex == -1) {
if (once) {
fprintf(stderr, "Error: Cannot watch node %s, not found\n", mynode);
once = FALSE;
}
return 1;
}
/* Select an action only for a specific node.
The value of mindex for node mynode has been determined in function
ng_getinitevtdata() given below. */
if (index == mindex)
fprintf(stdout, "Node %s, Index %d, Step %e, Value %s\n", mynode, index, step, svalue);
return 0;
}
char *evt_nodes[2][1000];
/* Immediately after initialization, get the list of event nodes as a string array:
evt_nodes[0][x]: node name
evt_nodes[1][x]: node type
index x: node number, may be used to access node value by using
function ng_getevtdata(index, ...) */
int
ng_getinitevtdata(int index, int max_index, char * name, char *type, int ident, void *userdata)
{
evt_nodes[0][index] = strdup(name);
evt_nodes[1][index] = strdup(type);
/* for a given node name, find the corresponding index */
if (cieq(name, mynode))
mindex = index;
return 0;
}
/* Funcion called from main thread upon receiving signal SIGTERM */
void
alterp(int sig) {
((int * (*)(char*)) ngSpice_Command_handle)("bg_halt");
}
/* Unify LINUX and Windows dynamic library handling:
Add functions dlopen, dlsym, dlerror, dlclose to Windows by
tranlating to Windows API functions.
*/
#if defined(__MINGW32__) || defined(_MSC_VER)
void *dlopen(const char *name,int type)
{
return LoadLibrary((LPCSTR)name);
}
funptr_t dlsym(void *hDll, const char *funcname)
{
return GetProcAddress(hDll, funcname);
}
char *dlerror(void)
{
LPVOID lpMsgBuf;
char * testerr;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL
);
testerr = (char*)lpMsgBuf;
strcpy(errstr,lpMsgBuf);
LocalFree(lpMsgBuf);
if (ciprefix("Der Vorgang wurde erfolgreich beendet.", errstr))
return NULL;
else
return errstr;
}
int dlclose (void *lhandle)
{
return (int)FreeLibrary(lhandle);
}
#endif
/* Case insensitive str eq.
Like strcasecmp( ) XXX */
int
cieq(register char *p, register char *s)
{
while (*p) {
if ((isupper(*p) ? tolower(*p) : *p) !=
(isupper(*s) ? tolower(*s) : *s))
return(false);
p++;
s++;
}
return (*s ? false : true);
}
/* Case insensitive prefix. */
int
ciprefix(const char *p, const char *s)
{
while (*p) {
if ((isupper(*p) ? tolower(*p) : *p) !=
(isupper(*s) ? tolower(*s) : *s))
return(false);
p++;
s++;
}
return (true);
}
Loading…
Cancel
Save