Overview
SIMATIC STL (Statement List) is the IEC 61131-3 textual programming language still shipped with every S7-300, S7-400, and S7-1500 CPU. Although TIA Portal promotes ladder logic (LAD), function block diagram (FBD), and structured control language (SCL) as the first-class citizens, STL remains the lingua franca for migrating legacy STEP 7 V5 projects, debugging low-level scan-order issues, and writing tight bit-manipulation routines where ladder contacts would obscure intent. Two questions dominate every introductory STL thread on the Siemens Industry Online Support portal:
- What do the single letters
L,T, andAactually do in a snippet of STL code? - Why does Siemens expose two address types for the same physical input — for example
IB 4versusPIB 4?
This reference answers both at a level appropriate for a commissioning engineer who can read ladder logic but has not written STL before. It documents the meaning of L, T, and A, the difference between the process input image (PII) and the peripheral area, the canonical addressing syntax in TIA Portal V14 and later, and the boundary cases that make peripheral access a sharp tool rather than a default approach. Field-proven caveats — including why writing to inputs (T IB) is a recognised but discouraged pattern — are spelled out in the closing section.
The reference pattern that motivates this article is taken from the official Siemens support article "Where and when do you need peripheral addressing?", which uses the three-letter stub:
L PIB 204
T IB 4
A ...
Each line corresponds to one of the STL fundamentals; subsequent sections decode the snippet, expand each instruction into its alternatives, and show how to verify it under TIA Portal’s online monitor.
Prerequisites
- TIA Portal V14 SP1 or later installed, including the optional "STEP 7 Professional" package that ships the STL editor (LAD/FBD/STL buttons on the toolbar).
- A project containing at least one S7-1500 CPU, S7-300 CPU, or S7-400 CPU. S7-1500 is preferred because STL under TIA Portal V14 is first-class; S7-300/400 STL imports from STEP 7 V5 project archives (
.s7por converted.ap14) and recompiles cleanly. - Familiarity with boolean logic operations (AND, OR, NOT) and the idea of a binary contact (NO / NC) in ladder logic.
- Access to the Siemens Industry Online Support portal for cross-reference against the canonical FAQ 18325417 on peripheral addressing and FAQ 109736536 on shared-device / MSI / MSO configuration.
STL Mnemonic Meanings: L, T, A
In STL, every line is an instruction that operates on one of two 32-bit accumulators (ACCU 1 and ACCU 2) or on the binary result of logic operation (RLO) flag. The three letters from the source snippet decode as follows:
| Letter | Mnemonic | Operand type | Effect |
|---|---|---|---|
L |
Load | Bit, byte, word, double word, constant | Reads the operand and places the value into ACCU 1, shifting the previous ACCU 1 into ACCU 2. |
T |
Transfer | Bit, byte, word, double word | Copies the current content of ACCU 1 to the addressed operand without altering any accumulator. |
A |
AND, scan for "1" | Bit (boolean) only | Computes a logical AND between the addressed bit and the current RLO. The bit operand itself is read; the result overwrites the RLO. |
Three observations follow directly from the table:
-
LandTare scalar, addressing bytes, words, or double words indiscriminately.Ais restricted to a single bit operand (or its negated formAN). -
Tnever alters ACCU 1 or ACCU 2; it is purely a one-way memory write. -
Adoes not load a value into ACCU 1 — it only updates the RLO. To read a bit value into ACCU 1 you must useLwith a byte/word/double-word operand (for exampleL IB 4places the byte at process-image address 4 into ACCU 1, and you can then manipulate the bit of interest withA,O, orXon a derived mask).
The canonical reference pattern from the source can therefore be parsed mechanically:
L PIB 204 // Load Peripheral Input Byte at byte address 204 into ACCU 1
T IB 4 // Transfer ACCU 1 to process-image Input Byte 4
A M 10.0 // AND-test bit M 10.0 (RLO := RLO AND M 10.0)
The first line reads the current physical state of a remote I/O byte directly from the backplane or PROFINET slot, bypassing the OB1 process image. The second line deposits that byte into the local process image at IB 4, replacing whatever the cyclic OB1 update placed there. From that point forward, every A I 4.x, L IW 4, or comparison against IB 4 in the same cycle sees the freshly copied value rather than the cycle-stale image. The third line reads from bit memory — not from process I/O — to decide the next branch.
Why the mnemonic A instead of AND
Siemens STL was designed in the 1980s when every CPU instruction needed to fit into a tight instruction word. Dropping the trailing "ND" shrank the opcode and the parser surface without sacrificing semantic clarity. The German mnemonic convention uses U (from UND) and O (from ODER) for AND / OR. International projects switch mnemonics under “Options > Settings > International” in TIA Portal (and under “Tools > Options > Customise > Mnemonics” in STEP 7 V5). The semantic meaning of L, T, and A is identical in either locale.
Process Image vs. Peripheral I/O Access
Every S7 CPU maintains two views of the same physical inputs and outputs. The table below maps the address prefix used in STL onto the CPU’s view of the same byte.
| View | Mnemonic prefix | Updated | Scope | Speed / determinism |
|---|---|---|---|---|
| Process Image Input (PII) |
I / E (e.g. IB 4, IW 4, ID 4) |
Beginning of OB1 (read from physical modules into the PII) | Cyclic, snapshotted, all user code sees a consistent image | Faster access (memory read), one-shot consistent |
| Process Image Output (PIQ) |
Q / A (e.g. QB 4, QW 4) |
End of OB1 (written from PIQ to physical modules) | Buffered through the cycle | Faster write, no bus traffic mid-cycle |
| Peripheral Input |
PI (e.g. PIB 204, PIW 204, PID 204) |
Never buffered | Direct backplane / PROFINET read at the moment of the STL instruction | Slower per access, can return inconsistent values across a multi-byte read if the bus re-cycles |
| Peripheral Output |
PQ (e.g. PQB 204, PQW 204, PQD 204) |
Never buffered | Direct write at the moment of the STL instruction | Slower per access, can interleave with later reads |
The two views are illustrated below.
When peripheral access is the right choice
- The I/O area exceeds the configured process image size for that CPU (for example, a remote PROFINET station with addresses 0…32767 where only 0…1023 are mapped into the PII).
- The application must read fresh data from a fast-changing signal — such as a high-speed counter or a motion encoder — within the same OB1 cycle that produced the request, rather than waiting for the next cycle boundary.
- The application is time-deterministic relative to a hardware event and cannot tolerate the jitter caused by PII snapshotting.
- The application needs sample-and-publish behaviour: it captures a peripheral input as a snapshot, writes it back into its own process image area, and downstream logic operates on the stable value for the rest of the cycle.
When peripheral access is the wrong choice
- Multiple OBs read the same input — every direct read returns a different physical value, producing inconsistent states within the cycle.
- Outputs are written to from multiple interrupt OBs — direct peripheral writes do not merge cleanly with the PIQ buffer.
- The code is intended to be portable to other SIMATIC platforms; sticking to the process image keeps the addressing pure and reusable.
- The application can tolerate up to one OB1 cycle of latency on that signal.
L PIB … / T IB … / A as a fallback for refreshing the process image outside the normal OB1 update — useful in special libraries and time-critical blocks, but explicitly not recommended as a default programming style. Read the linked article for the conditions that justify the pattern.STL Operand Areas and Data Widths
STL addresses operands with a letter (or letter pair) for the memory area, an optional data-width suffix (B byte, W word, D double word), and the integer address. A trailing dot followed by a bit number addresses a single bit. The supported areas are:
| Area | Mnemonic | Bit / Byte / Word / DWord specifiers | Typical use |
|---|---|---|---|
| Process-input |
I / E
|
I 4.0 · IB 4 · IW 4 · ID 4
|
Standard digital and analog inputs |
| Process-output |
Q / A
|
Q 4.0 · QB 4 · QW 4 · QD 4
|
Standard digital and analog outputs |
| Bit memory (flags) | M |
M 10.0 · MB 10 · MW 10 · MD 10
|
Scratch, intermediate results, retentive flags |
| Data block | DB |
DBX 4.0 · DBB 4 · DBW 4 · DBD 4
|
Structured data; opened with OPN DB in older STL before access (S7-1500 allows the qualified DB prefix directly) |
| Local (stack) data | L |
L 0.0 · LB 0 · LW 0 · LD 0
|
Temporary variables inside FC, FB, and OB; lost on block exit |
| Peripheral input | PI |
PIB 4 · PIW 4 · PID 4
|
Direct read bypassing PII |
| Peripheral output | PQ |
PQB 4 · PQW 4 · PQD 4
|
Direct write bypassing PIQ |
| Counters | C |
C 0 … C Z
|
Counter word (BCD or binary) |
| Timers | T |
T 0 … T Z
|
Timer word |
Address-byte alignment matters. STL never enforces it for you — the T IB 4 line from the source is valid even though semantically it overwrites a previously buffered input byte. If you substitute a word transfer, address increments by two (for example T IW 4 writes bytes 4 and 5). A double-word transfer increments by four. Where the hardware requires word alignment (for example, analog channels mapped to peripheral words above byte 0), the configurator in TIA Portal enforces the alignment automatically; in raw STL imports, verify that the chosen address does not split a multi-byte channel.
Mixed-size transfers
Loading a 16-bit PIW into the 32-bit ACCU 1 leaves the upper 16 bits zero-extended. Loading a 32-bit PID uses all 32 bits. Transferring a 32-bit MD to a 16-bit MW truncates — only the low 16 bits land in the destination. STL silently performs these truncations; nothing is flagged at compile time, so a wrong transfer width is a common source of “value looks wrong but compiles fine” bugs.
TIA Portal STL Configuration Walk-Through
This procedure produces the exact L / T / A pattern from the source on an S7-1500 CPU using TIA Portal V14.
Step 1 — Enable STL on a code block
- In the project tree, right-click “Program blocks” and choose “Add new block > Function block” (or open an existing FB).
- Open the block, then choose “View > STL” from the menu (or click the STL button on the toolbar).
- If the menu item is greyed out, open the project properties and select “STEP 7 Professional” as the programming package; reinstall if necessary. TIA Portal “Basic” does not include STL.
- Verify the block’s general properties show “LAD/FBD/STL” enabled for the chosen language combination (LAD/FBD, FBD/STL, or STL only).
Step 2 — Declare the working variables
Declare one input at the start of the FB so the L instruction has a typed operand. The block interface below uses symbolic names; TIA Portal resolves them to absolute addresses during compilation.
| Section | Name | Data type | Initial value | Comment |
|---|---|---|---|---|
| Input | remoteByte | Byte | 16#00 | Peripheral byte read from the remote station at address 204 |
| Input | bitMask | Bool | false | Single-bit selector (1 = use mirrored value, 0 = use raw PIB) |
| Output | checkBit | Bool | false | Result of the A M 10.0 test |
| Static | mirror | Byte | 16#00 | Mirror dropped into local MB 100 for stable bit testing |
Step 3 — Add the STL source segment
Inside Network 1 of the FB, paste the following STL code. Comments after // explain each line.
// Network 1: refresh local mirror from peripheral input 204
L PIB 204 // ACCU 1 := remote input byte at slot 204
T MB 100 // MB 100 mirror for bit-level testing
// Network 2: bit test and branch decision
A M 100.0 // RLO := RLO AND M 100.0 (first-check load)
JC _BitSet // Jump if RLO = 1
JU _BitClr // Otherwise jump to clear
_BitSet:
SET // Make RLO = 1 explicitly
S #checkBit
JU _End
_BitClr:
CLR // Make RLO = 0 explicitly
R #checkBit
_End: NOP 0
For an even tighter pattern that mirrors the source snippet exactly, drop the staging MB write and replace T MB 100 with T IB 4 — but only if you are inside a Siemens library that documents the pattern as intentional. Otherwise the safer choice is T MB 100 as shown above, because writing to a process-image input byte is a non-default operation that confuses the OB1 read-back path during the next cycle.
Step 4 — Compile, download, and go online
- Click “Compile > Software (rebuild all)”. Resolve any syntax errors; TIA Portal flags spurious
Aoperations on byte operands with a “Bit operand expected” message and flagsAon non-boolean tag types with “Operand type not permitted”. - Click “Download to device > Software and hardware configuration”. Confirm that the CPU is in STOP for the initial download, or that TIA Portal negotiated a “RUN” hot reload for the target firmware. S7-1500 supports online block changes from RUN; S7-300/400 require a STOP download for most STL block changes.
- Right-click the block and choose “Monitor / modify > Monitor (STL)”. The window now shows the current ACCU 1, ACCU 2, RLO, BR, OV, OS, CC 0, and CC 1 status bits line by line as each statement executes.
- To force a value (for example, to simulate a stuck input), open “Force table” via “Watch & force tables” and insert a forced input. Verify the operand type matches; STL expects bit operands on
Aand integer operands onL.
Verification and Online Diagnostics
The STL monitor view in TIA Portal exposes the runtime state line by line. The colour map and meaning are:
| Visual cue | Means | Action |
|---|---|---|
| Green background behind an instruction | Instruction was scanned in the current cycle | None — informational |
| Yellow background on an operand | Operand value changed since the previous cycle | Confirm the change is expected; investigate if not |
| Red background on a transfer | Force value is active or a write error occurred | Check the Force table and clear any unwanted forces |
| RLO column shows 1 / 0 | Last bit-test result | Use to validate the A decision path |
| Status word BR, OV, OS | Binary result, overflow, overflow stored | Inspect after every arithmetic block to detect lost precision |
| CC 0 / CC 1 pair | Condition code from the last integer or real operation | Verify == 0, > 0, or < 0 comparisons |
For cyclic verification, drop a counter into a test block: every A M 100.0 that returns 1 must increment the counter by exactly one per OB1 cycle. If the increment is random, the input is changing mid-cycle — switch from peripheral access back to the process image to confirm whether the bug is real-time noise or programming jitter.
Troubleshooting matrix
| Symptom | Likely cause | Recommended fix |
|---|---|---|
| Compiler error: “Bit operand expected” |
A applied to byte, word, or constant operand |
Replace A IB 4 with A I 4.0; use L IB 4 if a byte value is needed |
| Compiler warning: “Same scan condition” | Adjacent A / O instructions produce the same RLO update |
Reorder or remove the redundant instruction |
| Output toggles every OB1 cycle | Direct peripheral access returns a different value than the next read | Bind the result to a process-image bit (or MB 100 mirror) and use that bit for the rest of the cycle |
| Fatal SF (system fault) shortly after download |
T IB x outside a documented library — inputs are read-only on most hardware and the SF comes from a downstream SFB call failing |
Replace T IB x with T MB x (scratch) or T QB x (driving an output) depending on intent |
| CPU STOP with “OB not loaded” after firmware update | Firmware no longer supports some old STL opcode | Recompile under the target firmware’s compiler; check STEP 7 release notes for removed opcodes |
| “Symbol not found” at compile time | Symbolic name not exported from the symbol table | Open the PLC symbol table, add the tag, or switch to absolute addressing (IB 4 instead of "myInput") |
| PLC goes STOP with “Cycle time exceeded” | A long-running loop inside an STL block; L PIB calls in a tight loop burn bus cycles |
Move the loop out of the cyclic OB into an interrupt OB, or batch reads with L PID / L PIW
|
A on a BOOL tag never produces a 1 |
The BOOL was overwritten by a previous T to the same address; the tag is shared with an FB instance that scrubs it |
Inspect the watch table for hidden writes; rename the tag if aliasing is suspected |
Bit Testing with the A Instruction
The A mnemonic does far more than “load a bit”. It is the foundation of every STL boolean network. The full family of bit-test instructions is:
| Mnemonic | Logical operation | RLO after scan |
|---|---|---|
A |
AND, scan for “1” | RLO := RLO AND operand_bit |
AN |
AND-NOT, scan for “0” | RLO := RLO AND NOT operand_bit |
O |
OR, scan for “1” | RLO := RLO OR operand_bit |
ON |
OR-NOT, scan for “0” | RLO := RLO OR NOT operand_bit |
X |
Exclusive OR, scan for “1” | RLO := RLO XOR operand_bit |
XN |
Exclusive OR-NOT, scan for “0” | RLO := RLO XOR NOT operand_bit |
= |
Assign (write RLO to operand) | RLO unchanged, operand := RLO |
A complete STL network equivalent to a ladder rung with two NO contacts in series and an output coil looks like this:
A I 0.0 // First contact - first check loads I 0.0 into RLO
A I 0.1 // Second contact - RLO := RLO AND I 0.1
= Q 8.0 // Drive output Q 8.0 if both inputs are "1"
A rung with two NO contacts in parallel:
O I 0.0 // First parallel - first check loads I 0.0 into RLO
O I 0.1 // Second parallel - RLO := RLO OR I 0.1
= Q 8.0
A mixed series / parallel rung with a final NC contact:
A I 0.0
A ( // Open parenthesis for the OR chain
O I 0.1
O I 0.2
) // Close parenthesis restores the host AND chain
AN M 5.3 // NC contact on flag M 5.3
= Q 8.0
First-check / RLO edge
The first A, O, X instruction in a network does not AND/OR/XOR anything — it simply loads the state of the addressed bit into the RLO. From the second instruction onward, the operation is RLO := RLO <op> operand_bit. Treat the first line of every network as “first check” and every subsequent line as an accumulation. To override that initialisation, use:
-
SET— set RLO = 1 unconditionally -
CLR— set RLO = 0 unconditionally -
NOT— invert the current RLO -
SAVE— copy the current RLO into the BR (binary result) bit for use by other blocks
Edge-detected bit tests (FP and FN)
Beyond the combinational A, STL exposes FP (rising-edge detect) and FN (falling-edge detect). Internally FP maintains a per-operand edge bit; the RLO is set to 1 only when the current operand state is “1” and the previous scan was “0”. This is the STL equivalent of a ladder P-contact.
A I 0.0
FP M 100.0 // M 100.0 must be a non-retain flag reserved for the edge bit
= M 50.0 // Edge flag ready for further use
PROFINET and Multiple Shared I/O Context
The same L / T / A building blocks become meaningful in a multi-controller PROFINET topology when one of the controllers wants to read inputs owned by another controller. The IO Device publishes those inputs as “shared inputs” under the Multiple Shared Input (MSI) feature, and consuming controllers reach them via the same peripheral-or-process-image access pattern.
| Concept | Mnemonic / variable | Description |
|---|---|---|
| IO Controller | Master role | The CPU that owns the PROFIsafe / PROFINET schedule |
| IO Device | Slave role | The remote I/O station, configured as a shared device if multiple controllers read it |
| MSI (Multiple Shared Input) | Shared-input slots | Inputs visible to multiple controllers, slot ranges defined at design time |
| MSO (Multiple Shared Output) | Slot-based ownership | Outputs owned by exactly one controller at a time; ownership is exclusive |
| Shared device | Per-controller projection | The IO Device presents a different projection to each assigned controller |
For the canonical “read inputs from a second S7-1500 controller across PROFINET” workflow, see Siemens FAQ 109736536 on shared-device and MSI / MSO configuration in TIA Portal. The configuration property “Copy from controller” lights up only when the IO Device has been set to operate in shared-device mode with at least two controllers assigned and an MSI slot range defined; if the option is greyed out, revisit the IO-Device assignment table first.
In STL, the consumer-side logic is unchanged:
L PIB 204 // Shared input byte from the partner controller
T MB 110 // Local mirror in bit memory
A M 110.3 // Test a single bit of the shared input
= Q 12.7 // Drive a local output
Solid arrows denote the controller that owns a particular slot; dashed arrows denote MSI-consumer links that read the same data without owning it. Each consuming controller downloads its projection of the shared device, then accesses the corresponding slot addresses locally — either via the process image or, for time-critical work, via L PIB as above.
Common Pitfalls and Field-Proven Caveats
-
Writing to inputs is rarely meaningful. Inputs are sourced by the field wiring. A
T IB xonly makes sense when the destinationIBis mirrored back through a documented library function — never blanket. UseT QB xif you intend to drive an output, orT MB xif you want scratch memory. -
Mixing bit and byte operators in one statement chain. Always use
A(orO,X) for single bits andL/Tfor bytes, words, and double words. The compiler acceptsL IB 4followed byA M 4.0, but notA IB 4— a byte operand is not a bit operand. -
Byte alignment of word and double-word transfers.
L PIW 5on an odd peripheral address overlaps bytes 5 and 6 on most backplane buses; either reserve even addresses or move the whole block to a clean offset. -
Cycle time of repeated peripheral reads. Every
L PIBre-reads the physical device. A loop that scans 32 peripheral bytes burns 32 bus cycles, while a singleL PID xplus a 4-byteT MD xconsumes the same number of bytes with one bus transaction. - PLC migration between S7 platforms. STL compiles to the same mnemonics across S7-300, S7-400, and S7-1500, but the environment differs. Re-import V5.x STL blocks into a TIA Portal V14+ project and recompile before field use; legacy STL opcodes (some early correlator / sequence instructions) are deprecated and trigger warnings on S7-1500.
-
Real-number comparison after L. Loading a double-word real into ACCU 1 and immediately scanning with
Areads only the low bit of the real’s binary image. Always use a typed comparison (L,L,>R,<R, etc.) for floating-point decisions. -
Re-entrancy of FB local data.
L L 0.0in an FB references the instance’s static buffer, not the DB opened globally withOPN DB. Make theL/Toperand unambiguous by qualifying the variable name with the instance DB number on multi-instance FBs. - Symbol-table vs absolute address. When the project imports an external STL source that uses absolute addresses, TIA Portal will not warn you on compile. Always inspect the generated compiler listing (“Project tree > Program blocks > Compile output”) to confirm the resolver mapped every absolute to the right symbolic tag.
-
Force / unforce after the force table is closed. A forced bit continues to read “1” against
Aeven after the table is closed. Clear forces explicitly with “Force table > Stop forcing” before relying on the live PLC state for diagnostics. - STL and security. STL is a textual language, which makes it harder for a casual operator to “see” what the block does. Treat STL as security-sensitive: compile with knowledge protection enabled (“Block properties > Protection”) on any controller exposed to less-trusted networks.
// Refresh local image from remote station per Siemens FAQ 18325417) so future maintainers know that T IB x is intentional and not a bug. A single comment prevents months of confusion when the next engineer tries to “fix” the unwanted write to an input.Frequently Asked Questions
What does L stand for in Siemens STL?
L stands for “Load”. It reads the addressed operand (a constant, a flag, an input, or a peripheral byte) and stores the value in the 32-bit accumulator ACCU 1, shifting the previous ACCU 1 into ACCU 2. L does not modify the RLO flag — for that you use A, O, X or their negated forms.
What is the difference between IB and PIB?
IB (input byte) reads from the process input image — a memory snapshot refreshed at the start of OB1 and held steady for the rest of the cycle. PIB (peripheral input byte) reads directly from the physical module or remote station at the moment of the STL instruction. Use IB for normal program logic; reserve PIB for high-priority bursts, oversized I/O areas, or library functions that document peripheral access explicitly.
Why does Siemens allow T IB even though inputs are read-only?
Standard input modules do not accept writes from the PLC, so T IB x has no effect on the field wiring. The pattern exists only as a documented workaround (see Siemens FAQ 18325417) where the IB is part of a library’s data exchange buffer and the write redirects what subsequent L IB reads return. For ordinary user programs the equivalent should be a T MB x into bit memory.
Where in TIA Portal V14 do I enter STL code?
Open the project, then create or open a function block (FB), function (FC), or organisation block (OB). Confirm “LAD/FBD/STL” is enabled under the block’s general properties, then switch the view with “View > STL” or the toolbar button. Paste the statements into the editor, compile, download to the CPU, and use “Monitor (STL)” to step through the accumulator and RLO values online.
Can three S7-1500 controllers share the same PROFINET inputs?
Yes. Configure the IO Device as a shared device in TIA Portal (its properties page enables “Share this device with other controllers”) and assign at least two controllers with overlapping MSI slots. Each receiving controller reads those inputs through its own process image or, for time-critical work, through peripheral access using the same L PIB / T IB / A bit pattern documented above. Refer to Siemens FAQ 109736536 for the configuration walk-through.