Siemens S7 Data Blocks: Global vs Instance DB Architecture Guide

David Krause16 min read
SiemensTechnical ReferenceTIA Portal
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 S7 Data Blocks: Global vs Instance DB Architecture Reference

This reference consolidates field-proven guidance for designing STEP 7 / TIA Portal user programs around Data Blocks (DB). It addresses the most common question asked by engineers migrating from the Rockwell/Allen-Bradley (A-B) Logix platform: should the application use Global DBs with Functions (FC), or Instance DBs tied to Function Blocks (FB)? The guidance below covers block memory layout, the FC/FB call model, byte-ordering rules, IEC timer/counter selection, Organization Block (OB) usage, User-Defined Types (UDT), and structured design patterns that scale from a single conveyor to multi-section plant code.

Scope: Targets S7-300/S7-400 with STEP 7 V5.x and S7-1200/S7-1500 with TIA Portal V16-V20. Concepts are portable to older S7-200/S7-300 with SIMATIC Manager. Wherever behavior diverges between classic STEP 7 and TIA Portal, both cases are labeled.

1. Data Block Architecture in S7

Data Blocks are the storage containers for variable user data in the S7 user program. Unlike the Process Image (PII/PIQ), Bit Memory (M), or Local / Temp (L) stack, DBs are addressable as named memory regions that survive between scans and can be referenced by every block in the program. Per the official TIA Portal V20 programming reference, "Data blocks thus contain variable data that is used by the user program" and sit alongside OBs, FBs, and FCs as first-class elements of the program.

Two physical flavors of DB exist:

DB Type Storage Class Created By Structure Source Typical Use
Global DB (GDB) Global, named Engineer / compile Manual declaration in the DB editor or via UDT Shared recipes, HMI tags, cross-section data, communication buffers
Instance DB (IDB) Global, named, but logically owned by one FB Auto-generated at FB call Mirrors the FB's VAR_INPUT, VAR_OUTPUT, VAR_IN_OUT, VAR_STATIC, VAR_TEMP declaration Per-equipment state (one DB per motor, valve, conveyor, PID loop)

Both DB types are accessed the same way at runtime (DB1.DBX0.0, DB1.DBW2, DB1.DBD4). The difference is semantic: a Global DB is a free-form data structure you author by hand; an Instance DB is automatically generated to match the declaration of its parent FB. Per Siemens documentation, an Instance DB's STRUCT is locked to the FB interface and cannot be edited directly in the DB editor; changes must be made in the FB and recompiled.

2. Global Data Blocks (GDB) — Technical Details

A Global DB is simply a named area of work memory. It has no associated code block; the engineer declares its STRUCT manually. GDBs are ideal for data that does not belong to a single piece of equipment, including:

  • Recipes and machine setpoints read by HMI
  • Production counters and shift totals
  • Cross-equipment interlocks (e.g., Permissive_Common)
  • HMI message buffers and alarm history
  • Communication buffers for PUT / GET / BSEND / USEND on S7-300/400, or for READ / WRITE on S7-1200/1500

Per the TIA Portal V20 programming basics manual, Global DBs are part of the standard block set and can be created from Program blocks > Add new block > Data block. The resulting block is downloaded to the PLC and can be opened in online watch without restrictions.

Optimized vs. non-optimized access: On S7-1200/1500, GDBs default to optimized (symbolic-only) block access. For PUT/GET, BSEND/BRCV, or any communication with an S7-300/400 partner that uses absolute addresses, the DB must be non-optimized (set "Disable optimized block access" in the DB attributes). This is a frequent source of 80A1 / 80A2 errors in cross-PLC tag exchanges — see Section 11.

Authoring tip: split a GDB into sections by purpose (Settings, Status, Production, Comm) using comment dividers. Avoid using a single monolithic GDB for an entire machine — it becomes unsearchable past a few hundred tags and bloats online diff views.

3. Instance Data Blocks (IDB) — Technical Details

An Instance DB is the runtime memory of a Function Block (FB). When an FB is called with a Call instruction, you either name an existing IDB or let the compiler auto-generate a single-instance or multi-instance IDB. The IDB's STRUCT is rebuilt from the FB declaration every time the FB's interface is recompiled.

Standard FB declaration layout:

FUNCTION_BLOCK FB_Conveyor
VAR_INPUT
    i_Start         : BOOL;     // Start command from HMI or upstream
    i_Stop          : BOOL;     // Stop command (NC contact)
    i_SpeedSetpoint : REAL;     // Hz or %
END_VAR
VAR_OUTPUT
    q_Running       : BOOL;
    q_Fault         : BOOL;
    q_ActualSpeed   : REAL;
END_VAR
VAR_IN_OUT
    io_Motor        : BOOL;     // shared drive enable signal
END_VAR
VAR
    s_TON_Run       : TON;      // IEC on-delay, STATIC retention
    s_LastStart     : BOOL;     // edge-detection bit
    s_RunTimeSec    : DINT;     // accumulated run time
    s_StartPulse    : BOOL;     // one-shot memory
END_VAR
VAR_TEMP
    t_TempDword     : DWORD;    // scratch / intermediate calc only
END_VAR
BEGIN
    // FB body
END_FUNCTION_BLOCK

When FB_Conveyor is called as a single instance, the compiler creates an IDB (e.g., DB_Conveyor_1) containing two substructures: a Input, Output, InOut, and Static view that mirrors the FB declaration. Temp variables are not stored in the IDB; they live on the local stack of the calling OB and must not be used after the FB exits.

Calling the same FB multiple times (e.g., Conveyor_1, Conveyor_2, Conveyor_3) can be done as:

  • Single-instance: each call uses its own IDB. Recommended when the equipment instances are independent and the FB may be reused in other projects.
  • Multi-instance: each call stores its data inside the IDB of a parent FB. Recommended for tightly-coupled subsystems where the parent is the only caller.

Multi-instance syntax (in a parent FB):

FUNCTION_BLOCK FB_Line
VAR
    Conveyor1 : FB_Conveyor;   // multi-instance, stored in FB_Line's IDB
    Conveyor2 : FB_Conveyor;
    Conveyor3 : FB_Conveyor;
END_VAR

4. Functions (FC) vs. Function Blocks (FB)

The choice between FC and FB is the central design decision in any S7 program. The trade-off is summarized below.

Aspect FC (Function) FB (Function Block)
Memory between calls None. Local (L) stack is overwritten each call. Retained in the IDB's Static area.
Parameter passing Inputs only (In, Out, InOut) — no stored state Inputs, Outputs, InOuts, plus Static for state
Multi-instance No Yes
Timers / counters Requires separate DB or M-bit flag for each instance IEC timer/counter declared as STAT occupies the IDB
Reusability across projects High (stateless) High (state encapsulated in IDB)
A-B equivalent Add-On Instruction (AOI) without state, or a Subroutine Add-On Instruction (AOI) with internal tags

Rule of thumb from the field:

  • Use an FC when the routine is purely a calculation or conversion (e.g., scaling a 4–20 mA raw value to engineering units, computing a CRC). It is also the fastest path to a first working program under deadline pressure.
  • Use an FB when the routine has state: a motor, a valve, a PID loop, a state machine, anything that needs to remember between scans.

Combining both is the typical pattern: the OB calls FBs (one per device instance), and each FB calls shared FCs (for math, scaling, alarm formatting). The shared, non-volatile settings live in a single Global DB; the per-device state lives in IDBs.

5. M Memory, Bit Memory, and When to Avoid It

Bit Memory (M / MB / MW / MD) is the legacy scratch-pad of S7. It is faster to type than DBx.DBWy, but it has three structural problems that scale poorly:

  1. No online structure view. Watching M10.0 in the variable table is fine; watching 300 M bits mixed across a machine is not.
  2. Retentivity is per-byte, not per-bit. A BOOL in MB10 inherits the retentive setting of the entire byte.
  3. No symbol-only access on S7-1200/1500 optimized blocks. Optimized FBs cannot reference M bits symbolically; everything must go through a DB.

Practical guidance: keep M reserved for low-level handshakes (e.g., FirstScan, AlwaysTrue, Heartbeat_100ms) and put all real program state in DBs. This mirrors A-B practice of using program tags (controller-scoped) instead of legacy global tags in older SLC/PLC-5 conventions.

6. Byte Ordering, Data Types, and the Ladder Pitfall

S7 is a big-endian architecture for declared types but the bit/byte numbering of absolute addresses can mislead engineers coming from PLC-5 or Logix. The rule to memorize:

MB0 is the most significant byte of MW0 and of MD0. MB1 is the LSB of MW0; MB3 is the LSB of MD0. This is reversed from the natural reading order of an A-B engineer used to B3:0/0 as the lowest bit of a 32-bit word.

When you execute a MOVE (ladder) or T (STL) instruction, the CPU stores the value according to the target's declared type. If you turn off "Type check of operands" in the compiler settings to silence mismatched-type warnings, the program may compile but execute with wrong byte order. The correct fix is to align source and destination types (INT to INT, REAL to REAL) and to swap bytes explicitly with TAW / TAD when interfacing with a device that delivers little-endian data (most Modbus RTU slaves, some ASCII scales).

Recommended data types by use case:

Application Value S7 Type Range Notes
Digital I/O, coils, status BOOL 0 / 1 One bit per address
Counter, BCD, small integer INT / WORD -32768 .. 32767 Use INT for math, WORD for bit-masks
Counter, large integer, accumulator DINT / DWORD ±2.1e9 Default for production counts
Analog, scaling, PID REAL ±3.4e38 (IEEE-754 32-bit) Always REAL, never use INT for analog on S7-1200/1500
Time, date, timestamps TIME, DTL, DATE_AND_TIME Various DTL since TIA V13, replaces legacy DT
String (HMI display) STRING[n] n=1..254 chars First two bytes are max length and actual length

7. IEC Timers and Counters — The Right Choice

S7 ships two timer families. S5 timers (SP, SE, SD, SS, SF, SA) are bit-mapped legacy blocks from the S5 era. IEC timers are System Function Blocks found in Libraries > Standard Library > System Function Blocks:

Block Function Inputs Output
SFB3 TP — pulse IN, PT Q, ET
SFB4 TON — on-delay IN, PT Q, ET
SFB5 TOF — off-delay IN, PT Q, ET
SFB0 CTU — count up CU, R, PV Q, CV
SFB1 CTD — count down CD, LOAD, PV Q, CV
SFB2 CTUD — count up/down CU, CD, R, LOAD, PV QU, QD, CV

On S7-1200/1500 the IEC blocks are called TON_TIME / TOF_TIME / TP_TIME / CTU / CTD / CTUD in the Instructions > Timer operations and Counter operations task cards. Their semantics match the A-B TON / TOF / CTU / CTD instructions almost exactly, which makes them the preferred choice for migration projects.

Two IEC timer behaviors to remember:

  1. Edge-triggered start. A TON/TOF starts on a rising edge of IN. If IN is already TRUE on the first scan, the timer does not start. Initialize the timer input from a conditional that produces a clean edge, or call SFB3/SFB4/SFB5 with IN driven by a one-shot.
  2. PT = 0 never passes power. A TON with a preset of T#0ms leaves Q = FALSE forever. S5 timers behaved the opposite way (PT=0 meant "always true"). Always use a positive PT and validate HMI entries for <= 0.

Reading the elapsed time (ET / CV) does not interfere with the running timer. To compute the remaining time, use Remaining := PT - ET in REAL/DINT math. S5 timers require the extra LC (load BCD) and ITD (BCD-to-integer) steps to make the remaining time accessible as a usable number — another reason to standardize on IEC blocks.

8. Organization Blocks (OB) and Startup Behavior

OBs are the entry points the CPU calls; they cannot be called from user code. The most common are:

OB Trigger Use
OB1 End of last OB (cyclic) Main scan
OB10–OB17 Time-of-day interrupt Scheduled tasks (e.g., hourly report)
OB30–OB38 Cyclic interrupt (S7-300/400) Deterministic 5/10/20/100/200/500 ms task
OB40–OB47 Hardware interrupt Fast response to a digital input
OB80–OB87 Error / fault Default handler; pass through to keep CPU in RUN
OB100 Warm restart (S7-300/400) / startup Initialize variables, set defaults, write to GDB
OB101 Hot restart (S7-400 only) Same role, hot-restart semantics
OB102 Cold restart (S7-400 only) Full re-init of retentive areas
OB121 Programming error Default handler (often empty) so CPU keeps running
OB122 I/O access error Default handler (often empty) so CPU keeps running

The startup OBs (100/101/102) execute once when the CPU transitions from STOP to RUN, before OB1 begins cycling. They are the place to:

  • Copy default values into the GDB Settings structure
  • Initialize edge-detection bits (s_LastStart := FALSE)
  • Pre-load recipe parameters from a non-volatile source
  • Reset non-retentive counters and production totals
Do not call FBs that manipulate outputs from inside OB100. The process image is not yet valid at startup. Wait for OB1 to call the FB after the first PII update.

9. User-Defined Types (UDT) for Reusable Structures

A UDT is a user-defined data type, like a struct in C. It can be referenced in the declaration of any DB or FB and it guarantees identical layout across instances. UDTs are the single most effective way to scale a Siemens program from one device to one hundred.

Typical usage — a Motor UDT shared by every motor block:

TYPE UDT_Motor
STRUCT
    StartCmd       : BOOL;
    StopCmd        : BOOL;
    Running        : BOOL;
    Faulted        : BOOL;
    ActualSpeed    : REAL;
    SetpointSpeed  : REAL;
    RunHours       : DINT;
    LastStartTime  : DTL;
END_STRUCT
END_TYPE

Reference in a DB:

DATA_BLOCK DB_Equipment
STRUCT
    Conveyor1 : UDT_Motor;
    Conveyor2 : UDT_Motor;
    Conveyor3 : UDT_Motor;
    Shared    : UDT_CommonSettings;  // second UDT for setpoints
END_STRUCT
END_DATA_BLOCK

Reference in an FB's Static area:

FUNCTION_BLOCK FB_Conveyor
VAR
    s_Motor : UDT_Motor;
END_VAR

Now an HMI tag like DB_Equipment.Conveyor1.Running is identical in shape to DB_Equipment.Conveyor2.Running. WinCC, TIA HMI, and third-party SCADA systems can use a single tag prefix and an index to address all motors.

UDT edit rule: changing a UDT automatically updates every block that uses it. Always recompile the entire program (not just the changed FB) after a UDT change, and verify IDB sizes in the project tree.

10. Addressing Mode: Symbolic vs. Absolute

Two ways to reference a variable exist:

  • AbsoluteDB1.DBX4.0, MW10, I0.0
  • SymbolicData_Recipe.SpeedSP, Conveyor1.Running

Best practice for new programs: set the project priority to Symbolic in the block-folder properties. This makes the symbol the default, the absolute the fallback, and the ladder editor stops inserting raw DB1.DBX4.0 tags on first use. On TIA Portal V20, optimized blocks enforce symbolic-only access at compile time, so the choice is effectively made for you.

11. Common Errors and Verification Matrix

Symptom Likely Cause Resolution
SF LED on; CPU in STOP after download IDB out of sync with FB declaration Right-click the FB > Compile > re-download all changed blocks. Delete and re-create the IDB if structure mismatch persists.
PUT/GET from S7-1500 to S7-300 returns SF 80A1 Source DB on S7-1500 is optimized Open DB attributes > Attributes > uncheck Optimized block access. Recompile and re-download.
Online watch shows wrong byte order for an analog value Source device is little-endian, DB declared as INT Insert TAW (word swap) or TAD (dword swap) in ladder, or use SWAP in STL. Better: change source to network order.
Ton with PV=0 never closes Q IEC TON behavior (PT>0 required) Clamp PV to minimum T#1ms in HMI tag limit, or use TP for one-shot.
Timer does not start on first scan IEC TON is edge-triggered, IN was already TRUE Reset edge bit in OB100, or feed IN from a one-shot pulse.
HMI loses connection to GDB tags Connection resource exhausted, or access level too low Check Protection & Security > Connection mechanisms; enable PUT/GET server access for the HMI.
Compiling produces "Instance DB cannot be generated" FB contains an unsupported data type or is recursive Inspect the FB declaration; ensure no ARRAY of FB (use multi-instance instead) and no PLC-tag-of-PLC-tag.

12. Migration Checklist: A-B / Logix → S7

For engineers moving from Studio 5000 / RSLogix 5000 to STEP 7 / TIA Portal, the following mapping helps a clean conversion.

Logix Concept S7 Equivalent Notes
Program Tag (controller scope) Global DB or Static of a project-wide FB Prefer GDB for cross-program data
Add-On Instruction (AOI) FB + IDB One IDB per instance; multi-instance for nested AOIs
Subroutine (no state) FC Inputs only, no retained memory
User-Defined Data Type (UDT in Logix) UDT Same purpose, identical layout propagation
Produced / Consumed Tags PUT/GET or BSEND/BRCV across PN/IE DB must be non-optimized for cross-CPU access
Message (MSG) instruction PUT/GET / BSEND / USEND / TCP native / Modbus blocks Library: Communication > SIMATIC NET
Periodic Task (50 ms) Cyclic OB (OB30–OB38) on S7-300/400; Cyclic interrupt in TIA Verify CPU supports the requested phase
SFC (Sequential Function Chart) S7-GRAPH FB Optional add-on package

13. Field-Proven Project Layout

For a mid-size machine (one PLC, 10–50 devices, one HMI), the following structure scales cleanly:

  1. OB1 — calls FB_Line_Control (the master FB) and the standalone FBs for HMI handshake, alarm collection, and recipe handling.
  2. OB100 — initializes DB_Settings with default values, clears non-retentive counters.
  3. DB_Settings (GDB, non-optimized for HMI) — recipes, setpoints, machine parameters.
  4. DB_Production (GDB, retentive) — counters, shift totals, fault history.
  5. DB_Comm (GDB, non-optimized) — buffers for PUT/GET to subordinate PLCs or drives.
  6. UDT_Motor / UDT_Valve / UDT_PID — reusable structures.
  7. FB_Conveyor / FB_Pump / FB_Valve / FB_PID — equipment blocks, each a multi-instance of the master FB_Line_Control or a single-instance with its own IDB.
  8. FC_Scale_4_20 / FC_Alarm_Format / FC_Linearize_TC — stateless utility routines.

The same UDT_Motor shows up in DB_Equipment for HMI tag prefixing, in the Static of every motor FB, and (if needed) in a Global DB for a section overview panel. One change to the UDT propagates everywhere.

14. References and Standards

Verify behavior against the following official Siemens manuals and standards when implementing these patterns in a certified project:

Should I use a Global DB or an Instance DB for a motor block?

Use an Instance DB. Declare the motor as a Function Block (FB) with Static variables, and call the FB once per motor. The Instance DB is auto-generated with the FB's STRUCT and is the clean way to scale from one motor to one hundred. Reserve Global DBs for cross-equipment settings, recipes, and HMI-visible data that does not belong to a single device.

Why does my TON timer not start on the very first scan?

IEC TON/TOF/TP blocks are edge-triggered. If the input (IN) is already TRUE when the block is first called, the timer does not start. Reset the enable bit in OB100 so the first cycle sees a FALSE-to-TRUE transition, or feed IN from a one-shot pulse generated from FirstScan memory.

Why is my PUT/GET access from another S7-1500 returning an 80A1 error?

The target DB on the source PLC is optimized. Open the DB's Attributes, disable Optimized block access, recompile, and re-download. The DB now exposes absolute offsets that PUT/GET can address. This is the most common cause of cross-PLC DB access faults on S7-1200/1500.

Can I edit the structure of an Instance DB directly?

No. An Instance DB's structure is locked to its parent FB's declaration. To add or modify a variable, edit the FB's interface (VAR_INPUT, VAR_OUTPUT, VAR_IN_OUT, VAR_STATIC) and recompile. The IDB is regenerated automatically. Direct edits are rejected by the editor to keep the FB and its IDB in sync.

What is the difference between MB0, MW0, and MD0?

They are three views of the same physical bytes. MB0 is the most significant byte of MW0, MB1 is its least significant byte, and MB3 is the least significant byte of MD0. When using MOVE or T instructions, the CPU stores the value according to the target's declared type. Turn off type-checking in the compiler only as a last resort — the runtime byte order is fixed regardless of the editor's tolerance.

How do I retain values across a power cycle?

Mark the GDB or the FB's Static variables as Retain in the block properties. On S7-300/400, the retentivity is also controlled by the CPU's hardware retain area; on S7-1200/1500, declare individual tags as Retain in the IDB/GDB and the CPU stores them in NVRAM. Avoid retaining timers and counters — recompute them on startup from OB100.

Back to blog