Generated reference › API — ICoreSDK/ICoreCodegen
kind: generated#api#icoresdk-icorecodegen

API — ICoreSDK/ICoreCodegen

The public contract of 12 header(s) under src/ICoreSDK/ICoreCodegen — 6 class/struct definition(s), 79 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.

ICoreCodeExportTarget.h#

src/ICoreSDK/ICoreCodegen/ICoreCodeExportTarget.h

Opt-in reproducible verification stimulus. Unset (the default), each verification run draws a fresh random pulse train; set, the same seed reproduces the same stimulus, so a failing combination can be re-run and debugged on the numbers that failed.

ICoreCodeExportTarget#

ICoreCodeExportTarget.h:8 · class · pImpl · 28 declaration(s)

class ICoreCodeExportTarget {
public:
    explicit ICoreCodeExportTarget();

    void setTargetName(const std::string &newTargetName);
    void setCodeType(const std::string& newCodeType);
    void setSourceSubsystemPath(const std::string& newSourceSubsystemPath);
    void setTargetPath(const std::string& newExportTargetPath);
    void setVerificationLevel(const std::string& newVerificationLevel);
    void setResidualRelativeTolerancePercent(double newResidualRelativeTolerancePercent);
    void setTestingPulsesWidth(double newTestingPulsesWidth);
    void setTestingAmplitudeMin(double newTestingAmplitudeMin);
    void setTestingAmplitudeMax(double newTestingAmplitudeMax);
    void setCompilerScanEnabled(bool enabled);
    void setCustomCompilerPath(const std::string& path);
    // Opt-in reproducible verification stimulus. Unset (the default), each
    // verification run draws a fresh random pulse train; set, the same seed
    // reproduces the same stimulus, so a failing combination can be re-run
    // and debugged on the numbers that failed.
    void setTestingSeed(unsigned int seed);
    void clearTestingSeed();

    std::string getTargetName() const;
    std::string getCodeExportType() const;
    std::string getSourceSubsystemPath() const;
    std::filesystem::path getTargetExportPath() const;
    std::string getVerificationLevel() const;
    double getResidualRelativeTolerancePercent() const;
    double getTestingPulsesWidth() const;
    double getTestingAmplitudeMin() const;
    double getTestingAmplitudeMax() const;
    bool getCompilerScanEnabled() const;
    std::string getCustomCompilerPath() const;
    bool hasTestingSeed() const;
    unsigned int getTestingSeed() const;

    ~ICoreCodeExportTarget();

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};

ICoreCodegen.h#

src/ICoreSDK/ICoreCodegen/ICoreCodegen.h

ICoreCodeEngine -- the code-export coordinator.

THIS CLASS IS Qt-FREE, AND THAT IS A PROPERTY TO PRESERVE, NOT A COINCIDENCE. It names no Qt type, includes no Qt header and includes no ICoreStudio header (DEVELOPER_GUIDELINES.md Rule 2). It coordinates parsing, export and verification, all of which is model + filesystem work that has no reason to know a GUI exists.

The three things it genuinely cannot do alone -- run a callback on the application's main thread, ask the user a question, and put a notification on screen -- arrive as plain std::function HOST SERVICES, installed once at start-up by ICoreCodeEngineHost (ICoreStudio/Panels/CodeExportPanels/). That is the whole seam: everything Qt-shaped sits on the far side of it.

ICoreSignalBitSize#

ICoreCodegen.h:39 · struct · 0 declaration(s)

struct ICoreSignalBitSize {
public:
    int intBits;    // integer bits including sign
    int fracBits;   // fractional bits
};
};

ICoreCodeEngine#

ICoreCodegen.h:43 · class · 34 declaration(s)

class ICoreCodeEngine {
public:

    // ---- Structs ----

    // ====================[Host Services]======================
    // Installed once, from the main thread, before any export runs. Each is
    // optional: the fallback in brackets is what an installer-less host gets.

    // Runs `callback` on the application's main thread and returns immediately.
    // [fallback: the callback runs inline, on the calling thread]
    //
    // Installing this also records the calling thread as the main thread, which
    // is what lets askContinue-style prompts know whether they must marshal.
    using MainThreadInvoker = std::function<void(std::function<void()> callback)>;
    static void setMainThreadInvoker(MainThreadInvoker invoker);

    // Asks the user a yes/no question and blocks until they answer.
    // [fallback: answers NO and logs it -- a headless run must not hang waiting
    //  for a person, and "no" is the safe answer for every question the engine
    //  asks, all of which are "carry on despite a failure?"]
    using QuestionHandler = std::function<bool(const std::string& title,
                                               const std::string& text)>;
    static void setQuestionHandler(QuestionHandler handler);

    enum class NotificationKind { Friendly, Warning };

    // Shows a notification to the user. [fallback: ICoreLogger]
    using NotificationSink = std::function<void(NotificationKind kind,
                                                const std::string& title,
                                                const std::string& message)>;
    static void setNotificationSink(NotificationSink sink);

    // ====================[Listeners]======================
    // Single-listener, not lists: each has exactly one consumer today, and the
    // infrastructure rule is to add API when a call site needs it.

    // Fired when the SET of export targets changes -- created, deleted, cleared.
    // A UI listening to this rebuilds its list from getAllExportTargets(), which
    // destroys and recreates widgets, so it is not safe to fire from inside a
    // handler owned by one of them.
    using TargetsChangedListener = std::function<void()>;
    static void setTargetsChangedListener(TargetsChangedListener listener);
    static void notifyTargetsChanged();

    // Fired when a background job claims (true) or releases (false) the parser
    // thread, on the thread that claimed it -- the main thread in practice.
    using JobStateListener = std::function<void(bool jobRunning)>;
    static void setJobStateListener(JobStateListener listener);

    // ====================[Code Types]======================
    static std::vector<std::string> getAvailableCodeTypes();
    // The icon for a code type is presentation and lives in ICoreStudio --
    // see ICoreCodeTypeIcons::forCodeType().

    // ====================[Export Targets]======================
    static ICoreCodeExportTarget* createNewCodeExportTarget();

    static void deleteCodeExportTarget(const ICoreCodeExportTarget* targetToDelete);
    static std::vector<ICoreCodeExportTarget *> getAllExportTargets();

    // Drops every target. Used when a project is closed or replaced: targets are
    // project data (they name a source subsystem inside THIS diagram), so
    // carrying them into the next project would point them at subsystems that
    // no longer exist. Refuses while a job owns the parser thread, like the
    // create/delete calls above, and returns false when it does.
    static bool clearAllExportTargets();

    static void generateSimpleTestingTargetsSet();

    // ====================[Fire Targets]======================
    static bool fireAllTargets();
    static bool fireTarget(const ICoreCodeExportTarget *targetToFire);

    // ====================[Export Verification]======================
    // The engine's single verifier. Everything the verifier computes is static; the
    // instance exists only to own the verification window, which is why it is created
    // on first request rather than at start-up -- a console run never builds a widget
    // it will not show. Call it from the main thread only: the first call constructs
    // the verifier's UI.
    static ICoreCodeExportVerifier* getCodeExportVerifier();

    // ====================[Parser Worker Thread]======================
    // The engine owns ONE background thread, and every code parser / export / verification
    // run happens on it -- callers never spawn their own. Because that work shares the
    // global model + codegen state, a single thread is what makes it safe: jobs are
    // serialised by construction instead of by luck.
    //
    // It is a plain std::thread draining a FIFO queue, NOT a Qt event loop: that is what
    // took QThread, QObject, QMetaObject and QPointer out of this class. `work` runs on
    // that thread; `onFinished` is handed to the MainThreadInvoker once `work` returns.
    //
    // `requesterLifetime` replaces the QPointer the Qt version used. The caller keeps a
    // std::shared_ptr<void> member alive for as long as it can receive the callback, and
    // passes it here; if that owner is destroyed mid-job the completion callback is
    // dropped instead of reaching freed memory, and the job slot is released so the
    // parser does not stay "busy" forever. Pass an empty weak_ptr for a caller that
    // outlives every job.
    static void postToParserThread(std::weak_ptr<void> requesterLifetime,
                                   std::function<void()> work,
                                   std::function<void()> onFinished);
    static bool isOnParserThread();
    static void shutdownParserThread();   // called once at application exit

    // ====================[Background-job guard]======================
    // Only one job may own the parser thread at a time. tryBeginJob() atomically claims
    // the slot; tryBeginParserJob() is the UI-facing form that also pops the
    // "Parser is busy!" notification when the claim fails.
    static bool tryBeginJob();   // false if a job is already running
    static bool tryBeginParserJob(const std::string& requestedAction);
    static void notifyParserBusy(const std::string& requestedAction);
    static void endJob();
    static bool isJobRunning();

    // Cooperative cancellation: requestCancel() asks the running activity to stop. Chains
    // (verify-all / deploy) stop before the next target; a single job aborts at the next
    // step boundary and discards its result. A call already inside an external tool runs
    // to completion. clearCancel() is called when a fresh user action starts.
    static void requestCancel();
    static bool isCancelRequested();
    static void clearCancel();

    // ====================[Signal Name Generator (Linker)]======================
    static void resetSignalNameSpace();
    static void resetBlockNameSpace();
    static bool generateUniqueSignalName(ICorePort* port);
    static std::string getGeneratedUniqueSignalName(ICorePort* port);
    static bool isSignalNameGenerated(ICorePort* port);   // membership check, no logging

    // Read a verification <name>_input.csv into numeric rows (header skipped, all columns
    // incl. the leading time column). Empty if the file is missing/unreadable. Used by the
    // *ForVerification testbench builders to bake the test-input stimulus.
    static std::vector<std::vector<double>> readVerificationInputRows(const std::string& csvPath);

    // Boundary input-gate output ports (drivers outside the export scope -> fed externally).
    // These form the core's external-input interface; CSV input columns map onto them in
    // row-major order. Operates on the current ICoreModelBuild::getOrderedBlocks() state.
    static std::vector<ICorePort*> collectBoundaryInputPorts();
    static bool generateUniqueBlockName(ICoreBlock* block);
    static std::string getUniqueBlockFunctionName(ICoreBlock* block);
    static ICoreSignalBitSize getSignalBitSize(ICorePort* outputPort);

    // Sanitize a subsystem name into an identifier that is legal as a file name AND as a
    // module/class/entity name across every export language (C/C++/Rust/Java/Python/MATLAB/
    // VHDL/Verilog/SystemVerilog/PLC-ST). Keeps [A-Za-z0-9], collapses every run of other
    // characters - INCLUDING literal underscores - to a single '_', drops a leading or
    // trailing '_', prefixes a leading digit with "ICore_", and falls back to
    // "ExportedModel" if nothing usable remains. The underscore rules come from VHDL and
    // Structured Text, the strictest of the ten: both reject "A__B", "_A" and "A_". The
    // file name and the in-code identifiers are derived from the same result, so they
    // always match.
    static std::string sanitizeCodeIdentifier(const std::string& rawName);

    // ====================[Code Types]======================
    static const std::string CODE_TYPE_PYTHON;
    static const std::string CODE_TYPE_MATLAB;
    static const std::string CODE_TYPE_JAVA;
    static const std::string CODE_TYPE_RUST;
    static const std::string CODE_TYPE_CPP;
    static const std::string CODE_TYPE_C;
    // static const std::string CODE_TYPE_ARM;
    // static const std::string CODE_TYPE_x86;
    // static const std::string CODE_TYPE_DSP;
    static const std::string CODE_TYPE_SYSTEM_VERILOG;
    static const std::string CODE_TYPE_VERILOG;
    static const std::string CODE_TYPE_VHDL;
    // ST is the only IEC 61131-3 language the engine exports. LD / FBD / SFC are
    // graphical languages with no textual exporter behind them -- they used to be
    // offered as target types and could only ever fail at export, so they are gone.
    static const std::string CODE_TYPE_PLC_ST;
    static std::vector<std::string> AVAILABLE_CODE_TYPES;

    // Code types that support export verification (emulation + residual comparison).
    static const std::vector<std::string> VERIFIABLE_CODE_TYPES;

    // ====================[Code Templates Delimiters]======================
    static const std::string DELIMITER_IMPORTS;
    static const std::string DELIMITER_CONFIG;
    static const std::string DELIMITER_GLOBAL_TIME;
    static const std::string DELIMITER_SIGNALS;
    static const std::string DELIMITER_BLOCK_PARAMS;
    static const std::string DELIMITER_EXECUTE;
    static const std::string DELIMITER_BLOCK_FUNC_NAME;
    static const std::string DELIMITER_SOLVE_METHOD_NAME;
    static const std::string DELIMITER_COMPUTE_METHOD_NAME;
    static const std::string DELIMITER_BLOCK_FIELDS;
    static const std::string DELIMITER_BLOCK_INSTANCES;

};
};

ICoreSystemVerilogParser.h#

src/ICoreSDK/ICoreCodegen/CodeParsers/HDL/ICoreSystemVerilogParser.h

Declares no class of its own — see the file.

ICoreVHDLParser.h#

src/ICoreSDK/ICoreCodegen/CodeParsers/HDL/ICoreVHDLParser.h

Declares no class of its own — see the file.

ICoreVerilogParser.h#

src/ICoreSDK/ICoreCodegen/CodeParsers/HDL/ICoreVerilogParser.h

Declares no class of its own — see the file.

ICoreCParser.h#

src/ICoreSDK/ICoreCodegen/CodeParsers/Others/ICoreCParser.h

Declares no class of its own — see the file.

ICoreCppParser.h#

src/ICoreSDK/ICoreCodegen/CodeParsers/Others/ICoreCppParser.h

ICoreCppParser#

ICoreCppParser.h:28 · class · 4 declaration(s)

ICoreCppParser Exports a block diagram to a fixed-size, heap-free C++ project: <name>_deployableCore.hpp (header-only DeployableCore) <name>_testbench.cpp (runnable driver) Mirrors the Rust fixed-s...

class ICoreCppParser {
public:

    // ---- Entry Point ----
    static bool exportToCpp(const std::filesystem::path& pathToWriteCodeTo,
                            const ICoreSubsystemTreeNode* sourceTreeNode);

    // ---- Verification entry: emits the core + a RECORDING testbench that steps the
    //      horizon, records `portsToRecord` each step (time + signal columns, same order
    //      as the native sim), and writes <name>_output.csv. ----
    static bool exportToCppForVerification(const std::filesystem::path& pathToWriteCodeTo,
                                           const ICoreSubsystemTreeNode* sourceTreeNode,
                                           const std::vector<ICorePort*>& portsToRecord);

    // ---- Public Helpers (used by block generateBodyCode_Cpp / generateParamsCode_Cpp) ----
    // C++ aggregate initializer for a std::array-of-std::array literal: {{ {{a, b}}, {{c, d}} }}
    static std::string toCppFixedArray(const ICoreMatrix& matrix);
    // Mat<R, C> type for a port's signal.
    static std::string fixedType(const ICorePort* port);
    // Value-initialised (zero) Mat<R, C>{} for a port's signal.
    static std::string zerosFor(const ICorePort* port);
    // signals.<src> if connected & in-scope, else a fixed-size zero matrix.
    static std::string readInputExpr(const ICorePort* inputPort);

    // ---- Name Constants (used by block generateBodyCode_Cpp) ----
    static const std::string SIGNALS_STRUCT_NAME;    // "signals"
    static const std::string PARAMS_STRUCT_NAME;     // "params"
    static const std::string TIME_ARG_NAME;          // "t"
    static const std::string SOLVE_METHOD_NAME;      // "solve"
};
};

ICoreJavaParser.h#

src/ICoreSDK/ICoreCodegen/CodeParsers/Others/ICoreJavaParser.h

Declares no class of its own — see the file.

ICoreMatlabParser.h#

src/ICoreSDK/ICoreCodegen/CodeParsers/Others/ICoreMatlabParser.h

Entry Point Exports two files, mirroring the Python separation: <name>_deployableCore.m -> classdef handle: params + signals + state + execute_blocks <name>_testbench.m -> runnable script that instantiates and drives the core

ICoreMatlabParser#

ICoreMatlabParser.h:13 · class · 5 declaration(s)

class ICoreMatlabParser {
public:

    // -------------------------------------------------------
    //  Entry Point
    // -------------------------------------------------------
    // Exports two files, mirroring the Python separation:
    //   <name>_deployableCore.m  -> classdef handle: params + signals + state + execute_blocks
    //   <name>_testbench.m       -> runnable script that instantiates and drives the core
    static bool exportToMatlab(const std::filesystem::path& pathToWriteCodeTo,
                               const ICoreSubsystemTreeNode* sourceTreeNode);

    // ---- Verification entry: core + a RECORDING testbench (script) that records
    //      `portsToRecord` each step (time + signal columns) to <name>_output.csv. ----
    static bool exportToMatlabForVerification(const std::filesystem::path& pathToWriteCodeTo,
                                              const ICoreSubsystemTreeNode* sourceTreeNode,
                                              const std::vector<ICorePort*>& portsToRecord);

    static std::string toMatlabMatrix(const ICoreMatrix& matrix);

    // ---- Fixed-size block-body helpers (each block owns its full solve) ----
    // MATLAB expression for a zero matrix sized to `port`.
    static std::string zerosFor(const ICorePort* port);
    // MATLAB expression that reads an input port's source signal by name, or a zero
    // matrix when the port is unconnected / its source is out of the export scope.
    static std::string readInputExpr(const ICorePort* inputPort);

    // Per-block local clock (replaces the old global t_global). Emits lazily-initialised
    // state on obj.state.<blockFuncName>_* and sets obj.state.<blockFuncName>_time.
    static std::string getBlockLocalClock(const std::string& blockFuncName);

    // The seconds-per-execute_blocks() step the local clocks bake in. Set by the
    // export entry points above from the source subsystem's sampling time; any
    // OTHER driver of the block-level MATLAB codegen (the parity suite's
    // ICoreParityCoreEmitter) must set it before generating bodies, or source
    // blocks inherit whatever the last export left here.
    static void setSourceSamplingTime(double newSourceSamplingTime);

    // -------------------------------------------------------
    //  Method / Accessor Name Constants
    // -------------------------------------------------------
    static const std::string SOLVE_METHOD_NAME;      // "solve"
    static const std::string COMPUTE_METHOD_NAME;    // "compute"
    static const std::string SIGNALS_STRUCT_NAME;    // "obj.signals"
    static const std::string PARAMS_STRUCT_NAME;     // "obj.params"
    static const std::string STATE_STRUCT_NAME;      // "obj.state"
};
};

ICorePythonParser.h#

src/ICoreSDK/ICoreCodegen/CodeParsers/Others/ICorePythonParser.h

---- Fixed-size block-body helpers (each block owns its full solve) ---- Python expression for a zero-initialised array sized to port.

ICorePythonParser#

ICorePythonParser.h:11 · class · 8 declaration(s)

class ICorePythonParser {
public:
    static bool exportToPython(const std::filesystem::path &pathToWriteCodeTo,
                               const ICoreSubsystemTreeNode* sourceTreeNode,
                               const std::string& verificationLevel,
                               const std::vector<ICorePort*>& portsToRecord);

    static std::string parseBlockSolveMethod(const ICoreBlock* block, const std::string &prefix);
    static std::string toPythonNPArray(const ICoreMatrix& matrix);

    // ---- Fixed-size block-body helpers (each block owns its full solve) ----
    // Python expression for a zero-initialised array sized to `port`.
    static std::string zerosFor(const ICorePort* port);
    // Python expression that reads an input port's source signal by name, or a fresh
    // zero array when the port is unconnected / its source is out of the export scope.
    static std::string readInputExpr(const ICorePort* inputPort);

    static std::string getParsedIIREmulator();

    static double getSourceNodeSamplingTime();

    static std::string getBlockLocalClockDeclaration();

    static std::string getBlockLocalClock();

    static const std::string SOLVE_METHOD_NAME;
    static const std::string COMPUTE_METHOD_NAME;
    static const std::string INPUTS_VECTOR_NAME;
    static const std::string OUTPUTS_VECTOR_NAME;
    static const std::string SIGNALS_MAP_NAME;
    static const std::string PARAMS_CLASS_NAME;
    static const std::string PARAMS_INSTANCE_NAME;
    static const std::string MODEL_MODULE_NAME;
};
};

ICoreRustParser.h#

src/ICoreSDK/ICoreCodegen/CodeParsers/Others/ICoreRustParser.h

Declares no class of its own — see the file.

ICorePLC_ST_Parser.h#

src/ICoreSDK/ICoreCodegen/CodeParsers/PLC/ICorePLC_ST_Parser.h

Declares no class of its own — see the file.