PLC Structured Text.st
IEC 61131-3 Structured Text: the model as a function block, one call per PLC scan.
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.
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.
Deploy writes
<name>_deployableCore.st<name>_testbench.st
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.
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 scanWhere 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.
| Target class | Tolerance | Observed |
|---|---|---|
| Software · 7 languages | 0.1 % | ≈1e-11 % |
| HDL · Q16.16 | 1 % | ≈1e-3 % |
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.
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.