matlab-generate-wlan-waveform

$npx mdskill add matlab/matlab-agentic-toolkit/matlab-generate-wlan-waveform

Generate standard-compliant IEEE 802.11 waveforms for testing and simulation.

  • Creates WLAN test waveforms for any 802.11 standard from 802.11a to 802.11bn.
  • Depends on MATLAB WLAN Toolbox for waveform generation and configuration.
  • Selects PHY format, payload size, and MAC frame type based on user request.
  • Returns time-domain IQ waveform and optional plots for analysis.

SKILL.md

.github/skills/matlab-generate-wlan-waveformView on GitHub ↗
---
name: matlab-generate-wlan-waveform
description: >
  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.
license: MathWorks BSD-3-Clause
metadata:
  author: MathWorks
  version: "1.0"
---

# 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

| Standard | Marketing | Config Object | Users |
|----------|-----------|---------------|-------|
| 802.11b | Wi-Fi 1 | `wlanNonHTConfig` (DSSS) | SU only |
| 802.11a/g | Wi-Fi 1/3 | `wlanNonHTConfig` | SU only |
| 802.11n | Wi-Fi 4 | `wlanHTConfig` | SU only |
| 802.11ac | Wi-Fi 5 | `wlanVHTConfig` | SU or MU-MIMO |
| 802.11ax | Wi-Fi 6 | `wlanHESUConfig` | SU only |
| 802.11ax | Wi-Fi 6 | `wlanHESUConfig` (ExtendedRange) | SU — extended range |
| 802.11ax | Wi-Fi 6 | `wlanHEMUConfig(allocIdx)` | OFDMA and/or MU-MIMO |
| 802.11ax | Wi-Fi 6 | `wlanHETBConfig` | SU uplink (trigger-based) |
| 802.11be | Wi-Fi 7 | `wlanEHTMUConfig(allocIdx)` | OFDMA and/or MU-MIMO / MRU |
| 802.11be | Wi-Fi 7 | `wlanEHTMUConfig("CBW...")` | Non-OFDMA MU-MIMO (full-band RU) |
| 802.11be | Wi-Fi 7 | `wlanEHTMUConfig("CBW...", EHTDUPMode=true)` | SU — DUP mode (MCS 14 only) |
| 802.11be | Wi-Fi 7 | `wlanEHTTBConfig` | SU uplink (trigger-based) |
| 802.11bn | Wi-Fi 8 | `uhrMUConfig(allocIdx)` | OFDMA / MU-MIMO / UEQM (example helpers) |
| 802.11bn | Wi-Fi 8 | `uhrMUConfig("CBW...")` | Non-OFDMA MU-MIMO (example helpers) |
| 802.11bn | Wi-Fi 8 | `uhrTBConfig` | SU uplink / DRU (example helpers) |
| 802.11bn | Wi-Fi 8 | `uhrELRConfig` | SU 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](references/he-allocation-indices.md)
and [references/eht-allocation-indices.md](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](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**.

| Config | Function | Example |
|--------|----------|---------|
| `wlanNonHTConfig` | `wlanPSDULength(cfg, 'TxTime', us)` | `cfg.PSDULength = wlanPSDULength(cfg, 'TxTime', 500);` |
| `wlanHTConfig` | `wlanPSDULength(cfg, 'TxTime', us)` | `cfg.PSDULength = wlanPSDULength(cfg, 'TxTime', 1000);` |
| `wlanVHTConfig` (SU only) | `wlanAPEPLength(cfg, 'TxTime', us)` | `cfg.APEPLength = wlanAPEPLength(cfg, 'TxTime', 2000);` |
| `wlanHESUConfig` | `wlanAPEPLength(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 config | Iterative `transmitTime` loop | See 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):

```matlab
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.

| Config | How to get PSDU length | Notes |
|--------|----------------------|-------|
| `wlanNonHTConfig` | `cfg.PSDULength` | Settable property |
| `wlanHTConfig` | `cfg.PSDULength` | Settable property |
| `wlanVHTConfig` | `cfg.PSDULength` | Read-only property (derived from APEPLength). Vector for MU. |
| `wlanHESUConfig` | `getPSDULength(cfg)` | Method call. Not a property. |
| `wlanHEMUConfig` | `getPSDULength(cfg)` | Method call. Returns vector (one per user). |
| `wlanHETBConfig` | `getPSDULength(cfg)` | Method call. Same as HE-SU/HE-MU. |
| `wlanEHTMUConfig` | `psduLength(cfg)` | **Different method name** from HE. Returns vector. |
| `wlanEHTTBConfig` | `psduLength(cfg)` | Same method name as EHT-MU. |

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

## Key Functions

| Function | Purpose |
|----------|---------|
| `wlanWaveformGenerator(bits, cfg)` | Generate time-domain IQ waveform |
| `wlanSampleRate(cfg)` | Get sample rate for the configuration — always use this |
| `wlanHETBConfig` | Configure HE trigger-based uplink (single STA) |
| `wlanEHTTBConfig` | Configure EHT trigger-based uplink (single STA) |
| `wlanMACFrame(payload, cfgMAC)` | Generate MAC frame bits (see [references/mac-frame-properties.md](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](references/documentation-links.md).

## Patterns

### Single-User Waveform with Target Duration

```matlab
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

```matlab
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](references/he-allocation-indices.md) for
the full index-to-RU mapping.

```matlab
% 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):**

| Index | RU Layout | Users |
|-------|-----------|-------|
| 0 | Nine 26-tone | 9 |
| 96 | Two 106-tone | 2 |
| 112 | Four 52-tone | 4 |
| 192 | One 242-tone | 1 |
| 193 | One 242-tone | 2 (MU-MIMO) |
| 200 | One 484-tone (40 MHz pair) | 1 |
| 208 | One 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](references/eht-allocation-indices.md) for
the full mapping.

```matlab
% 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

```matlab
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):

```matlab
% 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:

| Bandwidth | Index for N users | Zero-user index |
|-----------|-------------------|-----------------|
| 20 MHz | `192 + N - 1` | N/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](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](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.

### Trigger-Based (TB) Uplink

See [references/trigger-based-uplink.md](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](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.

| Format | How to get PSDU length | Wrong approach |
|--------|----------------------|---------------|
| Non-HT, HT | `cfg.PSDULength` (property) | `getPSDULength(cfg)` — errors |
| VHT | `cfg.PSDULength` (read-only) | Setting it — errors |
| HE-SU, HE-MU, HE-TB | `getPSDULength(cfg)` | `psduLength(cfg)` — errors |
| EHT-MU, EHT-TB | `psduLength(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](references/he-allocation-indices.md).

### Preamble Puncturing vs STAID=2046

| Goal | HE | EHT (OFDMA) | EHT (non-OFDMA) |
|------|-----|-------------|-----------------|
| Fully puncture subchannel | Allocation index **113** | Allocation index **26** | `PuncturedChannelFieldValue` at construction |
| Disable user data only | STAID=2046 | STAID=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](references/eht-allocation-indices.md)
for the full list and examples.

### Format-Specific Constraints

| Constraint | Details |
|-----------|---------|
| **HT MCS encodes streams** | MCS 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 properties** | Use `DataRate` ('1Mbps'...'11Mbps'). No `ChannelBandwidth`, `MCS`, `NumTransmitAntennas`, or `NumSpaceTimeStreams`. |
| **HE ER + Upper106ToneRU** | Restricts MCS to 0. The 242-tone ER variant allows MCS 0-2. |
| **VHT GroupID** | 0/63 = SU. 1-62 = MU-MIMO. Silently accepts wrong values. |
| **`wlanAPEPLength` is SU-only** | Works 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 versions** | Direct the user to the [WLAN Toolbox Release Notes](https://mathworks.com/help/wlan/release-notes.html). |

----

Copyright 2026 The MathWorks, Inc.

More from matlab/matlab-agentic-toolkit

SkillDescription
matlab-access-datafeed>
matlab-add-awgnRead BEFORE writing any code that adds Additive White Gaussian Noise (AWGN) to signals and converts between SNR, Eb/No, Es/No, and per-subcarrier SNR for communications simulations, using awgn(), convertSNR(), berawgn(). The default MATLAB patterns for AWGN (e.g., 'measured' option, manual SNR formulas) produce subtly incorrect results. This skill specifies the correct calling conventions, required function usage, and critical anti-patterns that must be avoided.
matlab-analyze-ams-waveformAnalyze AMS waveform data using Mixed-Signal Blockset utilities: phase noise measurement, clock jitter, anti-aliased resampling, timing measurements, lock time, INL/DNL, ADC/DAC calibration, HSpice import. Use when analyzing time-domain voltage from PLL/VCO/clock simulations, measuring phase noise from variable-step solver output, computing jitter, or resampling non-uniform data.
matlab-analyze-dataAnalyze data using MATLAB. Use when the task involves tables, timetables, time-series data, numeric arrays, sensor matrices, or gridded data — including but not limited to exploring, filtering, sorting, cleaning, transforming, aggregating, smoothing, padding, trimming, and answering questions about data. MATLAB provides extensive, easy-to-use built-in functions for these workflows with no additional products required.
matlab-analyze-dependenciesAnalyze the effective toolbox file set to produce a Dependency Manifest — classify all transitive dependencies as included, product, add-on, or external-unresolved, then present resolution options with tradeoffs. Use after matlab-define-toolbox-api when the spec is approved.
matlab-analyze-emS-parameters, insertion loss, fields, currents, mesh control, and solver selection for RF PCB performance validation. TRIGGER: user asks to compute S-parameters, analyze insertion/return loss, extract fields or currents, compare MoM vs FEM, or control mesh for any RF PCB component. Invoke BEFORE writing sparameters() or solver code — API is non-obvious. SKIP: designing or creating components (use the specific matlab-design-pcb-* skill), material/stackup setup only (use matlab-manage-pcb-material), optimization sweeps (use matlab-optimize-pcb-design), PDN/IR-drop analysis (use matlab-analyze-pcb-pdn).
matlab-analyze-installed-antennaAnalyze antennas installed on electrically large conducting platforms using MATLAB Antenna Toolbox. Loads platform geometry from STL/STEP/IGES, installs antenna elements, selects electromagnetic solvers (MoM-PO, FMM, MoM), and computes patterns, impedance, coupling, and efficiency. Use when the user wants to model an antenna on a vehicle, aircraft, ship, satellite, or other large structure.
matlab-analyze-pcb-pdnPDN DC voltage/current analysis, IR drop, design rule checking, and multi-net batch analysis on imported PCB layouts. TRIGGER: user asks about power integrity, PDN analysis, IR drop, voltage distribution, current density, power nets, or design rule checking on a PCB. Invoke BEFORE writing code — the PDN API chain is specialized and non-obvious. SKIP: importing a PCB file (use matlab-read-pcb-layout), EM field/S-parameter extraction (use matlab-analyze-em), material/stackup setup only (use matlab-manage-pcb-material), transmission line design (use matlab-design-pcb-txline).
matlab-analyze-rcsCalculate and visualize monostatic and bistatic radar cross section (RCS) using MATLAB Antenna Toolbox. Computes RCS of platforms, antennas, and arrays with PO, MoM, and FMM solvers, supporting HH/VV/HV/VH polarization, GPU acceleration, and near-field observation. Use when the user wants to compute, plot, or analyze radar cross section.
matlab-analyze-rf-propagationAnalyze RF propagation and plan wireless sites using MATLAB Antenna Toolbox. Creates transmitter/receiver sites, computes signal strength, coverage maps, SINR, line-of-sight, and ray tracing in geographic or indoor environments. Supports multiple propagation models (free-space, close-in, Longley-Rice, ray tracing, rain/gas/fog), custom terrain, building data, and directional antennas. Use when the user wants to compute coverage, signal strength, path loss, SINR, ray tracing, or plan a wireless network.