|
BWP(Carrier Bandwidth Part) in Detail
This page is about another new concept in NR called BWP(BandWidth Part). BWP is a part of the total channel bandwidth configured for a cell that is used for a UE at a specific moment of operation. Usually a cell configures multiple BWPs out of the total channel bandwidth and select a specific one at each moment of operation. I think the purpose and concept of BWP is very similar to NarrowBand in LTE M1.
Definition of BWP
According to 38.211 4.4.5, A carrier bandwidth part is defined as follows :
Carrier Bandwidth Part is a contiguous set of physical resource blocks,selected from a contiguous subset of the common resource blocks for a given numerology(u) on a given carrier. It can be illustrated as below.
This single sentence from the specification is short, but almost every word in it is carrying weight. So before looking at the illustration, let me take the definition apart word by word, because each part answers a different question about what a BWP actually is.
"a contiguous set of physical resource blocks" - a BWP cannot have holes in it. You are not allowed to build one BWP out of RB 0 to 9 plus RB 50 to 59. It has to be one single unbroken block of spectrum. This restriction is not an accident : it is exactly what allows the UE to narrow its receiver down to just that block, and that is where most of the power saving benefit of BWP comes from."selected from a contiguous subset of the common resource blocks" - this is where the two different resource block numbering systems come from. Thecommon resource blocks (CRB) are the absolute grid that runs across the whole carrier, and a BWP is carved out of that grid. Inside the BWP, however, the resource blocks are renumbered from 0 asphysical resource blocks (PRB) . So a BWP is fully described by just two numbers : where it starts in CRB terms, and how many resource blocks long it is."for a given numerology (u)" - this is the most important part of the definition and it is the easiest one to read past.Each BWP carries its own numerology , i.e, its own subcarrier spacing and cyclic prefix. Two BWPs on the same carrier can use 15 kHz and 60 kHz spacing respectively. This is what makes BWP much more than a simple 'use a narrower band' feature - switching BWP can also mean switching the whole frame structure the UE is working with."on a given carrier" - a BWP belongs to one carrier (one serving cell). If the UE is doing carrier aggregation, every serving cell has its own independent set of BWPs and its own active BWP.
It is just as useful to notice what the definition does
The two numbers mentioned above - the starting point and the length - are not just a way of talking. They are literally what gets signalled to the UE, packed into a single RRC field called
NOTE : Maximum 4 BWP can be specified in DL and UL. Following illustration is only an example showing the case of 3 BWP. (NOTE : CRB in this illustration stands for Carrier Resource Block which is numbered from the one end through the other end of Carrier Band (this is a kind of global resource block), the PRB stands for Physical Resource Block is the resource blocks numbered within each BWP).

It is worth walking through this illustration slowly, because almost every symbol that appears later on this page is already in it.
- Start at the very bottom. The green block marked
CRB0 is where the common resource block grid begins, and the arrow underneath it points atPoint A . Everything else in the picture is measured from here. Point A is the origin of the coordinate system, and it is shared by the network and the UE. - Each of the three bandwidth parts is then described by exactly the two numbers mentioned above.
N(start,BWP i) is how far the BWP begins from CRB0, counted in common resource blocks, andN(size,BWP i) is how many resource blocks it contains. Notice that all three start arrows on the left are drawn from the same place - they are all measured from CRB0, not from the BWP below. - Look at the numbering inside each of the blue blocks. Every BWP starts again at
PRB0 and counts up to its own PRB N. So there are three different resource blocks in this picture that are all called 'PRB0'. This is exactly why the picture carries two separate labels at the bottom : "PRB 0 within a carrier bandwidth" pointing at the first block of BWP 0, and "PRB 0 in Reference Resource Block" pointing at CRB0. - The blue arrow on the far right is the
carrier bandwidth , i.e, the whole channel the cell is operating on. The BWPs live inside it, and none of them has to fill it.
The consequence of all this is a point that confuses many people when they first read a log :
Point A indicates a common reference point for resource block grids and is obtained from the following higher-layer parameters as described in 38.211 - 4.4.4.2:
- PRB-index-DL-common for a PCell downlink represents the frequency offset between point A and the lowest subcarrier of the lowest resource block of the SS/PBCH block used by the UE for initial cell selection;
- PRB-index-UL-common for a PCell uplink in paired spectrum represents the frequency offset between point A and the frequency location based on ARFCN of the uplink indicated in SIB1;
- PRB-index-UL-common for a PCell uplink in unpaired spectrum represents the frequency offset between point A and the lowest subcarrier of the lowest resrouce block of the SS/PBCH block used by the UE for initial cell selection;
- PRB-index-DL-Dedicated for an SCell downlink represents the frequency offset between point A and the frequency location based on ARFCN in the higher-layer SCell configuration;
- PRB-index-UL-Dedicated for an SCell uplink represents the frequency offset between point A and the frequency location based on ARFCN in the higher-layer SCell configuration;
- PRB-index-SUL-common for a supplementary uplink represents the frequency offset between point A and the frequency location based on ARFCN in the higher-layer SUL configuration.
Carrier Bandwidth Part allocation for DL and UL
The previous section explained what a BWP
Almost everything in the two lists below comes out of one pair of numbers :
The distinction between those two words is the single most important idea in this section, so let me spell it out.
Configured means the BWP has been written into the UE's RRC configuration. The UE knows its start point, its size, its numerology, its CORESETs and so on - but it is not using it. Think of it as a preset that has been stored but not selected.Active means this is the one the UE is actually working on right now. Exactly one downlink BWP and exactly one uplink BWP are active per serving cell at any instant.
This separation is what makes the whole feature practical. Because all four BWPs are configured in advance, moving from one to another does not need an RRC reconfiguration - it only needs a couple of bits in a DCI, or a timer expiring. That is why BWP switching can happen in a few slots rather than in tens of milliseconds.
The second thing that runs through both lists is the rule that the UE does not receive or transmit anything
The same rule immediately explains the CORESET requirements in the downlink list, which otherwise look like arbitrary bookkeeping. If the UE only listens inside the active BWP, then anything the network wants to say to it has to be sent inside that BWP - including the message that tells it to switch to another one. A downlink BWP with no CORESET in it would therefore be a trap : the UE would move in, stop hearing the network, and have no way of being told to come back. Hence every DL BWP must carry at least one CORESET with a UE specific search space, and on the primary carrier at least one BWP must also carry a common search space so that broadcast and paging type signalling still has somewhere to land.
The SSB requirement in the list works the same way. A BWP has to be at least as wide as the SS Block, but it does not have to contain one. If the active DL BWP happens not to contain the SSB, the UE simply cannot perform SSB based synchronisation and measurement while it is there, which is something the network has to plan around.
Finally, a word about how the downlink and uplink lists relate to each other, because this depends on the duplex mode :
- In
FDD (paired spectrum) the downlink and the uplink are on different frequencies, so the DL BWPs and the UL BWPs are configured and switched independently of each other. - In
TDD (unpaired spectrum) they are not independent. A DL BWP and an UL BWP that share the same bwp-Id are treated as a pair, and the UE expects both of them to have the same centre frequency. Switching one therefore switches the other as well - which makes sense, since a TDD radio cannot be tuned to two different places at the same time.
With that in mind, the detailed rules are as follows.
< Downlink >
- A UE can be configured with up to four carrier bandwidth parts
- The bandwidth of each BW should be equal or greater than SS Block BW, but it may or may not contain SS Block.
- Only one carrier bandwidth part can be active at a given time
- The UE is not expected to receive PDSCH, PDCCH, CSI-RS, or TRS outside an active bandwidth part.
- Each DL BWP include at least one CORESET with UE Specific Search Space (USS).
- In primary carrier, at least one of the configured DL BWPs includes one CORESET with common search space (CSS)
< Uplink >
- A UE can be configured with up to four carrier bandwidth parts
- Only one carrier bandwidth part can be active at a given time
- If a UE is configured with a supplementary uplink
- The UE can in addition be configured with up to four carrier bandwidth parts in the supplementary uplink
- Only one carrier bandwidth part can be active at a given time
- The UE shall not transmit PUSCH or PUCCH outside an active bandwidth part.
Mapping between nCRB and nPRB
nCRB indicates a resource block location in common resource block, nPRB indicates a resource block within a specific carrier bandwidth part. In other words, you can think of nCRB is a position in an absolute (reference) coordinate system and nPRB is a position in a relative coordinate system. The relationship between nCRB and nPRB is defined as follows (38.211 v2.0.0 - 4.4.4.4).
![]()
This is probably the simplest formula in the whole of 38.211 - it is one addition - but it is worth slowing down on, because it is used constantly and because getting it backwards is a very common source of confusion when reading a log.
Read the formula as a
Three details in the formula are worth pointing out explicitly.
It only runs in one direction as written. The formula converts PRB into CRB. Going the other way is just a subtraction, n(PRB) = n(CRB) - N(start,BWP), but that result is only meaningful if the resource block actually falls inside the BWP, i.e, if the answer lies between 0 and N(size,BWP) - 1. If it does not, the question simply has no answer, because that resource block is not part of the BWP at all.N(start,BWP) is measured from CRB 0, which is Point A - not from the BWP below it and not from the edge of the carrier. This is the same starting arrow that appeared in the illustration in the Definition of BWP section.The subscript i (the BWP index) is doing real work. There is a different N(start) for every configured BWP, so the very same n(PRB) translates into a different n(CRB) depending on which BWP happens to be active. That is not a side effect of the formula ; it is the whole point of it.
This can be illustrated as an example shown below.

The illustration works through one example for each of the three bandwidth parts, and if you read the three labels on the left together the pattern becomes obvious.
- For
PRB0 of BWP 0 the label reads n(CRB) = 0 + N(start,BWP 0). The PRB index contributes nothing here because it is zero, so the answer is just the starting offset of that BWP. - For
PRB1 of BWP 1 it reads n(CRB) = 1 + N(start,BWP 1). One step up inside the BWP means one step up in the common grid as well. - For
PRB N3 of BWP 2 it reads n(CRB) = N3 + N(start,BWP 2). Same rule again, this time at the top edge of the BWP.
So nothing else enters the calculation. The index inside the BWP contributes, the start of the BWP contributes, and that is all.
Before putting real numbers into this, it is worth being clear about
Bandwidth part indicator (0, 1 or 2 bits) - this sayswhich BWP . It is 0 bits if there is nothing to choose from, 1 bit for two configured BWPs and 2 bits for three or four.Frequency domain resource assignment , usually shortened to FDRA - this sayswhich resource blocks inside that BWP . For a Type 1 (contiguous) allocation it is a single coded number called RIV which packs together the starting resource block and the length ; for a Type 0 allocation it is a bitmap of resource block groups.
So the BWP indicator on its own would never be enough. It tells the UE where to tune, but not where inside that band its data is sitting. The FDRA answers that second question, and it counts
Now let us put some real values in. Suppose the three BWPs start at CRB 0, CRB 40 and CRB 80, and in each case the FDRA decodes to a starting resource block of 3.
|
Active BWP |
N(start,BWP) |
Start RB decoded from the FDRA |
Which resource block that really is |
|
BWP 0 |
0 |
PRB 3 |
CRB 3 |
|
BWP 1 |
40 |
PRB 3 |
CRB 43 |
|
BWP 2 |
80 |
PRB 3 |
CRB 83 |
The FDRA decodes to the same starting resource block in all three rows, and yet the UE ends up transmitting or receiving on three completely different pieces of spectrum.
Two practical consequences follow from this, and both of them catch people out.
The size of the FDRA field changes with the BWP. The number of bits the field needs depends on how many resource blocks the BWP contains, so switching to a BWP of a different size does not only move the frequency, it can also change the length of the DCI itself. This creates an obvious chicken and egg problem when a DCI is the thing ordering the switch : the UE has to decode the DCI before it knows it is being moved. 3GPP solves it by fixing thesize of the DCI according to the currently active BWP, whileinterpreting the fields according to the newly indicated one, padding or truncating the FDRA field as needed. It is also one of the reasons a BWP switch takes a measurable amount of time rather than happening instantly.The CRB grid itself depends on the numerology. Common resource blocks are numbered from 0 upwards separatelyfor each subcarrier spacing , with CRB 0 of every grid lined up on Point A. So 'CRB 43' in a 15 kHz grid and 'CRB 43' in a 30 kHz grid are not the same frequency - the second one is twice as far from Point A. Since each BWP carries its own numerology, you have to know the subcarrier spacing before a CRB number can be turned into a frequency.
Putting the last point together, the full chain from a scheduling grant to an actual frequency runs like this : the DCI gives you
BWP types
There are several different types of BWPs : Initial BWP, firstActiveBWP, Default BWP and (regular) BWPs. These are defined in RRC message as follows. Regarding the role of each BWP, refer to the diagram in this section and RRC parameter description in this section.
There is one idea that makes this whole section much easier, and it is the thing that trips people up most often here.
The roles are assigned simply by pointing an ID at a BWP. That means one and the same BWP can hold several roles at once : it is perfectly normal for BWP #1 to be the first active BWP and the default BWP at the same time, and for BWP #0 to be the initial BWP and the default BWP at the same time. So when a document says 'the default BWP', it is not describing a special sort of BWP - it is describing whichever BWP the defaultDownlinkBWP-Id happens to be pointing at.
With that in mind, the four terms line up like this.
|
Term |
What it is in RRC |
What it is for |
|
|
initialDownlinkBWP / initialUplinkBWP. Always |
The BWP the UE lives in before it has any dedicated configuration - this is where initial access happens, and it is derived from the cell's broadcast information. It always exists, and it is the safety net the UE can always fall back to. |
|
|
The entries of downlinkBWP-ToAddModList / uplinkBWP-ToAddModList, carrying |
The ordinary working bandwidth parts that the network defines for this particular UE. These are the ones the UE is switched between during normal operation. |
|
|
firstActiveDownlinkBWP-Id / firstActiveUplinkBWP-Id. A |
Answers the question "which BWP should be active the moment this configuration takes effect ?". For an SpCell that is when the RRC reconfiguration is applied ; for an SCell it is when the SCell is activated by MAC. If it is absent, the reconfiguration does not force any BWP switch. |
|
|
defaultDownlinkBWP-Id. Again a |
Answers the question "where should the UE go when nothing is happening ?". When the bwp-InactivityTimer expires the UE falls back to this one. If the field is absent, the initial BWP is used as the default. |
So two of the four are actual configurations, and two of them are just pointers. Keeping that separation in your head is most of the battle.
< BWP configuration in ENDC RRCReconfig >

Reading this tree from the top, a few things are worth pointing out.
- The initial BWP appears
twice , and this is not a mistake. Once underspCellConfigCommon , which is the cell specific part that every UE in the cell shares, and once underspCellConfigDedicated , which is the UE specific part for the same BWP #0. This common plus dedicated split is exactly what the second illustration below is about. - The orange comment on the right of the figure points at the real difference between BWP #0 and the rest :
the initial BWP has no bwp-Id field at all . It does not need one, because the specification simply declares that the initial BWP is ID 0. The four entries in downlinkBWP-ToAddModList, on the other hand, each carry their own bwp-Id, which is what the other pointers refer to. - The green and yellow arrows are the 'roles are just pointers' idea drawn out.
firstActiveDownlinkBWP-id anddefaultDownlinkBWP-id sit at the bottom of the list and each of them selectsone of the BWPs above - and notice that the arrows reach the initial BWP as well, not only BWP[1] to BWP[4]. That is how BWP #0 can be made the default. - Look at the uplink branch at the bottom and compare it with the downlink branch. It has InitialUplinkBWP, uplinkBWP-ToAddModList and firstActiveUplinkBWP-id - but no default. This is the same asymmetry mentioned in the note above, now visible in the structure itself.
Using the basic types and configuration structure as shown above, you can take various options of BWP configuration as shown below.

Source : A Primer on Bandwidth Parts in 5G New Radio
This second illustration is more interesting than it first looks, so it is worth decoding. Every BWP in the picture is built out of up to four blocks, and the legend at the bottom tells you what they are :
Option 1 : BWP #0 hasonly the Common blocks. It is a usable BWP, but it has no dedicated configuration of its own.Option 2 : BWP #0 has the Common blocksand the dedicated blocks, so it looks exactly like any other BWP.
Now look at the red numbers at the right hand end of each row, because that is where the consequence shows up. In Option 1 the network may go on adding BWPs up to
Since the UE can only support four configured BWPs in total, the arithmetic is simply :
- Option 1 - BWP #0 does not count, so the four slots are #1, #2, #3 and #4.
- Option 2 - BWP #0 does count, so it takes one of the four slots and only #1, #2 and #3 are left.
Which option to use is therefore a real trade off rather than a matter of taste.
Option 1 gives you one more usable BWP , but BWP #0 is then limited. With no dedicated configuration there is no UE specific search space in it, so the UE can only be scheduled there with the fallback DCI formats - and as explained earlier, DCI format 1_0 has no bandwidth part indicator. That meansgetting out of BWP #0 needs an RRC reconfiguration rather than a quick DCI based switch.Option 2 makes BWP #0 a first class citizen that can be switched into and out of by DCI just like any other BWP, at the cost of one BWP slot.
One last practical remark. In both options the illustration says the network
RRC Parameters for BandwidthPart Configuration
Everything described so far - the start and the size of a BWP, its numerology, the four configured BWPs, the first active one, the default one and the inactivity timer - has to be written down somewhere and sent to the UE. This section is that 'somewhere' : the ASN.1 of TS 38.331.
A raw ASN.1 dump is hard to read cold, so it is worth having the shape of it in your head before you start. The BWP configuration is not one flat structure. It is a
ServingCellConfig <-- one instance per serving cell | |-- initialDownlinkBWP --------> BWP-DownlinkDedicated (the dedicated part of BWP #0) |-- downlinkBWP-ToAddModList --> BWP-Downlink (1..4) | |-- bwp-Id | |-- bwp-Common -----> BWP-DownlinkCommon | | |-- genericParameters --> BWP | |-- bwp-Dedicated --> BWP-DownlinkDedicated |-- downlinkBWP-ToReleaseList |-- firstActiveDownlinkBWP-Id ... a BWP-Id, i.e, just a pointer |-- defaultDownlinkBWP-Id ....... a BWP-Id, i.e, just a pointer |-- bwp-InactivityTimer | |-- uplinkConfig --------------> UplinkConfig | |-- initialUplinkBWP ------> BWP-UplinkDedicated | |-- uplinkBWP-ToAddModList -> BWP-Uplink (1..4) | | (same three part structure as BWP-Downlink above) | |-- uplinkBWP-ToReleaseList | |-- firstActiveUplinkBWP-Id | |-- supplementaryUplink -------> UplinkConfig (a second, independent set for SUL)
Three things in that tree are worth pointing out, because once you see them the ASN.1 below stops looking arbitrary.
Every BWP is built from three parts. BWP-Downlink is nothing more than an identity (bwp-Id) plus a common part plus a dedicated part, andBWP-Uplink has exactly the same shape. Once you have understood one of them you have understood all four.The frequency itself is buried three levels down. The thing that actually says where the BWP is and how wide it is - locationAndBandwidth, subcarrierSpacing, cyclicPrefix - lives in the little IE called simplyBWP , which is reached as BWP-Downlink > bwp-Common > genericParameters. It is easy to hunt for it at the top level and not find it. Everything else in the tree is either an identifier, a pointer, or channel configuration that happens to be per BWP.Common and dedicated mean cell specific and UE specific. TheCommon parts hold what every UE in the cell must agree on and they line up with what is broadcast in system information ; theDedicated parts hold what belongs to this one UE. This is exactly the split that Option 1 and Option 2 in the BWP types section were about.
Two conventions of 38.331 also show up all over the listing below and are worth knowing, because they are not specific to BWP.
ToAddModList and ToReleaseList - RRC does not resend the whole configuration every time. It sends a delta : the entries indownlinkBWP-ToAddModList are added or modified, the IDs listed indownlinkBWP-ToReleaseList are deleted, and any BWP that is mentioned in neither list is simply left exactly as it was. This is why you can add one BWP without disturbing the other three.The -- Need and -- Cond comments on the right - these are not documentation, they are normative. They tell the UE what to do when a field isabsent from a message.
|
Comment |
Means |
What the UE does if the field is not in the message |
|
-- Need M |
Maintain |
Keeps whatever value it already had. The field is stored, so leaving it out is the way of saying "no change". |
|
-- Need N |
No action |
Nothing. These are one shot fields that are not stored at all - their presence triggers a single action and that is the end of it. |
|
-- Need R |
Release |
Releases the current value. Here, leaving the field out is |
|
-- Need S |
Specified |
Whatever the field description says. defaultDownlinkBWP-Id is a good example : the text tells you that if it is absent the UE uses the initial BWP as the default. |
|
-- Cond xxx |
Conditional |
Whether the field may or must be present depends on a condition, which is written out in a small table underneath the IE in the specification. For example bwp-Common is |
Following is based on
ServingCellConfig ::= SEQUENCE { tdd-UL-DL-ConfigurationDedicated TDD-UL-DL-ConfigDedicated OPTIONAL, -- Cond TDD initialDownlinkBWP BWP-DownlinkDedicated OPTIONAL, -- Need M downlinkBWP-ToReleaseList SEQUENCE (SIZE (1..maxNrofBWPs)) OF BWP-Id OPTIONAL, -- Need N downlinkBWP-ToAddModList SEQUENCE (SIZE (1..maxNrofBWPs)) OF BWP-Downlink OPTIONAL, -- Need N firstActiveDownlinkBWP-Id BWP-Id OPTIONAL, -- Cond SyncAndCellAdd bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500, ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8, spare7, spare6, spare5, spare4, spare3, spare2, spare1 } OPTIONAL, --Need R defaultDownlinkBWP-Id BWP-Id OPTIONAL, -- Need S uplinkConfig UplinkConfig OPTIONAL, -- Need M supplementaryUplink UplinkConfig OPTIONAL, -- Need M pdcch-ServingCellConfig SetupRelease { PDCCH-ServingCellConfig } OPTIONAL, -- Need M pdsch-ServingCellConfig SetupRelease { PDSCH-ServingCellConfig } OPTIONAL, -- Need M csi-MeasConfig SetupRelease { CSI-MeasConfig } OPTIONAL, -- Need M sCellDeactivationTimer ENUMERATED {ms20, ms40, ms80, ms160, ms200, ms240, ms320, ms400, ms480, ms520, ms640, ms720, ms840, ms1280, spare2,spare1} OPTIONAL, -- Cond ServingCellWithoutPUCCH crossCarrierSchedulingConfig CrossCarrierSchedulingConfig OPTIONAL, -- Need M tag-Id TAG-Id, dummy1 ENUMERATED {enabled} OPTIONAL, -- Need R pathlossReferenceLinking ENUMERATED {spCell, sCell} OPTIONAL, -- Cond SCellOnly servingCellMO MeasObjectId OPTIONAL, -- Cond MeasObject ... -- remaining fields and the r16/r17/r18/r19 extensions are not BWP related } maxNrofBWPs INTEGER ::= 4 -- Maximum number of BWPs per serving cell BWP-Id ::= INTEGER (0..maxNrofBWPs) UplinkConfig ::= SEQUENCE { initialUplinkBWP BWP-UplinkDedicated OPTIONAL, -- Need M uplinkBWP-ToReleaseList SEQUENCE (SIZE (1..maxNrofBWPs)) OF BWP-Id OPTIONAL, -- Need N uplinkBWP-ToAddModList SEQUENCE (SIZE (1..maxNrofBWPs)) OF BWP-Uplink OPTIONAL, -- Need N firstActiveUplinkBWP-Id BWP-Id OPTIONAL, -- Cond SyncAndCellAdd pusch-ServingCellConfig SetupRelease { PUSCH-ServingCellConfig } OPTIONAL, -- Need M carrierSwitching SetupRelease { SRS-CarrierSwitching } OPTIONAL, -- Need M ... -- remaining r16/r18 extensions are not BWP related } BWP-Downlink ::= SEQUENCE { bwp-Id BWP-Id, bwp-Common BWP-DownlinkCommon OPTIONAL, -- Cond SetupOtherBWP bwp-Dedicated BWP-DownlinkDedicated OPTIONAL, -- Cond SetupOtherBWP ... } BWP-DownlinkCommon ::= SEQUENCE { genericParameters BWP, pdcch-ConfigCommon SetupRelease { PDCCH-ConfigCommon } OPTIONAL, -- Need M pdsch-ConfigCommon SetupRelease { PDSCH-ConfigCommon } OPTIONAL, -- Need M ... } BWP-DownlinkDedicated ::= SEQUENCE { pdcch-Config SetupRelease { PDCCH-Config } OPTIONAL, -- Need M pdsch-Config SetupRelease { PDSCH-Config } OPTIONAL, -- Need M sps-Config SetupRelease { SPS-Config } OPTIONAL, -- Need M radioLinkMonitoringConfig SetupRelease { RadioLinkMonitoringConfig } OPTIONAL, -- Need M ..., [[ sps-ConfigToAddModList-r16 SPS-ConfigToAddModList-r16 OPTIONAL, -- Need N sps-ConfigToReleaseList-r16 SPS-ConfigToReleaseList-r16 OPTIONAL, -- Need N sps-ConfigDeactivationStateList-r16 SPS-ConfigDeactivationStateList-r16 OPTIONAL, -- Need R beamFailureRecoverySCellConfig-r16 SetupRelease {BeamFailureRecoveryRSConfig-r16} OPTIONAL, -- Cond SCellOnly sl-PDCCH-Config-r16 SetupRelease { PDCCH-Config } OPTIONAL, -- Need M sl-V2X-PDCCH-Config-r16 SetupRelease { PDCCH-Config } OPTIONAL -- Need M ]], [[ preConfGapStatus-r17 BIT STRING (SIZE (maxNrofGapId-r17)) OPTIONAL, -- Cond PreConfigMG beamFailureRecoverySpCellConfig-r17 SetupRelease { BeamFailureRecoveryRSConfig-r16} OPTIONAL, -- Cond SpCellOnly harq-FeedbackEnablingforSPSactive-r17 BOOLEAN OPTIONAL, -- Need R cfr-ConfigMulticast-r17 SetupRelease { CFR-ConfigMulticast-r17 } OPTIONAL, -- Need M dl-PPW-PreConfigToAddModList-r17 DL-PPW-PreConfigToAddModList-r17 OPTIONAL, -- Need N dl-PPW-PreConfigToReleaseList-r17 DL-PPW-PreConfigToReleaseList-r17 OPTIONAL, -- Need N nonCellDefiningSSB-r17 NonCellDefiningSSB-r17 OPTIONAL, -- Need R servingCellMO-r17 MeasObjectId OPTIONAL -- Cond MeasObject-NCD-SSB ]], [[ tci-InDCI-r18 SetupRelease {TCI-InDCI-r18} OPTIONAL -- Need M ]], [[ sbfd-Config2-Reception-r19 ENUMERATED {enabled} OPTIONAL, -- Need S pathlossOffsetPRACH-DCI-1-0-r19 ENUMERATED { enabled } OPTIONAL, -- Need R prachAssociationDCI-1-0-r19 ENUMERATED { enabled } OPTIONAL -- Need R ]] } BWP-Uplink ::= SEQUENCE { bwp-Id BWP-Id, bwp-Common BWP-UplinkCommon OPTIONAL, -- Cond SetupOtherBWP bwp-Dedicated BWP-UplinkDedicated OPTIONAL, -- Cond SetupOtherBWP ... } BWP-UplinkCommon ::= SEQUENCE { genericParameters BWP, rach-ConfigCommon SetupRelease { RACH-ConfigCommon } OPTIONAL, -- Need M pusch-ConfigCommon SetupRelease { PUSCH-ConfigCommon } OPTIONAL, -- Need M pucch-ConfigCommon SetupRelease { PUCCH-ConfigCommon } OPTIONAL, -- Need M ..., [[ rach-ConfigCommonIAB-r16 SetupRelease { RACH-ConfigCommon } OPTIONAL, -- Need M useInterlacePUCCH-PUSCH-r16 ENUMERATED {enabled} OPTIONAL, -- Need R msgA-ConfigCommon-r16 SetupRelease { MsgA-ConfigCommon-r16 } OPTIONAL -- Cond SpCellOnly2 ]], [[ enableRA-PrioritizationForSlicing-r17 BOOLEAN OPTIONAL, -- Cond RA-PrioSliceAI additionalRACH-ConfigList-r17 SetupRelease { AdditionalRACH-ConfigList-r17 } OPTIONAL, -- Cond SpCellOnly2 rsrp-ThresholdMsg3-r17 RSRP-Range OPTIONAL, -- Need R numberOfMsg3-RepetitionsList-r17 SEQUENCE (SIZE (4)) OF NumberOfMsg3-Repetitions-r17 OPTIONAL, -- Cond Msg3Rep mcs-Msg3-Repetitions-r17 SEQUENCE (SIZE (8)) OF INTEGER (0..31) OPTIONAL -- Cond Msg3Rep ]], [[ additionalRACH-perPCI-ToAddModList-r18 SEQUENCE (SIZE (1.. maxNrofAdditionalPRACHConfigs-r18)) OF RACH-ConfigTwoTA-r18 OPTIONAL, -- Cond 2TA-Only additionalRACH-perPCI-ToReleaseList-r18 SEQUENCE (SIZE (1.. maxNrofAdditionalPRACHConfigs-r18)) OF AdditionalPCIIndex-r17 OPTIONAL, -- Need N rsrp-ThresholdMsg1-RepetitionNum2-r18 RSRP-Range OPTIONAL, -- Need R rsrp-ThresholdMsg1-RepetitionNum4-r18 RSRP-Range OPTIONAL, -- Need R rsrp-ThresholdMsg1-RepetitionNum8-r18 RSRP-Range OPTIONAL, -- Need R preambleTransMax-Msg1-Repetition-r18 ENUMERATED {n1, n2, n4, n6, n8, n10, n20, n50, n100, n200} OPTIONAL -- Cond Msg1Rep1 ]], [[ preambleTransMaxRO-Type-r19 ENUMERATED {n1, n2, n4, n6, n8, n10, n20, n50, n100, n200} OPTIONAL, -- Need R sbfd-RO-Type-r19 ENUMERATED {sbfd, non-sbfd} OPTIONAL, -- Need S sbfd-RSRP-ThresholdRO-Type-r19 RSRP-Range OPTIONAL, -- Need S sbfd-RSRP-ThresholdRO-TypeUsage-r19 ENUMERATED {above,below} OPTIONAL, -- Need S sbfd-RSRP-ThresholdMsg1-RepetitionNum2-r19 RSRP-Range OPTIONAL, -- Need R sbfd-RSRP-ThresholdMsg1-RepetitionNum4-r19 RSRP-Range OPTIONAL, -- Need R sbfd-RSRP-ThresholdMsg1-RepetitionNum8-r19 RSRP-Range OPTIONAL, -- Need R sbfd-RACH-Config-r19 CHOICE { sbfd-RACH-SingleConfig-r19 NULL, sbfd-RACH-DualConfig-r19 SBFD-RACH-DualConfig-r19 } OPTIONAL -- Need R ]] } BWP-UplinkDedicated ::= SEQUENCE { pucch-Config SetupRelease { PUCCH-Config } OPTIONAL, -- Need M pusch-Config SetupRelease { PUSCH-Config } OPTIONAL, -- Need M configuredGrantConfig SetupRelease { ConfiguredGrantConfig } OPTIONAL, -- Need M srs-Config SetupRelease { SRS-Config } OPTIONAL, -- Need M beamFailureRecoveryConfig SetupRelease { BeamFailureRecoveryConfig } OPTIONAL, -- Cond SpCellOnly ..., [[ sl-PUCCH-Config-r16 SetupRelease { PUCCH-Config } OPTIONAL, -- Need M cp-ExtensionC2-r16 INTEGER (1..28) OPTIONAL, -- Need R cp-ExtensionC3-r16 INTEGER (1..28) OPTIONAL, -- Need R useInterlacePUCCH-PUSCH-r16 ENUMERATED {enabled} OPTIONAL, -- Need R pucch-ConfigurationList-r16 SetupRelease { PUCCH-ConfigurationList-r16 } OPTIONAL, -- Need M lbt-FailureRecoveryConfig-r16 SetupRelease { LBT-FailureRecoveryConfig-r16 } OPTIONAL, -- Need M configuredGrantConfigToAddModList-r16 ConfiguredGrantConfigToAddModList-r16 OPTIONAL, -- Need N configuredGrantConfigToReleaseList-r16 ConfiguredGrantConfigToReleaseList-r16 OPTIONAL, -- Need N configuredGrantConfigType2DeactivationStateList-r16 ConfiguredGrantConfigType2DeactivationStateList-r16 OPTIONAL -- Need R ]], [[ ul-TCI-StateList-r17 CHOICE { explicitlist SEQUENCE { ul-TCI-ToAddModList-r17 SEQUENCE (SIZE (1..maxUL-TCI-r17)) OF TCI-UL-State-r17 OPTIONAL, -- Need N ul-TCI-ToReleaseList-r17 SEQUENCE (SIZE (1..maxUL-TCI-r17)) OF TCI-UL-StateId-r17 OPTIONAL -- Need N }, unifiedTCI-StateRef-r17 ServingCellAndBWP-Id-r17 } OPTIONAL, -- Need R ul-powerControl-r17 Uplink-powerControlId-r17 OPTIONAL, -- Cond NoTCI-PC pucch-ConfigurationListMulticast1-r17 SetupRelease { PUCCH-ConfigurationList-r16 } OPTIONAL, -- Need M pucch-ConfigurationListMulticast2-r17 SetupRelease { PUCCH-ConfigurationList-r16 } OPTIONAL -- Need M ]], [[ pucch-ConfigMulticast1-r17 SetupRelease { PUCCH-Config } OPTIONAL, -- Need M pucch-ConfigMulticast2-r17 SetupRelease { PUCCH-Config } OPTIONAL -- Need M ]], [[ pathlossReferenceRSToAddModList-r17 SEQUENCE (SIZE (1..maxNrofPathlossReferenceRSs-r17)) OF PathlossReferenceRS-r17 OPTIONAL, -- Need N pathlossReferenceRSToReleaseList-r17 SEQUENCE (SIZE (1..maxNrofPathlossReferenceRSs-r17)) OF PathlossReferenceRS-Id-r17 OPTIONAL -- Need N ]], [[ sbfd-Config2-Transmission-r19 ENUMERATED {enabled} OPTIONAL, -- Need S sbfd-Config2-PUSCH-RB-Offset-r19 INTEGER(0..maxNrofPhysicalResourceBlocks-1) OPTIONAL, -- Need R ul-Muting-NonSBFD-Symbol-r19 ENUMERATED {enabled} OPTIONAL, -- Need S twoTA-Without-MultiDCI-MultiTRP-r19 ENUMERATED {enabled} OPTIONAL -- Need R ]] } BWP ::= SEQUENCE { locationAndBandwidth INTEGER (0..37949), subcarrierSpacing SubcarrierSpacing, cyclicPrefix ENUMERATED { extended } OPTIONAL -- Need R }
If configured for an SpCell, this field contains the ID of the DL BWP to be activated upon performing the reconfiguration in which it is received. If the field is absent, the RRC reconfiguration does not impose a BWP switch (corresponds to L1 parameter 'active-BWP-DL-Pcell'). If configuredfor an SCell, this field contains the ID of the downlink bandwidth part to be used upon MAC-activation of an SCell. The initial bandwidth part is referred to by BWP-Id = 0
The NW may trigger the UE to swtich UL or DL BWP using a DCI field. The four code points in that DCI field map to the RRC-configured
- BWP-ID as follows: For up to 3 configured BWPs (in addition to the initial BWP) the DCI code point is equivalent to the BWP ID
- (initial = 0, first dedicated = 1, ...). If the NW configures 4 dedicated bandwidth parts, they are identified by DCI code
- points 0 to 3. In this case it is not possible to switch to the initial BWP using the DCI field.
- Corresponds to L1 parameter 'UL-BWP-index' / 'DL-BWP-index'.
How BWP are defined ?
As mentioned in Carrier Bandwidth Part allocation for DL and UL, maximum 4 BWPs can be defined in DL and UL. Each of BWP are configured by RRC messages as described in RRC Parameters for BandwidthPart Configuration.
That is the short answer. But 'defining a BWP' involves rather more than picking a start point and a width, and it is worth listing the whole set of decisions in one place, because they are spread over several different IEs in the ASN.1.
To define one bandwidth part, the network has to settle all of the following.
An identity - thebwp-Id . Values 1 to 4 for the dedicated ones ; 0 is reserved for the initial BWP and is assigned by the specification rather than signalled.Where it sits and how wide it is -locationAndBandwidth , a single value that packs both numbers together. How that packing works is the subject of the next section.Its numerology -subcarrierSpacing andcyclicPrefix . Remember that this is per BWP, so this is a real decision and not a formality.Its cell specific channel configuration - thebwp-Common part. In the downlink that is PDCCH-ConfigCommon and PDSCH-ConfigCommon ; in the uplink it is RACH-ConfigCommon, PUSCH-ConfigCommon and PUCCH-ConfigCommon.Its UE specific channel configuration - thebwp-Dedicated part. In the downlink that is PDCCH-Config (the CORESETs and search spaces), PDSCH-Config, SPS-Config and RadioLinkMonitoringConfig ; in the uplink it is PUCCH-Config, PUSCH-Config, ConfiguredGrantConfig, SRS-Config and BeamFailureRecoveryConfig.What role it plays - whether some other field points at it as thefirst active or thedefault BWP. This is not part of the BWP itself, as explained in the BWP types section.
Look at how long that list is, and at what is on it. This leads to the point that is really worth taking away from this section :
In NR, almost everything in the physical layer configuration is defined
- Switching BWP does not only retune the radio - it
swaps the whole physical layer configuration at the same time. That is the real reason a BWP switch costs a measurable amount of time rather than being instant, and it is why BWP switching delay deserves a section of its own. - When you look at an RRC configuration in a log, you will see PDSCH-Config, PUCCH-Config and friends appear
once for every configured BWP . That is not the log repeating itself. Those are genuinely separate configurations, and they may well hold different values.
The network is not completely free when it makes these choices. The rules gathered from the earlier sections of this page are :
- the BWP must be
contiguous and must fit inside the carrier ; - a DL BWP must be at least as wide as the SS Block, although it does not have to contain one ;
- every DL BWP needs at least one CORESET with a UE specific search space, and on the primary carrier at least one DL BWP must also carry a common search space ;
- in TDD, a DL BWP and the UL BWP with the
same bwp-Id form a pair and must share the same centre frequency.
When and where the definitions actually reach the UE
One more thing is worth knowing, because it explains why BWP #0 is special. The BWP definitions do not all arrive at once. They are built up in three steps as the UE works its way into the network.
Step 1 - from the MIB. Before the UE knows anything about bandwidth parts, it usesCORESET#0 , whose frequency location comes from pdcch-ConfigSIB1 in the MIB. This is the first piece of downlink spectrum the UE can use at all, and strictly speaking it is not yet a BWP.Step 2 - from SIB1. Thecommon part of the initial BWP arrives here : initialDownlinkBWP (a BWP-DownlinkCommon) inside DownlinkConfigCommonSIB, and initialUplinkBWP (a BWP-UplinkCommon) inside UplinkConfigCommonSIB. 38.331 requires the network to choose the locationAndBandwidth of the initial DL BWP so that itcontains the whole of CORESET#0 . Note also a subtlety in the field description : the UE applies this locationAndBandwidth as soon as it reads it, but it keeps using CORESET#0 for PDCCH until RRCSetup, RRCResume or RRCReestablishment arrives.Step 3 - from RRCSetup or RRCReconfiguration. Only now doesServingCellConfig appear, bringing thededicated part of BWP #0 and, if the network wants them, the dedicated BWPs 1 to 4 with both their common and dedicated parts.
So the answer to "how are BWPs defined" is really a sequence rather than a single event. This is also the cleanest way to see why the initial BWP behaves differently from the others :
How BWP location and bandwidth is specified in RRC ?
The location (starting position and the bandwidth of a BWP is specified in RRC parameter called locationAndBandwidth and this parameter is specified as RIV that can be calculated according to the following specification.
< 38.213-12 Bandwidth part operation > states as follows :
a first PRB and a number of contiguous PRBs by higher layer parameter locationAndBandwidth that is interpreted as RIV according to TS 38.214, setting
, and the first PRB is a PRB offset relative to the PRB indicated by higher layer parameters offsetToCarrier and subcarrierSpacing
< 38.214-5.1.2.2.2 Downlink resource allocation type 1> defines RIV as follows :

Two questions come out of this formula almost immediately : why is the location and the bandwidth squeezed into
Think about which combinations of start and length are actually legal. A BWP must fit inside the carrier, so
And that is where the two branches come from. The set of valid (start, length) pairs is
The number 275, and where the ASN.1 range comes from
Now look again at the quote from 38.213 above. It does not say "use the size of this BWP" - it explicitly
locationAndBandwidth is always computed with N = 275 , whatever the real carrier bandwidth or subcarrier spacing happens to be. This is why every single line of the table below has 275 in it, even the 5 MHz cases.It explains the odd looking range in the ASN.1. With N = 275 there are 275 x 276 / 2 = 37950 valid pairs, numbered 0 to 37949 - andINTEGER (0..37949) is exactly what the BWP IE says. That bound is not an arbitrary choice by somebody in 3GPP ; it is simply the count of legal combinations.
Going the other way : RIV back to start and length
When you are reading a log you usually have the opposite problem - you have the locationAndBandwidth value and you want to know where the BWP is. The formula can be inverted in three lines. With N = 275 :
L' = floor(RIV / 275) + 1
S' = RIV mod 275
if L' + S' <= 275 -> L_RBs = L' RB_start = S' (came from equation 1)
else -> L_RBs = 275 - L' + 2 RB_start = 275 - 1 - S' (came from equation 2)
The test in the middle is doing the un-folding. If the straightforward reading would produce an allocation that runs off the end of the carrier, then the value must have come from equation (2) and the mirror image has to be undone.
Two worked examples, using values from the table further down :
RIV = 2750 : L' = floor(2750/275) + 1 = 11, S' = 0. Since 11 + 0 is not larger than 275, this came from equation (1), soL_RBs = 11 and RB_start = 0 . That is the 5 MHz row.RIV = 3574 : L' = floor(3574/275) + 1 = 13, S' = 274. Now 13 + 274 = 287, which is larger than 275, so this one came from equation (2) : L_RBs = 275 - 13 + 2 =264 and RB_start = 275 - 1 - 274 =0 . That is the 400 MHz FR2 row - and notice how a naive reading would have given you 13 resource blocks starting at 274, which is completely wrong.
Combining the two specification mentioned above, I would come up with some examples as shown below. All these examples are based on the assumption that RB_start = 0, BWP takes up the maximum RB for the specified channel bandwidth and subcarrierspacing = 30 Khz, FR1
|
CBW |
max RB |
Equation |
RIV Calculation |
locationAndBandwidth |
|
5 |
11 |
(1) |
275*(11-1)+0 |
2750 |
|
10 |
24 |
(1) |
275*(24-1)+0 |
6325 |
|
15 |
38 |
(1) |
275*(38-1)+0 |
10175 |
|
20 |
51 |
(1) |
275*(51-1)+0 |
13750 |
|
25 |
65 |
(1) |
275*(65-1)+0 |
17600 |
|
30 |
78 |
(1) |
275*(78-1)+0 |
21175 |
|
40 |
106 |
(1) |
275*(106-1)+0 |
28875 |
|
50 |
133 |
(1) |
275*(133-1)+0 |
36300 |
|
60 |
162 |
(2) |
275*(275-162+1)+(275-1-0) |
31624 |
|
70 |
189 |
(2) |
275*(275-189+1)+(275-1-0) |
24199 |
|
80 |
217 |
(2) |
275*(275-217+1)+(275-1-0) |
16499 |
|
90 |
245 |
(2) |
275*(275-245+1)+(275-1-0) |
8799 |
|
100 |
273 |
(2) |
275*(275-273+1)+(275-1-0) |
1099 |
Following is the table that I calculated for subcarrier spacing = 15 Khz based on the assumption that RB_start = 0, BWP takes up the maximum RB for the specified channel bandwidth
|
CBW |
max RB |
Equation |
RIV Calculation |
locationAndBandwidth |
|
5 |
25 |
(1) |
275*(25-1)+0 |
6600 |
|
10 |
52 |
(1) |
275*(52-1)+0 |
14025 |
|
15 |
79 |
(1) |
275*(79-1)+0 |
21450 |
|
20 |
106 |
(1) |
275*(106-1)+0 |
28875 |
|
25 |
133 |
(1) |
275*(133-1)+0 |
36300 |
|
30 |
160 |
(2) |
275*(275-160+1)+(275-1-0) |
32174 |
|
40 |
216 |
(2) |
275*(275-216+1)+(275-1-0) |
16774 |
|
50 |
270 |
(2) |
275*(275-270+1)+(275-1-0) |
1924 |
Following is the table that I calculated for subcarrier spacing = 120 Khz based on the assumption that RB_start = 0, BWP takes up the maximum RB for the specified channel bandwidth
|
CBW |
max RB |
Equation |
RIV Calculation |
locationAndBandwidth |
|
50 |
32 |
(1) |
275*(32-1)+0 |
8525 |
|
100 |
66 |
(1) |
275*(66-1)+0 |
17875 |
|
200 |
132 |
(1) |
275*(132-1)+0 |
36025 |
|
400 |
264 |
(2) |
275*(275-264+1)+(275-1-0) |
3574 |
There is one thing in these tables that looks like a mistake on first reading, and it is worth pointing out because it is actually the folding at work. Follow the locationAndBandwidth column downwards in any of the tables. It rises as the channel bandwidth grows - 2750, 6325, 10175 and so on - and then, at the row where the Equation column flips from (1) to (2), it suddenly
Nothing is wrong. The flip happens as soon as L_RBs - 1 becomes larger than floor(275/2) = 137, i.e, once the BWP occupies more than about half of the maximum carrier. From that point on the value is being written into the folded half of the numbering space, and it counts backwards. So :
If you are eyeballing a configuration and trying to guess the bandwidth from the size of the number, you will be wrong about half the time. Decode it properly with the three lines above.
One more trap : RB_start is not a CRB number
Look once more at the end of the sentence quoted from 38.213 at the top of this section :
This matters. The RB_start that comes out of the RIV is
N(start,BWP) = offsetToCarrier + RB_start
That N(start,BWP) is the same quantity used in the nCRB / nPRB mapping earlier on this page. If you take RB_start straight out of the RIV and use it as a CRB index, every frequency you calculate afterwards will be wrong by offsetToCarrier - and because offsetToCarrier is often not zero, this is a mistake that produces plausible looking but incorrect numbers.
A good habit when decoding a real configuration is therefore to finish with two sanity checks : that RB_start + L_RBs does not exceed the actual number of resource blocks in the carrier, and that the resulting BWP is at least as wide as the SS Block if it is a downlink BWP.
How a specific BWP is selected (BWP switching) ?
Even though multiple (max 4) BWPs can be defined in DL and UL, only one BWP can be active at each specific moment. It implies there is some mechainism to select a specific BWP as the active one. According to 38.321-5.15 Bandwidth Part (BWP) operation, BWP selection (or BWP switching) can be done by several different way
s as listed below.
- By PDCCH (i.e, DCI) : A specific BWP can be activated by Bandwidth part indicator in DCI Format 0_1 (a UL Grant) and DCI Format 1_1 (a DL Schedule)
- By the bwp-InactivityTimer : ServingCellConfig.bwp-InactivityTimer
- By RRC signalling
- By the MAC entity itself upon initiation of Random Access procedure
These four (or five) mechanisms look like alternatives, but they are not really interchangeable. They differ in who starts them, in how fast they are, and in what they are for. Putting them side by side makes the picture much clearer.
|
Mechanism |
Who decides |
How fast |
What it is really for |
|
|
Network |
Fastest |
The normal, everyday way. The scheduler decides that this UE now needs a wider (or narrower) BWP and says so in the same DCI that schedules the data. This is the one that makes BWP a dynamic feature rather than a configuration option. |
|
|
UE (autonomously) |
Fast |
Power saving. Nobody sends anything ; the UE notices that nothing has happened for a while and falls back to the default BWP on its own. The network runs the same timer, so both sides stay in step without any signalling. |
|
|
Network |
Slow |
Used when the BWP set itself is being (re)configured - at cell addition, handover, or reconfiguration with sync. firstActiveDownlinkBWP-Id / firstActiveUplinkBWP-Id say which BWP is active once the new configuration is applied, and 38.321 states this happens |
|
|
UE (autonomously) |
Fast |
A safety mechanism rather than an optimisation. If the UE has to do random access but the active UL BWP has no PRACH occasions in it, the UE cannot even start - so it moves itself somewhere it can. This is Case 1 below. |
Two things are worth noticing in that table.
Two of the four are UE decisions. BWP switching is not purely network controlled. The UE moves itself on inactivity and on random access, which is why both sides have to implement exactly the same rules - if they disagree about which BWP is active, the UE is listening in one place while the network transmits in another, and the connection is effectively dead until something resets it.The DCI that switches the BWP is usually also a scheduling DCI. The bandwidth part indicator lives inside DCI format 0_1 and 1_1, which are the formats that grant uplink and schedule downlink. So the switch is not a separate command - the network says "move to BWP 2, and by the way here is your data on BWP 2" in one shot. The frequency domain resource assignment in that same DCI is already interpreted against thenew BWP.
With using the mechanisums listed above, a specific BWP become active depending on various situations in the call processing.The switching process can be summarized in illustration as follows.

Reading this timeline from left to right, it walks through the whole life of a connection and shows which mechanism is in charge at each point.
- The UE starts in the
Initial BWP , because that is all it has - the dedicated BWPs do not exist for it yet. - When the initial attach completes, RRC has arrived, and the UE jumps to the
First Active BWP . Notice there is no arrow labelled DCI at that point : this move comes from firstActiveDownlinkBWP-Id in the configuration itself. - Then comes the ordinary working phase - the run of green dashed lines marked
DCI or RRC . The UE is moved between BWP n1 and BWP n2 as the scheduler sees fit, and this can happen many times. - Finally the traffic stops, nothing more is scheduled, and the
bwp-InactivityTimer expires . No message is sent at all - the UE simply drops to theDefault BWP by itself.
The vertical axis is worth a glance too : the boxes are drawn at different widths and different positions, which is a reminder that the BWPs need not be the same size and need not sit on top of each other.
Another well presented illustration of BWP change/adaptation is shown below :

Source : A Primer on Bandwidth Parts in 5G New Radio
This second illustration tells the same story but with real resource block counts, and it adds the part that happens before RRC connection - which is where the earlier picture starts.
Sync and MIB - the UE has only the SSB, 20 RBs wide. There is no BWP yet.Acquire SIB1 - the UE usesCORESET#0 , 24 RBs, whose position came from the MIB.Random access - now the initial BWPs exist, taken from SIB1. In this example both DL BWP#0 and UL BWP#0 are 24 RBs, i.e, the initial DL BWP has been made exactly big enough to contain CORESET#0, which is what 38.331 requires.RRC configuration applied - the UE moves to the first active BWPs, and here they are 270 RBs. This is the jump that matters : from 24 RBs to 270 RBs, more than ten times the bandwidth, in one step.Inactivity timer expiry - the DL falls back to the default BWP, 52 RBs. Notice that the uplink doesnot move : it stays on UL BWP#1. This is the downlink only nature of the default BWP that was mentioned in the BWP types section, drawn out.
The numbers in this figure are a good illustration of why the feature exists at all. A UE that has nothing to do sits in 52 RBs rather than 270, and a UE that is only doing random access sits in 24. The receiver only has to be wide enough for the BWP it is actually in.
The bwp-InactivityTimer in a little more detail
Of the four mechanisms, the inactivity timer is the one that is easiest to list and hardest to picture, so it is worth spelling out how it actually behaves. The rules are in 38.321-5.15.1.
The timer does not always run. It only runs while the active DL BWP isnot the default one. That makes sense - the timer exists to bring the UE back to the default BWP, so once it is there, there is nothing left to do. If defaultDownlinkBWP-Id was never configured, the initial BWP takes its place, and the timer runs whenever the UE is not on the initial BWP.Activity restarts it. Receiving a PDCCH addressed to C-RNTI or CS-RNTI that carries a downlink assignment or an uplink grant restarts the timer, and so does sending or receiving a MAC PDU on a configured grant or configured assignment. In other words, any real scheduling activity keeps the UE where it is.Random access suspends the logic. While a random access procedure is going on, the timer is not restarted by these events - only once the procedure has finished (or if there was none in the first place).On expiry the UE switches by itself to the BWP given by defaultDownlinkBWP-Id, or to the initial BWP if that field is absent.Being moved by a DCI also starts it. When a PDCCH switches the UE to a BWP that is not the default one, the timer is started or restarted at that moment - so the countdown begins as soon as the UE arrives.
Followings are some of the examples of BWP switching for specific cases based on the statement in 3GPP specification. If you have overall understanding as shown above, following description would sound clearer to you.
if PRACH occasions are not configured for the active UL BWP:
For UL,set the active UL BWP = initialUplinkBWP;
For DL,
if the Serving Cell is a SpCell:
set the active DL BWP = initialDownlinkBWP.
if PRACH occasions are configured for the active UL BWP
For UL,set the active UL BWP = the configured UL BWP
For DL,
if the Serving Cell is a SpCell:
set the active DL BWP = DL BWP with the same bwp-Id as the active UL BWP.
Perform RACH procedure with the active BWP selected as above.
an initial DL BWP is defined by a location and number of contiguous PRBs, starting from a PRB with the lowest index and ending at a PRB with the highest index among PRBs of a CORESET for Type0-PDCCH CSS set, and a SCS and a cyclic prefix for PDCCH reception in the CORESET for Type0-PDCCH CSS set ==> It mean that the initialDlBWP takes up the full RBs defined in FrequencyInfoDL (i.e, Full RB in the CBW)
- Active BWP for DL = firstActiveDownlinkBWP-Id
- Active BWP for UL = firstActiveUplinkBWP-Id
"Reconfiguration with sync" is a common mechanism of activing NR cell in NSA (i.e, Adding NR Cell to LTE cell). In this case, Active BWP for DL and UL is set to be as follows .
Check if there is any on-going RACH procedure. If there is no on-going RACH procedure or RACH procedure is just completed by the received DCI (masked with C-RNTI).
set the active BWP = the BWP specified by the DCI
For unpaired spectrum operation, a DL BWP from the set of configured DL BWPs with index provided by BWP-Id is linked with an UL BWP from the set of configured UL BWPs with index provided by BWP-Id when the DL BWP index and the UL BWP index are same. ==> Simply put, DL BWP id = UL BWP id
For unpaired spectrum operation, a UE does not expect to receive a configuration where the center frequency for a DL BWP is different than the center frequency for an UL BWP when the BWP-Id of the DL BWP is same as the BWP-Id of the UL BWP ==> Simply put, Center frequency of DL BWP = Center Frequency of UL BWP
BWP Switching Delay
Changing BWP (Switching BWP) is the process of changing huge set of configurations. So it would need at least a certain amount of time to complete the switching. This time delay can be illustrated as follows based on 38.133-8.6.2
It is worth being clear about
The radio has to be retuned. The new BWP is somewhere else in frequency and may use a different subcarrier spacing, so the RF front end has to move and settle. This is analogue hardware behaviour and it does not care how fast the digital clock is running.The whole physical layer configuration has to be swapped. As described in How BWP are defined, a BWP carries its own CORESETs, search spaces, PUCCH resources, SRS setup and so on. All of that has to be torn down and rebuilt.
Two properties of this delay are worth remembering before looking at the diagrams.
It is normative, not implementation defined. 38.133 does not describe what a UE typically takes ; it sets an upper bound that the UEmust meet. The value depends on the UE's own declared capability, which is why the tables have two columns.The UE is deaf and mute while it lasts. 38.133 states that during T(BWPswitchDelay) the UE is not required to transmit uplink signals or receive downlink signals on the cell where the switch is happening. So this is not a soft transition - it is a real hole in the service, and that is exactly why a network cannot switch BWP casually.
Time Delay for DCI based BWP switching
This is the case where the switch was ordered by a PDCCH, i.e, by the bandwidth part indicator inside DCI format 1_1 or 0_1, as described in How a specific BWP is selected. It is by far the most common case in normal operation, so this is the delay that a scheduler has to live with every day.
The question that 38.133 has to answer here is narrower than it first looks. It is not "how long does a UE take to switch" in general - it is
There is also a scheduling consequence that is specific to the DCI case and does not arise with the timer. Remember that the DCI which switches the BWP is normally a scheduling DCI as well - it carries a downlink assignment or an uplink grant at the same time. But that assignment refers to the

Reading the timeline at the top of this figure :
- The clock starts at the
beginning of the DL slot in which the DCI is received - 38.133 calls it slot n. Note that it is the start of the slot, not the end of the DCI, so part of the budget is already gone by the time the UE has finished decoding the PDCCH. - After T(BWPswitchDelay) has elapsed, the UE must be able to receive PDSCH or transmit PUSCH on the new BWP, starting from the first DL or UL slot that occurs after the duration.
- The one exception to the silence is the DCI itself : the UE is of course still receiving the PDCCH that ordered the switch.
The little
Y = 0 when the DCI arrives on the same serving cell as the one whose BWP is changing. This is the ordinary case.Y = 1 when the DCI arrives on adifferent serving cell from the one that is switching, i.e, with cross carrier scheduling. The UE is granted one more slot, which is fair enough - the instruction has to cross from one carrier's processing chain to another's. In this case the specification also says that T(BWPswitchDelay) + Y follows the smaller SCS among the scheduling cell and the scheduled cells before and after the change.
Time Delay for Timer based BWP switching
This is the other case - the switch was not ordered by anybody. The bwp-InactivityTimer simply ran out, and the UE goes back to the default BWP on its own.
The interesting thing about this case is that
That is why the specification has to define the starting point differently, and rather more carefully. It cannot say "start counting from the slot with the DCI", so instead it says
Once that starting slot has been established, everything from there on is identical to the DCI case - the same T(BWPswitchDelay) from the same Table 8.6.2-1, and the same silence while it lasts.

The timer case is almost the same, with one extra step at the front that explains the two coloured boxes marked FR1 and FR2 in the figure.
When the bwp-InactivityTimer expires, the UE does
- in
FR1 , slot n is the first slot of the DLsubframe immediately after the timer expires - the green box labelled 'First slot' ; - in
FR2 , slot n is the first slot of the DLhalf subframe immediately after the timer expires - the blue box labelled 'First half subframe'.
From that slot n onwards, exactly the same T(BWPswitchDelay) applies as in the DCI case, and the UE is again neither transmitting nor receiving until it is over. So the total time from timer expiry to being usable again is a little longer than the table value alone : there is a short alignment wait first, then the switch itself.
Reading Table 8.6.2-1
Both figures quote the same table, so it is worth reading it once properly.
The two columns,
The table is written in slots, and that hides something interesting. If you convert the slot counts into milliseconds using the slot length in the same table, this is what comes out :
|
μ |
SCS |
Slot length |
Type 1 (slots) |
Type 1 in ms |
Type 2 (slots) |
Type 2 in ms |
0 |
15 kHz |
1 ms |
1 |
1 ms |
3 |
3 ms |
1 |
30 kHz |
0.5 ms |
2 |
1 ms |
5 |
2.5 ms |
2 |
60 kHz |
0.25 ms |
3 |
0.75 ms |
9 |
2.25 ms |
3 |
120 kHz |
0.125 ms |
6 |
0.75 ms |
18 |
2.25 ms |
Look down the two 'in ms' columns. The slot counts grow steeply - 1, 2, 3, 6 and 3, 5, 9, 18 - but the actual time barely moves : roughly
That is not a coincidence, and it is the most useful thing to take away from this table. The switching delay is fundamentally a
Two practical consequences follow from all of this.
The bwp-InactivityTimer should not be set too short. If it expires while traffic is still arriving in bursts, the UE keeps falling back to the default BWP and being pulled out again, and it pays the switching gap every single time. A timer that is slightly too aggressive can cost more throughput than the power saving is worth.BWP switching and tight latency budgets do not mix well. A gap of 2 to 3 ms is very large next to a URLLC packet delay budget of a few milliseconds. This is one of the practical reasons why latency critical traffic tends to be kept on one BWP rather than being moved around.
RRC for BWP Switching
The RRC Parameters for BandwidthPart Configuration section listed everything needed to
There are only four of them, and each one answers a different question.
firstActiveDownlinkBWP-Id / firstActiveUplinkBWP-Id - "which BWP is active the moment this configuration is applied ?" This is the RRC based switch. Note that the uplink field lives inside UplinkConfig, not directly in ServingCellConfig, which is why the two are shown separately below.bwp-InactivityTimer - "how long may nothing happen before the UE goes home by itself ?" This is the timer based switch.defaultDownlinkBWP-Id - "where is home ?" The two work as a pair : the timer decides when, this field decides where. There is deliberately no uplink equivalent.
Notice what is
Following is based on
ServingCellConfig ::= SEQUENCE {
...
firstActiveDownlinkBWP-Id BWP-Id OPTIONAL, -- Cond SyncAndCellAdd
bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30,
ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500,
ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8,
spare7, spare6, spare5, spare4, spare3, spare2, spare1 }
OPTIONAL, -- Need R
defaultDownlinkBWP-Id BWP-Id OPTIONAL, -- Need S
uplinkConfig UplinkConfig OPTIONAL, -- Need M
...,
[[
dormantBWP-Config-r16 SetupRelease { DormantBWP-Config-r16 } OPTIONAL, -- Need M
...
]]
}
UplinkConfig ::= SEQUENCE {
...
firstActiveUplinkBWP-Id BWP-Id OPTIONAL, -- Cond SyncAndCellAdd
...
}
DormantBWP-Config-r16 ::= SEQUENCE {
dormantBWP-Id-r16 BWP-Id OPTIONAL, -- Need M
withinActiveTimeConfig-r16 SetupRelease { WithinActiveTimeConfig-r16 } OPTIONAL, -- Need M
outsideActiveTimeConfig-r16 SetupRelease { OutsideActiveTimeConfig-r16 } OPTIONAL -- Need M
}
WithinActiveTimeConfig-r16 ::= SEQUENCE {
firstWithinActiveTimeBWP-Id-r16 BWP-Id OPTIONAL, -- Need M
dormancyGroupWithinActiveTime-r16 DormancyGroupID-r16 OPTIONAL -- Need R
}
OutsideActiveTimeConfig-r16 ::= SEQUENCE {
firstOutsideActiveTimeBWP-Id-r16 BWP-Id OPTIONAL, -- Need M
dormancyGroupOutsideActiveTime-r16 DormancyGroupID-r16 OPTIONAL -- Need R
}
DormancyGroupID-r16 ::= INTEGER (0..4)
The
dormantBWP-Id-r16 is the BWP the SCell is put into when it is told to go dormant.firstWithinActiveTimeBWP-Id-r16 andfirstOutsideActiveTimeBWP-Id-r16 say which BWP to wake up into, and there are two of them because the answer differs depending on whether the UE is inside DRX Active Time or not.DormancyGroupID-r16 lets several SCells be put to sleep and woken up together with one instruction, rather than one at a time.
Note also that this whole block sits in ServingCellConfig, which means it is per serving cell - and as 38.321 states, dormancy is not supported for an SpCell or for a PUCCH SCell.
UE Capability
Everything on this page so far has described what the specification
The capabilities sit at two different levels, and the level tells you the scope :
Phy-ParametersCommon - these apply to thewhole UE . This is where the switching speed is declared.BandNR - these are declaredper band . The same UE can therefore support four BWPs on one band and only two on another, which is entirely normal, because the hardware behind different bands is often different.
Between them, the fields below answer three separate questions.
How many BWPs, and may they differ in numerology ? - bwp-SameNumerology and bwp-DiffNumerology. Notice that supporting 4 BWPs and supporting 4 BWPswith different subcarrier spacings are two separate declarations. The second one is considerably harder for a UE, since it means the whole frame structure changes at the switch.How fast can it switch ? - bwp-SwitchingDelay, which selects the Type 1 or Type 2 column of the table in the BWP Switching Delay section, plus the Release 16 fields that cover switching several carriers at once.Must the BWP contain CORESET#0 and SSB ? - bwp-WithoutRestriction. Without this capability the network is not free to place a DL BWP anywhere it likes on the PCell.
The last one is worth pausing on, because it is the capability that most directly limits what a network can do in practice. A UE that does not report bwp-WithoutRestriction forces every UE specific DL BWP on the PCell to be wide enough to swallow CORESET#0 and the SSB - which quietly puts a floor under how narrow the power saving BWP can be.
Following is based on
Phy-ParametersCommon ::= SEQUENCE {
...
bwp-SwitchingDelay ENUMERATED {type1, type2} OPTIONAL,
...,
[[
-- R4 9-1: BWP switching on multiple CCs RRM requirements
bwp-SwitchingMultiCCs-r16 CHOICE {
type1-r16 ENUMERATED {us100, us200},
type2-r16 ENUMERATED {us200, us400, us800, us1000}
} OPTIONAL
]],
[[
-- R4 6-3: Dormant BWP switching on multiple CCs RRM requirements
bwp-SwitchingMultiDormancyCCs-r16 CHOICE {
type1-r16 ENUMERATED {us100, us200},
type2-r16 ENUMERATED {us200, us400, us800, us1000}
} OPTIONAL
]],
...
}
BandNR ::= SEQUENCE {
...
bwp-WithoutRestriction ENUMERATED {supported} OPTIONAL,
bwp-SameNumerology ENUMERATED {upto2, upto4} OPTIONAL,
bwp-DiffNumerology ENUMERATED {upto4} OPTIONAL,
...
}
The word to notice there is
An uplink / downlink constraint that is not stated anywhere else on this page. The current text of both bwp-SameNumerology and bwp-DiffNumerology says :"Except for SUL, the UE only supports the same numerology for the active UL and DL BWP" . So although each BWP carries its own subcarrier spacing, in practice the active DL BWP and the active UL BWP of a serving cell have to use thesame one - the supplementary uplink being the only exception.The reporting rule for bwp-SwitchingDelay is now conditional. It reads "It is mandatory to report type 1 or type 2when bwp-SameNumerology or bwp-DiffNumerology is supported on at least one band ", and it adds that the capability is optional for an NCR-MT. The older wording made the report unconditional.RedCap changes the CORESET#0 rule. For a UE that reports supportOfRedCap-r17 or supportOfERedCap-r18, the UE specific DL BWPmay not include the bandwidth of CORESET#0 and the SSB on the PCell - which is the opposite of the rule quoted in the descriptions below, and it exists precisely because a RedCap UE may be too narrowband to contain them.
Why BWP ?
When I first saw the descriptions on BWP, I asked myself 'why we need this ? We already has pretty flexible mechanism of changing Bandwidth dynamically. Just by changing the number of RBs and starting RB, we can change the operation bandwidth. Then, why we still need another mechanism of restricting bandwidth ?'.
The purpose of BWP is more for UE rather than for Network, especially for low end UEs which cannot afford to such a wideband operation.
In most case, NR would operate in very wideband and there wouldn't be any issues for the network (gNB) and high end UEs to handle the full operating band, but we cannot expect every types of UE to be able to work with this kind of wideband. So we need another special mechanism to tell some UEs 'Hey... we are operating in this wide band, but you don't need to worry about covering the full band. this is a fraction of spectrum you only need to care'. This is how (and why) we came out with the new concept called BWP. It would remind you of NarrowBand in LTE M1. (Refer to Ref[1] if you want to know more detailed stories on various alternatives on NR Wideband operation).
Coming back to the question at the top
The question asked at the start of this section is a good one and it deserves a direct answer, because at first sight resource allocation really does look as if it already does the job. If the scheduler can give a UE 10 resource blocks out of 273, has it not already narrowed the bandwidth ?
No - and the reason is the single most important idea behind the whole feature :
Think about what a UE has to do when it is only ever scheduled on 10 resource blocks but the carrier is 100 MHz wide. It still has to keep its receiver open across the whole carrier, because :
- it has no idea
where the next grant will be - the scheduler is free to move it anywhere in the carrier from one slot to the next ; - it has to monitor PDCCH wherever the CORESET happens to sit ;
- and the parts of the receive chain that actually cost power - the wideband analogue front end, the ADC sample rate, the FFT - are sized by the bandwidth the UE is
prepared to receive, not by the bandwidth it happens to be given in one particular slot.
So a narrow allocation saves the network some resource blocks, but it saves the UE almost nothing. The UE is still paying the full price for a wideband receiver that is mostly idle.
What BWP adds is not a new way of allocating resources. It adds a
This also explains a rule from much earlier on this page that can look like arbitrary bookkeeping - that the UE neither receives nor transmits anything outside the active BWP. Read as a restriction it seems pointless. Read as the promise that makes the narrowing possible, it is the whole point.
The full set of reasons
The low end UE argument above is the original motivation and it is still the clearest one, but by the time the feature was finished it was serving several purposes at once. In practice there are four.
|
Reason |
What it means, and which part of the feature serves it |
|
|
The dominant reason in real deployments. A UE with nothing to do sits in a narrow BWP and only opens up when there is traffic. This is what the |
|
|
The argument made above. A device whose maximum bandwidth is smaller than the carrier can still camp on that carrier and be served properly. This is what later became the basis of RedCap, and it is why the |
|
|
Because each BWP carries its own |
|
|
The network can steer UEs into a particular part of the band - to keep a region clear, to work around interference, or in shared spectrum to fit around what else is going on. This one is a genuine network side benefit rather than a UE one. |
It is worth adding a word about the network side, because the section above says the purpose is more for the UE than for the network - which is true from the radio point of view but understates the deployment argument. Without BWP, an operator who wanted to serve narrowband devices on a wide carrier would have to deploy a separate narrow carrier for them. BWP means
How this compares with LTE
The comparison with LTE-M NarrowBand made above is a good one, and the differences are instructive :
- the LTE-M narrowband is
fixed at 6 PRBs and hard-wired into the design, whereas a BWP is configurable in position, in sizeand in numerology ; - the LTE-M narrowband exists only for a specific low cost device category, whereas BWP applies to every NR UE including the most capable ones ;
- and for an ordinary LTE UE there was no bandwidth adaptation at all - the UE simply had to handle the full cell bandwidth, all the time, whatever it was doing.
That last point is the real change. In LTE, cell bandwidth was something the UE had to cope with. In NR, the bandwidth a UE works in became something the network can adjust on the fly, per UE, in milliseconds.
BWP Configuration Examples
Everything up to this point has been definitions, formulas and ASN.1. This section is where it turns into something you can actually look at - real configurations taken from a running system, with real numbers in them.
These examples are worth more than they look, because a single configuration quietly touches almost every section of this page at once. When you open one, it is a good habit to walk through it in the following order rather than reading it top to bottom.
First find the carrier. Look forabsoluteFrequencyPointA ,offsetToCarrier andcarrierBandwidth in scs-SpecificCarrierList. These tell you where the resource block grid begins and how many resource blocks the carrier has. Nothing else can be interpreted until you have these, because everything is measured from Point A.Then decode the BWP. TakelocationAndBandwidth and run it through the three lines in the RIV section. That gives you RB_start and the number of resource blocks. Remember that RB_start is relative to offsetToCarrier, not to Point A.Check the numerology. ThesubcarrierSpacing next to it decides how wide a resource block actually is, so it is what turns a count of resource blocks into megahertz.Then look at what has to fit inside. The CORESET and the SSB both live in the initial DL BWP, so their positions and widths are the constraint that the BWP had to be built around.
A good self test with any of these examples is to decode locationAndBandwidth by hand before reading the annotations, and then check whether your answer matches the resource block count that the channel bandwidth and subcarrier spacing imply. If the two agree, you have understood the RIV section properly. You should also find your value sitting in one of the rows of the table of worked RIV examples earlier on this page, since those rows cover exactly the case of a BWP filling the whole carrier.
It is also worth noticing what these examples tend to show about real networks, which is the point made at the end of the Why BWP section. Most of them configure the initial BWP and little else. The four BWP configurations with active switching between them, which take up most of the specification, are far less common in the field than the amount of text devoted to them would suggest.
Example 01 > Band78, CBW 20 Mhz
Following is an example configuration from Amarisoft. (NOTE : You may need additional knowledge about Coreset Bandwidth. Refer to this note for CORESET interpretation)

Let me now walk through this configuration in the order suggested at the top of this section, because every highlighted field in the listing can be turned into a number, and all of those numbers can be checked against each other.
Step 1 : where is the carrier ?
Three fields answer this, and they have to be read together.
absoluteFrequencyPointA = 632016 . This is an NR-ARFCN, and it marks the absolute position of Common RB 0. Band 78 sits in the 3000 to 24250 MHz range, where the conversion is F = 3000 MHz + 15 kHz x (N - 600000). So 3000 + 0.015 x (632016 - 600000) =3480.24 MHz , which is the value written next to Point A in the picture.offsetToCarrier = 0 . The carrier begins at Point A itself, so in this particular configuration CRB 0 and the first resource block of the carrier are the same thing. That is convenient but not typical - when offsetToCarrier is not zero, the two differ, which is the trap described in the RIV section.subcarrierSpacing = kHz30 andcarrierBandwidth = 51 . So the carrier is 51 resource blocks wide at 30 kHz, i.e, 51 x 12 x 30 kHz =18.36 MHz - which is the number in the NOTE above, and it agrees with 38.101-1 Table 5.3.2-1 for a 20 MHz channel at 30 kHz spacing. The remaining 1.64 MHz of the 20 MHz channel is guard band.
Step 2 : decode the BWP
The initial downlink BWP carries
L' = floor(13750 / 275) + 1 = 50 + 1 = 51
S' = 13750 mod 275 = 0
L' + S' = 51, which is not greater than 275 -> this came from equation (1)
L_RBs = 51 RB_start = 0
So the initial DL BWP is
This is worth pausing on as a cross check. The value 13750 is exactly the one in the
Step 3 : the CORESET
The CORESET is described by
Note that 24 resource blocks sit comfortably inside the 51 of the BWP, so the requirement that the initial DL BWP must contain the whole CORESET is satisfied - trivially so here, because the BWP is the whole carrier.
Step 4 : the SSB
There is a detail here that catches people out. absoluteFrequencySSB does
10 RB at 30 kHz = 10 x 12 x 30 kHz = 3.6 MHz
SSB bottom edge = 3483.84 - 3.6 = 3480.24 MHz
And 3480.24 MHz is Point A exactly. So in this configuration the SS block starts precisely at Common RB 0 and occupies
Everything in one table
|
Item |
In the configuration |
What it works out to |
Point A (CRB 0) |
ARFCN 632016 |
3480.24 MHz |
Carrier |
offsetToCarrier 0, carrierBandwidth 51, SCS 30 kHz |
Starts at Point A, 51 RB = 18.36 MHz inside a 20 MHz channel |
Initial DL BWP |
locationAndBandwidth 13750 |
RB_start = 0, 51 RB - the whole carrier |
CORESET |
frequencyDomainResources '1111 0000 ...', duration 1 |
4 x 6 = 24 RB = 8.64 MHz, 1 symbol |
SSB |
ARFCN 632256 |
Centre 3483.84 MHz, 20 RB = 7.2 MHz, occupying CRB 0 to 19 |
What this example does and does not show
Two observations are worth taking away from it.
This is the simplest possible BWP configuration. The BWP is the whole carrier, it starts at Point A, and it shares the carrier's numerology. Every constraint from earlier on this page is satisfied without anyone having to think about it - the BWP contains the CORESET, it is wider than the SSB, and it is contiguous. A configuration like this is a good baseline to compare more interesting ones against.There is no BWP switching here at all. Look at what is missing from the listing : no downlinkBWP-ToAddModList, no firstActiveDownlinkBWP-Id, no defaultDownlinkBWP-Id, no bwp-InactivityTimer. Only the initial BWP is configured, so this UE will spend its whole connection on BWP #0 and none of the switching machinery described earlier is ever exercised. As mentioned in the Why BWP section, this is a great deal more typical of real deployments than the four BWP examples in the specification.
BWP Switching Operation Examples
The previous section showed what a BWP configuration looks like when it is sitting still. This section shows the configuration being
There are two examples, and between them they cover two of the four switching mechanisms described earlier : Example 1 is a switch triggered by
Before going into either of them, there is one thing that makes reading a BWP switch in a log different from reading almost any other procedure :
There is no equivalent of an RRCReconfigurationComplete here. The UE is not asked to acknowledge the switch, and in the timer based case there is no message in either direction at all. So you cannot find a BWP switch by searching for it - you have to
The configuration - where the bandwidth parts were defined in the first place, and what their sizes and positions are. Without this the rest of the log cannot be interpreted at all, which is why both examples below start by showing SIB1 and the RRC reconfiguration rather than jumping straight to the switch.The trigger - the thing that ordered the move. How visible this is depends entirely on the mechanism, which is the main practical difference between the two examples. An RRC trigger is an ordinary IE that you can read at a glance ; a DCI trigger is a couple of bits buried inside a downlink control message, and you only see it if your tool decodes DCI.The evidence - the proof that the UE really moved. This is where the physical layer view matters more than the signalling view : after the switch, PDCCH and PDSCH simply start appearing somewhere else in frequency. That change of position is the only direct confirmation that the switch took effect, and it is why Example 1 includes a picture of the channels before and after rather than only the messages.
Keeping those three apart - configuration, trigger, evidence - is the most useful habit when working through these examples, and it is also the practical answer to the question "how do I check in a log whether BWP switching is actually being used in this network ?"
NOTE : If you want to see the contents of full log with Amarisoft Log viewer, go to LogAnalysis section and click on 'Sample Log' in this tutorial of Amarisoft TechAcademy.
Example 1 > BWP Switching by DCI
This is an example from Amari Callbox with a commercial UE showing the BWP switching triggered by DCI.
This example is worth working through slowly, because it is one of the few places where the whole chain can be checked end to end : the BWPs are defined in the RRC messages, the switch is ordered in a DCI, and the effect shows up in the physical layer log. The eight steps below are
[1] and [2] in the following RRC log is the places where all the BWP is configured.

Following is the sequence of physical channels showing the PDCCH/PDSCH before and after BWP switching.

[1] SIB1
This is the cell level configuration, so it is where
Check on this for full message.
message c1: systemInformationBlockType1: {
....
servingCellConfigCommon {
downlinkConfigCommon {
frequencyInfoDL {
frequencyBandList {
{
freqBandIndicatorNR 78
}
},
offsetToPointA 30,
scs-SpecificCarrierList {
{
offsetToCarrier 0,
subcarrierSpacing kHz30,
carrierBandwidth 106
}
}
},
initialDownlinkBWP { // DL BWP 0
genericParameters {
locationAndBandwidth 12928,
subcarrierSpacing kHz30
},
....
},
uplinkConfigCommon {
frequencyInfoUL {
scs-SpecificCarrierList {
{
offsetToCarrier 0,
subcarrierSpacing kHz30,
carrierBandwidth 106
}
}
},
initialUplinkBWP { // UL BWP 0
genericParameters {
locationAndBandwidth 12928,
subcarrierSpacing kHz30
},
....
}
carrierBandwidth 106 at 30 kHz - the carrier is 106 x 12 x 30 kHz =38.16 MHz , i.e, a 40 MHz channel. AndoffsetToCarrier 0 means the carrier starts at Point A, so a resource block index from the RIV is directly a CRB index here.locationAndBandwidth 12928 - decoding it with N = 275 : L' = floor(12928/275) + 1 = 48, S' = 12928 - 12925 = 3, and 48 + 3 is not greater than 275, so this came from equation (1). That gives48 resource blocks starting at RB 3 , or 17.28 MHz.
So the initial BWP is
[2] RrcSetup
Now the dedicated configuration arrives and
Check on this for full message.
{
message c1: rrcSetup: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcSetup: {
...
spCellConfig {
spCellConfigDedicated {
initialDownlinkBWP {
...
downlinkBWP-ToAddModList {
{
bwp-Id 1,
bwp-Common { // DL BWP 1
genericParameters {
locationAndBandwidth 28875,
subcarrierSpacing kHz30
},
...
bwp-Dedicated {
pdcch-Config setup: {
...
},
pdsch-Config setup: {
...
},
firstActiveDownlinkBWP-Id 0,
uplinkConfig {
initialUplinkBWP {
pucch-Config setup: {
..
},
...
},
uplinkBWP-ToAddModList {
{
bwp-Id 1,
bwp-Common {
genericParameters { // UL BWP 1
locationAndBandwidth 28875,
subcarrierSpacing kHz30
},
pusch-ConfigCommon setup: {
...
},
pucch-ConfigCommon setup: {
...
}
},
bwp-Dedicated {
pucch-Config setup: {
...
},
resourceToAddModList {
...
},
pusch-Config setup: {
...
},
firstActiveUplinkBWP-Id 0,
...
},
....
}
}
}
}
}
}
locationAndBandwidth 28875 for both DL BWP 1 and UL BWP 1 - decoding again with N = 275 : L' = floor(28875/275) + 1 = 106, S' = 0, so106 resource blocks starting at RB 0 . That is the entire carrier. You will find this exact value in the RIV example table earlier on this page, in the row for 106 RB.firstActiveDownlinkBWP-Id 0 andfirstActiveUplinkBWP-Id 0 - and this is the important one. The network has just defined a nice wide BWP 1, and then told the UE to stay on BWP 0 anyway.
That second point is what makes this a DCI example rather than an RRC one. If firstActiveDownlinkBWP-Id had been 1, the UE would have moved to BWP 1 the moment it applied this message and there would have been nothing left to see. Instead the wide BWP is
So at this point the UE is running on a 48 RB BWP while a 106 RB BWP sits ready and unused.
[3] PDCCH
From here on we are in the physical layer log, and this is where the switch actually happens. The field to watch in every one of these DCIs is
Message: ss_id=2 cce_index=12 al=2 dci=1_1
Data:
bwp=0
rb_alloc=0x5f
time_domain_rsc=0
mcs1=21
ndi1=0
rv_idx1=3
harq_process=10
dai=0
tpc_command=1
pucch_rsc=0
harq_feedback_timing=4
antenna_ports=2
srs_request=0
dmrs_seq_init=0
[4] PDSCH
Message: harq=10 prb=3:48 symb=2:12 k1=4 nl=2 CW0: tb_len=8709 mod=8 rv_idx=3 cr=0.69 retx=3
These two lines belong together, and between them they show how a grant is expressed
- The DCI says
bwp=0 , so the UE is still on the narrow BWP, andrb_alloc=0x5f = 95. - That 95 is an RIV again - but this time it is decoded with the size of the
active BWP , which is 48, and not with 275. This is the distinction flagged in the RIV section : same formula, different N. With N = 48 : L' = floor(95/48) + 1 = 2, S' = 95 - 48 = 47, and 2 + 47 = 49 which is greater than 48, so this came from equation (2) : L = 48 - 2 + 2 =48 and RB_start = 48 - 1 - 47 =0 . The whole of BWP 0. - Now look at the PDSCH line :
prb=3:48 , i.e, 48 resource blocks starting at 3. The DCI said "start at 0" and the PDSCH appears at 3. That is not a contradiction - it is the nCRB / nPRB mapping in front of your eyes. n(CRB) = n(PRB) + N(start,BWP) = 0 + 3 = 3. The DCI counts from the start of the BWP ; the physical layer log prints the position in the carrier.
[5] PDCCH
Message: ss_id=2 cce_index=2 al=2 dci=0_1 k2=7
Data:
bwp=1
rb_alloc=0x139
time_domain_rsc=0
mcs=9
ndi=1
rv_idx=0
harq_process=0
dai=3
tpc_command=1
antenna_ports=0
srs_request=0
dmrs_seq_init=0
ul_sch_indicator=1
Here is the switch, and notice which direction goes first. This is
[6] PDCCH
Message: ss_id=4 cce_index=4 al=2 dci=1_1
Data:
bwp=1
rb_alloc=0xd3
time_domain_rsc=0
mcs1=23
ndi1=0
rv_idx1=0
harq_process=0
dai=0
tpc_command=1
pucch_rsc=0
harq_feedback_timing=1
antenna_ports=2
srs_request=0
dmrs_seq_init=0
And now the downlink follows :
[7] PDSCH
Message: harq=0 prb=0:106 symb=2:12 k1=7 nl=2 CW0: tb_len=22026 mod=8 rv_idx=0 cr=0.83 retx=0
[8] PUSCH
Message: harq=0 prb=101:3 symb=0:14 CW0: tb_len=141 mod=4 rv_idx=0 cr=0.61 retx=0 crc=KO snr=-0.4 epre=-124.0 ta=8.8
The last two lines are the evidence that the switch really took effect, and both of them match the DCIs exactly.
[7] PDSCH prb=0:106 - 106 resource blocks starting at 0. Compare with [4], where the same UE was getting prb=3:48. The downlink has gone from 48 resource blocks to the full 106, and because BWP 1 starts at CRB 0 the PRB and CRB numbering now coincide.[8] PUSCH prb=101:3 - 3 resource blocks starting at 101, which is exactly what the uplink grant in [5] decoded to. Note that RB 101 does not even exist inside the old BWP 0, which only ran from CRB 3 to CRB 50. This transmission is only possiblebecause the uplink switched.
The whole example on one page
Step |
What is in the log |
What it means |
[1] |
locationAndBandwidth 12928 |
BWP 0 = 48 RB starting at CRB 3, out of a 106 RB carrier. The narrow initial BWP. |
[2] |
locationAndBandwidth 28875, firstActive...BWP-Id 0 |
BWP 1 = 106 RB starting at CRB 0 is |
[3][4] |
bwp=0, rb_alloc=0x5f -> prb=3:48 |
Before the switch. All 48 RB of BWP 0, appearing at CRB 3 in the carrier. |
[5] |
dci=0_1, bwp=1 |
The uplink switch, carried inside an ordinary UL grant. |
[6] |
dci=1_1, bwp=1, ss_id=4 |
The downlink switch, carried inside an ordinary DL assignment, and monitored in a different search space. |
[7][8] |
prb=0:106 and prb=101:3 |
After the switch. The full 106 RB in the downlink, and an uplink transmission at a position that did not exist in the old BWP. |
Three things are worth taking away from this example.
There is no BWP switch message. Steps [5] and [6] are ordinary scheduling DCIs that happen to carry a different bandwidth part indicator. Nothing announces the switch and nothing confirms it, which is the point made in the introduction to this section.The uplink and the downlink switched separately. [5] moved the uplink and [6] moved the downlink, in two different DCIs. In a TDD cell they are paired and end up on the same bwp-Id, but they are still ordered independently.Every number in the log checks against every other number. The RIV in the DCI, the PRB range in the PDSCH line and the BWP definition in the RRC message all agree, provided you decode the DCI RIV with the BWP size and remember to add N(start,BWP) when comparing with the physical layer log. If they do not agree in a log you are working on, one of those two steps is usually the reason.
Example 2 > BWP Switching by RRC
This is an example from Amari Callbox with Amari UEsim
The starting point of this example is


[1] SIB1
Following is bwp related parts in SIB1. See this for the whole message.
{
message c1: systemInformationBlockType1: {
...
servingCellConfigCommon {
downlinkConfigCommon {
frequencyInfoDL {
frequencyBandList {
{
freqBandIndicatorNR 78
}
},
offsetToPointA 30,
scs-SpecificCarrierList {
{
offsetToCarrier 0,
subcarrierSpacing kHz30,
carrierBandwidth 106
}
}
},
initialDownlinkBWP {
genericParameters {
locationAndBandwidth 12928,
subcarrierSpacing kHz30
},
...
uplinkConfigCommon {
frequencyInfoUL {
scs-SpecificCarrierList {
{
offsetToCarrier 0,
subcarrierSpacing kHz30,
carrierBandwidth 106
}
}
},
initialUplinkBWP {
genericParameters {
locationAndBandwidth 12928,
subcarrierSpacing kHz30
},
...
}
Nothing new here. This is the same cell configuration as in Example 1 :
[2] RrcSetup
Following is bwp related parameters in RrcSetup. See this for the whole message.
{
message c1: rrcSetup: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcSetup: {
radioBearerConfig {
...
spCellConfig {
spCellConfigDedicated {
initialDownlinkBWP {
....
downlinkBWP-ToAddModList {
{
bwp-Id 1,
bwp-Common {
genericParameters {
locationAndBandwidth 28875,
subcarrierSpacing kHz30
},
....
firstActiveDownlinkBWP-Id 0,
....,
uplinkBWP-ToAddModList {
{
bwp-Id 1,
bwp-Common {
genericParameters {
locationAndBandwidth 28875,
subcarrierSpacing kHz30
},
....
firstActiveUplinkBWP-Id 0,
}
Also the same as before.
So once again we arrive at the same situation : a wide BWP 1 configured and waiting, and the UE working in the narrow BWP 0. From here the two examples part company.
[3] RrcReconfiguration
{
message c1: rrcReconfiguration: {
rrc-TransactionIdentifier 0,
criticalExtensions rrcReconfiguration: {
nonCriticalExtension {
masterCellGroup {
cellGroupId 0,
spCellConfig {
spCellConfigDedicated {
firstActiveDownlinkBWP-Id 1,
uplinkConfig {
firstActiveUplinkBWP-Id 1
},
tag-Id 0
}
}
}
}
}
}
}
This is the switch, and the contrast with Example 1 could hardly be sharper. Look at how little is in this message. There is no BWP being defined, no locationAndBandwidth, no channel configuration - almost the entire RRCReconfiguration consists of two fields :
firstActiveDownlinkBWP-Id 1 firstActiveUplinkBWP-Id 1
Both were 0 in the RrcSetup and both are now 1. That single change is the whole instruction. The bandwidth parts themselves were already configured back in step [2] and are not touched here at all - the network is simply moving the pointer.
Two things about this are worth noticing.
firstActiveDownlinkBWP-Id is being used as a switching command. The name suggests something that only matters at setup, and the field description talks about the BWP to activate when the reconfiguration is applied - but "when the reconfiguration is applied" is exactly what is happening here. Sending a reconfiguration whose only content is a new value of this field is how RRC based BWP switching is done.The downlink and the uplink move together, in one message. Compare that with Example 1, where the uplink needed its own DCI and the downlink another one.
[4] PDCCH @ SFN = 334.3
Message: ss_id=2 cce_index=8 al=2 dci=1_1
Data:
bwp=0
rb_alloc=0x2f
time_domain_rsc=0
mcs1=9
ndi1=1
rv_idx1=0
harq_process=0
dai=0
tpc_command=1
pucch_rsc=0
harq_feedback_timing=2
antenna_ports=2
srs_request=0
dmrs_seq_init=0
This is the last downlink assignment
[5] PDCCH @ SFN = 360.5
Message: ss_id=4 cce_index=8 al=2 dci=1_1
Data:
bwp=1
rb_alloc=0x0
time_domain_rsc=0
mcs1=9
ndi1=1
rv_idx1=0
harq_process=0
dai=0
tpc_command=1
pucch_rsc=0
harq_feedback_timing=4
antenna_ports=2
srs_request=0
dmrs_seq_init=0
And this is the first assignment
Example 1 and Example 2 side by side
Since the two examples start from an identical configuration, putting them next to each other isolates exactly what the choice of trigger changes.
|
Example 1 - by DCI |
Example 2 - by RRC |
The bandwidth part indicator inside an ordinary scheduling DCI |
An RRCReconfiguration containing little more than firstActive...BWP-Id |
|
Hard - a couple of bits, only visible if your tool decodes DCI |
Easy - a named IE you can read at a glance |
|
Ordered separately, one DCI each ([5] and [6]) |
Both in the same message |
|
Fast - a few slots, no signalling round trip |
Slow - a full RRC procedure |
|
Everyday traffic adaptation |
At (re)configuration time, or when the BWP set itself changes |
One qualification to something said in the introduction to this section. It was stated there that a BWP switch is never confirmed - and for the DCI and timer cases that is completely true. The RRC case is the partial exception : there is still no BWP specific confirmation, but the reconfiguration itself is an acknowledged procedure, so the RRCReconfigurationComplete that follows does at least tell you that the UE received and applied the message containing the new pointer. That is one more reason RRC based switching is the easier of the two to debug, even though it is far too slow to be the everyday mechanism.
Reference
[1] NR Wide Bandwidth Operations by Jeongho Jeon, Intel Corporation
[2] Impact of Bandwidth Part (BWP) Switching on 5G NR System Performance (Fuad Abinader et al, IEEE)
[3] A Primer on Bandwidth Parts in 5G New Radio
[4] 5G NR BWP Types and BWP Operations
YouTube
[1] BandWidth Part (BWP): A 5G feature for improving spectrum flexibility and power savings
[2] 5G Course - 5G Bandwidth Parts (5G Initial BWP Active BWP Default BWP)
|
|
|