>
Home5G NRPHY — Physical LayerFreq-Domain Alloc (RIV)
📶 PHY — Physical LayerAdvanced

Frequency-Domain Resource Allocation (Type 0/1 & RIV) in 5G NR

How the DCI points to PRBs in frequency — resource allocation Type 0 (RBG bitmap) and Type 1 (the RIV start/length code).

📚 3GPP-basedTS 38.214TS 38.212

When a DCI schedules your data, it has to say which Physical Resource Blocks in frequency carry it. That is the job of the Frequency Domain Resource Assignment (FDRA) field — and 5G NR gives the gNB two ways to describe the allocation: a coarse bitmap over Resource Block Groups (Type 0) or a compact contiguous range packed into one number, the Resource Indication Value (RIV, Type 1). This page is grounded in TS 38.214 (resource allocation) and TS 38.212 (DCI field sizing).

Introduction

Frequency-domain resource allocation is the part of a scheduling grant that answers "which subcarriers are mine?". Every DCI that assigns a PDSCH in the downlink or grants a PUSCH in the uplink carries a Frequency Domain Resource Assignment (FDRA) field, and decoding that field into a concrete set of Physical Resource Blocks is one of the first things a UE does with any grant.

It is used constantly and everywhere in the UE lifecycle: the very first SIB1, RAR and paging grants during initial access carry an FDRA, and so does every unicast data grant once the UE is connected. Because the field is blind-decoded as part of the DCI, its size and interpretation are strictly tied to the active Bandwidth Part — a UE never allocates outside its current BWP, and the field width is computed from that BWP's size.

NR deliberately offers two encodings with opposite trade-offs — a flexible bitmap (Type 0) and a compact contiguous range (Type 1) — plus a dynamic-switch mode that lets the gNB pick per DCI. This page walks through both, the exact RIV and bitmap arithmetic, how the field is sized and configured, and the VRB-to-PRB mapping step that decides where the allocated blocks physically land.

Why frequency-domain allocation is needed

💡

In plain words: think of the BWP as a long shelf of numbered boxes (the PRBs). The gNB has to tell you exactly which boxes hold your parcel — but it wants to do it in as few words as possible. If your boxes are one unbroken run, it just says "start at box 20, take 50" — one compact instruction (that is the RIV). If your boxes are scattered to dodge interference, it hands you a checklist with a tick against each group of boxes (that is the Type 0 bitmap). Same shelf, two ways to describe a selection, chosen for whichever is cheaper.

The reason both schemes exist is that DCI is expensive: every bit is blind-decoded many times per slot, so the FDRA field must be as small as possible while still describing whatever the scheduler needs. A single clean contiguous block is by far the most common case and compresses to a handful of bits via the RIV. But sometimes the scheduler wants a non-contiguous pattern — to place different UEs in the best frequency chunks (frequency-selective scheduling) or to avoid a narrowband interferer — and that inherently needs a bitmap. NR gives the gNB both, and a dynamicSwitch mode so it can choose per grant.

What

The FDRA field in a scheduling DCI: a bit field the UE decodes into "these PRBs in my active BWP are mine." Its size and interpretation depend on the resource-allocation type in force for the BWP.

Why

The gNB must point the UE at exact frequency resources with as few bits as possible. A contiguous block needs only a start and length; a scattered pattern needs a bitmap. Offering both lets the gNB minimise overhead per situation.

How

RRC configures resourceAllocation per BWP as resourceAllocationType0, resourceAllocationType1, or dynamicSwitch; with dynamic switch, one MSB of the FDRA field selects the type per DCI.

The FDRA Field and the Two Types

Every scheduling DCI that grants a PDSCH (downlink) or PUSCH (uplink) contains a Frequency Domain Resource Assignment (FDRA) field. This field encodes the set of frequency resources — PRBs — inside the active BWP that carry the transport block. The whole allocation is always relative to the active Bandwidth Part; a UE never allocates outside its current BWP, and the field width itself is computed from the active BWP size.

What

The FDRA field in a scheduling DCI: a bit field whose value the UE decodes into "these PRBs in my active BWP are mine." Its size and interpretation depend on the resource allocation type in force for that BWP.

Why

The gNB must point the UE at exact frequency resources with as few bits as possible — DCI is expensive and every bit is blind-decoded. A contiguous block can be sent in a handful of bits; a scattered pattern needs a bitmap. NR offers both so the gNB picks per situation.

How

RRC configures resourceAllocation per BWP as resourceAllocationType0, resourceAllocationType1, or dynamicSwitch. With dynamicSwitch, one MSB of the FDRA field selects Type 0 vs Type 1 per DCI.

The two schemes answer the same question — which PRBs? — with opposite trade-offs:

  • Type 0 is a bitmap of Resource Block Groups (RBGs). Flexible and non-contiguous, but coarse — you can only select whole groups of PRBs.
  • Type 1 is a single contiguous run described by a start PRB and a length, packed into one Resource Indication Value (RIV). Compact, but the allocation must be one unbroken block.
🎯

Rule of thumb: scattered/fragmented spectrum or frequency-selective scheduling → Type 0 bitmap. A single clean block (and most everyday scheduling) → Type 1 RIV, which is more bit-efficient.

Type 0 — the RBG Bitmap in Full

Type 0 divides the active BWP into Resource Block Groups. An RBG is a set of P consecutive PRBs, and the FDRA field is simply a bitmap with one bit per RBG: bit set = that RBG is allocated, bit clear = it is not. Because any subset of RBGs can be chosen, Type 0 supports non-contiguous, frequency-selective allocations — at the cost of granularity P.

The nominal RBG size P

The RBG size P is not fixed. TS 38.214 gives a table keyed on the BWP size, and RRC picks a column via rbg-Size (config1 or config2). This is the nominal RBG size table — the values are 2, 4, 8, or 16:

BWP size (PRBs)config1 (P)config2 (P)
1 – 3624
37 – 7248
73 – 144816
145 – 2751616

Notice that for the largest BWPs both columns collapse to P = 16 — there is no finer option, because a bitmap over a 275-PRB BWP at P = 8 would already be 35 bits. config2 always trades granularity for a shorter field.

How the bits map to RBGs, including the partial edges

The subtlety is that a BWP does not have to start on a nominal RBG boundary. The RBGs are aligned to Common Resource Block 0 of the carrier, not to the start of the BWP. So the first RBG of the BWP can be smaller than P (its size is P − (N_BWP_start mod P)), and the last RBG can be smaller than P too (its size is (N_BWP_start + N_BWP_size) mod P, or P if that is zero). Every RBG in between is a full P PRBs.

The number of bits in the bitmap is the number of RBGs, N_RBG:

N_RBG = ⌈(N_BWP_size + (N_BWP_start mod P)) / P⌉

first RBG size = P − (N_BWP_start mod P)    last RBG size = (N_BWP_start + N_BWP_size) mod P (or P if 0)

The bitmap is ordered MSB first: the most significant bit corresponds to the lowest-frequency RBG (RBG 0), the next bit to RBG 1, and so on down to RBG N_RBG − 1 in the LSB. When a set bit selects a partial edge RBG, the UE is granted only the PRBs that RBG actually contains — the bitmap position is unchanged, only the number of PRBs behind that bit differs.

💡

Mental model: Type 0 is like ticking cells in a row of buckets aligned to the carrier grid, not to your BWP. Your BWP can begin mid-bucket, so the first and last buckets you can tick may hold fewer than P PRBs. You still cannot tick half a full bucket.

A worked bitmap

Take a BWP of N_BWP_size = 100 PRBs starting at N_BWP_start = 4, with P = 8 (config1, 73–144 range). Then N_BWP_start mod P = 4, so N_RBG = ⌈(100 + 4)/8⌉ = ⌈13⌉ = 13 bits. The first RBG holds 8 − 4 = 4 PRBs; the last RBG holds (4 + 100) mod 8 = 0 → 8 PRBs (a full one). So a 13-bit bitmap like 1 0110 0000 0001 would grant the small 4-PRB first RBG, two full 8-PRB RBGs in the middle, and the final full RBG — a deliberately fragmented, frequency-selective pattern.

Type 1 — Contiguous Allocation and the RIV

Type 1 describes one contiguous run of PRBs with two numbers: the starting resource block RB_start (0-indexed within the BWP) and the number of contiguously allocated blocks L_RBs (which must be at least 1). Rather than send both fields separately, NR jointly encodes them into a single Resource Indication Value (RIV), defined in TS 38.214:

if (L_RBs − 1) ≤ ⌊N_BWP / 2⌋:
    RIV = N_BWP × (L_RBs − 1) + RB_start
else:
    RIV = N_BWP × (N_BWP − L_RBs + 1) + (N_BWP − 1 − RB_start)

where N_BWP = size of the active BWP in PRBs,   0 ≤ RB_start,   1 ≤ L_RBs ≤ N_BWP − RB_start

The two-branch trick keeps every valid (RB_start, L_RBs) pair mapping to a unique RIV in the range 0 … N_BWP×(N_BWP+1)/2 − 1, so the field only needs ⌈log2(N_BWP(N_BWP+1)/2)⌉ bits. The first branch handles short-to-medium lengths; the "else" branch folds long lengths back into the same numeric space.

Worked encodings

Take a wideband 100 MHz carrier at 30 kHz SCS, so N_BWP = 273.

Example A — the whole BWP. RB_start = 0, L_RBs = 273. Check: L_RBs − 1 = 272, and ⌊273/2⌋ = 136. Since 272 > 136 we take the else branch: RIV = 273×(273 − 273 + 1) + (273 − 1 − 0) = 273×1 + 272 = 545.

Example B — a mid-range block. RB_start = 20, L_RBs = 50. Check: L_RBs − 1 = 49 ≤ 136, so the first branch: RIV = 273×(50 − 1) + 20 = 273×49 + 20 = 13377 + 20 = 13397.

Decoding a RIV back

To reverse it, first try the first-branch assumption: L_RBs − 1 = ⌊RIV / N_BWP⌋ and RB_start = RIV mod N_BWP. If the resulting RB_start + L_RBs exceeds N_BWP, the value came from the else branch, so recompute with L_RBs' = N_BWP − (L_RBs − 1) and RB_start' = N_BWP − 1 − RB_start.

Decode RIV = 13397 (N_BWP = 273): ⌊13397/273⌋ = 49 → L_RBs = 50; 13397 mod 273 = 20 → RB_start = 20. Check 20 + 50 = 70 ≤ 273 → first branch valid. Result: start 20, length 50 — matching Example B.

🔑

Why the two branches: a naive RIV = N_BWP×(L_RBs−1) + RB_start would run out of code space for long allocations. Mirroring long lengths into the else branch packs all valid pairs into exactly N_BWP(N_BWP+1)/2 codepoints with no collisions.

More decodes at a glance

Two more concrete decodes for N_BWP = 273, applying the reverse procedure above:

RIV⌊RIV/N_BWP⌋RIV mod N_BWPBranch checkResult
5452 (→ L=3)272 (→ start=272)272 + 3 = 275 > 273 → else branchRB_start = 0, L_RBs = 273 (whole BWP)
1339749 (→ L=50)20 (→ start=20)20 + 50 = 70 ≤ 273 → first branchRB_start = 20, L_RBs = 50
00 (→ L=1)0 (→ start=0)0 + 1 = 1 ≤ 273 → first branchRB_start = 0, L_RBs = 1 (single PRB)
2741 (→ L=2)1 (→ start=1)1 + 2 = 3 ≤ 273 → first branchRB_start = 1, L_RBs = 2

Note how RIV 545 first looks like start = 272, length = 3, but that overruns the BWP, which flags the else branch and flips it to the full-band allocation. That flip is exactly the encoder's mirror running in reverse.

resourceAllocation: Type0, Type1 and dynamicSwitch

Which of the two schemes a UE uses is not left to chance — it is configured per BWP by the RRC field resourceAllocation inside PDSCH-Config / PUSCH-Config. It takes one of three values, and the third changes the shape of the FDRA field itself:

resourceAllocationFDRA field contentField width (bits)
resourceAllocationType0RBG bitmap onlyN_RBG
resourceAllocationType1Single RIV only⌈log2(N_BWP(N_BWP+1)/2)⌉
dynamicSwitch1 MSB flag + max(Type0, Type1) payloadmax(N_RBG, ⌈log2(N_BWP(N_BWP+1)/2)⌉) + 1

With dynamicSwitch, the gNB can pick per DCI. The most significant bit of the FDRA field is the type indicator: MSB = 0 selects Type 0, MSB = 1 selects Type 1. The remaining bits are sized to the larger of the two payloads so both fit, and the shorter type simply ignores (or zero-pads) the surplus bits. That extra bit is the price of runtime flexibility — a small, fixed overhead on every grant.

🎯

Field width follows the BWP: both N_RBG and the RIV bit-count are functions of the active BWP size. So when the UE switches BWP, the FDRA field width changes, and the whole DCI size can change with it — which is why DCI size budgeting (TS 38.212) is tied to the active BWP.

A practical consequence worth internalising: because Type 0 and Type 1 field widths are computed independently and only rarely coincide, dynamicSwitch almost always pays the padding cost on one of the two types. On a mid-size BWP the RIV count and N_RBG can differ by several bits, so whichever type is shorter carries dead bits on every DCI that uses it. Networks that never need non-contiguous grants therefore often pin the BWP to resourceAllocationType1 outright and reclaim both the flag bit and the padding — a small but real saving multiplied across every scheduled slot.

One important carve-out: DCI format 1_0 in a common search space (for example the SIB1, RAR, or paging grants) always uses resource allocation Type 1, regardless of the RRC resourceAllocation setting — there may be no dedicated configuration yet. Its RIV is computed against a fixed reference: the size of CORESET#0 if the UE has one (typical during initial access), otherwise the size of the initial DL BWP. This keeps the field a known, decodable width before any per-UE configuration exists.

Seeing Both Types on the Grid

Picture one BWP of PRBs laid out left to right, with the nominal RBG boundaries marked. Type 0 ticks whole RBGs anywhere (note the smaller first RBG where the BWP starts mid-group); Type 1 marks one contiguous run from RB_start spanning L_RBs blocks.

Type 0 — RBG bitmap (RBG boundaries aligned to CRB grid; first RBG is partial) 1 0 1 1 0 0 1 0 1 0 RBG0 RBG1 RBG2 RBG3 last first RBG = partial (P − N_start mod P PRBs); last RBG may be partial too bitmap 1011001010 → RBGs 0,2,3,6,8 allocated (non-contiguous) Type 1 — contiguous run: RB_start .. RB_start + L_RBs − 1 (one RIV) L_RBs contiguous PRBs RB_start (offset in BWP) whole bar = active BWP (N_BWP PRBs); shaded = allocated block encoded as one RIV
Figure 1. (top) Type 0 selects whole RBGs anywhere in the BWP via a bitmap; the first and last RBG can be smaller than P because the RBG grid is aligned to CRB 0, not to the BWP start. (bottom) Type 1 marks a single contiguous run, given by RB_start and L_RBs, encoded into one RIV.
AspectType 0Type 1
EncodingBitmap, one bit per RBGSingle RIV from RB_start & L_RBs
ContiguityAny subset of RBGs (non-contiguous OK)Must be one contiguous run
GranularityCoarse (P PRBs per bit)Single-PRB start & length
FDRA field sizeN_RBG bits⌈log2(N_BWP(N_BWP+1)/2)⌉ bits
Config knobrbg-Size = config1 / config2(no extra size knob)
Fallback DCI 1_0 (CSS)Not usedAlways Type 1
Best forFrequency-selective / fragmentedCompact contiguous grants
🔀

LTE ↔ NR: LTE also defines resource-allocation Type 0/1/2 and uses the same RIV idea for its contiguous Type 2 — the joint start/length encoding carries straight over. But LTE allocates against the whole system bandwidth with a fixed RBG size derived only from that bandwidth, whereas NR allocates against the active BWP, so the RBG size table, the N_RBG count, and the RIV field width all move with the current BWP. NR also adds the per-DCI dynamicSwitch flag between Type 0 and Type 1, which LTE does not have, and ties everything to CORESET#0/initial DL BWP sizing for the fallback DCI 1_0.

Within the BWP: VRB-to-PRB Mapping and Hopping

One subtlety: what the FDRA allocates are strictly Virtual Resource Blocks (VRBs) inside the active BWP. A further step, the VRB-to-PRB mapping, decides where those VRBs actually land in physical frequency:

  • Non-interleaved mapping: VRB n maps straight to PRB n (within the BWP). What you allocate is what you get, physically contiguous.
  • Interleaved mapping: VRBs are permuted across the band in bundles, spreading a contiguous VRB allocation over scattered PRBs to gain frequency diversity against fading.

The interleaver is a bundle-based block interleaver defined in TS 38.211. Contiguous VRBs are first grouped into resource-block bundles of size L (the bundle size is 2 or 4 PRBs, selected by vrb-ToPRB-Interleaver), and it is the bundles, not individual VRBs, that are written into a two-row/column block interleaver and read out permuted. Bundling keeps the DMRS channel estimate coherent across each bundle while still scattering the allocation across the band. The mode is signalled per DCI (for formats that support it, via a VRB-to-PRB mapping flag) or fixed by fallback rules, and it operates after Type 0/Type 1 has chosen the resource set.

💡

Two questions, in order: Type 0/1 answers "which resource blocks (VRBs)"; VRB-to-PRB mapping answers "where in the physical spectrum those blocks actually sit."

Frequency hopping for PUSCH Type 1

On the uplink, a Type 1 PUSCH can additionally use frequency hopping for diversity. When hopping is enabled, the UE splits the transmission into two hops in frequency. The clever part is where the hop offset comes from: the most significant bits of the FDRA/RIV field are repurposed as the frequency-offset indicator — 1 bit for BWPs of fewer than 50 PRBs (choosing between 2 offset values) and 2 bits for larger BWPs (choosing among 4). The remaining lower bits still carry the RIV, but the RIV is now computed against a reduced BWP size because fewer bits are available. The second hop's start PRB is the first hop's start plus (or wrapped around by) the signalled offset, giving intra-slot or inter-slot hopping.

⚠ Common pitfalls / gotchas

  • Allocating relative to the carrier instead of the BWP. RB_start is 0-indexed within the active BWP, and both the RBG grid alignment and the RIV are BWP-relative — mixing in CRB offsets gives the wrong PRBs.
  • Decoding a RIV with only the first branch. Always run the S+L overrun check; a value like RIV = 545 first looks like start=272/L=3 and only the check reveals it is the full-band else-branch allocation.
  • Forgetting the DCI size changes on BWP switch. N_RBG and the RIV bit-count both track the active BWP, so the FDRA width — and thus the whole DCI size — changes when the UE switches BWP.
  • Overlooking the partial edge RBGs. When the BWP starts mid-RBG, the first (and possibly last) RBG holds fewer than P PRBs; the bitmap position is unchanged but the PRB count behind that bit is smaller.
  • Assuming interleaving reorders arbitrarily. The VRB-to-PRB interleaver works on 2- or 4-PRB bundles, not individual VRBs, precisely to keep each bundle coherent for DMRS-based channel estimation.

Summary

Frequency-domain allocation turns an FDRA field into a concrete set of PRBs inside the active BWP, using one of two encodings. Type 0 is an RBG bitmap: the BWP is divided into groups of P PRBs (P = 2/4/8/16 from the TS 38.214 table and rbg-Size), one bit per RBG, MSB-first, aligned to CRB 0 so the edge RBGs can be partial — flexible and non-contiguous, ideal for frequency-selective scheduling. Type 1 is a single contiguous run encoded as a RIV via the two-branch TS 38.214 formula, sized to ⌈log2(N_BWP(N_BWP+1)/2)⌉ bits — compact, and the everyday default.

Which encoding is in force is set per BWP by resourceAllocation (type0 / type1 / dynamicSwitch, the last adding an MSB type flag per DCI), while the fallback DCI 1_0 in a common search space always uses Type 1 sized against CORESET#0 or the initial DL BWP. Two things then decide where the blocks physically land: VRB-to-PRB mapping (non-interleaved for straight-through placement, or bundle-based interleaving for frequency diversity), and, on the uplink, Type 1 PUSCH frequency hopping that repurposes the top FDRA bits as a hop offset. Keep every quantity BWP-relative, always run the RIV overrun check when decoding, and remember the field width — and the DCI size — move with the BWP.

Quick Q&A

Q&A Quick Q&A

Q. What is a RIV and why encode RB_start and L_RBs together?

A. The Resource Indication Value jointly encodes the start PRB and the length of a contiguous Type 1 allocation into a single number. Joint encoding packs both fields into the minimum bits — only every valid (start, length) pair gets a codepoint — keeping the FDRA field, and therefore the DCI, small.

Q. When would the gNB prefer Type 0 over Type 1?

A. When the allocation needs to be non-contiguous — e.g. frequency-selective scheduling that dodges interference or picks the best RBGs across the band. Type 1 can only describe one contiguous run, so a scattered pattern requires the Type 0 bitmap.

Q. What decides the RBG size P, and how many bitmap bits result?

A. The active BWP size selects a row in the TS 38.214 nominal RBG table, and rbg-Size (config1/config2) selects the column, giving P = 2, 4, 8, or 16. The bitmap has N_RBG = ⌈(N_BWP_size + (N_BWP_start mod P))/P⌉ bits, because the first (and possibly last) RBG can be partial.

Q. In dynamicSwitch, how does the UE know which type a given DCI used?

A. The most significant bit of the FDRA field is a type flag: 0 = Type 0, 1 = Type 1. The rest of the field is sized to the larger of the two payloads, so both fit, and that MSB is one extra bit of overhead per grant.

Q. Which resource allocation type does DCI 1_0 in a common search space use?

A. Always Type 1. Its RIV is sized against CORESET#0 if the UE has one, otherwise the initial DL BWP — a fixed reference that works before any dedicated configuration.

Q. What does the interleaved VRB-to-PRB mapping buy, and how does it work?

A. Frequency diversity. Contiguous VRBs are grouped into bundles of 2 or 4 PRBs and passed through a block interleaver, scattering them across the band while keeping each bundle coherent for DMRS-based channel estimation.

Where frequency allocation connects

Choosing the PRBs is only the frequency half of a grant. The DCI also fixes the time-domain resources, all of it rides on the control channel over the resource grid, and the field widths are governed by DCI format sizing rules.

Time-Domain Resource Allocation & SLIV — the time half of the grantPDCCH & DCI Formats — how the FDRA field is carried and sizedResource Grid & BWP — the PRBs and BWP this allocates within