Siemens STEP 7 STL to LADDER Conversion: Methods and Limitations

David Krause14 min read
S7-300SiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Siemens STEP 7 STL to LADDER Conversion: Methods and Limitations

Statement List (STL) and Ladder Diagram (LAD) are both IEC 61131-3 programming languages supported by STEP 7 (SIMATIC Manager V5.x) on the S7-300 and S7-400 platforms. While the editor provides a one-click toggle between views, STL programs frequently fail to convert when they contain indirect addressing, pointer arithmetic, or accumulator-based logic that has no direct graphical equivalent. This reference explains the exact procedure for forcing a conversion, lists every instruction category that the compiler rejects, and provides field-tested workarounds for the most common blocking constructs.

Environment scope: This article targets STEP 7 V5.4 / V5.5 with SIMATIC Manager running on S7-300 (CPU 312, 314, 315, 317, 319) and S7-400 (CPU 412, 414, 416, 417). TIA Portal uses a different editor and conversion path; refer to the Siemens STEP 7 (TIA Portal) documentation for that environment.

1. STL, LAD, and FBD Language Profiles in STEP 7

STEP 7 stores every program block (OB, FB, FC, DB) in a single internal SCL/STL representation. The view toggle (View > LAD, View > FBD, View > STL) does not transform logic — it asks the compiler to render the same instructions in a graphical form. The render fails silently for any segment whose instruction mix has no graphical primitive.

Language Editor Strength Limitation
STL (Statement List) Textual Full CPU instruction set, indirect addressing, accumulator operations Not IEC-textual, steep reading curve
LAD (Ladder Diagram) Graphical Visual scan flow, contact/coil model matches relay logic Limited subset of CPU instructions
FBD (Function Block Diagram) Graphical Box-and-wire model, good for math and selection logic Same instruction subset restrictions as LAD
SCL (Structured Control Language) Textual, Pascal-like High-level loops, CASE, WHILE, structured data Requires optional SCL package
CFC (Continuous Function Chart) Graphical Free-form placement, signal feedback lines Optional package, not for cyclic OB1

Because LAD and FBD share the same allowed instruction subset, converting STL to either is governed by one rule set. The remainder of this document refers to LAD, but FBD follows identical selection logic.

2. Prerequisites

Confirm the following before attempting conversion:

  1. STEP 7 V5.4 SP5 or later installed, with the S7-SCL optional package if SCL blocks are present.
  2. Project access offline — open the project in SIMATIC Manager and double-click the block to enter the editor. Online blocks downloaded from the CPU cannot be re-edited in LAD; they must first be uploaded to the offline project via PLC > Upload Station to PG.
  3. Source file (optional but recommended) — if the project contains .s7p / .s7l STL source files, regenerate the blocks before conversion. STL source is the canonical text and recompiles cleanly.
  4. No active online connection to the CPU while editing; otherwise the editor opens read-only.
  5. Know the program structure: count segments with Edit > Go To > Segment Number and identify any that use the instructions listed in Section 4.

3. The One-Click Toggle and Why It Fails

Clicking View > LAD (or pressing Ctrl+K shortcut, then selecting LAD) initiates a per-segment parse. Each STL segment is examined in isolation:

  1. The first instruction must map to a power rail (LAD) or a signal input pin (FBD).
  2. The logic chain must be expressible with contacts, comparators, SR/RS flip-flops, timers, counters, arithmetic boxes, and jump boxes.
  3. Branch operations must form an ordered tree — not a parallel/parallel-on-parallel-of-parallel net that exceeds the editor nesting depth.

If any segment fails the parse, STEP 7 leaves the entire block in STL — it does not partially convert. This is the most common cause of the symptom reported by users who click Display LAD and see nothing change.

Key behavior: A successful toggle is block-wide. If a single segment contains non-convertible STL, the whole block stays in STL even though every other segment would have rendered correctly. The fix is to split the offending segment into multiple segments (Section 6).

4. Instructions That Cannot Be Converted to LAD

The following STL instruction categories have no graphical equivalent and will silently block conversion of the containing segment:

Category Example STL Reason it cannot render
Pointer load L P#10.0
L P#DBX 5.0
Pointer literals are address-arithmetic values, not signal references.
Indirect addressing load L IW [AR1,P#2.0]
L DBW [MD 20]
No graphical box expresses "load from address contained in AR1 + offset".
AR1/AR2 manipulation LAR1 P#M 10.0
TAR1 MD 40
+AR1 P#2.0
Address register arithmetic has no LAD primitive.
DB-register switching with parameter OPN DB [MW 10]
CDB
Dynamic DB open cannot be modelled.
Loop instruction LOOP NEXT Backward branch is unbounded in graphical form.
Master Control Relay MCRA / MCRD / MCR( / )MCR Deprecated; graphical editor shows it as raw ladder with suppressed outputs.
Save/load accumulator (multi-step) TAK
PUSH / POP (S7-400)
Implicit stack manipulation is invisible to the renderer.
Bit logic with status word writes SET
CLR
No contact source.
Process interrupt register access L PIW [P#...] Same as indirect addressing.
Complex multi-assignments on one line A I 0.0
AN I 0.1
= M 1.0
= Q 4.0
Graphical coil count ≤ 1 per rung in most cases; multiple parallel assigns require splitting.

5. Step-by-Step STL to LADDER Conversion Procedure

  1. Open the block in the editor. In SIMATIC Manager, navigate to S7 Program > Blocks, right-click the target block (FB/FC/OB) and choose Open Object, or double-click it.
  2. Verify the editor is in STL. The bottom-right status bar reads STL. If it reads LAD or FBD, switch to STL first via View > STL so you can see what the compiler is rejecting.
  3. Inspect each segment. Use the segment navigator on the left margin. For each segment, mentally check against the Section 4 list. Segments that obviously contain pointer loads or indirect addressing are guaranteed conversion blockers.
  4. Split offending segments. Place the cursor at the end of the first non-blocker line, press Ctrl+Enter or use Insert > Segment, and move the blocking instructions into the new segment(s). Repeat until every segment contains only convertible STL.
  5. Switch to LAD. With the block open, click View > LAD (or press F9 in some keyboard maps; the standard shortcut is View > LAD). The compiler parses segment-by-segment.
  6. Watch the status bar. A successful conversion keeps the cursor inside the graphical view; the segment header shows ladder rungs. If the editor reverts to STL, the offending segment retains its original text and the cursor jumps to it — fix that segment and retry.
  7. Save and compile. File > Save, then PLC > Consistency Check to validate the block.
  8. Download to the CPU via PLC > Download if the program structure has changed.
Note on segment splitting: A single STL "segment" in the editor corresponds to one rung in LAD. Each LAD rung begins at the left power rail and terminates at a coil, jump, or RETURN. Therefore, every STL instruction sequence that must terminate a ladder rung (e.g., =, S, R, JU, JC) should be the last line of its segment.

6. Splitting Complex Networks for Conversion

The cleanest way to split a complex STL block is to preserve program behavior exactly. The classic technique is to materialize an intermediate bit or memory word between two sequences that would otherwise share an accumulator value.

Before (STL, single segment, will not convert):

A   I 0.0
L   MW 10
+   1
T   MW 12
A   M 1.0
=   Q 4.0

After (LAD, two segments):

// Segment 1
A   I 0.0
JCN _SKIP
L   MW 10
+   1
T   MW 12
_SKIP: NOP 0

// Segment 2
A   M 1.0
=   Q 4.0

The first segment uses JCN (jump if RLO = 0) plus a NOP 0 label as a sink, which LAD renders as a --(\label) box. The JCN instruction itself converts to a graphical jump coil (--("label")) at the end of a rung. NOP 0 at the label target is invisible to LAD and required only so the assembler does not flag the label as undefined.

Pattern: Split-and-Materialize for Multi-Coil Logic

STL allows parallel assigns from one RLO. LAD does not. Use this rewrite:

// STL (won't convert):
A   I 0.0
A   I 0.1
=   Q 4.0
=   M 1.0
=   DB1.DBX 2.0
// LAD-friendly:
// Segment 1
A   I 0.0
A   I 0.1
=   M 0.0    // intermediate flag

// Segment 2
A   M 0.0
=   Q 4.0

// Segment 3
A   M 0.0
=   M 1.0

// Segment 4
A   M 0.0
=   DB1.DBX 2.0

The extra scan-time cost is negligible (single-bit RLO read) and the result is graphically convertible, IEC-61131-3 compliant, and easier to maintain.

7. Manual Conversion Patterns and Workarounds

7.1 Pointer loads (L P#x.x)

Pointer literals are almost always used as inputs to indirect memory access or to initialize address registers for loops. Replace the pointer literal with an inline constant in the destination instruction if the address is static:

// STL (pointer-driven):
L   P#M 10.0
LAR1
L   MW [AR1,P#2.0]
T   MW 20

// LAD-friendly equivalent (static address):
L   MW 12        // = MW (10.0 byte-offset 2 = MW12)
T   MW 20

If the offset is truly dynamic, keep the segment in STL and isolate it inside its own FC. Comment it as // STL: indirect addressing — cannot render in LAD and place it at the end of the FC after all convertible segments so the rest of the block still renders.

7.2 Indirect loads (L IW [AR1,P#2.0])

Indirect addressing is sometimes replaceable with an indexed DB access using the S7 DB[DI] mechanism. If not, leave the segment in STL — this is a permanent limitation, not a bug. Document the segment with a comment block so future readers understand why.

7.3 Loop (LOOP) and backward jumps

Replace LOOP with a counter-down + conditional jump pattern that the editor can render:

// STL LOOP:
L   MW 100        // loop counter
BACK: T   MW 100
... body ...
L   MW 100
LOOP BACK

// LAD-friendly:
// Segment 1: initialize
L   L#0
T   MD 100

// Segment 2: counter check & body
A   M 0.0         // run enable
JCN ENDLP
L   MD 100
L   L#1
+D
T   MD 100
... body ...
ENDLP: NOP 0

Use JC (jump if RLO = 1) to skip the body when the loop is complete, which LAD renders as a coil element.

7.4 Master Control Relay (MCR)

MCR is deprecated. Siemens recommends replacing every MCR(/)MCR block with an enable flag (A M 0.7) gating the affected assignments. This both converts cleanly to LAD and avoids the dependency on the MCR bit behavior on modern firmware.

8. Handling the Download Step

If the conversion changed the block's source representation, you must download to the running CPU:

  1. Establish an online connectionPLC > Display Accessible Nodes, then PLC > Connect to Target System. The yellow online indicator in the status bar must be lit.
  2. Stop the CPU if the block is used in OB1PLC > Operating Mode > Stop. For FBs/FCs called from cyclic OBs, a download in RUN is supported (S7-300/400 "Download in RUN") only if PLC > Download offers it; otherwise stop is mandatory.
  3. Drag the converted block from offline Blocks folder to the online CPU folder, or use PLC > Download from the editor.
  4. Confirm the dialog — STEP 7 will warn if the block interface changed. Click OK only after verifying no instance DBs reference the changed FB with mismatched IN/OUT/STAT signatures.
  5. Restart the CPU (cold restart OB100 or warm restart OB101) only if the modification requires re-initialization. A pure view change in STL↔LAD does not require restart — the compiled machine code is identical.
Critical: Converting STL to LAD does not alter the compiled code in the CPU. The MC7 code generated from either view is byte-identical for the same source. You do not need to download after a view toggle unless other changes were made.

9. Verification After Conversion

Confirm the conversion produced behaviorally identical code:

  1. Consistency Check: PLC > Consistency Check (or Edit > Check Block Consistency) reports unresolved labels, invalid jump targets, or interface mismatches.
  2. Cross-reference: Options > Reference Data > Display and search the converted block. Every operand in the original STL must appear exactly once in the cross-reference (or N times if the same tag was used N times in the original).
  3. Program Status test: Connect online, Debug > Monitor (or click the eyeglass icon). Cycle through the segments and observe RLO, STA, and the operand values. Power-flow lines on the ladder must light up identically to the equivalent STL evaluation.
  4. Stack / BR test: If the original STL relied on BR (binary result) bit for chaining calls (e.g., UC FB1 followed by A BR), manually insert --(SAVE) coils at the right place after conversion. LAD hides the BR-handling pattern in the compiler, so verifying with Monitor is essential.
  5. Force / watch tables: Open Insert > S7 Block > Variable Table (VAT), define the test I/Q/M tags, force inputs, and walk through every ladder rung with the table open.

10. Troubleshooting Common Conversion Errors

Symptom Likely Cause Fix
Display LAD does nothing; status bar stays at STL One or more segments contain non-convertible STL (Section 4) Identify offending segments, split them, retry
Block opens read-only — cannot toggle view Online connection active, no write access Disconnect: PLC > Disconnect
Conversion succeeds but the rung is empty / greyed out Original STL used NOP 0 or unconditional jump Replace with JC label rendering as a coil
LAD shows stray contact that never closes SET / CLR preceded the network Materialize as A M 0.0 / AN M 0.0 against a flag initialized in OB100
Cross-reference shows duplicate operands Original used multi-coil RLO assigns Apply the split-and-materialize pattern (Section 6)
Download fails with "Block exists with different interface" FB signature changed during manual rewrite Re-initialize instance DBs or recompile the FB before download
Status bar reports "Cannot convert network N" Specific STL line fails LAD rules Navigate to network N, isolate it, fix per Section 7 patterns

11. When to Leave the Block in STL

Forcing every block into LAD is not a goal. The IEEE/IEC 61131-3 standard explicitly endorses mixed-language projects: STL where indirect addressing is required, LAD where scan-flow clarity matters, SCL where structured data and loops dominate. The Siemens programming guideline Programming and Operating Manual SIMATIC S7-300 and the S7-400 reference manual both treat the three editors as interchangeable rendering modes for compatible subsets, not as targets.

Practical rule: if a block is documented, version-controlled, and uses STL for legitimate reasons (dynamic DB selection, pointer arithmetic, mid-scan arithmetic cascades), keep it in STL. Reserve LAD for relay-style discrete logic, safety circuits, and HMI-tagged I/O. Reserve SCL for math, array processing, and recipe handling.

12. Quick Reference: STL-to-LAD Compatibility Matrix

STL Instruction Group LAD-Convertible Workaround
Bit logic (A, AN, O, ON, X, XN, =, S, R, NOT, SET, CLR) Yes (except SET/CLR) Use A M 0.0 / AN M 0.0
Comparators (==I, <>I, >I, <I, ==R, etc.) Yes Box renders automatically
Timers (SP, SE, SD, SS, SF, FR, R) Yes Box renders automatically
Counters (CU, CD, S, R, FR) Yes Box renders automatically
Math (+, -, *, /, MOD) Yes Box renders automatically
Word logic (AW, OW, XOW, AD, OD) Yes Box renders automatically
Shift (SLW, SRW, SLD, SRD) Yes Box renders automatically
Jumps (JU, JC, JCN, JL, JUR, JP, JM, JN, JO) Yes (with label boxes) Add NOP 0 at label target
Block calls (CALL, UC, CC) Yes Box renders automatically
Pointer load (L P#x.x) No Inline static address or isolate segment
Address register (LAR1, TAR1, LAR2, TAR2, +AR1, +AR2) No Use indexed DB access if possible
Indirect memory access (L/T with [AR...] modifier) No Keep in STL
LOOP No Counter + jump pattern
MCR (MCRA, MCRD, MCR(), )MCR) Deprecated Replace with enable flag
Data block operations (OPN, CDB) No (with parameter) Use static DB number
TAK, PUSH, POP No Reorder logic
Accu swap/rotate (CAW, CAD) No Manually sequence L/T

FAQ

Why does the LAD view toggle not change anything when I click it?

The block stays in STL because at least one network contains instructions with no LAD primitive (pointer loads, address-register arithmetic, indirect memory access, LOOP, multi-coil assignments, or MCR). STEP 7 reverts the whole block rather than partially converting. Use Edit > Go To > Segment Number to scan each segment and split the offending ones per Section 6.

Can I convert STL pointer instructions like L P#10.0 to LAD?

Not directly. Pointer literals are address-arithmetic constants and have no graphical box equivalent. If the target address is static, replace the pointer pattern with a direct load (e.g., L MW 12 for an offset-2 pointer into MW10). If the address is dynamic, isolate the segment in its own FC, leave it in STL, and document it with a comment.

Will converting STL to LAD change the program executed by the CPU?

No. The MC7 machine code generated from STL and from LAD is byte-identical for the same source logic. The view toggle is a compiler-level render, not a re-translation. You only need to download to the CPU if you also restructured the logic (split segments, added flags, rewrote indirect access).

Is it possible to download a program that has both LAD and STL blocks?

Yes. STEP 7 supports mixed-language projects natively. The S7-300/S7-400 CPU stores all blocks as compiled MC7 regardless of source view. Open the offline Blocks container, select all modified blocks, and drag them to the online CPU folder, or use PLC > Download from the editor.

What is the difference between Display LAD and the LAD/FBD/STL dropdown in the toolbar?

Both invoke the same per-segment compiler. The dropdown simply exposes the same three View menu items (View > STL, View > LAD, View > FBD) in the toolbar. The conversion success criteria are identical — if any segment uses non-convertible STL, the entire block remains in its previous view.

Back to blog