5G/NR - 2Step RACH   

 

 

 

2 Step RACH

As the term implies 2 Step RACH indicates a type of RACH procedure that are complete in 2 steps. To be honest, the number of steps would look differently depending on how to split the whole procedure into smaller steps.  Highlevel view of the 2step RACH can be illustrated as below.

Overall Procedure

I think the biggest difference between the two step RACH and regular (existing, conventional) rach is with step 1. In two step RACH, PUSCH can be transmitted at the very first step whereas a PUSCH can be transmitted at step 3 in regular RACH.

The sequence below is the whole procedure on one screen, and the two blue boxes on the right are what makes it worth reading twice. They list the RRC that has to be in place before any of it can run, and almost all of that configuration belongs to Step 1.

two step RACH sequence, MsgA preamble and PUSCH from the UE and MsgB from the gNB, with the RRC parameters that configure each step

  • Step 1 is two transmissions, not one : B is the preamble and C is the PUSCH, and the brace on the left groups both into MsgA. That is the whole idea of two step RACH.
  • System information comes first : A carries the configuration, so the UE cannot attempt MsgA until it has read SIB1.
  • The configuration is lopsided : the upper box lists thirteen parameters for Step 1 and the lower box lists one, msgB-ResponseWindow, for Step 2.
  • MsgB arrives on PDCCH and PDSCH : D is scheduled the same way an ordinary downlink transmission is. The log further down therefore shows a PDCCH row beside the PDSCH row.

NOTE : Comparing the 2 Step RACH with the conventional 4 Step RACH, Step 1 (MsgA) is the combination of step 1 and step 3 and Step 2 (MsgB) is the combination of step 2 and step 4.

< Frame structure of two-step RACH and 4-step RACH >

The drawing below sets the two procedures side by side on the same six PRBs, which is the fairest way to compare them. The upper half is two step RACH and the lower half is four step, and the caption of each states the condition being assumed.

frequency and time layout comparing two step RACH, where preamble and PUSCH occasions share six PRBs, against four step RACH where six UEs each take one PRB

  • The same six PRBs are spent differently : the two step case puts a preamble beside two PUSCH occasions of three PRBs each. The four step case gives one PRB to each of six UEs.
  • Two step trades users for latency : six PRBs carry two msgA payloads in the upper half and six Msg3 payloads in the lower half. The capacity per occasion is lower.
  • The time axis is where it is won : the four step case needs a RAR window and then a Msg3 in Subframe #(n+1). The two step case has already sent its payload in Subframe #2.
  • Evaluation BW is a subset of System BW : the left hand panel marks the six PRBs inside the wider carrier, so neither scheme uses the whole band for random access.

Source : Figure 18 of Power Saving Techniques for 5G and Beyond (Ref [1])

Why 2 step RACH ?

I think the main purpose of 2 step RACH is to reduce the overall latency caused by RACH procedure. 2 Step RACH would reduce the delay in two ways.

  • Reduce the number of signaling steps for RACH procedure (4 steps to 2 steps) ==> reduce the control signal overhead
  • Reduce the latency
  • Allowing PUSCH transmission at the very first step
  • If it is used in Unlicensed spectrum, it can reduce the number of LBT(Listen Before Talk) attempt
  • Power Saving : By reducing the number of signaling steps, it can reduce the power consumption (For more about NR power saving techniques, refer to this note)
  • Latency is the point, and it is bought twice : once by removing two signalling steps, and again by letting the payload travel with the preamble rather than after it.
  • Unlicensed spectrum benefits most : each transmission needs its own listen before talk, so halving the transmissions halves the number of times the UE has to win the channel.
  • Power follows from the same saving : fewer transmissions and a shorter procedure mean the receiver spends less time awake waiting for a response.
  • It does not replace four step RACH : msgA-RSRP-Threshold-r16 in the listing further down is what selects between them, so a cell can offer both and let signal strength decide.

Possible Drawback of 2 step RACH

Sending the payload before the network has replied costs something, and the two problems below are both consequences of that. Neither of them exists in four step RACH, because there the network has already measured the preamble and told the UE how to correct itself.

Some possible drawback of 2 Step RACH is mentioned in the Introduction of this paper as follows :

  • The demodulation performance degradation observed without time offset compensation at the base station (gNB), specially for MR(mid range) or WA(wide area) cells
  • In the case that all preambles from multiple users (UEs) trying to perform the initial access are mapped to the same PUSCH physical resources, the associated data parts overlap and may result in unsuccessful decoding ==> There is therefore a trade-off between the collision probability of the PUSCH part of MsgA and the resource overhead for 2SR
  • The timing advance arrives too late to help : in four step RACH the RAR carries a timing advance and Msg3 uses it. In two step RACH the PUSCH has already been sent, so it must be decoded without that correction.
  • Cell size is therefore the limit : the degradation is described for mid range and wide area deployments. There the round trip delay is large enough for the uncorrected offset to matter.
  • Shared PUSCH resources create a second contention : two UEs can pick different preambles and still land on the same PUSCH resource. Resolving the preamble collision does not resolve the payload collision.
  • Both are why the RSRP threshold exists : restricting two step RACH to UEs with good signal keeps the procedure inside the range where these two effects stay small.

Overview on Configuration

In terms of RRC, you would see the huge list of parameters specified for 2step RACH as listed in RRC Parameters for Two Step RACH Process, but in terms of physical layer point of view the basic concept of each configuration almost same as existing RACH and PUSCH. I would not exaplain much of the physical layer parameters in this note. I would recommend you to refer to existing notes on PHY aspect of RACH and PUSCH linked below.

The split is worth stating plainly. Two step RACH adds a large number of RRC parameters and almost no new physical layer machinery, because MsgA is an ordinary preamble followed by an ordinary PUSCH. What is new is the configuration that ties the two together, and that is what the listings in the next section carry.

  • The physical layer is reused : the preamble is generated the way any RACH preamble is, and the payload is a PUSCH, so the pages linked above still apply unchanged.
  • The new work is in RRC : MsgA-PUSCH-Resource-r16 alone carries nineteen members, because the network has to describe a PUSCH the UE will send before it has any grant.
  • One parameter binds preamble to payload : msgA-PUSCH-TimeDomainOffset-r16 fixes how many slots after the preamble the PUSCH goes out, which is what removes the need for a grant.

RRC Parameters for Two Step RACH Process

Three groups sit in the listings below. RACH-ConfigCommonTwoStepRA-r16 and its generic half are broadcast and describe the preamble side. The MsgA-PUSCH family describes the payload side. CFRA-TwoStep-r16 is the dedicated case, where the network hands one UE its own resources.

Following is based on 38.331 v19.3.0 (Release 19)

RACH-ConfigCommonTwoStepRA-r16 ::=                   SEQUENCE {
    rach-ConfigGenericTwoStepRA-r16                      RACH-ConfigGenericTwoStepRA-r16,
    msgA-TotalNumberOfRA-Preambles-r16                   INTEGER (1..63)                                    OPTIONAL, -- Need S
    msgA-SSB-PerRACH-OccasionAndCB-PreamblesPerSSB-r16   CHOICE {
        oneEighth                                            ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32,n36,n40,n44,n48,n52,n56,n60,n64},
        oneFourth                                            ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32,n36,n40,n44,n48,n52,n56,n60,n64},
        oneHalf                                              ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32,n36,n40,n44,n48,n52,n56,n60,n64},
        one                                                  ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32,n36,n40,n44,n48,n52,n56,n60,n64},
        two                                                  ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32},
        four                                                 INTEGER (1..16),
        eight                                                INTEGER (1..8),
        sixteen                                              INTEGER (1..4)
    }                                                                                                                   OPTIONAL, -- Cond 2StepOnly
    msgA-CB-PreamblesPerSSB-PerSharedRO-r16              INTEGER (1..60)                                                OPTIONAL, -- Cond SharedRO
    msgA-SSB-SharedRO-MaskIndex-r16                      INTEGER (1..15)                                                OPTIONAL, -- Need S
    groupB-ConfiguredTwoStepRA-r16                       GroupB-ConfiguredTwoStepRA-r16                                 OPTIONAL, -- Need S
    msgA-PRACH-RootSequenceIndex-r16                     CHOICE {
        l839                                                 INTEGER (0..837),
        l139                                                 INTEGER (0..137),
        l571                                                 INTEGER (0..569),
        l1151                                                INTEGER (0..1149)
    }                                                                                                                   OPTIONAL, -- Cond 2StepOnly
    msgA-TransMax-r16                                    ENUMERATED {n1, n2, n4, n6, n8, n10, n20, n50, n100, n200}     OPTIONAL, -- Need R
    msgA-RSRP-Threshold-r16                              RSRP-Range                                                     OPTIONAL, -- Cond 2Step4Step
    msgA-RSRP-ThresholdSSB-r16                           RSRP-Range                                                     OPTIONAL, -- Need R
    msgA-SubcarrierSpacing-r16                           SubcarrierSpacing                                              OPTIONAL, -- Cond 2StepOnlyL139
    msgA-RestrictedSetConfig-r16                         ENUMERATED {unrestrictedSet, restrictedSetTypeA,
                                                                     restrictedSetTypeB}                                OPTIONAL, -- Cond 2StepOnly
    ra-PrioritizationForAccessIdentityTwoStep-r16        SEQUENCE {
        ra-Prioritization-r16                                RA-Prioritization,
        ra-PrioritizationForAI-r16                           BIT STRING (SIZE (2))
    }                                                                                                                   OPTIONAL, -- Cond InitialBWP-Only
    ra-ContentionResolutionTimer-r16                     ENUMERATED {sf8, sf16, sf24, sf32, sf40, sf48, sf56, sf64}     OPTIONAL, -- Cond 2StepOnly
    ...,
    [[
    ra-PrioritizationForSlicingTwoStep-r17               RA-PrioritizationForSlicing-r17              OPTIONAL, -- Cond InitialBWP-Only
    featureCombinationPreamblesList-r17 SEQUENCE (SIZE(1..maxFeatureCombPreamblesPerRACHResource-r17)) OF FeatureCombinationPreambles-r17 OPTIONAL  -- Cond AdditionalRACH
    ]]
}

 

Following is based on 38.331 v19.3.0 (Release 19)

GroupB-ConfiguredTwoStepRA-r16 ::=                       SEQUENCE {
    ra-MsgA-SizeGroupA-r16                               ENUMERATED {b56, b144, b208, b256, b282, b480, b640, b800,
                                                                     b1000, b72, spare6, spare5, spare4, spare3, spare2, spare1},
    messagePowerOffsetGroupB-r16                         ENUMERATED {minusinfinity, dB0, dB5, dB8, dB10, dB12, dB15, dB18},
    numberOfRA-PreamblesGroupA-r16                       INTEGER (1..64)
}

 

Following is based on 38.331 v19.3.0 (Release 19)

RACH-ConfigGenericTwoStepRA-r16 ::=     SEQUENCE {
    msgA-PRACH-ConfigurationIndex-r16       INTEGER (0..262)                                                OPTIONAL, -- Cond 2StepOnly
    msgA-RO-FDM-r16                         ENUMERATED {one, two, four, eight}                              OPTIONAL, -- Cond 2StepOnly
    msgA-RO-FrequencyStart-r16              INTEGER (0..maxNrofPhysicalResourceBlocks-1)                    OPTIONAL, -- Cond 2StepOnly
    msgA-ZeroCorrelationZoneConfig-r16      INTEGER (0..15)                                                 OPTIONAL, -- Cond 2StepOnly
    msgA-PreamblePowerRampingStep-r16       ENUMERATED {dB0, dB2, dB4, dB6}                                 OPTIONAL, -- Cond 2StepOnlyNoCFRA
    msgA-PreambleReceivedTargetPower-r16    INTEGER (-202..-60)                                             OPTIONAL, -- Cond 2StepOnlyNoCFRA
    msgB-ResponseWindow-r16                 ENUMERATED {sl1, sl2, sl4, sl8, sl10, sl20, sl40, sl80, sl160, sl320}
                                                                                                            OPTIONAL, -- Cond NoCFRA
    preambleTransMax-r16                    ENUMERATED {n3, n4, n5, n6, n7, n8, n10, n20, n50, n100, n200}  OPTIONAL, -- Cond 2StepOnlyNoCFRA
    ...,
    [[
    msgB-ResponseWindow-v1700               ENUMERATED {sl240, sl640, sl960, sl1280, sl1920, sl2560}        OPTIONAL  -- Cond NoCFRA2
    ]]
}

 

Following is based on 38.331 v19.3.0 (Release 19)

RACH-ConfigDedicated ::=        SEQUENCE {
    cfra                            CFRA                                                                    OPTIONAL, -- Need S
    ra-Prioritization               RA-Prioritization                                                       OPTIONAL, -- Need N
    ...,
    [[
    ra-PrioritizationTwoStep-r16    RA-Prioritization                                                       OPTIONAL, -- Need N
    cfra-TwoStep-r16                CFRA-TwoStep-r16                                                        OPTIONAL  -- Need S
    ]]
}

 

Following is based on 38.331 v19.3.0 (Release 19)

CFRA-TwoStep-r16 ::=                    SEQUENCE {
    occasionsTwoStepRA-r16                  SEQUENCE {
        rach-ConfigGenericTwoStepRA-r16         RACH-ConfigGenericTwoStepRA-r16,
        ssb-PerRACH-OccasionTwoStepRA-r16       ENUMERATED {oneEighth, oneFourth, oneHalf, one,
                                                            two, four, eight, sixteen}
    }                                                                                                     OPTIONAL, -- Need S
    msgA-CFRA-PUSCH-r16                     MsgA-PUSCH-Resource-r16,
    msgA-TransMax-r16                       ENUMERATED {n1, n2, n4, n6, n8, n10, n20, n50, n100, n200}    OPTIONAL, -- Need S
    resourcesTwoStep-r16                    SEQUENCE {
        ssb-ResourceList                        SEQUENCE (SIZE(1..maxRA-SSB-Resources)) OF CFRA-SSB-Resource,
        ra-ssb-OccasionMaskIndex                INTEGER (0..15)
    },
    ...
}

 

Following is based on 38.331 v19.3.0 (Release 19)

CFRA-SSB-Resource ::=           SEQUENCE {
    ssb                             SSB-Index,
    ra-PreambleIndex                INTEGER (0..63),
    ...,
    [[
    msgA-PUSCH-Resource-Index-r16   INTEGER (0..3071)     OPTIONAL  -- Cond 2StepCFRA
    ]]
}

 

Following is based on 38.331 v19.3.0 (Release 19)

CFRA-CSIRS-Resource ::=         SEQUENCE {
    csi-RS                          CSI-RS-Index,
    ra-OccasionList                 SEQUENCE (SIZE(1..maxRA-OccasionsPerCSIRS)) OF INTEGER (0..maxRA-Occasions-1),
    ra-PreambleIndex                INTEGER (0..63),
    ...
}

 

Following is based on 38.331 v19.3.0 (Release 19)

MsgA-PUSCH-Config-r16 ::=                      SEQUENCE {
    msgA-PUSCH-ResourceGroupA-r16                  MsgA-PUSCH-Resource-r16                                       OPTIONAL, -- Cond InitialBWPConfig
    msgA-PUSCH-ResourceGroupB-r16                  MsgA-PUSCH-Resource-r16                                       OPTIONAL, -- Cond GroupBConfigured
    msgA-TransformPrecoder-r16                     ENUMERATED {enabled, disabled}                                 OPTIONAL, -- Need S
    msgA-DataScramblingIndex-r16                   INTEGER (0..1023)                                             OPTIONAL, -- Need S
    msgA-DeltaPreamble-r16                         INTEGER (-1..6)                                               OPTIONAL  -- Need R
}

 

Following is based on 38.331 v19.3.0 (Release 19)

MsgA-PUSCH-Resource-r16 ::=                    SEQUENCE {
    msgA-MCS-r16                                   INTEGER (0..15),
    nrofSlotsMsgA-PUSCH-r16                        INTEGER (1..4),
    nrofMsgA-PO-PerSlot-r16                        ENUMERATED {one, two, three, six},
    msgA-PUSCH-TimeDomainOffset-r16                INTEGER (1..32),
    msgA-PUSCH-TimeDomainAllocation-r16            INTEGER (1..maxNrofUL-Allocations)                            OPTIONAL, -- Need S
    startSymbolAndLengthMsgA-PO-r16                INTEGER (0..127)                                              OPTIONAL, -- Need S
    mappingTypeMsgA-PUSCH-r16                      ENUMERATED {typeA, typeB}                                     OPTIONAL, -- Need S
    guardPeriodMsgA-PUSCH-r16                      INTEGER (0..3)                                                OPTIONAL, -- Need R
    guardBandMsgA-PUSCH-r16                        INTEGER (0..1),
    frequencyStartMsgA-PUSCH-r16                   INTEGER (0..maxNrofPhysicalResourceBlocks-1),
    nrofPRBs-PerMsgA-PO-r16                        INTEGER (1..32),
    nrofMsgA-PO-FDM-r16                            ENUMERATED {one, two, four, eight},
    msgA-IntraSlotFrequencyHopping-r16             ENUMERATED {enabled}                                          OPTIONAL, -- Need R
    msgA-HoppingBits-r16                           BIT STRING (SIZE(2))                                          OPTIONAL, -- Cond FreqHopConfigured
    msgA-DMRS-Config-r16                           MsgA-DMRS-Config-r16,
    nrofDMRS-Sequences-r16                         INTEGER (1..2),
    msgA-Alpha-r16                                 ENUMERATED {alpha0, alpha04, alpha05, alpha06,
                                                               alpha07, alpha08, alpha09, alpha1}                OPTIONAL, -- Need S
    interlaceIndexFirstPO-MsgA-PUSCH-r16           INTEGER (1..10)                                               OPTIONAL, -- Need R
    nrofInterlacesPerMsgA-PO-r16                   INTEGER (1..10)                                               OPTIONAL, -- Need R
    ...
}

 

Following is based on 38.331 v19.3.0 (Release 19)

MsgA-DMRS-Config-r16 ::=                       SEQUENCE {
    msgA-DMRS-AdditionalPosition-r16               ENUMERATED {pos0, pos1, pos3}                                 OPTIONAL, -- Need S
    msgA-MaxLength-r16                             ENUMERATED {len2}                                             OPTIONAL, -- Need S
    msgA-PUSCH-DMRS-CDM-Group-r16                  INTEGER (0..1)                                                OPTIONAL, -- Need S
    msgA-PUSCH-NrofPorts-r16                       INTEGER (0..1)                                                OPTIONAL, -- Need S
    msgA-ScramblingID0-r16                         INTEGER (0..65535)                                            OPTIONAL, -- Need S
    msgA-ScramblingID1-r16                         INTEGER (0..65535)                                            OPTIONAL  -- Need S
}

Example

The trace below is one complete two step attempt, captured end to end. Read it against the sequence diagram at the top of this page, because the six numbered markers in the log line up with the lettered arrows in that drawing.

 

Example 01 : FDD, UL 2x2

What identifies this as a two step attempt is one field in one row. The PRACH line carries two_steps=1, and everything after it follows from that. The six numbered markers group the rows into the two steps.

Thus example is from the test with Amarisoft Callbox and Amarisoft UEsim.

Amarisoft log trace of one two step RACH attempt, with Step 1 covering the PRACH and PUSCH rows and Step 2 covering the MSGB, PDSCH and PDCCH rows

  • Marker 2 is the preamble : the PRACH row at SFN 929.1 reads sequence_index=20 ta=1 prb=7:6 two_steps=1 snr=29.2, so preamble 20 was sent on six PRBs starting at PRB 7.
  • Marker 3 is the payload of the same MsgA : a PUSCH at SFN 929.5, four slots later, carrying tb_len=12 with QPSK. The RRC setup request sits inside it.
  • Step 1 spans both : the bracket on the left covers markers 2 and 3 together, which is the log showing what the sequence diagram calls MsgA.
  • Marker 4 is MsgB : the MAC row reads MSGB: uecri=0x1453233e84e6 mac_sdu=1, and the decoded box below it shows the C-RNTI of 0x8c01 being handed over.
  • Markers 5 and 6 are how MsgB travelled : a PDSCH and the PDCCH that scheduled it, both at SFN 929.9 on RNTI 0x460f. That is the MsgB-RNTI rather than the C-RNTI.
  • The C-RNTI takes over afterwards : every row below marker 6 uses 0x8c01, the value MsgB assigned, so the random access procedure is finished at that point.

 

[1] SIB1   (For the full SIB1 message, check here)

Decoded RRC, JER format. Field values are from a live capture, not from the specification.

  message c1: systemInformationBlockType1: {
    ....
      uplinkConfigCommon {
        ...
        initialUplinkBWP {
          genericParameters {
            locationAndBandwidth 28875,
            subcarrierSpacing kHz15
          },
          rach-ConfigCommon setup: {
            rach-ConfigGeneric {
              prach-ConfigurationIndex 16,
              msg1-FDM one,
              msg1-FrequencyStart 7,
              zeroCorrelationZoneConfig 15,
              preambleReceivedTargetPower -110,
              preambleTransMax n7,
              powerRampingStep dB4,
              ra-ResponseWindow sl10
            },
            ssb-perRACH-OccasionAndCB-PreamblesPerSSB one: n8,
            ra-ContentionResolutionTimer sf64,
            prach-RootSequenceIndex l839: 1,
            restrictedSetConfig unrestrictedSet
          },
          pusch-ConfigCommon setup: {
            pusch-TimeDomainAllocationList {
              {
                k2 4,
                mappingType typeA,
                startSymbolAndLength 41
              },
              {
                k2 4,
                mappingType typeA,
                startSymbolAndLength 27
              }
            },
            p0-NominalWithGrant -84
          },
          ...
          msgA-ConfigCommon-r16 setup: {
            rach-ConfigCommonTwoStepRA-r16 {
              rach-ConfigGenericTwoStepRA-r16 {
                msgB-ResponseWindow-r16 sl40
              },
              msgA-CB-PreamblesPerSSB-PerSharedRO-r16 16,
              msgA-RSRP-Threshold-r16 56
            },
            msgA-PUSCH-Config-r16 {
              msgA-PUSCH-ResourceGroupA-r16 {
                msgA-MCS-r16 5,
                nrofSlotsMsgA-PUSCH-r16 1,
                nrofMsgA-PO-PerSlot-r16 one,
                msgA-PUSCH-TimeDomainOffset-r16 4,
                startSymbolAndLengthMsgA-PO-r16 27,
                mappingTypeMsgA-PUSCH-r16 typeA,
                guardBandMsgA-PUSCH-r16 0,
                frequencyStartMsgA-PUSCH-r16 7,
                nrofPRBs-PerMsgA-PO-r16 1,
                nrofMsgA-PO-FDM-r16 four,
                msgA-DMRS-Config-r16 {
                  msgA-PUSCH-NrofPorts-r16 1
                },
                nrofDMRS-Sequences-r16 1
              },
              msgA-TransformPrecoder-r16 disabled
            }
          }
        },
        timeAlignmentTimerCommon infinity
      },
      ...
}

 

[2] MsgA : PRACH @ SFN 929.1

Log capture. Field values are from a live capture, not from the specification.

Message: sequence_index=20 ta=1 prb=7:6 two_steps=1 snr=29.2

 

[3] MsgA : PUSCH @ SFN 929.5

Log capture. Field values are from a live capture, not from the specification.

Message: harq=0 prb=7 symb=0:14 CW0: tb_len=12 mod=2 rv_idx=0 cr=0.37 retx=0 crc=OK snr=35.4 epre=-76.1 ta=0.9

 

[4] MsgB : RAR

Log capture. Field values are from a live capture, not from the specification.

Message: MSGB: uecri=0x1453233e84e6 mac_sdu=1

uecri=0x1453233e84e6
  ta=1
  harq_feedback_timing_ind=1
  pucch_rsc_ind=0
  pucch_tpc_command=0
  c-rnti=0x8c01
  mac_sdu=1

 

[5] PDSCH @ SFN 929.9 - PDSCH carrying MsgB

Log capture. Field values are from a live capture, not from the specification.

Message: harq=si prb=2:16 symb=1:13 CW0: tb_len=317 mod=2 rv_idx=0 cr=0.66

 

[6] PDCCH @ SFN 929.9 - PDCCH/DCI Scheduling the PDSCH carrying the RAR

Log capture. Field values are from a live capture, not from the specification.

Message: ss_id=1 cce_index=0 al=4 dci=1_0

rb_alloc=0x5a0
time_domain_rsc=0
vrb_to_prb_map=0
mcs=9
tb_scaling=0
lsb_sfn=1

Reference

[1] Power Saving Techniques for 5G and Beyond