Generated banner for Matlab Generate Wlan Waveform
Generated logo for Matlab Generate Wlan Waveform

Matlab Generate Wlan Waveform

MathWorksOfficialCreated by MathWorks

  • Skill
  • Tool integration
  • Software development
  • BSD-2-Clause
  • No issues found

From the author

Generate standard-compliant IEEE 802.11 waveforms using MATLAB WLAN Toolbox. Use when creating WLAN waveforms, PPDU packets, or the transmit side of a link-level simulation. Covers all formats: Non-HT (802.11a/g), HT (802.11n), VHT (802.11ac), HE-SU/HE-MU/HE-TB (802.11ax), EHT-MU/EHT-TB (802.11be), UHR-MU/UHR-TB/UHR-ELR (802.11bn). Handles single-user, MU-MIMO, OFDMA, trigger-based uplink, extended range, preamble puncturing, UEQM, and DRU. Use when asked to generate test waveforms, create packets with MAC frames, configure OFDMA resource units, build trigger-based uplink transmissions, target a specific transmit duration, or build multi-packet waveforms.
— the description by MathWorks

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured approach to generating IEEE 802.11 standard-compliant waveforms for device testing and link-level simulations. It covers the entire transmit chain, from configuring PHY parameters and payload sizes to generating time-domain IQ waveforms. The skill supports a wide range of standards, including legacy 802.11a/g/n/ac and modern 802.11ax/be/bn, handling complex features like OFDMA, MU-MIMO, trigger-based uplink, and preamble puncturing.

What it does

  • Configures PHY formats for various 802.11 standards
  • Generates time-domain IQ waveforms for simulation or testing
  • Calculates payload lengths based on target transmit durations
  • Configures OFDMA resource units and MU-MIMO spatial streams
  • Builds MAC frame payloads for packet-level testing
  • Visualizes RU allocations and waveform properties

When to use it

  • When creating test signals for Wi-Fi device validation
  • When building the transmit side of a link-level simulation
  • When configuring complex OFDMA or MU-MIMO transmissions
  • When targeting specific packet durations or transmit times
  • When working with 802.11be (Wi-Fi 7) or 802.11bn (Wi-Fi 8) features

Advantages

  • Ensures standard-compliant waveform generation
  • Simplifies complex configuration of MU-MIMO and OFDMA
  • Provides clear patterns for duration-based payload sizing
  • Supports advanced features like MRU and preamble puncturing
  • Includes built-in verification tools like showAllocation

Usage examples

“Generate an 80 MHz 802.11ax waveform with four 242-tone RUs.”
The agent will construct a wlanHEMUConfig object with allocation indices [192 192 192 192], configure per-user MCS and APEPLength, and generate the waveform using wlanWaveformGenerator.
“How do I set the payload size for a 2ms transmission in 802.11ac?”
The agent will provide the code to use wlanAPEPLength(cfg, 'TxTime', 2000) and assign the result to the APEPLength property of the wlanVHTConfig object.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/matlab/matlab-generate-wlan-waveform/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip matlab-generate-wlan-waveform.zip -d .agents/skills

Documentation by MathWorks

Generate WLAN Waveforms

Generate standard-compliant IEEE 802.11 waveforms for device testing, link-level simulation, or signal analysis. This skill covers the transmit chain: configure the PHY format, size the payload, generate the time-domain IQ waveform, and plot.

When to Use

  • Generating WLAN/Wi-Fi test waveforms for any 802.11 standard

  • Creating the transmit side of a link-level simulation

  • Building packets with specific MAC frame types (Data, Block Ack, Beacon, etc.)

  • Configuring OFDMA resource unit allocations (HE-MU, EHT-MU, or UHR-MU)

  • Configuring MU-MIMO transmissions (VHT, HE, EHT, UHR)

  • UHR features: UEQM (per-stream MCS), DRU, LDPC2x, ELR (enhanced long range)

  • Targeting a specific packet duration or transmit time

When NOT to Use

  • Channel modeling, receiver processing, EVM/spectral mask — not covered

  • Non-WLAN waveforms (5G NR, LTE, Bluetooth)

UHR (802.11bn) requires R2026a or later. If the user requests a UHR waveform and their release is older, inform them that UHR support was introduced in R2026a and recommend upgrading.

Workflow

Every waveform generation follows this pipeline:

  1. Select format → create the config object (see Format Selection)

  2. Configure PHY → set bandwidth, MCS, spatial streams, antennas

  3. Size the payload → set PSDU/APEP length directly or from a target duration

  4. Create payload bits → random bits or MAC frame via wlanMACFrame

  5. Generate waveform → wlanWaveformGenerator(bits, cfg)

  6. Plot and verify → time-domain magnitude, showAllocation for HE/EHT/UHR configs

Format Selection

StandardMarketingConfig ObjectUsers
802.11bWi-Fi 1wlanNonHTConfig (DSSS)SU only
802.11a/gWi-Fi 1/3wlanNonHTConfigSU only
802.11nWi-Fi 4wlanHTConfigSU only
802.11acWi-Fi 5wlanVHTConfigSU or MU-MIMO
802.11axWi-Fi 6wlanHESUConfigSU only
802.11axWi-Fi 6wlanHESUConfig (ExtendedRange)SU — extended range
802.11axWi-Fi 6wlanHEMUConfig(allocIdx)OFDMA and/or MU-MIMO
802.11axWi-Fi 6wlanHETBConfigSU uplink (trigger-based)
802.11beWi-Fi 7wlanEHTMUConfig(allocIdx)OFDMA and/or MU-MIMO / MRU
802.11beWi-Fi 7wlanEHTMUConfig("CBW...")Non-OFDMA MU-MIMO (full-band RU)
802.11beWi-Fi 7wlanEHTMUConfig("CBW...", EHTDUPMode=true)SU — DUP mode (MCS 14 only)
802.11beWi-Fi 7wlanEHTTBConfigSU uplink (trigger-based)
802.11bnWi-Fi 8uhrMUConfig(allocIdx)OFDMA / MU-MIMO / UEQM (example helpers)
802.11bnWi-Fi 8uhrMUConfig("CBW...")Non-OFDMA MU-MIMO (example helpers)
802.11bnWi-Fi 8uhrTBConfigSU uplink / DRU (example helpers)
802.11bnWi-Fi 8uhrELRConfigSU enhanced long range (example helpers)

For OFDMA formats (HE-MU, EHT-MU), the constructor takes allocation indices, not RU sizes. See references/he-allocation-indices.md and references/eht-allocation-indices.md.

UHR (802.11bn / Wi-Fi 8) uses example helper files, not built-in toolbox objects. Copy helpers into the script's working folder with setupExample("wlan/UHRParameterizationExample", scriptFolder). UHR supports UEQM (per-stream MCS), DRU, LDPC2x, ELR (enhanced long range), and new MCS values (15-23). Same allocation indices as EHT. See references/uhr-waveform-generation.md.

See Critical Rules for format-specific constraints (allocation index schemes, HT MCS encoding, DSSS properties).

EHT DUP mode duplicates the signal across subchannels for robust coverage. Set at construction: wlanEHTMUConfig("CBW80", EHTDUPMode=true). Constraints: MCS 14 (BPSK-DCM) only, single user, 1 spatial stream, no puncturing, 80/160/320 MHz. EHTDUPMode is read-only after construction.

Duration Targeting

Calculate payload size from target duration. All values are integer microseconds.

ConfigFunctionExample
wlanNonHTConfigwlanPSDULength(cfg, 'TxTime', us)cfg.PSDULength = wlanPSDULength(cfg, 'TxTime', 500);
wlanHTConfigwlanPSDULength(cfg, 'TxTime', us)cfg.PSDULength = wlanPSDULength(cfg, 'TxTime', 1000);
wlanVHTConfig (SU only)wlanAPEPLength(cfg, 'TxTime', us)cfg.APEPLength = wlanAPEPLength(cfg, 'TxTime', 2000);
wlanHESUConfigwlanAPEPLength(cfg, 'TxTime', us)cfg.APEPLength = wlanAPEPLength(cfg, 'TxTime', 3000);
wlanEHTMUConfig (SU non-OFDMA)wlanAPEPLength(cfg, 'TxTime', us)cfg.User{1}.APEPLength = wlanAPEPLength(cfg, 'TxTime', 1000);
Any MU/OFDMA configIterative transmitTime loopSee below — wlanAPEPLength errors on MU/OFDMA

Duration argument is integer microseconds, not seconds. Pass 2000, not 2e-3.

MU Duration Targeting (iterative)

For any MU config (homogeneous users — same MCS, RU size, and spatial streams):

targetDuration = 1e-3; apepLen = 2000; % initial guess
for iter = 1:10
    for u = 1:numUsers, cfg.User{u}.APEPLength = apepLen; end
    txTime = transmitTime(cfg);
    if abs(txTime - targetDuration)/targetDuration < 0.01, break; end
    apepLen = round(apepLen * targetDuration / txTime);
end

Heterogeneous users (different MCS/RU/STS): Lowest-capacity user sets duration. Set per-user APEPLength based on traffic demand; use transmitTime(cfg).

PSDU Length Access

The way to get PSDU length varies by format. Using the wrong pattern throws errors.

ConfigHow to get PSDU lengthNotes
wlanNonHTConfigcfg.PSDULengthSettable property
wlanHTConfigcfg.PSDULengthSettable property
wlanVHTConfigcfg.PSDULengthRead-only property (derived from APEPLength). Vector for MU.
wlanHESUConfiggetPSDULength(cfg)Method call. Not a property.
wlanHEMUConfiggetPSDULength(cfg)Method call. Returns vector (one per user).
wlanHETBConfiggetPSDULength(cfg)Method call. Same as HE-SU/HE-MU.
wlanEHTMUConfigpsduLength(cfg)Different method name from HE. Returns vector.
wlanEHTTBConfigpsduLength(cfg)Same method name as EHT-MU.

getPSDULength and psduLength are not interchangeable. HE uses getPSDULength. EHT uses psduLength.

Key Functions

FunctionPurpose
wlanWaveformGenerator(bits, cfg)Generate time-domain IQ waveform
wlanSampleRate(cfg)Get sample rate for the configuration — always use this
wlanHETBConfigConfigure HE trigger-based uplink (single STA)
wlanEHTTBConfigConfigure EHT trigger-based uplink (single STA)
wlanMACFrame(payload, cfgMAC)Generate MAC frame bits (see references/mac-frame-properties.md)
wlanAPEPLength(cfg, 'TxTime', us)APEP length for target duration (VHT-SU, HE-SU, EHT-MU single-user)
wlanPSDULength(cfg, 'TxTime', us)PSDU length for target duration (NonHT/HT)
transmitTime(cfg) or transmitTime(cfg, 'microseconds')Get transmit time — use unit argument instead of * 1e6
showAllocation(cfg) or showAllocation(cfg, ax)Plot RU allocation — pass axes handle to embed in tiledlayout
ruInfo(cfg)Query RU sizes, indices, user counts

If you need to verify property names, check valid values for a config object, or look up parameters not covered in this skill, consult the online documentation links in references/documentation-links.md.

Patterns

Single-User Waveform with Target Duration
cfg = wlanVHTConfig;
cfg.ChannelBandwidth = 'CBW80';
cfg.MCS = 9;
cfg.NumTransmitAntennas = 4;
cfg.NumSpaceTimeStreams = 4;
cfg.SpatialMapping = 'Fourier';

% Size payload for 2 ms transmit time
cfg.APEPLength = wlanAPEPLength(cfg, 'TxTime', 2000);

% Generate waveform: 3 packets, 20 us idle
psduBits = randi([0 1], cfg.PSDULength * 8, 1);
waveform = wlanWaveformGenerator(psduBits, cfg, ...
    'NumPackets', 3, 'IdleTime', 20e-6);

fs = wlanSampleRate(cfg);
DSSS (802.11b) Waveform
cfg = wlanNonHTConfig;
cfg.Modulation = 'DSSS';
cfg.DataRate = '11Mbps';   % '1Mbps', '2Mbps', '5.5Mbps', or '11Mbps'
cfg.PSDULength = 1000;

psduBits = randi([0 1], cfg.PSDULength * 8, 1);
waveform = wlanWaveformGenerator(psduBits, cfg);
fs = wlanSampleRate(cfg);  % 11 MHz (chip rate)
HE-MU OFDMA Waveform

For OFDMA, the constructor takes allocation indices per 20 MHz subchannel. Read references/he-allocation-indices.md for the full index-to-RU mapping.

% 80 MHz, four 242-tone RUs (index 192 = one 242-tone RU per subchannel)
cfg = wlanHEMUConfig([192 192 192 192]);
cfg.NumTransmitAntennas = 4;

% Configure per-user parameters
for u = 1:4
    cfg.User{u}.MCS = u + 6;               % MCS 7, 8, 9, 10
    cfg.User{u}.NumSpaceTimeStreams = 1;
    cfg.User{u}.APEPLength = 4000;
    cfg.User{u}.ChannelCoding = 'LDPC';
end

% Use Fourier spatial mapping when NumSTS < NumTransmitAntennas per RU
for r = 1:numel(cfg.RU)
    cfg.RU{r}.SpatialMapping = 'Fourier';
end

% Generate PSDU bits per user
psduLen = getPSDULength(cfg);
txData = cell(1, numel(psduLen));
for u = 1:numel(psduLen)
    txData{u} = randi([0 1], psduLen(u) * 8, 1);
end

waveform = wlanWaveformGenerator(txData, cfg);
showAllocation(cfg);

Common HE allocation indices (per 20 MHz subchannel):

IndexRU LayoutUsers
0Nine 26-tone9
96Two 106-tone2
112Four 52-tone4
192One 242-tone1
193One 242-tone2 (MU-MIMO)
200One 484-tone (40 MHz pair)1
208One 996-tone (80 MHz quad)1

For 40 MHz, provide 2 indices. For 80 MHz, provide 4. For 160 MHz, provide 8.

EHT-MU OFDMA Waveform (with MRU)

EHT allocation indices support Multi-Resource Units (MRU) — non-contiguous tone blocks assigned to a single user. Read references/eht-allocation-indices.md for the full mapping.

% 80 MHz: 484+242 MRU on subchannels 1-3, 106+26+106 on subchannel 4
% Index 120 = 484+242 MRU (1 MU-MIMO user), 29/28 = continuation, 25 = 106+26+106
cfg = wlanEHTMUConfig([120 29 28 25]);
cfg.NumTransmitAntennas = 2;

% Set APEPLength appropriate to RU size (26-tone RUs have low throughput)
apepPerUser = [2000, 500, 100, 500]; % MRU, 106-tone, 26-tone, 106-tone
mcsPerUser  = [7, 4, 2, 4];
for u = 1:numel(cfg.User)
    cfg.User{u}.APEPLength = apepPerUser(u);
    cfg.User{u}.MCS = mcsPerUser(u);
    cfg.User{u}.NumSpaceTimeStreams = 1;
    cfg.User{u}.ChannelCoding = 'LDPC';
end

for r = 1:numel(cfg.RU)
    cfg.RU{r}.SpatialMapping = 'Fourier';
end

% EHT uses psduLength(), NOT getPSDULength()
psduLens = psduLength(cfg);
txData = cell(1, numel(psduLens));
for u = 1:numel(psduLens)
    txData{u} = randi([0 1], psduLens(u) * 8, 1);
end

waveform = wlanWaveformGenerator(txData, cfg);
showAllocation(cfg);

EHT continuation indices: When an RU spans multiple 20 MHz subchannels, use continuation indices for the additional subchannels:

  • 28 — subchannel is part of a larger 242-tone allocation

  • 29 — subchannel is part of a 484-tone allocation

  • 30 — subchannel is part of a 996-tone allocation

VHT MU-MIMO Waveform
cfg = wlanVHTConfig;
cfg.ChannelBandwidth = 'CBW80';
cfg.NumUsers = 2;
cfg.NumTransmitAntennas = 4;
cfg.NumSpaceTimeStreams = [2 2];
cfg.MCS = [8 8];
cfg.APEPLength = [1024 1024];
cfg.GroupID = 2;                    % MU-MIMO: must be 1-62
cfg.SpatialMapping = 'Fourier';    % Required when total STS < NumTxAntennas

psduLen = cfg.PSDULength;           % Read-only vector for MU
txData = cell(1, cfg.NumUsers);
for u = 1:cfg.NumUsers
    txData{u} = randi([0 1], psduLen(u) * 8, 1);
end

waveform = wlanWaveformGenerator(txData, cfg);
Non-OFDMA MU-MIMO Waveform (EHT and HE)

When the user requests MU-MIMO without OFDMA (all users share a single full-bandwidth RU), use these patterns. If the user says "MU-MIMO" without mentioning OFDMA or multiple RUs, default to non-OFDMA.

EHT — use the string constructor (no allocation indices needed):

% 80 MHz, 2 MU-MIMO users on a single 996-tone RU (non-OFDMA)
cfg = wlanEHTMUConfig("CBW80", NumUsers=2);
cfg.NumTransmitAntennas = 4;
cfg.User{1}.NumSpaceTimeStreams = 2;
cfg.User{1}.MCS = 9;
cfg.User{1}.APEPLength = 4000;
cfg.User{1}.ChannelCoding = 'LDPC';
cfg.User{2}.NumSpaceTimeStreams = 2;
cfg.User{2}.MCS = 7;
cfg.User{2}.APEPLength = 4000;
cfg.User{2}.ChannelCoding = 'LDPC';
cfg.RU{1}.SpatialMapping = 'Fourier';

psduLens = psduLength(cfg);
txData = cell(1, numel(psduLens));
for u = 1:numel(psduLens)
    txData{u} = randi([0 1], psduLens(u) * 8, 1);
end
waveform = wlanWaveformGenerator(txData, cfg);

Valid bandwidths: "CBW20", "CBW40", "CBW80", "CBW160", "CBW320". Up to 8 users. Supports puncturing via PuncturedChannelFieldValue.

HE — no string constructor; use full-band allocation indices:

BandwidthIndex for N usersZero-user index
20 MHz192 + N - 1N/A
40 MHz[200 + N - 1, 114]114
80 MHz[208 + N - 1, 115, 115, 115]115
160 MHz[216 + N - 1, 115, 115, 115, 115, 115, 115, 115]115

Follow the same per-user/per-RU pattern as EHT above, using getPSDULength(cfg) instead of psduLength(cfg). Example: cfg = wlanHEMUConfig([209 115 115 115]) for 80 MHz with 2 users.

MAC Frame Payload

See references/mac-frame-properties.md for:

  • Argument order, payload format (hex octets), and PHY config requirements

  • Frame types, properties, and aggregation (A-MSDU, A-MPDU)

  • Common mistakes and calling conventions

Multi-Packet Waveforms

See references/multi-packet-waveforms.md for:

  • A-MPDU aggregation with wlanMSDULengths (cell array of uint8 MSDUs)

  • Multi-packet waveforms — identical (NumPackets, IdleTime) or mixed-format concatenation with SIFS/DIFS/PIFS spacing

Quick reference — inter-frame spacing: SIFS=16 μs, DIFS=34 μs, PIFS=25 μs.

See references/trigger-based-uplink.md for:

  • HE TB (wlanHETBConfig), EHT TB (wlanEHTTBConfig), UHR TB (uhrTBConfig)

  • RUSize/RUIndex from ruInfo(cfgMU), LTF symbols, OversamplingFactor

  • UHR DRU — distributed resource units with DBW/RU size rules

Conventions

  • After generating a waveform, unless the user asks for something specific:

    1. Tell the user the waveform variable name, size, and sample rate

    2. Plot the time-domain waveform magnitude with a time axis in milliseconds

    3. For HE, EHT, or UHR configurations, call showAllocation(cfg)

    4. Save the generation code as a plain-text Live Code .m file using the matlab-create-live-script skill format (%[text] markup, %% sections, required appendix). Open it in the editor with edit('scriptName.m').

  • UHR scripts use a working folder — copy helpers into the same folder as the script with setupExample. See references/uhr-waveform-generation.md.

  • Single-user payload is a plain column vector — use a cell array only for multi-user. wlanWaveformGenerator(bits, cfg) not wlanWaveformGenerator({bits}, cfg).

  • Always use wlanSampleRate(cfg) — never hardcode. For UHR configs use wlanSampleRate(cfg.ChannelBandwidth) (UHR objects are not yet supported).

  • OFDMA bandwidth is read-only — inferred from allocation index vector length (1→20, 2→40, 4→80, 8→160 MHz).

  • Units: IdleTime in seconds (20e-6). Duration functions in integer microseconds (2000). OversamplingFactor multiplies wlanSampleRate. transmitTime(cfg, 'microseconds') — use the unit argument for display, not * 1e6. Valid units: 'seconds', 'milliseconds', 'microseconds', 'nanoseconds'.

  • Verify multi-user configs with ruInfo(cfg) — after constructing any OFDMA or MU-MIMO config, call ruInfo and check NumUsers, NumUsersPerRU, and RUSizes match what was requested. Wrong allocation indices silently produce wrong user counts.

  • ruInfo: HE returns numeric arrays. EHT returns cell arrays (MRU support).

  • Plotting: tiledlayout/nexttile (not subplot). showAllocation(cfg, ax) embeds in existing layout.

Critical Rules

These constraints cause the most errors. Check them before calling wlanWaveformGenerator.

PSDU Length Method Varies by Format

Using the wrong accessor throws "Undefined function" or silent wrong results.

FormatHow to get PSDU lengthWrong approach
Non-HT, HTcfg.PSDULength (property)getPSDULength(cfg) — errors
VHTcfg.PSDULength (read-only)Setting it — errors
HE-SU, HE-MU, HE-TBgetPSDULength(cfg)psduLength(cfg) — errors
EHT-MU, EHT-TBpsduLength(cfg)getPSDULength(cfg) — errors
Allocation Indices Are Not RU Sizes

wlanHEMUConfig(242) is invalid. Use wlanHEMUConfig(192) for a 242-tone RU. wlanEHTMUConfig(242) is also invalid — use wlanEHTMUConfig(64). Always consult the allocation index reference tables.

HE and EHT use completely different index schemes. A 242-tone RU is index 192 for HE but index 64 for EHT. Never mix them.

HE-MU multi-subchannel RU indices signal users per content channel — see references/he-allocation-indices.md.

Preamble Puncturing vs STAID=2046
GoalHEEHT (OFDMA)EHT (non-OFDMA)
Fully puncture subchannelAllocation index 113Allocation index 26PuncturedChannelFieldValue at construction
Disable user data onlySTAID=2046STAID=2046—

STAID=2046 does not puncture — it only disables one user's data.

Non-OFDMA puncturing uses PuncturedChannelFieldValue (1–4 for 80 MHz, mapping to subchannels 1–4). Must be set at construction: wlanEHTMUConfig("CBW80", NumUsers=2, PuncturedChannelFieldValue=3)

Spatial Mapping Rules
NumSpaceTimeStreams < NumTransmitAntennas per RU  →  SpatialMapping = 'Fourier'
NumSpaceTimeStreams == NumTransmitAntennas         →  SpatialMapping = 'Direct'

Using 'Direct' when STS < antennas causes a dimension mismatch error.

Non-OFDMA Is the Default for MU-MIMO

When the user says "MU-MIMO" without mentioning OFDMA or multiple RUs, default to non-OFDMA (single full-bandwidth RU shared by all users):

  • EHT: wlanEHTMUConfig("CBW80", NumUsers=N)

  • HE: Full-band allocation indices (see Patterns section)

Trigger-Based RUIndex From ruInfo

TB config RUIndex values are subcarrier-based positions from ruInfo(cfgMU).RUIndices, not sequential RU numbers. Using wrong indices causes subcarrier overlap errors.

Construction-Time-Only Properties

EHTDUPMode, PuncturedChannelFieldValue, and NumUsers on wlanEHTMUConfig are read-only after construction — pass them as name-value pairs in the constructor. See references/eht-allocation-indices.md for the full list and examples.

Format-Specific Constraints
ConstraintDetails
HT MCS encodes streamsMCS 0-7 = 1 SS, 8-15 = 2 SS, 16-23 = 3 SS, 24-31 = 4 SS. Set NumSpaceTimeStreams = floor(MCS/8) + 1.
DSSS has no OFDM propertiesUse DataRate ('1Mbps'...'11Mbps'). No ChannelBandwidth, MCS, NumTransmitAntennas, or NumSpaceTimeStreams.
HE ER + Upper106ToneRURestricts MCS to 0. The 242-tone ER variant allows MCS 0-2.
VHT GroupID0/63 = SU. 1-62 = MU-MIMO. Silently accepts wrong values.
wlanAPEPLength is SU-onlyWorks for VHT-SU, HE-SU, and EHT-MU single-user (non-OFDMA). Errors on any MU/OFDMA config — use iterative transmitTime loop.
Do not fabricate IEEE versionsDirect the user to the WLAN Toolbox Release Notes.

Copyright 2026 The MathWorks, Inc.

Files

references/eht-allocation-indices.md

EHT-MU (802.11be) Allocation Index Reference

wlanEHTMUConfig(allocIdx) takes per-20-MHz-subchannel allocation indices. For 80 MHz, provide a 4-element vector. For 160 MHz, provide an 8-element vector. Valid ranges: 0-25 (per-subchannel), 26-27 (puncturing), 28-30 (continuation), 32-55 (per-subchannel MRU), 64-87 (full-band), 96-127 (large RU/MRU for 80 MHz), 144-151 (large MRU for 160 MHz).

Continuation Indices

When an RU or MRU spans multiple subchannels, use continuation indices on the additional subchannels:

IndexMeaning
28Subchannel is part of a 242-tone allocation
29Subchannel is part of a 484-tone allocation
30Subchannel is part of a 996-tone allocation

Puncturing Indices

IndexMeaning
26Punctured subchannel (no preamble or data)
27Punctured subchannel (alternate encoding)

Use index 26 in the allocation vector to fully puncture a 20 MHz subchannel. This is different from HE, which uses index 113 for puncturing.

% 160 MHz with SC2, SC6, SC7 punctured
cfg = wlanEHTMUConfig([64 26 64 64 64 26 26 64]);

Per-20-MHz Subchannel Indices (0-25)

IndexRU LayoutUsers
026+26+26+26+26+26+26+26+269
126+26+26+26+26+26+26+528
626+26+52+26+52+26+267
726+26+52+26+52+526
1552+52+26+52+525
1626+26+26+26+26+1066
20106+26+26+26+26+266
2452+52+52+524
25106+26+1063

Per-20-MHz MRU Indices (32-55)

These indices produce Multi-Resource Units — non-contiguous tone blocks.

IndexRU LayoutUsersMRU Detail
4026+26+26+26+[26 106]5[26+106] MRU
4352+52+[26 106]3[26+106] MRU
44[106 26]+26+26+26+265[106+26] MRU
47[106 26]+52+523[106+26] MRU
48[106 26]+1062[106+26] MRU + 106
50106+[26 106]2106 + [26+106] MRU

Full-Band Indices

Full-band indices (64+) cannot be used for 20 MHz. A 242-tone RU IS the full 20 MHz band, making it a single-user or full-band MU-MIMO configuration. For both of these, use the string constructor: wlanEHTMUConfig("CBW20") or uhrMUConfig("CBW20"). Use index 64+ only in multi-subchannel vectors for wider bandwidths (e.g., [64 64 64 64] for 80 MHz).

242-tone (indices 64-71, per subchannel)

Users per RU = index - 63.

cfg = wlanEHTMUConfig([64 64 64 64]);  % 80 MHz, 4x242-tone, 1 user each
cfg = wlanEHTMUConfig([65 65 65 65]);  % 80 MHz, 4x242-tone, 2 MU-MIMO each
484-tone (indices 72-79, spans 2 subchannels)

Uses continuation index 29. Users per RU = index - 71.

cfg = wlanEHTMUConfig([72 29]);          % 40 MHz, 484-tone, 1 user
cfg = wlanEHTMUConfig([72 29 72 29]);    % 80 MHz, 2x484-tone, 1 user each
996-tone (indices 80-87, spans 4 subchannels)

Uses continuation index 30. Users per RU = index - 79.

cfg = wlanEHTMUConfig([80 30 30 30]);    % 80 MHz, 996-tone, 1 user
cfg = wlanEHTMUConfig([81 30 30 30]);    % 80 MHz, 996-tone, 2 users
484+242 MRU (indices 96-127, spans 3 subchannels in 80 MHz)

There are four variants depending on which subchannels carry the 484 and 242 parts. Each variant leaves one subchannel free for an independent allocation.

RangeLayoutMRU SubchannelsIndependent SCMixed Pattern
96-103242+484SC2(242) + SC3,SC4(484)SC1[25 28 96 29]
104-111242+484SC1(242) + SC3,SC4(484)SC2[28 25 104 29]
112-119484+242SC1,SC2(484) + SC4(242)SC3[112 29 25 28]
120-127484+242SC1,SC2(484) + SC3(242)SC4[120 29 28 25]

The independent subchannel uses any valid per-subchannel index (0-25, 32-55, or 64-71). In the mixed patterns above, 25 = 106+26+106 layout.

Full-MRU patterns (no independent subchannel, MU-MIMO users on the MRU):

RangeFull-MRU PatternUsers
96-103[96 28 96 96](index - 95) * 3
104-111[28 104 104 104](index - 103) * 3
112-119[112 112 112 28](index - 111) * 3
120-127[120 120 28 120](index - 119) * 3
% 484+242 MRU on SC1+SC2+SC4, independent 106+26+106 on SC3
cfg = wlanEHTMUConfig([112 29 25 28]);  % SC3 independent
% 484+242 MRU on SC1+SC2+SC3, independent 106+26+106 on SC4
cfg = wlanEHTMUConfig([120 29 28 25]);  % SC4 independent
996+484 MRU (indices 144-151, 160 MHz only)

For 160 MHz, a 996+484 MRU spans 6 of the 8 subchannels. The 996-tone part uses continuation index 30, the 484-tone part uses continuation index 29. The remaining 2 subchannels are independent.

Users per MRU = index - 143. Index 144 = 1 user, 151 = 8 users.

% 160 MHz: 996+484 MRU (8 users) + two 242-tone RUs
cfg = wlanEHTMUConfig([151 30 30 30 64 64 29 29]);

In this layout: SC1-4 carry the 996-tone part (index 151 + three 30s), SC5-6 are independent 242-tone RUs (index 64), and SC7-8 carry the 484-tone part (two 29s).

160 MHz allocation vectors are 8 elements (one per 20 MHz subchannel). wlanEHTMUConfig expands a 1x8 vector to a 2x8 AllocationIndex matrix (two content channels).

Common Configurations

80 MHz: Four 242-tone RUs (1 user each)
cfg = wlanEHTMUConfig([64 64 64 64]);
80 MHz: Two 484-tone RUs
cfg = wlanEHTMUConfig([72 29 72 29]);
80 MHz: One 996-tone RU (1 user)
cfg = wlanEHTMUConfig([80 30 30 30]);
80 MHz: 484+242 MRU (1 user) + 106+26+106 on subchannel 4
cfg = wlanEHTMUConfig([120 29 28 25]);
40 MHz: One 484-tone (1 user)
cfg = wlanEHTMUConfig([72 29]);
160 MHz: 242-tone RUs with punctured subchannels
cfg = wlanEHTMUConfig([64 26 64 64 64 26 26 64]);  % SC2, SC6, SC7 punctured
160 MHz: 996+484 MRU (8 users) + two 242-tone
cfg = wlanEHTMUConfig([151 30 30 30 64 64 29 29]);

Key Differences from HE

  • MRU support: EHT indices 32-55 produce MRUs (non-contiguous tone blocks). HE has no MRUs.

  • ruInfo returns cell arrays: ri.RUSizes{r} can be a vector for MRUs (e.g., [484 242]). HE ruInfo returns numeric arrays.

  • PSDU length method: Use psduLength(cfg), NOT getPSDULength(cfg).

  • Non-OFDMA mode: wlanEHTMUConfig("CBW80", NumUsers=N) creates a single full-bandwidth RU with N MU-MIMO users (no allocation index needed). Valid bandwidths: "CBW20", "CBW40", "CBW80", "CBW160", "CBW320". Max 8 users.

Construction-Time-Only Properties

These wlanEHTMUConfig properties are read-only after construction. They must be passed as name-value pairs in the constructor call. Attempting to set them after construction errors with "Unable to set ... because it is read-only."

PropertyPurposeValid ValuesExample
EHTDUPModeEnable EHT DUP modetrue / falsewlanEHTMUConfig("CBW80", EHTDUPMode=true)
PuncturedChannelFieldValuePuncture subchannel (non-OFDMA)0–4 (80 MHz), 0–24 (wider)wlanEHTMUConfig("CBW80", NumUsers=2, PuncturedChannelFieldValue=3)
NumUsersNumber of MU-MIMO users (non-OFDMA)1–8wlanEHTMUConfig("CBW160", NumUsers=4)
PuncturedChannelFieldValue Mapping (80 MHz)
ValuePuncturingPatternMeaning
0[0 0 0 0]No puncturing
1[1 0 0 0]Subchannel 1 punctured
2[0 1 0 0]Subchannel 2 punctured
3[0 0 1 0]Subchannel 3 punctured
4[0 0 0 1]Subchannel 4 punctured
EHT DUP Mode Constraints

EHT DUP duplicates the signal across subchannels. Strict requirements:

  • MCS 14 (BPSK-DCM) — only valid MCS

  • Single user, 1 spatial stream

  • No puncturing

  • 80, 160, or 320 MHz only

cfg = wlanEHTMUConfig("CBW160", EHTDUPMode=true);
cfg.NumTransmitAntennas = 1;
cfg.User{1}.MCS = 14;
cfg.User{1}.NumSpaceTimeStreams = 1;
cfg.User{1}.APEPLength = 500;
cfg.User{1}.ChannelCoding = 'ldpc';

psduLen = psduLength(cfg);
txData = randi([0 1], psduLen * 8, 1);
waveform = wlanWaveformGenerator(txData, cfg);
Non-OFDMA Puncturing Example
% 80 MHz MU-MIMO, 2 users, subchannel 3 punctured
cfg = wlanEHTMUConfig("CBW80", NumUsers=2, PuncturedChannelFieldValue=3);
cfg.NumTransmitAntennas = 4;
cfg.User{1}.NumSpaceTimeStreams = 2;
cfg.User{1}.MCS = 9;
cfg.User{1}.APEPLength = 4000;
cfg.User{1}.ChannelCoding = 'ldpc';
cfg.User{2}.NumSpaceTimeStreams = 2;
cfg.User{2}.MCS = 7;
cfg.User{2}.APEPLength = 4000;
cfg.User{2}.ChannelCoding = 'ldpc';

psduLens = psduLength(cfg);
txData = cell(1, numel(psduLens));
for u = 1:numel(psduLens)
    txData{u} = randi([0 1], psduLens(u) * 8, 1);
end
waveform = wlanWaveformGenerator(txData, cfg);

Notes

  • Per-user config: cfg.User{u}.MCS, cfg.User{u}.APEPLength, etc.

  • Per-RU config: cfg.RU{r}.SpatialMapping.

  • Use showAllocation(cfg) to visualize the RU layout.

  • Max PPDU duration: 5484 μs. Small RUs (26-tone) with large APEPLength will exceed this — reduce APEPLength for small RUs.


Copyright 2026 The MathWorks, Inc.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
MathWorks
Publisher
MathWorks (Official)
Source
matlab/matlab-agentic-toolkit · skills-catalog/wireless-communications/matlab-generate-wlan-waveform · commit 2a7f215
Licence
BSD 2-Clause License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE.md)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by MathWorks.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download matlab-generate-wlan-waveform.zip