Easier mixed mode simulation (and real world comparison!)

This is a follow on from Mixed mode simulation including C code and verilog - #21 by 2norderEDO

I’ve improved my mixed mode model and made it a little (not much) more user friendly. The intention is that you can run exactly the same control algorithm code on your microcontroller and your simulation.

mixed_mode_sim.zip (697.8 KB)

All code tested on Ubuntu 24.04, I don’t have a suitable Windows or Apple machine so I’d happily take suitable modifications from someone who does.

There’s a few more files in the pack. Ideally, if you want to simulate something with one 16 bit PWM channel and three 10 bit ADCs then you should only have to modify models.bus to set the PWM clock (currently 16MHz), the controller trigger clock (25kHz) and otherwise it’s just modify microcontroller.h, microcontroller.c and replace buck_controller.h and buck_controller.c with your own algorithm. If you want to add any more ADCs or PWM channels then you have to modify in_data_message, out_data_message, DIGITAL_IN and DIGITAL_OUT in microcontroller.h and add the adcs or PWMs in microcontroller.bus. The structs both use bit fields to make them the right size.

microcontroller.h and microcontroller.h are there to replace your microcontroller environment. Use this to set up any variables that need to be there for your controller. It also reads the file “parameters.p” which you can use to store things like set points and gains that you might want to change without recompiling the code. Ideally, you can take the control loop code that would be in your microcontroller and just “#include “controller.h”” without modifying anything. The control loop example is the one that’s running on an example DCDC I have running.

Buck converter:

Simulation of no load start up:

Measured no load start up:

XSPICE doesn’t appear to have buses. These would be useful to make the models easier to read and write so I’ve got a script that takes a “.bus” file and produces a “.lib” file by replacing any string with the format “_BUS_xxxn” where x is text and n is a number with "bus_xxx0 bus_xxx1… bus_xxx[n-1]. This is currently hard coded to work on microcontroller.bus and models.bus. Run “generate_buses.py”

As a reminder, you need kicad 8+ and gcc and yosys if you want to recompile the examples. Run “compile_all.sh” if you’re on a linux machine.

Before you run the example provided, you still need to change the text on the schematic to set the directory that it’s run from. Kicad 8.07 still doesn’t appear to set the directory correctly.

Any questions, please ask. Also, another big thanks to @uros and @holger for their work on ngspice.

3 Likes

I have run the design successfully on Windows 11 using KiCad 8.0.6.
Two C files (microcontroller.h, microcontroller_ngut.c) needed additional #ifdef statements to deal with packed structs and using binary mode for the pipes to the controller.exe process.
Using a Developer Command Prompt terminal, the C files are compiled using compile.bat.
mixed_mode_sim.7z (1.4 KB)

Thank you @Briant. Glad it works for someone else and thank you for getting it running on Windows.

Hi @Briant, could you help with another issue I’ve come up against with the d_process?

I’m trying to run the model using named pipes so that I can run the code model in a debugger like in the original example by @uros ( The Easiest Way of Simulating C/C++ Code Together with an Analog & Digital Spice Simulation — ISOTEL ). I had to make a couple of modifications as I hadn’t understood properly on the previous ones how the pipe naming works so I’ve attached a new model (with your previous modifications in it as well).

I’ve made the pipes “controller_in” and “controller_out” in the model directory where the executable “controller” is and added a ‘|’ to the d_process command.

I keep getting the following error in the Kicad simulator:

Instance: a.xu2.acontrol Message: ERROR: d_process failed to open in fifo
Error: ngspice.dll cannot recover and awaits to be detached

My assumption is that ngspice is looking in the wrong place for the pipes but it’s equally possible that I’ve missed something important.
mixed_mode_sim_named_pipes.zip (1.1 MB)

Hello @slh, I am investigating what is happening with your test case. This may be an ngspice bug where the process_file parameter is handled incorrectly in your firmware .model d_process statement. I will keep you posted about what I find. It’s strange because the pipes example in ngspice/examples/d_process works just fine.

Here is a workaround you can try.
slh.txt (1.2 KB)

Hi @Briant,

Thank you for looking into this, The workaround didn’t work at first but when I named the pipes directly (instead of a symbolic link) ‘controller|_in’ and ‘controller|_out’ it worked perfectly.

For anyone else who wants to give it a go, I also had to rename them in “microcontroller_ngut.c”.

When I used the symbolic links I would get the following error: “ERROR: d_process returned invalid version: XXX”, where XXX would be an apparently random number.

Cheers,
Stephen

The fix to correctly handle named pipes will be in ngspice-44 which should be available early in 2025. When KiCad switches to the ngspice-44 release, you won’t need to apply your workaround. Regards, Briant