ICore Blocks / Targets / Industrial

PLC Structured Text.st

IEC 61131-3 Structured Text: the model as a function block, one call per PLC scan.

Industrial Verified with matiec (iec2c) LREAL 756 of 806 blocks
DPT_Feedback_Discrete_deployableCore.st
✓ verified · 0.1 %
FUNCTION_BLOCK FB_DPT_Feedback_Discrete
VAR_INPUT
    (* ---- Tunable parameters (set from the testbench: core.<name> := ...) ---- *)
    gain_blk2 : ARRAY[0..0, 0..0] OF LREAL := [LREAL#1.8000000000000000];   (* tunable gain *)
    in_sig0 : ARRAY[0..0, 0..0] OF LREAL;   (* external input: ICore Blocks/Home/DPT_Feedback_Discrete/In1/ICoreDouble-Out-0 *)
END_VAR
VAR_OUTPUT
    (* ---- Signals (observable from the testbench: core.<name>) ---- *)
    sig0 : ARRAY[0..0, 0..0] OF LREAL;   (* ICore Blocks/Home/DPT_Feedback_Discrete/In1/ICoreDouble-Out-0 *)
    sig1 : ARRAY[0..0, 0..0] OF LREAL;   (* ICore Blocks/Home/DPT_Feedback_Discrete/Error/ICoreDouble-Out-0 *)
    sig2 : ARRAY[0..0, 0..0] OF LREAL;   (* ICore Blocks/Home/DPT_Feedback_Discrete/Ctrl_Gain/ICoreDouble-Out-0 *)
    sig3 : ARRAY[0..0, 0..0] OF LREAL;   (* ICore Blocks/Home/DPT_Feedback_Discrete/Plant/ICoreDouble-Out-0 *)
    sig4 : ARRAY[0..0, 0..0] OF LREAL;   (* ICore Blocks/Home/DPT_Feedback_Discrete/ICoreDouble-Out-0 *)
END_VAR
VAR
    (* ---- Persistent block state ---- *)
    (* blk3: ICore Blocks/Home/DPT_Feedback_Discrete/Plant *)
    uh_blk3 : ARRAY[0..0, 0..0, 0..1] OF LREAL := [LREAL#0.0, LREAL#0.0];
    yh_blk3 : ARRAY[0..0, 0..0, 0..0] OF LREAL := [LREAL#0.0];
    y_blk3 : LREAL;
END_VAR

    (* ===== Ordered execution pass (one scan == executeBlocks) ===== *)
    (* blk0: ICore Blocks/Home/DPT_Feedback_Discrete/In1 *)
    sig0[0, 0] := in_sig0[0, 0];

    (* blk1: ICore Blocks/Home/DPT_Feedback_Discrete/Error *)
    sig1[0, 0] := sig0[0, 0] - sig3[0, 0];

    (* blk2: ICore Blocks/Home/DPT_Feedback_Discrete/Ctrl_Gain *)
    sig2[0, 0] := sig1[0, 0] * gain_blk2[0, 0];

    (* blk3: ICore Blocks/Home/DPT_Feedback_Discrete/Plant *)
    (* Discrete transfer function (direct-form IIR) applied per [p,m] entry: rotate u, y = sum num*u - sum den*y *)
    uh_blk3[0, 0, 1] := uh_blk3[0, 0, 0];
    uh_blk3[0, 0, 0] := sig2[0, 0];
    y_blk3 := 0.0;
    y_blk3 := y_blk3 + LREAL#0.0 * uh_blk3[0, 0, 0];
    y_blk3 := y_blk3 + LREAL#0.40000000000000002 * uh_blk3[0, 0, 1];
    y_blk3 := y_blk3 - LREAL#-0.59999999999999998 * yh_blk3[0, 0, 0];
    yh_blk3[0, 0, 0] := y_blk3;
    sig3[0, 0] := y_blk3;

    (* blk4: ICore Blocks/Home/DPT_Feedback_Discrete/Out1 *)
    sig4[0, 0] := sig3[0, 0];
END_FUNCTION_BLOCK

What Deploy writes for the reference model below, with only the file's header banner removed. Tunable parameters and the external input are VAR_INPUT, the signals are VAR_OUTPUT, and block state is VAR - so calling the function block once from your program is one scan and one sample, with the state surviving between scans by definition. Note what the emitter does with a 1×1 model: the loops are gone entirely and the pass is a handful of scalar assignments, including the plant's history rotation.

Export · Verify · Integrate

From the diagram to your PLC Structured Text 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.st
  • <name>_testbench.st
→ code/<name>/
02 · VerifyICore

Built, run and compared

Built with matiec (iec2c), 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 LREAL, and 756 of 806 library blocks export to PLC Structured Text.

FUNCTION_BLOCK FB_<name> - one call = one scan
With verification on, a failed comparison stops the export and says why, so a core that disagrees with the simulation never reaches your folder.
Industrial target

Where PLC Structured Text fits.

The core is a FUNCTION_BLOCK. Call it once per scan from your program and the model has advanced one sample - the same contract as every other target, expressed the way a PLC expects it. Numbers are LREAL, the ST equivalent of the double the software targets use, so this is a full-precision target and not a fixed-point one.

Structured Text and VHDL are the strictest of the ten about identifiers, and between them they set the naming rules the export applies to all targets - anything outside [A-Za-z0-9] collapses to an underscore, and a leading digit gets a prefix.

Verification compiles the generated ST with matiec (iec2c). If that transpiler is missing, every block fails this column at once - which is the signature to look for before suspecting the generator.

$ Code Engine → Code Export Verifier → Verify All
Target classToleranceObserved
Software · 7 languages0.1 %≈1e-11 %
HDL · Q16.161 %≈1e-3 %
Structured Text runs in LREAL, full double precision, so it is held to the software tolerance, not the fixed-point one. 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.