802.11 Reference Design: Event Log Architecture

The sections below describe the implementation of the logging framework in the CPU High code of the 802.11 Reference Design.

Log Storage

The log is stored in a pre-allocated region of DRAM in each WARP v3 node. As of 802.11 Reference Design v0.9 each node dedicates ~960 MB of DRAM for log storage. The remaining DRAM is set aside for the Tx packet queue and user scratch space.

The logging system enforces a few conventions on its DRAM allocation:

  • The first byte of the log space will always be the first byte of a log entry header (see below). Even when wrapping is enabled individual log entries will always be continuous in DRAM, starting at the beginning of the log DRAM space.
  • The logging system will never truncate a log entry at the end of the DRAM. The logging code remembers the index of the last byte of the last log entry written (called the "soft end" in code).

The logging code does not enforce any alignment on the user-supplied entries. The 802.11 Reference Design hardware includes alignment handling code and logic (MicroBlaze unaligned access exception handling and data realignment engine (DRE) in the axi_cdma) to handle arbitrary alignment of data in DRAM. However it is recommended that the size of user-defined log entries be a multiple of 4 bytes. This will improve performance in reading and writing log data from the 32-bit MicroBlaze processor and ease the parsing of log data after an experiment.


The logging system maintains 3 indexing values:

  • Oldest Address: the address of the first byte of the log entry header for the oldest complete log entry currently in DRAM
  • Next Address: the address where the next log entry will be written, when requested by MAC code
  • Num Wraps: the number of times the log has wrapped since last reset (see below for more on wrapping)

These indexes are used the logging system to track where new log entries should be written. They are also provided to user code to facilitate retrieval of log data. User code can request these indexes at any time to determine how much new log data should be retrieved.

Important: the logging code does not maintain any state about log retrieval. This is by design. The logging code does not care when users retrieve log data or how many simultaneous log consumers are accessing the same log data. Each log retrieval request includes a byte address and length. The logging code fulfills these requests, then purges all state related to the retrieval. This design enables multiple consumers to retrieve and process log data without burdening the node with tracking state for each consumer.

The 802.11 Reference Design wlan_exp_log Python framework implements suitable methods to track log write indexes and retrieve log data.


For many experiments the pre-allocated DRAM space will suffice to record the full log. However for long experiments the log may reach the end of the DRAM allocation. The logging system implements wrapping which, if enabled, will begin overwriting the oldest log entries as new log entries are created. Wrapping allows experiments to run non-stop for very long periods (limited only by the 32-bit num_wraps value).

Wrapping can be used two ways:

  • The user can read the log data continuously, retrieving log entries faster than they are written. This approach extends the limit on log size to the storage capabilities of the user's PC (typically much larger than the WARP v3 node's DRAM).
  • The MAC code records log entries continuously, wrapping as needed, with an application-defined stop condition implemented in the MAC code. Once stopped the log will be preserved for eventual retrieval by the user. This approach mimics a trigger condition on a logic analyzer. Following the trigger the user can look backwards in time to understand the series of events that preceded the trigger event.

Log Entry Format

Each log entry consists of two parts:

  • Log entry header: 8-byte header composed of four fields described below. The header format is defined in the entry_header struct in wlan_mac_event_log.h.
    • Delimiter (2 bytes): a "magic" value defined by the logging system to sanity-check log entries during retrieval and parsing
    • Sequence number (2 bytes): an auto-incremented value inserted by the logging code. This should only be used for sanity-checking log contents, as the 16-bit value will definitely wrap in long logs
    • Entry type ID (2 bytes): User-supplied entry type ID. The value 0 is reserved - all other values are valid.
    • Entry length (2 bytes): Length of user-supplied log data, in bytes. Must be in [0, 65535], inclusive.
  • Log data: log data supplied by the application. The logging system performs no processing of log data - user code must enforce whatever structure is required by the application.

An example of the log memory layout is illustrated below.

The 8-byte log entry headers are shown in blue. In this example there are 3 user-defined log entry types: TYPE_ID_RED, TYPE_ID_GREEN, TYPE_ID_YLW.

A few things to notice in this example:

  • Every log entry begins with an 8-byte log entry header
  • The user-supplied entry type ID is arbitrary
  • Log entries of the same type can be different sizes — the (type, length) tuple is supplied by the application per-entry
  • Entries should be aligned to 32-bit boundaries for predictable access by C code in the 32-bit MicroBlaze processor

Log Utilities

The wlan_exp Python package provides many utilities for retrieving and processing node log data. Refer to the package documentation for more details.

Last modified 10 years ago Last modified on Oct 24, 2014, 1:46:51 PM