Create
The project file is plain recipe text. The agent edits it in place and reloads; every line that did not apply comes back with its reason, so it fixes the line and reloads again.
ICore Blocks is a lightweight, industry-grade block-diagram simulator and code engine for control, robotics and machine-learning systems. It exports any level of a model to ten languages, then compiles that code, runs it, and compares it against its own simulation, sample by sample. The same engine embeds in your own platform as a C++ SDK.
generated cores with no run-time allocation · software targets · tolerance 0.1 % · observed agreement ≈1e-11 %
Claude Code, Codex, Gemini CLI or Cursor can create a model, simulate it, verify the generated code and deploy it to your own embedded hardware. That is not a chat feature bolted onto an editor. It works because ICore Blocks is infrastructure: a simulator, ten code generators and a verifier behind a plain-text model format and a command interface, which an agent drives exactly as a build script would.
Nothing in the loop needs the window.
agentServe opens a project headless and serves the same commands on a build
machine, and it is the same engine that embeds in your own platform as a C++ SDK.
When a person is watching, every command the agent runs appears in their Command
Window as it happens.
simulated 0 to 10 s, 101 steps; 1 signal(s): Home/Scope:in0 first 0 last 0.999879 min 0 max 0.999879 mean 0.798693
t = target(C) t.setConfig(Source, Home/Controller) t.setConfig(Folder, firmware/controller) t.setConfig(Verification, Strict - All Signals) t.fire()
The project file is plain recipe text. The agent edits it in place and reloads; every line that did not apply comes back with its reason, so it fixes the line and reloads again.
icore simulate runs the model and summarises every sink - first,
last, lowest, highest and mean - and lists every error or warning the run
logged.
The export builds the generated code with a real toolchain, drives it with a random stimulus and compares it with the simulation, sample by sample, against a tolerance.
C for your microcontroller board, VHDL or Verilog for an FPGA, Structured Text for a PLC. The core lands in the folder your firmware build reads: fixed-size, with nothing allocated at run time.
Most of what ICore Blocks is sold for never shows a window. The engine is a C++ library you link, a code generator whose output you ship, and a headless binary a build can drive - and the desktop application is the fourth way, not the only one.
The modelling engine as a library inside your own application: the block model, the solver, the 806-block library, the ten code generators and the editor surface. The public headers expose ICore types only, and you own the loop - so the engine steps on your clock, not on ours. Redistribution rights come with the licence.
What the SDK exposes →Or take no dependency at all. Export a subsystem and ship what it writes: a C core is a plain struct plus functions with no allocator, no hidden state and nothing beyond the standard library, so it drops into a bare-metal build as easily as a desktop one. One call advances the model exactly one sample - a PLC scan, an RTOS tick, a clock edge.
See all ten targets →Everything the window does has a console equivalent, and the console runs without a
window: --console executes a command and exits. 66 commands cover
loading a model, running it, reading results and deploying code - which is how a
model becomes a step in CI rather than something a person remembers to re-export.
The engine is deliberately light: one static platform library, no runtime services to stand up, and generated code with fixed-size storage and no allocation. That is what lets the same model reach a PLC, a microcontroller, an FPGA fabric and a robotics node without four separate toolchains - and what makes it embeddable in a platform that already has its own idea of how software is built.
FUNCTION_BLOCK called once per scan, carried in LREAL throughout - a full-precision target, not a fixed-point approximation of one.The engine is delivered as a C++ SDK in two layers you can adopt separately: a platform foundation that depends on nothing else in the product, and the modelling engine on top of it. Both are C++17, and both keep their dependencies to themselves.
find_package(ICoreBlocks 1.0) and the icore::sdk target, which carries the include root and C++17 and no toolkit target at all.std::string. Implementation details stay behind the interface you compile against, so an internal change is not your migration - and your own code never names the UI toolkit.run() is exactly while (isRunning()) tick();, and tick() is public - so an engine embedded in your application is stepped by your scheduler and never blocks in a loop it controls.icore::License is a read-only view of what a copy may do - state(), has(Feature), allowsCodegenTarget(), allowsCommercialUse(). It answers, never acquires, and before anything resolves it says Unlicensed with no features rather than crashing.#include <icore/Application.h>
#include <icore/EditorWindow.h>
int main(int argc, char** argv) {
icore::Application app(argc, argv);
auto editor = app.createEditorWindow();
editor->setTitle("ICoreBlocks");
editor->show();
return app.run();
}
find_package(ICoreBlocks 1.0 REQUIRED) target_link_libraries(my_app PRIVATE icore::sdk)
Every Team + SDK licence carries the right to redistribute the SDK inside your own product, fifteen floating seats, plugin loading - and 40 to 200 hours of our engineers working on your integration, in C++ or Python. The SDK downloads from the customer portal with the licence; the hours are how it gets fitted to your toolchain, which is why they are in the licence rather than sold beside it.
OEM re-badging, shipping the SDK to your own customers as a development tool, source escrow, air-gapped and offline activation, on-premises licence servers and contractual response SLAs are all quoted individually. Tell us what the deployment needs and we will come back with a quote.
Four steps, in order - whether a person walks them in the editor, a script walks them headlessly, or your own application walks them through the SDK. Everything in the window has a console equivalent, and everything the console does the API does too.
Place blocks from the library navigator and join them with signal links. Subsystems nest beneath the top level, so a model stays readable as it grows.
Set the start and stop time, the solver and the sampling. Continuous and discrete parts live in the same model - most real ones are mixed.
Scopes fill in as the run advances. Results are also variables: read them in the command window, chart them, or keep them for the next run.
Turn any subsystem - or the whole model - into a stand-alone program with a testbench and a build file, in the language the target needs. Or skip the file entirely and run the engine in-process, inside your own product.
Eleven things it does that you would otherwise assemble from separate tools.
Optimize a model before it deploys. Collapse blocks in series, in parallel or around a feedback loop into one exact state-space realization, so a deployed closed loop is discretized as one loop instead of block by block, with no loop delay between them and fewer signal buffers in RAM. A singular algebraic loop is refused rather than invented.
Read more →The project file is plain recipe text, so Claude Code, Codex or any other coding agent
edits it in place and tells the app to reload - the change lands in the window you
are working in, and every line that did not apply comes back with its reason. The
icore client and its MCP tools let the agent simulate the model and
fire its export targets itself, and every command it runs shows in your Command Window.
MATLAB and ICore each have their own grammar, and one dictionary translates between them:
bring a .m in as a script, or send a script out as a .m that runs on its
own. Models cross to Simulink and back, and both bridges are checked against MATLAB before every
release.
Any subsystem becomes a stand-alone program: a deployable core advancing one sample per call, a testbench, and a build file. C, C++, Rust, Python, MATLAB, Java, VHDL, Verilog, SystemVerilog and IEC 61131-3 Structured Text.
Read more →Continuous or discrete. Fixed-step: Euler (RK1), Improved Euler / Heun (RK2), Kutta (RK3), Runge–Kutta (RK4), and implicit Backward Euler and Trapezoidal for stiff plants. Variable-step: Dormand–Prince (RK45), Bogacki–Shampine (RK23) and implicit TR-BDF2. Subsystems may run at their own sampling rate, reconciled by a multi-rate tolerance you control.
Read more →A model that runs at several rates ships as several targets: each one names its own source subsystem, its own language and its own verification level, and each is generated at that subtree's rate. Targets are saved beside the project and go out together with Deploy All.
Read more →Drop a C or Python block into the diagram and your own source runs inside the simulation loop, with the ports you declare on it - for the part of a model that was never going to be a block.
Read more →The command window has a Python REPL's feel - a bare variable prints as a Python repr,
matrices print as lists - while keeping MATLAB's rules where they matter: a statement
ending in ; is silent, and matrices are stored in MATLAB syntax. Type either;
it understands both.
Make your own blocks and keep them. The wizard writes a .iblock file -
identity, ports, icon, description, and a body that is either recipe text or Python - and
it appears under My Blocks in the navigator, ready to import, export or hand to
someone else. A definition stamps into ordinary blocks when placed, so a project
that uses your library stays self-contained.
The linear algebra is Eigen underneath - Dense, plus Polynomials, Matrix Functions,
Splines, FFT, Numerical Differentiation and Levenberg–Marquardt - reached through
ICoreMatrix and its neighbours. You get the performance without binding your
own code to the dependency.
Matrices, polynomials, splines, time series and complex variables. Calculus, geometry, optimisation, signal processing and control-systems tooling - discretization, root locus, state-space and transfer-function conversion, time response - and the expression evaluator the console itself runs on.
Read more →Every export has the same shape: a deployable core that advances the model by exactly one sample per call, a testbench that drives it across the simulation window, and - where the language has one - a build file so the folder compiles as it is. Storage is fixed-size and nothing is allocated at run time, so this is the artifact that ends up on the PLC, the microcontroller or the FPGA.
| Target | Deploy writes | One call advances one sample |
|---|---|---|
| C | <name>_deployableCore.h/.c, testbench, CMakeLists.txt | DeployableCore_init(&core), then execute_blocks(&core) |
| C++ | <name>_deployableCore.hpp, testbench, CMakeLists.txt | struct DeployableCore · execute_blocks() |
| Rust | <name>_deployableCore.rs, testbench, Cargo.toml | execute_blocks(&mut self) |
| Python | <name>_deployableCore.py, testbench | execute_blocks() · needs numpy |
| MATLAB | <name>_deployableCore.m, testbench | classdef … < handle · core.execute_blocks() |
| Java | <name>_deployableCore.java, testbench | executeBlocks() |
| VHDL | icore_pkg.vhd, entity, testbench, Makefile (GHDL) | one rising clk edge |
| Verilog | icore_defs.vh, module, testbench, Makefile (Icarus) | one clk edge |
| SystemVerilog | icore_defs.svh, module, testbench, Makefile (Icarus) | one clk edge |
| PLC · ST | <name>_deployableCore.st, testbench | FUNCTION_BLOCK FB_<name> - one scan |
Most code generators ask for faith. This one exports the model, builds it with a real toolchain, runs it over the simulation window, and compares every sample against the solver - then reports the residual as a percentage. Choose how strict to be: output gates only, gates and sinks, or strict across all signals.
[[0], [0.632121], [0.864665], [0.950213], [0.981684], [0.993262]]
| Target class | Tolerance | Observed |
|---|---|---|
| Software · 7 languages | 0.1 % | ≈1e-11 % |
| HDL · Q16.16 | 1 % | ≈1e-3 % |
Every block bridged to Simulink is driven with a seeded random stimulus. The identical samples go through the Simulink counterpart and through the block's own generated MATLAB, and the outputs are compared sample-by-sample against a per-block tolerance. It is a pre-release suite: a block that drifts fails the release.
667 of the 806 library blocks carry a sample from a real headless run - a step, impulse, sine or ramp response, or an input-to-output table where that is the point - regenerated with the software, never drawn by hand. The same rule governs this page: every number on it is a measurement.
Blocks carry typed matrix signals over port-based links, so a controller, an estimator and a classifier sit in the same diagram and export through the same path. Each block's description - its ports, parameters and what it computes - is one text, shown in the library navigator, in its configuration dialog and on its documentation page. The four domains below hold 789 of them; the other 17 are the subsystem block and the parts that go inside one: its input and output gates, its enable, trigger, reset and action ports, and the iterator, If, Switch Case and function-call blocks that drive it.
Closed-loop control, subsystem building blocks and more ship with the application. Opening one creates a project of its own, so the template is never modified.
Anything done in the window has a console equivalent, and the console runs without one:
--console executes a command and exits, which is how models are driven in a
build.
.m files translate in and out of the console, and blocks carry a Simulink
mapping. Both are checked against MATLAB before every release.
Everything above is also a desktop application, and it is a real one - it is where models get drawn, run, read and exported before any of it is embedded, and it is how most teams evaluate the engine before they link it. Download it, open one of the 42 templates, and the first export is a few minutes away.
A short, plain message when a new ICore Blocks release lands - what changed, what it means for the SDK, and the new block responses. No newsletter, no drip sequence, and the list is never shared or sold.
Take the SDK into the platform the engine has to live in, or start with the application: download it and read the documentation - the manual, a page for every block, and the full command reference are public, with nothing behind a sign-in.