ngspice/examples/xspice/d_process
Brian Taylor 00ad25fbc9 Fix d_process named pipes example. Use the correct gtkwave command for MacOS.
The following is also required:
commit 527b8378e8
Author: Brian Taylor <lbwnet@comcast.net>
Date:   Wed Apr 10 13:24:48 2024 -0700

    Fix circuits so that gtkwave tests run on MacOS. Add encoder/decoder example.
2025-05-24 11:03:52 +02:00
..
README
checks.cir
clean.sh
compile.bat.txt
compile.sh
d_process.h
debugging.h
graycode.c
nggtk.tcl
prog-pipes.cir
prog1-4.cir
prog1in4out.c
prog4in1out.c

README

The d_process XSPICE model was developed by Uros Platise and he has
provided a non-trivial example and detailed descriptions at:
  https://www.isotel.eu/mixedsim/embedded/motorforce/index.html

This directory contains a simple test of the d_process model.

Compile the programs that are called from within d_process:

  ./compile.sh   (on Linux or Cygwin on Windows)

In a Windows Powershell using VisualC, copy compile.bat.txt to compile.bat,
then use it. In a Mingw Msys shell, you can use the VisualC compiled programs,
or use compile.sh. In both these environments the programs need to be compiled
this way to use binary mode pipes.

Run the test case (comment out the gtkwave lines or use plot if you like):

  ngspice prog1-4.cir

A typical instance/.model pair Looks like:

  ap1 [clk2] clk1 null [o1 o2 o3 o4] proc1
  .model proc1 d_process (process_file="prog1in4out"
  + process_params=["opt1", "qwerty"])

To clean up:

  ./clean.sh

NOTE that the prog-pipes.cir test needs fifos created on Linux or Cygwin
on Windows. This is not available on Windows VisualC or Mingw builds.

  mkfifo graycode_in
  mkfifo graycode_out

before ngspice prog-pipes.cir, and in another shell:

  ./graycode --pipe

needs to be started.

The file checks.cir can be run to test the error handling in d_process.

==============================================================================

NOTES ON THE PROGRAM STRUCTURE.

In the d_process .model statement the process_file parameter specifies
the name of the external program which is started by fork/exec or spawn,
and connections are established using pipes. The external program is written
in C, and first of all, in main() the argc, argv parameters can be read.
These command line parameters are those specified in the process_params field
of the d_process .model statement.

Notice that the input pipe defaults to stdin and the output pipe defaults
to stdout. On Windows VisualC and Mingw the _setmode(.., _O_BINARY) function
must be called to ensure binary data transfer on the pipes. The fifo pipes
are not used on those Windows builds. Since stdin and stdout are generally
used, if you need to write any messages, use stderr or write to some other
file.

A header is sent from ngspice to the external program which acknowledges
that the number of inputs and outputs match the instance statement in the
SPICE circuit file. Header d_process.h defines the call to d_process_init()
for the header response.

Thereafter, the external program executes a loop:
    while (read data from the input pipe and if it is OK) {
        compute output data for that input
        write the output data to the output pipe
    }
Data is passed in packets of struct in_s {..} and struct out_s {..}. The
input struct contains the execution time in ngspice, and if it is negative,
it signifies a reset has occurred. The compute(..) function can decide how
to handle the reset.

In the meantime the cm_d_process code in ngspice is writing data to its
output pipe at each clock change to ONE, then reading on its input pipe
the response from the external program.

==============================================================================

NOTE ON DEBUGGING. On Linux or Cygwin on Windows, gdb can be attached to
the running d_process programs, or in --pipe mode with fifos, the graycode
example can be run when invoked from gdb.

From a Windows Powershell, WinDbg can be attached to a running d_process
program.

To enable the debugging hooks in the programs (graycode.c, prog1in4out.c,
prog4in1out.c), edit them to #define ENABLE_DEBUGGING. The debugging
hooks are in the debugging.h include file.

Each program prints (to stderr) its process id when started. This makes
it easier to know the process when attaching a debugger.

All the programs (graycode.c, prog1in4out.c, prog4in1out.c) contain a call
to debug_info() which calls sleep() to give you time to attach a debugger.
Just after the sleep() call, there is a call to known_bp() on which you can
set a breakpoint. The sleep() is enabled by:

  export GO_TO_SLEEP=1   (on Linux, Cygwin)
  $env:go_to_sleep = '1' (on Windows Powershell)

Don't forget to remove the environment variables after use, or the
prog1-4.cir will sleep (for up to 1 minute) each time you rerun it.