Hi,
I am new to Qspice, and i am trying to implement a simple statemachine in C++ (which i want to implement later on a uC). I tried some simple things in C++, and it works well until i want to store states. I found some great examples on the net that i used as a starting point, but unfortunately i couldn’t get my implementation to work.
Thanks for helping me out
This is the statemachine i try to implement:
This is the code i got so far. The code passes the compiler phase, but nothing is moving on the outputs. Does anyone see what i am doing wrong?
// Automatically generated C++ file on Sun Dec 8 12:42:46 2024
//
// To build with Digital Mars C++ Compiler:
//
// dmc -mn -WD rectifier.cpp kernel32.lib
#include <cstdio>
#include <cstdlib>
#include <cmath>
union uData
{
bool b;
char c;
unsigned char uc;
short s;
unsigned short us;
int i;
unsigned int ui;
float f;
double d;
long long int i64;
unsigned long long int ui64;
char *str;
unsigned char *bytes;
};
// int DllMain() must exist and return 1 for a process to load the .DLL
int __stdcall DllMain(void *module, unsigned int reason, void *reserved) { return 1; }
// #undef pin names lest they collide with names in any header file(s) you might include.
#undef AC1
#undef AC2
#undef OUT1
#undef OUT2
#undef EN1
#undef EN2
#undef clk
#undef state_diag
// Structure to store instance-specific data
struct InstData {
int rectifier_state; // Represents the rectifier state
bool clk_n1; // Previous clock state
InstData() : rectifier_state(0.0), clk_n1(0.0) {}
};
extern "C" __declspec(dllexport) void rectifier(InstData **opaque, double t, union uData *data)
{
double AC1 = data[0].d; // input
double AC2 = data[1].d; // input
double &OUT1 = data[2].d; // output
double &OUT2 = data[3].d; // output
double &EN1 = data[4].d; // output
double &EN2 = data[5].d; // output
bool clk = data[6].b; // input
double &state_diag = data[7].d; // state diagnostics
// Allocate and initialize instance data if not already done
if (!*opaque) {
*opaque = new InstData;
if (!*opaque) {
printf("rectifier_controller error. Unable to allocate memory. Terminating simulation.\n");
std::exit(1);
}
}
InstData *inst = *opaque;
double V_trafo = AC2 - AC1;
if (clk && !inst->clk_n1) // Rising edge
{
switch (inst->rectifier_state) {
case 0:
EN1 = 0;
EN2 = 0;
OUT1 = 0;
OUT2 = 0;
if (V_trafo > 2.0)
{inst->rectifier_state = 1;}
else if (V_trafo < -2.0)
{inst->rectifier_state = 3;}
state_diag = inst->rectifier_state;
break;
case 1:
EN1 = 0;
EN2 = 1;
OUT1 = 0;
OUT2 = 1;
if (V_trafo > 2.0)
{inst->rectifier_state = 2;}
else if (V_trafo < 1.0)
{inst->rectifier_state = 0;}
state_diag = inst->rectifier_state;
break;
case 2:
EN1 = 1;
EN2 = 1;
OUT1 = 0;
OUT2 = 1;
if (V_trafo < 1.0)
{inst->rectifier_state = 1;}
state_diag = inst->rectifier_state;
break;
case 3:
EN1 = 0;
EN2 = 1;
OUT1 = 0;
OUT2 = 1;
if (V_trafo < -2.0)
{inst->rectifier_state = 4;}
else if (V_trafo > -1.0)
{inst->rectifier_state = 0;}
state_diag = inst->rectifier_state;
break;
case 4:
EN1 = 1;
EN2 = 1;
OUT1 = 0;
OUT2 = 1;
if (V_trafo > -1.0)
{inst->rectifier_state = 3;}
state_diag = inst->rectifier_state;
break;
default:
inst->rectifier_state = 0;
EN1 = 0;
EN2 = 0;
OUT1 = 0;
OUT2 = 0;
state_diag = inst->rectifier_state;
}
}
// Save clock state and rectifier state for the next step
inst->clk_n1 = clk;
}
extern "C" __declspec(dllexport) void Trunc(
InstData *inst, double t, union uData *data, double *timestep)
{
double clk = data[6].d; // input clock
const double ttol = 1e-9;
// If not rising clock edge, we're done
if (clk == inst->clk_n1 || !clk) { return; }
*timestep = ttol;
}
extern "C" __declspec(dllexport) void Destroy(InstData *inst)
{
// Free instance memory
delete inst;
}