S7 STL to LAD Conversion: Binary Constants and TEMP Variables

David Krause18 min read
S7-300SiemensTechnical Reference
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

S7 STL to LAD Conversion: Binary Constants and TEMP Variables

Statement List (STL) source generated from a STEP 7 V5.x project, particularly when downloaded from a SIMATIC S7-300/S7-400 CPU, often contains patterns that resist direct conversion back to Ladder (LAD) or Function Block Diagram (FBD). The two recurring problems engineers encounter are binary constants expressed as 2#... literals and Boolean operations that the FBD/LAD compiler has emitted as nested accumulator pushes (L of a 0 or 1 followed by a T into the L-stack). This reference decodes a representative STL fragment, explains why the value stored in #TEMP30 can appear to change between scans, and provides a working LAD equivalent for the parts the STEP 7 V5.6 converter can express.

Overview of STL, LAD, FBD, and SCL in STEP 7 V5.x

STEP 7 V5.x stores every code block (OB, FB, FC, DB) as compiled STL in the offline S7 program, regardless of which editor the engineer selected. The LAD or FBD view shown in the SIMATIC Manager Program Editor is reconstructed from the STL using a display algorithm that depends on block-relative symbol information written alongside the code. If that symbol information is missing, or if the STL uses operations that have no graphical representation, the editor shows the block as view = STL and refuses conversion to LAD/FBD.

Language German STEP 7 Editor Role
STL AWL (Anweisungsliste) Always available Source of truth; every block compiles to STL
LAD KOP (Kontaktplan) Graphic ladder Subset of STL; some STL lines have no graphical form
FBD FUP (Funktionsplan) Graphic function plan Subset of STL; same restrictions as LAD
SCL SCL PASCAL-style high-level Independent; compiles to STL after type check

Per the STEP 7 V5.5 Programming and Operating Manual, the View > LAD/FBD/STL menu in the SIMATIC Manager editor switches display only; it does not retranslate. Switching to LAD from STL works only when the STL contains the auxiliary commands BLD (display marker) and NOP 0 in the exact order that the LAD compiler originally emitted. The STEP 7 V5.6 release notes confirm that the LAD/FBD <-> STL converter is unchanged from V5.5. TIA Portal V14 and later use a different, more aggressive converter that accepts a larger subset of STL but still cannot represent arbitrary binary constants in a LAD contact.

Note: The LAD view is a presentation layer on top of compiled STL. If a third-party tool or hand-edited STL omits the BLD 256 and NOP 0 markers, STEP 7 displays the block as STL and disables the View > LAD option. The fix is to re-open the block in the Program Editor (not the external STL source editor) so the compiler regenerates the markers.

Source Code Analysis (STL, German Mnemonics)

The fragment under analysis is part of a Function Block (FB) called from OB1. The # prefix denotes block-local symbols. The code uses German mnemonics, so U = English A (AND), UN = AN (AND NOT). The data-access operators (DIX, PAW) are spelled the same in German and English.

Network header — constant load

L     2#1110001110000
T     #TEMP30
L     2#0
T     #TEMP31

The literal 2#1110001110000 is a 13-bit binary number = decimal 7280 = hex 0x1C70. It is loaded into ACCU1 and transferred to local word #TEMP30. ACCU1 is then overwritten with 2#0 and stored in #TEMP31. English mnemonics produce identical code; only the boolean operator mnemonics differ.

Boolean control logic

O(
U     DIX   58.0
UN    L      3.6
)
O     #IN18
=     L      9.0

The FBD-typical OR-AND-NOT pattern. The bracketed expression first checks instance-DB bit 58.0 ANDed with the NOT of local temporary L 3.6, then ORs the result with FB input #IN18, and finally writes the Boolean to L 9.0. In English: A( DIX 58.0 / AN L 3.6 ) / O #IN18 / = L 9.0.

U     DIX   58.0
U(
O     #IN18
O     DIX  58.1
)
=     L      9.3
=     L     10.1

Two parallel assignments: L 9.3 = (DIX 58.0) AND (#IN18 OR DIX 58.1), and the same Boolean also drives L 10.1. Dual assignment to multiple L-stack temporaries is an optimisation the STL compiler performs when the same rung output fans out to two contacts downstream; LAD represents it as a single coil with two parallel branches.

U     L      3.3
U     M      1.0
=     L      9.7
U     #IN4
=     L     11.0
=     L     11.2
U     #IN5
=     L     11.1
=     L     11.3

Four pure-Boolean rungs. L 3.3 AND M 1.0 → L 9.7; #IN4 → L 11.0 and L 11.2; #IN5 → L 11.1 and L 11.3.

Output stage

L     #TEMP30
T     PAW 556
L     #TEMP31
T     PAW 560

Read #TEMP30 into ACCU1 and write it to peripheral output word 556; then read #TEMP31 and write to PAW 560. The English mnemonic is PQW 556 and PQW 560. PAW/PQW writes bypass the process image and go directly to the backplane — necessary for high-speed analog output modules such as the 6ES7 332-5HB01-0AB0 or any SM 332 in direct-update mode.

STL to LAD Conversion Rules and Limitations

The STEP 7 V5.x LAD/FBD converter accepts STL only when the following conditions hold simultaneously:

  1. Every network starts with a BLD 256 (network marker) followed by NOP 0.
  2. Boolean operations use the bracket variants A(, O(, X( and their close ). The older U(/O( German forms still work but only when they originated from the original LAD compiler.
  3. No accumulator-only operations (L of a constant without a subsequent T) appear in the middle of a Boolean chain.
  4. No direct bit access to instance-DB combined with parentheses on the same line, as in U( O #IN18 O DIX 58.1 ), when the inner operands are themselves instance-DB bits — this is allowed but the converter can refuse and emit "The block cannot be displayed in LAD/FBD".
  5. The block has been opened in the Program Editor (not the STL source editor) at least once after compilation, so the display symbols were generated.

For the sample above, the converter will succeed on networks 4-7 (pure Boolean) and will fail on network 1 (binary constant L 2#...) and network 8 (T PAW 556 on a constant-loaded ACCU without an enclosing box). The standard engineering workaround is to split the block into two FBs: one FB that performs the Boolean logic in pure LAD, and a second FB or FC that pre-computes the constants and writes them to the PAWs.

Binary Constant Loading: 2# Syntax and Bit Order

STEP 7 STL accepts four numeric literal formats in L operands:

Format Example Value Bit width loaded
Decimal integer L 7280 7280 16 bit (INT) for word target, 32 bit (DINT) for double word target
Hexadecimal L W#16#1C70 0x1C70 = 7280 16 bit WORD
Binary L 2#1110001110000 0x1C70 = 7280 16 bit WORD; leading bits zero, no warning if fewer than 16 bits given
BCD L B#(0,0,1,12) or L C#123 BCD-coded 32 bit

The 2# prefix is documented in the STEP 7 STL Reference Manual. The bit string is right-aligned to bit 0 of the destination word: 2#1110001110000 written to #TEMP30 produces word 0x1C70 with bit pattern 0001 1100 0111 0000. LAD has no native graphical element for a constant 16-bit value; the equivalent is a MOVE box (MOVE_W) with the constant entered as decimal or hex on the box's IN pin.

Field note: A common typo in handwritten STL is to write L 2#11100011100000 (14 bits = 0x3870) instead of 13 bits. The compiler accepts any bit length up to 32 and silently zero-fills to the left. Always verify with the cross-reference (Ctrl+F7) that the loaded value matches the intended hex.

Instance DB Access with DIX / DIW / DIB / DID

DIX is a German/English-shared data type operator that means "instance-DB bit access." The X stands for "bit," so DIX 58.0 reads bit 0 of byte 58 of the currently opened instance DB. The full operator family is:

Operator Type Address Notes
DIB Byte 0..65535 Loads into ACCU1 bits 0..7, bits 8..31 cleared
DIW Word 0..65534 (even) Loads into ACCU1 bits 0..15
DID Double word 0..65532 (multiple of 4) Loads into ACCU1 bits 0..31
DIX Bit byte.bit, bit 0..7 Used in U/O/= only, not in L

The instance DB is opened by the CPU at the call of the FB and remains open until the FB exits. Inside a multi-instance FB (an FB that uses another FB as a static variable) the inner FB's instance data is prefixed by the outer FB's instance DB number and accessed with the same DIX syntax. The S7-300 Programmable Controller System Manual contains the full addressing rules for instance DBs in Chapter 6.

In the sample, DIX 58.0 and DIX 58.1 are almost certainly mapped to a static BOOL structure within the FB's instance DB. The two bytes from 58 onward are not part of the CPU's process image — they are pure DB memory and consume 8 bytes of instance-DB work memory per instance.

PAW / PQW Peripheral Output Word Addressing

Peripheral addresses are written by the CPU directly to the backplane without updating the process image output table (PIQ). For the S7-300 family, analog output modules occupy the PAW/PQW range starting at slot-dependent offsets:

Slot Default PQW base (SM 332) Typical module Channels
4 PQW 512..527 6ES7 332-5HB01-0AB0 / 332-5HD01 2 AO / 4 AO, ±10 V or 4..20 mA
5 PQW 528..543 6ES7 332-5HB01-0AB0 2 AO
6 PQW 544..559 6ES7 332-5HD01-0AB0 4 AO
7 PQW 560..575 6ES7 332-5HD01-0AB0 4 AO
8 PQW 576..591 6ES7 332-5HF00-0AB0 8 AO

So PAW 556 is the third output channel of a 4-channel SM 332 in slot 6 (channels 0-3 mapped to PQW 544, 546, 548, 550 in word-stepped mode; in byte-stepped mode the mapping is 544, 545, 546, 547; the exact layout depends on the hardware configuration in HW Config). PAW 560 is the first channel of the slot-7 module. Use the HW Config Addresses tab to confirm the exact PQW map for your rack.

Note: Writing to a PQW from STL uses T PAW x; the load is implicit because T writes the entire ACCU1 to the peripheral area. There is no equivalent LAD coil for a peripheral word; LAD forces you to first load the value into a temporary and then T PQW x in a separate network, or to use a MOVE box wired to a peripheral output via the system function SFC 58 (WR_REC) or by typing the PQW address in the box's OUT field. The SIMATIC Manager LAD editor accepts PQW on the OUT of a MOVE box from SP5 onward.

TEMP Variable Lifecycle and the "Constant Changes" Question

This is the central question of the source thread. The literal 2#1110001110000 is loaded into #TEMP30 in the first network. The output stage of the same block writes #TEMP30 to PAW 556. The question is whether #TEMP30 can be modified by anything that runs after the first network but before the output stage.

The answer depends entirely on the type of the local variable declared in the FB's interface:

Variable type Storage location Initialised by CPU? Persists across scans? Risk of overwrite
TEMP L stack (local stack frame) No (undefined at FB entry) No — same stack slot reused next call High if used before assignment
STAT Instance DB No (only at first cold restart of the DB) Yes — value kept between scans Low unless explicitly overwritten
IN/OUT/IN_OUT Instance DB No (caller initialises) Yes (via the caller) Depends on caller

Per the STEP 7 STL Reference Manual, Section 4.3, TEMP variables are not initialised by the CPU and are undefined on entry to the FB. They are guaranteed to be intact only between the L that loads them and the next L that overwrites ACCU1. Inside one OB1 cycle, if no other code between networks 1 and 8 modifies the L-stack slot occupied by #TEMP30, the value will still be 0x1C70 at network 8. The following situations can change the value:

  1. Multi-instance nesting: If the host FB is itself a multi-instance (called as a static of another FB), the compiler may reuse the L-stack slot for a different TEMP of the calling FB. The first network's L 2#1110001110000 / T #TEMP30 is the only load of that slot in this FB, so it is safe within one scan, but a watch table will show the value as 0x0000 if the FB is not currently executing.
  2. Watch table force: A value forced in the watch table on DBx.DBWy corresponding to a STAT that shares the same memory region can clobber the L-stack if the compiler placed the TEMP in a STAT-shadow area (rare, but possible with optimised block compilation in V5.4 SP5+).
  3. Indirect addressing: If any code path uses LAR1 / TAR to point at the L-stack area, an accidental T DIX [AR1,P#0.0] can overwrite. Inspect with Reference Data > Program Structure.
  4. Compiler quirks on uninitialised L-stack reads: The = L 9.0 and = L 10.1 lines read from L 9.0 and write to L 10.1, but if the symbol L 10.1 is shared with another network that runs earlier in the same scan, the second network will see whatever the first network wrote. Always inspect the FB's compiled interface ("Interface" view) to confirm slot allocation.

The pragmatic answer: within one scan, #TEMP30 remains the constant as long as no other network re-loads and re-transfers that slot. Between scans, TEMP memory is undefined. If the application needs the constant to survive across scans (e.g., as a default setpoint), promote it to a STAT of type WORD with a one-time initial value, or to a CONST in the instance DB.

Recommended fix: promote the constant to STAT

// In the FB interface (STEP 7 V5.x / TIA Portal both):
VAR
   iSetpoint1   : WORD := W#16#1C70;   // initialised once, kept between scans
   iSetpoint2   : WORD := W#16#0000;
END_VAR

// In STL:
L     W#16#1C70
T     #iSetpoint1
L     W#16#0
T     #iSetpoint2

// At output:
L     #iSetpoint1
T     PQW 556
L     #iSetpoint2
T     PQW 560

Manual LAD Conversion Attempt

The Boolean core of the sample translates directly. The following LAD networks (in STEP 7 V5.6 or TIA Portal V13+) reproduce networks 2-7 of the STL fragment:

Network 1 — Output to PQW 556 (constant setpoint)
      MOVE
EN   ENO
#iSetpoint1  --->  PQW556

Network 2 — Output to PQW 560 (default 0)
      MOVE
EN   ENO
#iSetpoint2  --->  PQW560

Network 3 — OR-AND-NOT (DIX 58.0 AND NOT L 3.6) OR #IN18 → L 9.0
   |--[ DIX58.0 ]--[/ L3.6 ]--|
   |                          |
   |--[ #IN18 ]---------------|
   |                          |
   +----------( L9.0 )--------+

Network 4 — DIX 58.0 AND (#IN18 OR DIX 58.1) → L 9.3 and L 10.1
   |--[ DIX58.0 ]--|--[ #IN18 ]--|
   |               |             |
   |               |--[ DIX58.1]--|
   |               |             |
   +---------------( L9.3 )------+
   |               
   +---------------( L10.1 )-----+

Network 5 — L 3.3 AND M 1.0 → L 9.7
   |--[ L3.3 ]--[ M1.0 ]--( L9.7 )--|

Network 6 — #IN4 → L 11.0 and L 11.2
   |--[ #IN4 ]--|--( L11.0 )--|
   |            +--( L11.2 )--+

Network 7 — #IN5 → L 11.1 and L 11.3
   |--[ #IN5 ]--|--( L11.1 )--|
   |            +--( L11.3 )--+

Networks 1 and 2 are unreachable from a pure LAD conversion when the input is the binary literal 2#... because the LAD contact grammar has no 16-bit constant source symbol. Use the Constant field of the MOVE box's IN pin and enter the value as decimal 7280 or hex W#16#1C70.

TIA Portal Differences

In TIA Portal V14 SP1 and later, the STL ↔ LAD converter is significantly improved. Three changes relevant to this case:

  • The MOVE box accepts the constant directly in hex / decimal / binary notation. The binary literal is shown as a tooltip but stored internally as the corresponding 16-bit WORD.
  • The Optimised block access option (FB properties) makes the compiler allocate TEMP variables into a structured local stack that survives across scans within the same priority class. This makes the "TEMP changes between scans" behaviour disappear for optimised FBs, but also breaks the ability to inspect a TEMP from a watch table when the FB is not running.
  • Instance-DB bit access "DB_name".Static_Var is preferred over DIX 58.0. TIA Portal will show a deprecation warning if the STL form is used.
Migration tip: When porting an S7-300 FB written in STL to an S7-1500 in TIA Portal, enable Optimised block access, change DIX 58.0 to a named static Bool (e.g., i_bEnable1), and promote the binary constant to a Tag in the PLC tag table or a STAT in the instance DB. The TIA Portal compiler will then accept the block for full LAD view.

Best Practices for STL/LAD Portability

  1. Use named STAT variables instead of anonymous L-stack temporaries (L 9.0). Named variables survive the LAD ↔ STL round trip cleanly.
  2. Initialise every TEMP that is read before it is written, even if the value is not yet defined. The SCL editor does this automatically; the STL editor does not.
  3. Prefer SET / CLR instructions to set Boolean results, or use L TRUE / L FALSE with T #BoolVar for clarity.
  4. Avoid the U( O x O y ) pattern when a single contact can be expressed in LAD — it compiles to a parallel branch with two contacts and a single coil, which is what LAD expects.
  5. Always place the constant-loading network first in the FB and the PAW/PQW output network last. This makes the data flow visible in both STL and LAD views.
  6. Document the binary constant in the FB header as both binary and hex (// 2#1110001110000 = W#16#1C70 = 7280 dec) so a future reader can verify the bit pattern.
  7. For IEC 61131-3 conformance, prefer SCL for arithmetic and string handling; STL for bit-level I/O and absolute addressing; LAD for discrete logic that maintenance technicians must read.

Verification Procedure

After converting the STL to LAD (or vice versa), validate the block with these steps in STEP 7 V5.6 or TIA Portal:

  1. Open the block in the Program Editor. The status bar must read "Block is consistent".
  2. PLC > Download the block to the CPU. The CPU must accept the download without an SF LED.
  3. Open the watch table, add the instance DB and the two PQW addresses, and run the block in single-scan mode (PLC > Operating Mode > Single Scan). Confirm that:
    • #iSetpoint1 or the equivalent TEMP shows the expected constant.
    • PQW556 = 7280 dec and PQW560 = 0.
    • The Boolean output bits (L 9.0, L 9.3, etc.) follow the logic table derived from the inputs.
  4. Force each of the two instance-DB bits (DIX 58.0, DIX 58.1) ON and OFF and verify the dependent Boolean outputs toggle.
  5. Stop the CPU, power-cycle, and confirm that the STAT values are retained while TEMP values reset.
  6. Use PLC > Monitor/Modify with trigger condition "Cycle start, OB1" to catch the TEMP value mid-execution and confirm W#16#1C70 is present at the moment the output stage runs.

Troubleshooting Matrix

Symptom Probable Cause Fix
"Block cannot be displayed in LAD/FBD" STL was hand-edited without BLD/NOP markers Re-open in STL view, let STEP 7 insert BLD 256 / NOP 0, then switch view
Constant 2#... shown as 0 in watch table FB not currently executing, TEMP is undefined Convert to STAT, or use single-scan to catch the value mid-cycle
PQW writes do not appear at the analog output Wrong slot, wrong channel, or output not enabled in HW Config Verify with HW Config > Addresses tab; check the analog module's "Enable" parameter
Boolean outputs are inverted Mixing of German U and English A mnemonics in the same block Use Options > Customize > Language to set mnemonics globally and recompile
Compiler SF: "T PAW 556 — operand not allowed" Attempted to write a PQW from a network where the source was a constant without an enclosing box Use a MOVE box; the LAD compiler will then emit T PQW 556
SF LED after download, diagnostic buffer: "Area length error writing PQW 556" Slot 6 has no analog output module, or module is configured as input Re-run HW Config, correct the module type, recompile and re-download HW
CPU STOP with "OB not loaded" after editing TEMP interface OB1 reference to FB instance DB was not refreshed PLC > Compile and Download Objects; verify instance DB length matches new TEMP count
Online value of TEMP differs from offline STL source Optimised block access in TIA Portal stores TEMP in symbolic area Disable optimised block access, or use a named STAT in place of the TEMP

FAQ

Why can't STEP 7 V5.6 convert every STL block to LAD?

The LAD view is reconstructed from the compiled STL using display symbols (BLD / NOP 0) inserted by the original compiler. STL written or edited by hand, downloaded from a third-party source, or containing L 2#... binary literals often lacks those markers, and the LAD converter refuses to display it. Split the block into smaller FBs without these patterns and the converter succeeds.

Can the value 2#1110001110000 stored in a TEMP variable change during execution?

Within a single scan, no — as long as no other network re-loads and re-transfers the same L-stack slot. Between scans, yes — TEMP memory is undefined at FB entry. Promote the value to a STAT with an initial value, or to a PLC tag, if the application needs the constant to persist across OB1 cycles.

What is the difference between PAW and PQW in Siemens documentation?

PAW is the German mnemonic (Peripherie-Ausgangswort) and PQW is the English mnemonic (Peripheral Output Word). They refer to the same physical address; STEP 7 displays whichever matches the installed language pack. See the S7-300 System Manual Chapter 4 for the full I/O address map.

How do I access an instance-DB bit in TIA Portal LAD?

Use a normally-open or normally-closed contact with the fully qualified instance-DB path, e.g., "Motor_FB_iDB".i_bEnable. The old DIX 58.0 form still compiles but generates a deprecation warning and cannot be displayed graphically. Renaming the bit to a meaningful tag is the recommended migration path.

Why does the MOVE box accept the constant in hex but not in binary notation in some STEP 7 versions?

STEP 7 V5.5 SP1 and earlier accept only decimal and hex on the MOVE box's IN pin. Binary literals (2#...) are accepted in STL only. TIA Portal V14 and later accept binary on the constant input of contacts, coils, and MOVE boxes. When in doubt, convert the binary literal to hex (2#1110001110000 = W#16#1C70) and enter the hex value.

Back to blog