ICore Blocks / Targets / Software

MATLAB.m

A classdef … < handle core - and the same code path the Simulink parity suite checks, block by block.

Software Verified with MATLAB double 800 of 806 blocks
DPT_Feedback_Discrete_deployableCore.m
✓ verified · 0.1 %
classdef DPT_Feedback_Discrete_deployableCore < handle

    properties
        params    % Tunable parameters (editable from the testbench)
        signals   % Signal storage (readable from the testbench)
        inputs    % External inputs (set before execute_blocks; input gates copy these in)
        state     % Internal block state
    end

    methods

        function obj = DPT_Feedback_Discrete_deployableCore()

            % --- Tunable Parameters ---
            obj.params = struct();
            % blk2: ICore Blocks/Home/DPT_Feedback_Discrete/Ctrl_Gain
            obj.params.blk2_gain = [1.8];

            % --- Signal Storage ---
            obj.signals = struct();
            % sig0: ICore Blocks/Home/DPT_Feedback_Discrete/In1/ICoreDouble-Out-0
            obj.signals.sig0 = zeros(1, 1);
            % sig1: ICore Blocks/Home/DPT_Feedback_Discrete/Error/ICoreDouble-Out-0
            obj.signals.sig1 = zeros(1, 1);
            % sig2: ICore Blocks/Home/DPT_Feedback_Discrete/Ctrl_Gain/ICoreDouble-Out-0
            obj.signals.sig2 = zeros(1, 1);
            % sig3: ICore Blocks/Home/DPT_Feedback_Discrete/Plant/ICoreDouble-Out-0
            obj.signals.sig3 = zeros(1, 1);
            % sig4 (boundary output): ICore Blocks/Home/DPT_Feedback_Discrete/ICoreDouble-Out-0
            obj.signals.sig4 = zeros(1, 1);

            % --- External Inputs ---
            obj.inputs = struct();
            obj.inputs.sig0 = zeros(1, 1);

            % --- Internal Block State ---
            obj.state = struct();
        end

        function execute_blocks(obj)

            % Execution order generated automatically from block diagram
            % blk0: ICore Blocks/Home/DPT_Feedback_Discrete/In1
            obj.blk0_solve();
            % blk1: ICore Blocks/Home/DPT_Feedback_Discrete/Error
            obj.blk1_solve();
            % blk2: ICore Blocks/Home/DPT_Feedback_Discrete/Ctrl_Gain
            obj.blk2_solve();
            % blk3: ICore Blocks/Home/DPT_Feedback_Discrete/Plant
            obj.blk3_solve();
            % blk4: ICore Blocks/Home/DPT_Feedback_Discrete/Out1
            obj.blk4_solve();
        end

        function blk0_solve(obj)

            obj.signals.sig0 = obj.inputs.sig0;
        end

        function blk1_solve(obj)

            output = zeros(1, 1);
            output = output + obj.signals.sig0;
            output = output - obj.signals.sig3;
            obj.signals.sig1 = output;
        end

        function blk2_solve(obj)

            gain = obj.params.blk2_gain;
            input = obj.signals.sig1;
            output = input * gain(1, 1);
            obj.signals.sig2 = output;
        end

        function blk3_solve(obj)

            num = [0, 0.40000000000000002];
            den = [-0.59999999999999998];
            if ~isfield(obj.state, 'blk3_u_hist')
                obj.state.blk3_u_hist = zeros(1, 1, 2);
                obj.state.blk3_y_hist = zeros(1, 1, 1);
            end
            u = obj.signals.sig2;
            out = zeros(1, 1);
            for r = 1:1
                for c = 1:1
                    uk = u(r, c);
                    obj.state.blk3_u_hist(r, c, 2:2) = obj.state.blk3_u_hist(r, c, 1:1);
                    obj.state.blk3_u_hist(r, c, 1) = uk;
                    yk = 0;
                    for i = 1:2
                        yk = yk + num(i) * obj.state.blk3_u_hist(r, c, i);
                    end
                    for i = 1:1
                        yk = yk - den(i) * obj.state.blk3_y_hist(r, c, i);
                    end
                    obj.state.blk3_y_hist(r, c, 1) = yk;
                    out(r, c) = yk;
                end
            end
            obj.signals.sig3 = out;
        end

        function blk4_solve(obj)

            obj.signals.sig4 = obj.signals.sig3;
        end

    end
end

What Deploy writes for the reference model below, with only the file's header banner removed. A handle class, so state persists across calls without being passed back and forth: construct the core once, call execute_blocks per sample, read obj.signals. The plant's history is created on first use inside blk3_solve, which keeps the constructor to declarations.

Export · Verify · Integrate

From the diagram to your MATLAB build.

Deploy writes the folder, ICore checks it against the simulation, and your code calls it once per sample.

01 · ExportICore

Deploy writes

  • <name>_deployableCore.m
  • <name>_testbench.m
→ code/<name>/
02 · VerifyICore

Built, run and compared

Built with MATLAB, run across the simulation window and compared with the solver sample by sample, against a 0.1 % tolerance.

observed ≈1e-11 %
03 · IntegrateYour build

One call, one sample

Numbers are double, and 800 of 806 library blocks export to MATLAB.

core = <name>_deployableCore(); core.execute_blocks();
With verification on, a failed comparison stops the export and says why, so a core that disagrees with the simulation never reaches your folder.
Software target

Where MATLAB fits.

The core is a handle class: construct it once, call execute_blocks once per sample, read the properties. Because it is a handle, state persists across calls without you passing anything back and forth.

This target carries more weight than its file count suggests. The Simulink parity suite drives each bridged block's generated MATLAB against the Simulink counterpart with a seeded random stimulus and compares sample by sample - so this generator is exercised against an independent implementation before every release, not just against our own solver.

$ Code Engine → Code Export Verifier → Verify All
Target classToleranceObserved
Software · 7 languages0.1 %≈1e-11 %
HDL · Q16.161 %≈1e-3 %
MATLAB runs the same double-precision arithmetic as the solver, so anything above noise would be a real defect. Passing runs measure about 1e-11 %. See verification.
The reference model

One model, ten targets.

Every target page shows the same model, so the ten are directly comparable: an input, an error junction, a gain of 1.8, a discrete plant and an output, with the plant's output fed back into the junction. The export-verification suite calls it DPT_Feedback_Discrete - which is where the names in the file come from.

DPT_Feedback_Discrete · 5 blocks
In1 Σ + − Error × 1.8 Ctrl_Gain 0.4z⁻¹ 1 − 0.6z⁻¹ Plant Out1 the previous sample, fed back
Get started

See it run on your own model.

Download the application from the customer portal, or read the documentation first - the manual, a page for every block, and the full command reference are public.