mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2aad91e9a | ||
|
|
d7bde4425d | ||
|
|
c481c36fd6 | ||
|
|
947b6901fb | ||
|
|
21738d5d1e | ||
|
|
690f1a97b1 | ||
|
|
0ae51d21c3 | ||
|
|
1c45af1617 | ||
|
|
c15cdda6d1 | ||
|
|
a4a2d94417 | ||
|
|
822889f8bf | ||
|
|
c05c74516f | ||
|
|
eb9f390473 | ||
|
|
25a8ebb64c |
@@ -35,7 +35,7 @@ int main(int argc, char *argv[])
|
||||
uint32_t decoderState = 0, blockErrorState = 0; // 0 = Success, -1 = Decoding failed, 1 = Block Error.
|
||||
uint16_t testLength = NR_POLAR_PBCH_PAYLOAD_BITS, coderLength = NR_POLAR_PBCH_E;
|
||||
uint16_t blockErrorCumulative = 0, bitErrorCumulative = 0;
|
||||
uint8_t aggregation_level = 8, decoderListSize = 8, logFlag = 0;
|
||||
uint16_t aggregation_level = 8, decoderListSize = 8, logFlag = 0;
|
||||
uint16_t rnti = 0;
|
||||
|
||||
if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) {
|
||||
@@ -138,8 +138,8 @@ int main(int argc, char *argv[])
|
||||
coderLength = 108 * aggregation_level;
|
||||
} else if (polarMessageType == 2) { // UCI
|
||||
// pucch2 parameters, 1 symbol, aggregation_level = NPRB
|
||||
AssertFatal(aggregation_level > 2, "For UCI formats, aggregation (N_RB) should be > 2\n");
|
||||
coderLength = 16 * aggregation_level;
|
||||
aggregation_level = 32*4;
|
||||
coderLength = aggregation_level;
|
||||
}
|
||||
|
||||
// Logging
|
||||
|
||||
@@ -35,7 +35,7 @@ int8_t polar_decoder(double *input,
|
||||
uint8_t listSize,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level)
|
||||
uint16_t aggregation_level)
|
||||
{
|
||||
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
|
||||
// Assumes no a priori knowledge.
|
||||
@@ -304,7 +304,7 @@ int8_t polar_decoder_dci(double *input,
|
||||
uint16_t n_RNTI,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level)
|
||||
uint16_t aggregation_level)
|
||||
{
|
||||
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
|
||||
|
||||
@@ -646,7 +646,7 @@ uint32_t polar_decoder_int16(int16_t *input,
|
||||
uint8_t ones_flag,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level)
|
||||
uint16_t aggregation_level)
|
||||
{
|
||||
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
|
||||
const uint N = polarParams->N;
|
||||
|
||||
@@ -103,14 +103,14 @@ typedef struct nrPolar_params {
|
||||
} tree_linearization;
|
||||
} t_nrPolar_params;
|
||||
|
||||
void polar_encoder(uint32_t *input, uint32_t *output, int8_t messageType, uint16_t messageLength, uint8_t aggregation_level);
|
||||
void polar_encoder(uint32_t *input, uint32_t *output, int8_t messageType, uint16_t messageLength, uint16_t aggregation_level);
|
||||
|
||||
void polar_encoder_dci(uint32_t *in,
|
||||
uint32_t *out,
|
||||
uint16_t n_RNTI,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level);
|
||||
uint16_t aggregation_level);
|
||||
|
||||
void polar_encoder_fast(uint64_t *A,
|
||||
void *out,
|
||||
@@ -118,21 +118,21 @@ void polar_encoder_fast(uint64_t *A,
|
||||
uint8_t ones_flag,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level);
|
||||
uint16_t aggregation_level);
|
||||
|
||||
int8_t polar_decoder(double *input,
|
||||
uint32_t *output,
|
||||
uint8_t listSize,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level);
|
||||
uint16_t aggregation_level);
|
||||
|
||||
uint32_t polar_decoder_int16(int16_t *input,
|
||||
uint64_t *out,
|
||||
uint8_t ones_flag,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level);
|
||||
uint16_t aggregation_level);
|
||||
|
||||
int8_t polar_decoder_dci(double *input,
|
||||
uint32_t *out,
|
||||
@@ -140,7 +140,7 @@ int8_t polar_decoder_dci(double *input,
|
||||
uint16_t n_RNTI,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level);
|
||||
uint16_t aggregation_level);
|
||||
|
||||
void generic_polar_decoder(t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U);
|
||||
|
||||
@@ -159,9 +159,9 @@ void build_polar_tables(t_nrPolar_params *polarParams);
|
||||
|
||||
void nr_polar_print_polarParams(void);
|
||||
|
||||
t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint8_t aggregation_level);
|
||||
t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint16_t aggregation_level);
|
||||
|
||||
uint16_t nr_polar_aggregation_prime(uint8_t aggregation_level);
|
||||
uint16_t nr_polar_aggregation_prime(uint16_t aggregation_level);
|
||||
|
||||
const uint8_t **nr_polar_kronecker_power_matrices(uint8_t n);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// input [a_31 a_30 ... a_0]
|
||||
// output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ...
|
||||
|
||||
void polar_encoder(uint32_t *in, uint32_t *out, int8_t messageType, uint16_t messageLength, uint8_t aggregation_level)
|
||||
void polar_encoder(uint32_t *in, uint32_t *out, int8_t messageType, uint16_t messageLength, uint16_t aggregation_level)
|
||||
{
|
||||
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
|
||||
uint8_t nr_polar_A[polarParams->payloadBits];
|
||||
@@ -113,7 +113,7 @@ void polar_encoder_dci(uint32_t *in,
|
||||
uint16_t n_RNTI,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level)
|
||||
uint16_t aggregation_level)
|
||||
{
|
||||
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
|
||||
|
||||
@@ -446,7 +446,7 @@ void polar_encoder_fast(uint64_t *A,
|
||||
uint8_t ones_flag,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
uint8_t aggregation_level)
|
||||
uint16_t aggregation_level)
|
||||
{
|
||||
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ static void nr_polar_delete(void)
|
||||
pthread_mutex_unlock(&PolarListMutex);
|
||||
}
|
||||
|
||||
t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint8_t aggregation_level)
|
||||
t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint16_t aggregation_level)
|
||||
{
|
||||
// The lock is weak, because we never delete in the list, only at exit time
|
||||
// therefore, returning t_nrPolar_params * from the list is safe for future usage
|
||||
@@ -113,8 +113,8 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
|
||||
// %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level);
|
||||
|
||||
} else if (messageType == NR_POLAR_UCI_PUCCH_MESSAGE_TYPE) {
|
||||
AssertFatal(aggregation_level > 2,
|
||||
"Aggregation level (%d) for PUCCH 2 encoding is NPRB and should be > 2\n",
|
||||
AssertFatal(aggregation_level > 32,
|
||||
"Aggregation level (%d) for PUCCH 2 encoding is number of channel bits and should be > 32\n",
|
||||
aggregation_level);
|
||||
AssertFatal(messageLength > 11, "Message length %d is too short for polar encoding of UCI\n", messageLength);
|
||||
|
||||
@@ -127,7 +127,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
|
||||
} else {
|
||||
AssertFatal(1 == 0, "L = %i is an invalid value\n", L);
|
||||
}
|
||||
newPolarInitNode->encoderLength = aggregation_level * 16;
|
||||
newPolarInitNode->encoderLength = aggregation_level;
|
||||
newPolarInitNode->i_seg = 0;
|
||||
if ((messageLength >= 360 && newPolarInitNode->encoderLength >= 1088) || (messageLength >= 1013)) {
|
||||
newPolarInitNode->i_seg = 1;
|
||||
@@ -250,7 +250,7 @@ void nr_polar_print_polarParams()
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t nr_polar_aggregation_prime(uint8_t aggregation_level)
|
||||
uint16_t nr_polar_aggregation_prime(uint16_t aggregation_level)
|
||||
{
|
||||
if (aggregation_level == 0)
|
||||
return 0;
|
||||
|
||||
@@ -115,7 +115,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
|
||||
crcTableInit();
|
||||
init_byte2m128i();
|
||||
init_pucch2_luts();
|
||||
init_pucch2_3_luts();
|
||||
|
||||
nr_init_fde(); // Init array for frequency equalization of transform precoding of PUSCH
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
|
||||
} //rb
|
||||
} // symb
|
||||
int nb_rb=0;
|
||||
int32_t n0_subband_tot_perANT[frame_parms->nb_antennas_rx];
|
||||
int64_t n0_subband_tot_perANT[frame_parms->nb_antennas_rx];
|
||||
memset(n0_subband_tot_perANT, 0, sizeof(n0_subband_tot_perANT));
|
||||
|
||||
bool init_meas = measurements->n0_subband_power == NULL;
|
||||
@@ -171,7 +171,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
|
||||
false);
|
||||
|
||||
for (int rb = 0 ; rb<frame_parms->N_RB_UL;rb++) {
|
||||
int32_t n0_subband_tot_perPRB=0;
|
||||
int64_t n0_subband_tot_perPRB=0;
|
||||
if (nb_symb[rb] > 0) {
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
tmp_n0_subband[aarx][rb] /= nb_symb[rb];
|
||||
@@ -192,9 +192,9 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
|
||||
if (nb_rb>0) {
|
||||
int64_t n0_subband_tot = 0;
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
measurements->n0_subband_power_avg_perANT_dB[aarx] = dB_fixed(n0_subband_tot_perANT[aarx] / nb_rb);
|
||||
n0_subband_tot += n0_subband_tot_perANT[aarx];
|
||||
measurements->n0_subband_power_avg_perANT_dB[aarx] = dB_fixed((int32_t)(n0_subband_tot_perANT[aarx] / nb_rb));
|
||||
n0_subband_tot += (int32_t)(n0_subband_tot_perANT[aarx]/nb_rb);
|
||||
}
|
||||
measurements->n0_subband_power_avg_dB = dB_fixed(n0_subband_tot / nb_rb);
|
||||
measurements->n0_subband_power_avg_dB = dB_fixed(n0_subband_tot/frame_parms->nb_antennas_rx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,6 @@ void nr_codeword_unscrambling_init(int16_t *s, uint32_t size, uint8_t q, uint32_
|
||||
|
||||
/**@}*/
|
||||
|
||||
void init_pucch2_luts(void);
|
||||
void init_pucch2_3_luts(void);
|
||||
void set_prach_tables(int N_ZC, c16_t** ru, uint32_t** zc_inv);
|
||||
#endif
|
||||
|
||||
@@ -227,12 +227,12 @@ void nr_decode_pucch1(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu);
|
||||
|
||||
|
||||
void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
c16_t **rxdataF,
|
||||
int frame,
|
||||
int slot,
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu,
|
||||
const nfapi_nr_pucch_pdu_t* pucch_pdu);
|
||||
void nr_decode_pucch2_3(PHY_VARS_gNB *gNB,
|
||||
c16_t **rxdataF,
|
||||
int frame,
|
||||
int slot,
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu,
|
||||
const nfapi_nr_pucch_pdu_t* pucch_pdu);
|
||||
|
||||
void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
c16_t **rxdataF,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
562
openair1/PHY/NR_TRANSPORT/pucch_rx_algorithms.md
Normal file
562
openair1/PHY/NR_TRANSPORT/pucch_rx_algorithms.md
Normal file
@@ -0,0 +1,562 @@
|
||||
# PUCCH Receiver Algorithms — `pucch_rx.c`
|
||||
|
||||
This document describes the physical-layer receiver algorithms in
|
||||
`openair1/PHY/NR_TRANSPORT/pucch_rx.c` for the 5G NR gNB.
|
||||
The file implements UCI reception for PUCCH Formats 0, 1, 2, and 3
|
||||
as specified in 3GPP TS 38.211, 38.212, and 38.213.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Overview](#1-overview)
|
||||
2. [Format 0 — `nr_decode_pucch0`](#2-pucch-format-0--nr_decode_pucch0)
|
||||
3. [Format 1 — `nr_decode_pucch1`](#3-pucch-format-1--nr_decode_pucch1)
|
||||
4. [Formats 2 & 3 — `nr_decode_pucch2_3`](#4-pucch-formats-2--3--nr_decode_pucch2_3)
|
||||
5. [Helper / Initialisation Functions](#5-helper--initialisation-functions)
|
||||
6. [Data Types and Key Structures](#6-data-types-and-key-structures)
|
||||
7. [Standards References](#7-standards-references)
|
||||
|
||||
---
|
||||
|
||||
## 1. Overview
|
||||
|
||||
PUCCH carries HARQ acknowledgements (ACK/NACK), Scheduling Requests (SR), and
|
||||
Channel State Information (CSI) from UE to gNB.
|
||||
|
||||
| Format | Symbols | PRBs | Bits | Encoding | Main use |
|
||||
|--------|---------|------|------|----------|----------|
|
||||
| 0 | 1–2 | 1 | 0–2 | Sequence selection | SR, 1–2 HARQ bits |
|
||||
| 1 | 4–14 | 1 | 1–2 | OCC + sequence | SR, 1–2 HARQ bits |
|
||||
| 2 | 1–2 | 1–16 | 3–64 | RM / polar + QPSK | HARQ + SR + CSI |
|
||||
| 3 | 4–14 | 1–16 | 3–64 | RM / polar + QPSK | HARQ + SR + CSI |
|
||||
|
||||
All decoders read from `gNB->common_vars.rxdataF` and write decoded UCI into
|
||||
an `nfapi_nr_uci_pucch_pdu_*` output structure.
|
||||
|
||||
### Non-Coherent Block Detection
|
||||
|
||||
All four formats use a common detection philosophy: **non-coherent block
|
||||
detection**. The fundamental assumption is that the channel is approximately
|
||||
constant over a *coherence block* — a contiguous set of REs in time and
|
||||
frequency over which the phase of the channel can be treated as unknown but
|
||||
fixed. The receiver therefore integrates signal energy within each block
|
||||
without relying on phase knowledge, which avoids the need for explicit
|
||||
per-subcarrier channel estimation on every resource.
|
||||
|
||||
For **Formats 0 and 1**, the PUCCH spans only a single PRB (12 subcarriers).
|
||||
The entire PRB constitutes one coherence block, and detection is a
|
||||
non-coherent correlation against the set of candidate sequences. Within a
|
||||
single PRB, however, the channel *is* assumed coherent across symbols that
|
||||
share the same PRB, so those symbols are combined **coherently** (phases are
|
||||
summed before squaring). When **intra-slot frequency hopping** is used, the
|
||||
two hops occupy different PRBs and the channels across the two hops cannot be
|
||||
assumed phase-coherent; the contributions from each hop are therefore combined
|
||||
**non-coherently** (squared magnitudes are summed).
|
||||
|
||||
For **Formats 2 and 3**, the PUCCH spans multiple PRBs and symbols. The
|
||||
receiver accumulates the correlation metric over all groups and all symbols
|
||||
non-coherently, summing the squared magnitudes of each group's contribution,
|
||||
so no inter-group phase alignment is assumed or required. The coherence block
|
||||
size depends on format and payload length:
|
||||
|
||||
- **Format 2, short block (3–11 bits):** 2 PRBs per coherence block.
|
||||
- **Format 2, polar code (12–64 bits):** a sub-PRB group of 4 REs is the
|
||||
coherence block, allowing the LLR computation to remain non-coherent at
|
||||
fine granularity.
|
||||
- **Format 3:** a full PRB (12 subcarriers) is the coherence block.
|
||||
|
||||
---
|
||||
|
||||
## 2. PUCCH Format 0 — `nr_decode_pucch0`
|
||||
|
||||
**Lines 129–466** | **1–2 symbols, 1 PRB, 0–2 bits**
|
||||
|
||||
Format 0 encodes information in the *cyclic shift index* of a 12-element
|
||||
low-PAPR sequence. No data symbols are transmitted; the receiver performs
|
||||
maximum-likelihood sequence detection.
|
||||
|
||||
### 2.1 Cyclic-Shift LUT (`get_pucch0_cs_lut_index`, lines 71–100)
|
||||
|
||||
Before detection, the cyclic-shift hopping sequence is pre-computed for the
|
||||
entire frame and cached, keyed by `pucch_GroupHopping` / `hoppingId`.
|
||||
`nr_cyclic_shift_hopping()` is called once per (slot, symbol) pair and the
|
||||
result is stored as an integer LUT (divided by $\pi/6$). Subsequent
|
||||
calls for the same hopping ID return immediately.
|
||||
|
||||
### 2.2 Candidate Sequence Generation
|
||||
|
||||
For each OFDM symbol, sequences are generated for all cyclic shifts
|
||||
$m_\text{cs} \in \{0, \ldots, 11\}$:
|
||||
|
||||
$$s_{m_\text{cs}}[n] = e^{j\,\alpha(m_\text{cs})\,n} \cdot r_{u,v}[n], \quad n = 0,\ldots,11$$
|
||||
|
||||
where $\alpha(m_\text{cs}) = 2\pi(m_\text{cs,initial} + m_\text{cs} + m_\text{cs,hop})/12$
|
||||
and $r_{u,v}[n]$ is the base sequence from TS 38.211 Table 5.2.2.2-2.
|
||||
|
||||
The number of tested hypotheses depends on payload size:
|
||||
|
||||
| Payload | Hypotheses |
|
||||
|---------|-----------|
|
||||
| SR only (0 HARQ bits) | 1 |
|
||||
| 1 HARQ bit ± SR | 4 |
|
||||
| 2 HARQ bits | 8 |
|
||||
|
||||
### 2.3 Received Signal Extraction
|
||||
|
||||
Twelve subcarriers starting at the configured PRB are extracted from
|
||||
`rxdataF` per antenna and per PUCCH symbol. Frequency hopping switches the
|
||||
PRB offset on the second symbol.
|
||||
|
||||
### 2.4 Correlation via 12-Point IDFT
|
||||
|
||||
The received vector $\mathbf{y}$ is correlated against each candidate sequence using
|
||||
a 12-point IDFT with pre-computed integer tables (`idft12_re`, `idft12_im`):
|
||||
|
||||
$$C_{aa}[m_\text{cs}] = \sum_{n=0}^{11} y_{aa}[n] \cdot s_{m_\text{cs}}^*[n]$$
|
||||
|
||||
implemented in fixed-point as:
|
||||
|
||||
$$C_{aa}[m_\text{cs}].\mathrm{re} = \sum_n \bigl( y[n].\mathrm{re} \cdot \texttt{idft12\_re}[m_\text{cs}][n] + y[n].\mathrm{im} \cdot \texttt{idft12\_im}[m_\text{cs}][n] \bigr)$$
|
||||
|
||||
$$C_{aa}[m_\text{cs}].\mathrm{im} = \sum_n \bigl( y[n].\mathrm{im} \cdot \texttt{idft12\_re}[m_\text{cs}][n] - y[n].\mathrm{re} \cdot \texttt{idft12\_im}[m_\text{cs}][n] \bigr)$$
|
||||
|
||||
### 2.5 Multi-Symbol Combining
|
||||
|
||||
| Configuration | Combining method |
|
||||
|---------------|-----------------|
|
||||
| 1 symbol | Non-coherent: $\Lambda = \sum_{aa} \lvert C_{aa} \rvert^2$ |
|
||||
| 2 symbols, no hop | Coherent: $\Lambda = \sum_{aa} \lvert C_{aa}^{(0)} + C_{aa}^{(1)} \rvert^2$ |
|
||||
| 2 symbols, freq hop | Non-coherent: $\Lambda = \sum_{aa} \bigl(\lvert C_{aa}^{(0)} \rvert^2 + \lvert C_{aa}^{(1)} \rvert^2\bigr)$ |
|
||||
|
||||
The ML decision is $\hat{m}_\text{cs} = \arg\max_{m_\text{cs}} \Lambda(m_\text{cs})$.
|
||||
|
||||
### 2.6 Bit Extraction
|
||||
|
||||
| `nb_harq_bits` | SR present | Decision |
|
||||
|----------------|------------|----------|
|
||||
| 0 | yes | SR $= 1$ if $\Lambda_\max > \text{threshold}$, else $0$ |
|
||||
| 1 | no/yes | HARQ $= \hat{m}_\text{cs} \gg 3$; SR $= \hat{m}_\text{cs} \mathbin{\&} 1$ |
|
||||
| 2 | no/yes | HARQ bits from $(\hat{m}_\text{cs} \gg 2)\mathbin{\&}1$, $(\hat{m}_\text{cs} \gg 3)\mathbin{\&}1$; SR $= \hat{m}_\text{cs} \mathbin{\&} 1$ |
|
||||
|
||||
SNR is computed from the peak-to-average metric ratio and mapped to a CQI
|
||||
value (0–255, covering $-64$ to $+63.5$ dB). A configurable threshold
|
||||
`gNB->pucch0_thres` gates the SR decision.
|
||||
|
||||
---
|
||||
|
||||
## 3. PUCCH Format 1 — `nr_decode_pucch1`
|
||||
|
||||
**Lines 468–1074** | **4–14 symbols, 1 PRB, 1–2 bits**
|
||||
|
||||
Format 1 modulates 1 or 2 HARQ bits onto a low-PAPR sequence and spreads the
|
||||
result across OFDM symbols with an orthogonal cover code (OCC). Alternating
|
||||
symbols carry DM-RS for channel estimation.
|
||||
|
||||
### 3.1 Symbol Layout
|
||||
|
||||
Even symbols (0, 2, 4, …) within the PUCCH allocation carry DM-RS; odd
|
||||
symbols carry data. Both use the same 12-subcarrier PRB.
|
||||
|
||||
### 3.2 Sequence Generation
|
||||
|
||||
For each symbol, the group hopping indices $u$, $v$ are obtained from
|
||||
`nr_group_sequence_hopping()`. The cyclic shift $\alpha$ from
|
||||
`nr_cyclic_shift_hopping()` is applied to the base sequence:
|
||||
|
||||
$$r_{u,v,\alpha}[n] = e^{j\alpha n} \cdot r_{u,v}[n], \quad n = 0,\ldots,11$$
|
||||
|
||||
implemented in fixed-point using a pre-computed $(\cos\alpha n,\,\sin\alpha n)$
|
||||
pair at each subcarrier and `c16mulShift()`.
|
||||
|
||||
### 3.3 OCC Spreading / Despreading
|
||||
|
||||
The OCC weight for data symbol index $m$ within spreading factor $N_\text{SF}$ is:
|
||||
|
||||
$$w_i(m) = e^{j 2\pi i m / N_\text{SF}}$$
|
||||
|
||||
Two operating modes:
|
||||
|
||||
- **No intra-slot hopping** — single OCC table
|
||||
`table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop` covers all symbols.
|
||||
- **Intra-slot frequency hopping** — separate tables for $m'=0$
|
||||
(first half-slot) and $m'=1$ (second half-slot).
|
||||
|
||||
Received symbols are multiplied by $w_i^*(m)$ and the conjugate of the
|
||||
reference sequence to despread both DM-RS and data.
|
||||
|
||||
### 3.4 Channel Estimation
|
||||
|
||||
The DM-RS symbols, after despreading, are averaged across all DM-RS symbols
|
||||
and subcarriers to yield a per-antenna channel estimate:
|
||||
|
||||
$$\hat{h}_r = \frac{1}{N_\text{DM-RS} \cdot 12} \sum_{m,n} z_\text{DM-RS}[r][12m+n]$$
|
||||
|
||||
For frequency hopping, independent estimates $\hat{h}_r$ and $\hat{h}_r^{(1)}$
|
||||
are computed for each hop.
|
||||
|
||||
### 3.5 ML Detection
|
||||
|
||||
The despread data accumulation across all data symbols gives $y_r$.
|
||||
|
||||
**1 HARQ bit (BPSK)** — two hypotheses $d \in \{+1, -1\}$:
|
||||
|
||||
$$\Lambda_d = \sum_r \left\lvert \hat{h}_r + \frac{d}{\sqrt{2}}\, y_r \right\rvert^2$$
|
||||
|
||||
The sign with the larger metric gives the decoded bit.
|
||||
|
||||
**2 HARQ bits (QPSK)** — four hypotheses
|
||||
$d \in \{+1+j,\; +1-j,\; -1+j,\; -1-j\} / \sqrt{2}$:
|
||||
|
||||
$$\Lambda_d = \sum_r \left\lvert \hat{h}_r + d\, y_r \right\rvert^2$$
|
||||
|
||||
The maximum-metric index maps to the 2-bit Gray-coded HARQ word.
|
||||
|
||||
For frequency hopping, metrics from both hops are summed non-coherently.
|
||||
|
||||
---
|
||||
|
||||
## 4. PUCCH Formats 2 & 3 — `nr_decode_pucch2_3`
|
||||
|
||||
**Lines 1138–1999** | **Variable symbols and PRBs, 3–64 bits**
|
||||
|
||||
Formats 2 and 3 share a single decoder function. Both apply QPSK modulation
|
||||
and either a Reed-Muller small-block code (3–11 bits) or a polar code
|
||||
(12–64 bits). The key difference is their time-frequency structure:
|
||||
|
||||
| | Format 2 | Format 3 |
|
||||
|---|---|---|
|
||||
| Symbols | 1–2 | 4–14 |
|
||||
| DM-RS density | Every symbol, RE positions 1,4,7,10 per PRB | Sparse: 2 or 4 dedicated DMRS symbols |
|
||||
| DM-RS generation | Gold sequence (TS 38.211 §6.4.1.3.2) | Low-PAPR sequence with group/cyclic-shift hopping |
|
||||
| Data transform | None (frequency domain directly) | FFT across groups of 4 time-domain symbols |
|
||||
|
||||
### 4.1 Signal Extraction and Scaling
|
||||
|
||||
All received REs are extracted per antenna and symbol into
|
||||
`rp[Prx][nb_symbols][nb_re_pucch]`. Total signal energy is accumulated:
|
||||
|
||||
$$E = \sum_{aa,\,l} \texttt{signal\_energy\_nodc}(\mathbf{r}_{aa,l})$$
|
||||
|
||||
A scaling exponent is derived to keep subsequent fixed-point products in range:
|
||||
|
||||
$$\texttt{scaling} = \max\!\left(\left\lfloor \tfrac{1}{2}\log_2 E \right\rfloor - 8,\; 0\right)$$
|
||||
|
||||
### 4.2 DM-RS Position Selection (Format 3)
|
||||
|
||||
DMRS symbol positions within the PUCCH allocation are selected from
|
||||
standardised tables based on the number of symbols and the
|
||||
`additional_dmrs` flag:
|
||||
|
||||
| `nr_of_symbols` | `additional_dmrs` | DMRS symbols (relative) |
|
||||
|-----------------|-------------------|-------------------------|
|
||||
| 4–9 | either | 2 symbols |
|
||||
| 10–14 | 0 | 2 symbols |
|
||||
| 10–14 | 1 | 4 symbols |
|
||||
|
||||
### 4.3 Data Scrambling
|
||||
|
||||
A Gold sequence is initialised with:
|
||||
|
||||
$$c_\text{init} = (\text{RNTI} \ll 15) + \text{data\_scrambling\_id}$$
|
||||
|
||||
The binary scrambling sequence is packed into SIMD registers and applied to
|
||||
data REs via `simde_mm_sign_epi16()` (multiply by $\pm 1$ per bit).
|
||||
|
||||
### 4.4 DM-RS Processing and Channel Estimation
|
||||
|
||||
**Format 2:** The Gold-sequence pilot values are generated on-the-fly. Each
|
||||
pilot RE is multiplied by the conjugate of the expected pilot, and an integer
|
||||
delay estimate is computed via `nr_est_delay()` (128-tap correlation). A
|
||||
pre-computed frequency-domain phase-ramp filter (`delay_table128`) compensates
|
||||
the detected delay across all data REs.
|
||||
|
||||
**Format 3:** The low-PAPR DM-RS sequence is generated per DMRS symbol using
|
||||
group/cyclic-shift hopping (same as Format 1). The received DMRS REs are
|
||||
multiplied by the conjugate of the expected sequence and accumulated into
|
||||
per-group, per-antenna correlation values `corr32[symb][group][aa]`.
|
||||
|
||||
### 4.5 Format 3 FFT Processing
|
||||
|
||||
For data symbols, Format 3 uses time-domain OCC spreading (analogous to
|
||||
Format 1). Groups of 4 consecutive data symbols are collected into an IDFT
|
||||
input buffer per antenna. When the buffer is full (or at end of PUCCH):
|
||||
|
||||
1. Conjugates are taken to convert to IDFT input form.
|
||||
2. A 12-, 24-, or 36-point FFT is applied via `dft()`.
|
||||
3. The output is transposed using SIMD unpack/shuffle operations to convert
|
||||
from time-interleaved to subcarrier-interleaved order.
|
||||
4. The gold scrambling sequence is removed with `simde_mm_sign_epi16()`.
|
||||
|
||||
The result is equivalent to the de-spread, unscrambled data RE grid used by
|
||||
Format 2.
|
||||
|
||||
### 4.6 Decoding — Short Blocks (3–11 bits), Format 2
|
||||
|
||||
`init_pucch2_3_luts()` pre-encodes every information word with
|
||||
`encodeSmallBlock()` (Reed-Muller / simplex code) and stores the BPSK-mapped
|
||||
symbols $b[k] \in \{1,-1\}$ in `pucch2_3_lut[N-3][cw]`. Note that $b[i]$ in TS 38.211 is a binary ${0,1}$ sequence which is mapped to BPSK here for convenience in the receiver.
|
||||
|
||||
#### Signal model and group structure
|
||||
|
||||
The non-coherent group size is $N_g = 2$ PRBs, giving
|
||||
$N_\text{group} = \lfloor P/2 \rfloor$ groups (where $P$ is `prb_size`).
|
||||
Each group spans 2 consecutive PRBs: $N_p = 8$ DMRS REs and $N_d = 16$ data
|
||||
REs per OFDM symbol.
|
||||
|
||||
The channel is assumed flat within a group. For group $g$, symbol $l$,
|
||||
and receive antenna $aa$:
|
||||
|
||||
$$r_\text{DM-RS}[aa,l,k] = h_{g,aa} \cdot p[k] + n[k], \quad k \in \mathcal{K}_\text{DM-RS}(g)$$
|
||||
|
||||
$$r_\text{data}[aa,l,k] = h_{g,aa} \cdot d[k] + n[k], \quad k \in \mathcal{K}_\text{data}(g)$$
|
||||
|
||||
where $p[k] = (1-2c(2k)+j(1-2c(2k+1)))/\sqrt{2}$ is the QPSK pilot value
|
||||
generated from the Gold sequence $c(i)$ (TS 38.211 §6.4.1.3.2.1), and
|
||||
$d[k] \in \{(\pm 1 \pm j)/\sqrt{2}\}$ is the QPSK-modulated codeword symbol
|
||||
corresponding to $d(i)$-sequence in TS 38.211 §6.3.2.5.2.
|
||||
|
||||
#### DMRS-assisted coherent reference per group
|
||||
|
||||
The DMRS REs within each group are correlated with the conjugate of the known
|
||||
pilot sequence to form a channel reference:
|
||||
|
||||
$$H[g,l,aa] = \sum_{k \in \mathcal{K}_\text{DM-RS}(g)} r_\text{DM-RS}[aa,l,k] \cdot p^*[k] \;\approx\; h_{g,aa} \cdot N_p$$
|
||||
|
||||
(stored as `corr32[l][g][aa]` in the code).
|
||||
|
||||
This reference is combined across OFDM symbols to initialise the detection
|
||||
statistic $Z$:
|
||||
|
||||
| Configuration | Initialisation of $Z[g,aa]$ |
|
||||
|---------------|------------------------------|
|
||||
| 1 symbol | $H[g,0,aa]$ |
|
||||
| 2 symbols, no freq hop | $H[g,0,aa] + H[g,1,aa]$ (coherent) |
|
||||
| 2 symbols, freq hop (hop $d$) | $H[g,d,aa]$ (separate per hop) |
|
||||
|
||||
#### Codeword correlation
|
||||
|
||||
The transmitted QPSK data symbol $d[k]$ encodes two scrambled bits per subcarrier:
|
||||
|
||||
$$d[k] = \frac{(1-2\tilde{b}(2k)) + j\,(1-2\tilde{b}(2k+1))}{\sqrt{2}}$$
|
||||
|
||||
where $\tilde{b}(i) = (b(i) + c_\text{scr}(i)) \bmod 2$ is the scrambled bit sequence
|
||||
(TS 38.211 §6.3.2.5.1) and $c_\text{scr}(i)$ is the Gold scrambling sequence
|
||||
initialised with $c_\text{init}$ from Section 4.3.
|
||||
|
||||
To follow the steps of the correlation with unscrambling
|
||||
Let $b'(i) = (1-2b(i))$ and $c'(i) = (1-2c(i))$ so that $\tilde{b}'(i)=(1-2b(i))(1-2c(i))$, and the $k^{\text{th}}$ received
|
||||
dimension is
|
||||
$$r_\text{data}(k) =(b'(2k)c'(2k)+jb'(2k+1)c'(2k+1))h(k) + z(k)$$
|
||||
The $k^{\text{th}}$ component of the desired correlation is
|
||||
$$\begin{align}r_\text{data}(k)(b'(2k)c'(2k) -jb'(2k+1)c'(2k+1)) = & \text{Re}(r_\text{data}(k))c'(2k)b'(2k) + \text{Im}(r_\text{data}(k))c'(2k+1)b'(2k+1) + \\
|
||||
& j(\text{Im}(r_\text{data}(k))c'(2k)b'(2k) - \text{Re}(r_\text{data}(k))c'(2k+1)b'(2k+1))\end{align}$$
|
||||
The receiver first applies the Gold sequence (`c_ptr`) to descramble the received
|
||||
REs, splitting into components which will later allow for separation of the real and imaginary components (`r_ext` and `r_ext2`
|
||||
in the code). These two components correspond to the real and imaginary parts of the $k^\text{th}$ component of the overall correlation shown above and are
|
||||
|
||||
$$r_\text{ext}[aa,l,k] = c'(2k) \cdot\text{Re}(r_\text{data}[aa,l,k]) +j c'(2k+1) \cdot\text{Im}(r_\text{data}[aa,l,k])$$
|
||||
|
||||
$$r_\text{ext2}[aa,l,k] = c'(2k) \cdot\text{Im}(r_\text{data}[aa,l,k]) - jc'(2k+1)\text{Re}(r_\text{data}[aa,l,k])$$
|
||||
and are implemented using the `simde_mm_sign_epi16`, `oai_mm_conj` and `simde_mm_shuffle_epi8` SIMD methods on the received data samples.
|
||||
|
||||
For each candidate codeword
|
||||
$\mathbf{b}$, the descrambled REs are correlated against the LUT and accumulated
|
||||
into $Z$:
|
||||
|
||||
$$\begin{align} Z[g,aa](\mathbf{b}) \mathrel{+}= \sum_{l} \sum_{k \in \mathcal{K}_\text{data}(g)}
|
||||
\bigl(&\mathrm{Re}(r_\text{ext}[aa,l,k]) \cdot b'[2k] + \mathrm{Im}(r_\text{ext}[aa,l,k]) \cdot b'[2k+1] + \bigr. \\
|
||||
& j(\mathrm{Re}(r_\text{ext2}[aa,l,k]) \cdot b'[2k] + \mathrm{Im}(r_\text{ext2}[aa,l,k]) \cdot b'[2k+1]) \bigr)
|
||||
\end{align}$$
|
||||
|
||||
where $L$ is the number of data symbols. After both DMRS initialisation and
|
||||
data accumulation:
|
||||
|
||||
$$Z[g,aa](\mathbf{b}) \approx h_{g,aa} \cdot \bigl(L \cdot N_p + L \cdot N_d \cdot \mathbf{1}\{\mathbf{b} = \mathbf{b}_\text{tx}\}\bigr) + \text{noise}$$
|
||||
|
||||
#### ML metric and decision
|
||||
|
||||
The per-group squared magnitude is summed non-coherently across groups and
|
||||
antennas:
|
||||
|
||||
$$\Lambda(\mathbf{b}) = \sum_{g,\,aa} \left\lvert Z[g,aa](\mathbf{b}) \right\rvert^2 \qquad \text{(no freq hop)}$$
|
||||
|
||||
$$\Lambda(\mathbf{b}) = \sum_{g,\,aa,\,\delta} \left\lvert Z[g,\delta,aa](\mathbf{b}) \right\rvert^2 \qquad \text{(freq hop, hop index } \delta\text{)}$$
|
||||
|
||||
Every codeword receives a baseline contribution of $|h|^2 (L N_p)^2$, while
|
||||
the correct codeword gains an additional $|h|^2 L^2 N_d (2 N_p + N_d)$.
|
||||
The decision is:
|
||||
|
||||
$$\hat{\mathbf{b}} = \arg\max_{\mathbf{b}}\; \Lambda(\mathbf{b})$$
|
||||
|
||||
### 4.6.1 Decoding — Short Blocks (3–11 bits), Format 3
|
||||
|
||||
Format 3 feeds the same LUT-based correlator as Format 2. The differences are
|
||||
in the coherence group geometry, the pilot type, and the data pre-processing
|
||||
that precedes the descrambling step.
|
||||
|
||||
#### Group structure
|
||||
|
||||
The coherence group is one full PRB (12 subcarriers), so $N_g = 1$ and
|
||||
$N_\text{group} = P$ (one group per PRB). Within each group every subcarrier
|
||||
carries either DM-RS or data depending on the symbol type:
|
||||
$N_p = 12$ DM-RS REs and $N_d = 12$ data REs per group per symbol.
|
||||
|
||||
#### DM-RS pilot and channel reference
|
||||
|
||||
The pilot sequence is the low-PAPR sequence $r_{u,v,\alpha}[k]$
|
||||
(TS 38.211 §6.3.2.6.3 / §6.4.1.3.2.2), generated with the same
|
||||
group/cyclic-shift hopping as Format 1. The channel reference per DMRS
|
||||
symbol $l_\text{DM-RS}$ is:
|
||||
|
||||
$$H[g, l_\text{DM-RS}, aa] = \sum_{k=0}^{11} r_\text{DM-RS}[aa, l_\text{DM-RS}, 12g+k]\cdot r_{u,v,\alpha}^*[k]
|
||||
\;\approx\; h_{g,aa} \cdot N_p$$
|
||||
|
||||
accumulated into `corr32[l_dmrs][g][aa]`. Contributions from the 2 or 4
|
||||
DMRS symbols (Section 4.2) are combined coherently to initialise $Z[g,aa]$,
|
||||
exactly as in the Format 2 table of Section 4.6.
|
||||
|
||||
#### OCC despreading (Section 4.5)
|
||||
|
||||
Before the descrambling step, the received data symbols are OCC-despread via
|
||||
IDFT. Each group of (up to) 4 consecutive data symbols is stacked into the
|
||||
IDFT input buffer with stride 4 (one sample per symbol per subcarrier), the
|
||||
input is conjugated, and a length-$N_d$ DFT is applied. The output is
|
||||
transposed to produce a subcarrier-interleaved layout equivalent to the
|
||||
single-symbol, frequency-domain data grid of Format 2.
|
||||
|
||||
#### Descrambling and codeword correlation
|
||||
|
||||
After IDFT despreading the Gold scrambling sequence (`c_ptr`) is applied
|
||||
identically to Format 2 to produce `r_ext` and `r_ext2`:
|
||||
|
||||
$$r_\text{ext}[aa,l,k] = c'(2k)\cdot\text{Re}(r_\text{data}[aa,l,k]) + j\,c'(2k+1)\cdot\text{Im}(r_\text{data}[aa,l,k])$$
|
||||
|
||||
$$r_\text{ext2}[aa,l,k] = c'(2k)\cdot\text{Im}(r_\text{data}[aa,l,k]) - j\,c'(2k+1)\cdot\text{Re}(r_\text{data}[aa,l,k])$$
|
||||
|
||||
The codeword correlation, ML metric, and decision are then **identical** to
|
||||
Section 4.6 with the Format 3 group parameters substituted:
|
||||
|
||||
| Parameter | Format 2 | Format 3 |
|
||||
|-----------|----------|----------|
|
||||
| Coherence group size | 2 PRBs | 1 PRB |
|
||||
| $N_p$ per group | 8 | 12 |
|
||||
| $N_d$ per group | 16 | 12 |
|
||||
| Pilot $p[k]$ | Gold-sequence QPSK: $(1-2c(2k)+j(1-2c(2k+1)))/\sqrt{2}$ | Low-PAPR $r_{u,v,\alpha}[k]$ |
|
||||
| Data pre-processing | None | IDFT despreading across 4 symbols |
|
||||
|
||||
### 4.7 Decoding — Polar Code (12–64 bits)
|
||||
|
||||
**LLR computation** (per 4-RE group):
|
||||
|
||||
For each group of 4 data REs and all 256 possible 8-bit partial codewords,
|
||||
a correlation is computed between the received vector and the coded pattern.
|
||||
LLR numerator and denominator for each bit $b$ are:
|
||||
|
||||
$$\lambda_b^+ = \max_{\mathbf{c}:\,c_b=1} \rho(\mathbf{c}), \qquad
|
||||
\lambda_b^- = \max_{\mathbf{c}:\,c_b=0} \rho(\mathbf{c})$$
|
||||
|
||||
$$\text{LLR}[b] = \lambda_b^+ - \lambda_b^-$$
|
||||
|
||||
where $\rho(\mathbf{c})$ is the per-group correlation energy. LUT tables
|
||||
(`pucch2_3_polar_llr_num_lut`) pre-encode the bit-to-pattern mapping as SIMD
|
||||
registers, enabling vectorised accumulation.
|
||||
|
||||
**Polar decoding:**
|
||||
|
||||
```c
|
||||
polar_decoder_int16(llrs, decodedPayload, NR_POLAR_UCI_PUCCH_MESSAGE_TYPE, ...)
|
||||
```
|
||||
|
||||
The decoded bit vector is bit-reversed to match the TS 38.212 interleaving
|
||||
convention.
|
||||
|
||||
### 4.8 UCI Payload Extraction
|
||||
|
||||
The decoded bitstream is partitioned in order:
|
||||
|
||||
| Field | Length |
|
||||
|-------|--------|
|
||||
| HARQ-ACK | `bit_len_harq` bits |
|
||||
| SR | 1 bit (if `sr_flag`) |
|
||||
| CSI Part 1 | `bit_len_csi_part1` bits |
|
||||
| CSI Part 2 | flagged in output bitmap |
|
||||
|
||||
---
|
||||
|
||||
## 5. Helper / Initialisation Functions
|
||||
|
||||
### `get_pucch0_cs_lut_index()` (lines 71–100)
|
||||
|
||||
Maintains a per-hopping-ID cache of cyclic-shift values for the entire frame.
|
||||
On first call for a given `hoppingId`, iterates over all slots and symbols,
|
||||
calls `nr_cyclic_shift_hopping()`, converts to an integer index (dividing by
|
||||
$\pi/6$), and stores in a flat LUT. Returns the cache slot index for use by
|
||||
`nr_decode_pucch0`.
|
||||
|
||||
### `init_pucch2_3_luts()` (lines 1098–1129)
|
||||
|
||||
Called once at gNB startup. Populates:
|
||||
|
||||
- `pucch2_3_lut[N-3][cw]` — QPSK-mapped small-block codewords
|
||||
for $N = 3,\ldots,11$ bits (8 to 2048 entries each).
|
||||
- `pucch2_3_polar_llr_num_lut[256]` — 8-bit partial-codeword patterns packed
|
||||
into SIMD registers for use in the polar LLR computation.
|
||||
|
||||
### `nr_fill_pucch()` (lines 34–69)
|
||||
|
||||
Finds a free slot in `gNB->pucch[]`, copies the incoming
|
||||
`nfapi_nr_pucch_pdu_t`, and allocates a beam index if beamforming is active.
|
||||
Aborts with `AssertFatal` if the PUCCH queue is full.
|
||||
|
||||
### `nr_dump_uci_stats()` (lines 2001–2064)
|
||||
|
||||
Writes per-UE UCI counters (trial counts, DTX events, noise powers, SR
|
||||
positive rates) to a file or stdout for monitoring.
|
||||
|
||||
---
|
||||
|
||||
## 6. Data Types and Key Structures
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `c16_t` | Complex 16-bit integer (`.r`, `.i`) |
|
||||
| `c32_t` | Complex 32-bit integer |
|
||||
| `c64_t` | Complex 64-bit integer |
|
||||
| `cd_t` | Complex double (used in Format 1 equalization) |
|
||||
| `cw_t` | Struct holding 16 $\times$ `c16_t` — one small-block codeword |
|
||||
| `nfapi_nr_pucch_pdu_t` | FAPI input: format, PRBs, symbols, RNTI, hopping config, payload lengths |
|
||||
| `nfapi_nr_uci_pucch_pdu_format_0_1_t` | UCI output for Formats 0 and 1 |
|
||||
| `nfapi_nr_uci_pucch_pdu_format_2_3_4_t` | UCI output for Formats 2, 3, and 4 |
|
||||
| `PHY_VARS_gNB` | gNB context; holds `rxdataF`, `pucch[]` queue, thresholds, statistics |
|
||||
|
||||
Fixed-point arithmetic is used throughout. Powers-of-two shifts replace
|
||||
division. SIMD acceleration (AVX2/SSE via the `simde` portability layer) is
|
||||
used in the Format 2/3 scrambling removal, LLR accumulation, and FFT transpose
|
||||
loops. Format 1 equalization uses `cd_t` (double) for the final channel
|
||||
estimate and hypothesis metrics.
|
||||
|
||||
---
|
||||
|
||||
## 7. Standards References
|
||||
|
||||
| Reference | Scope |
|
||||
|-----------|-------|
|
||||
| TS 38.211 §5.2.2 | Low-PAPR base sequences |
|
||||
| TS 38.211 §6.3.2.2 | Group and sequence hopping |
|
||||
| TS 38.211 §6.3.2.3 | PUCCH Format 0 sequence |
|
||||
| TS 38.211 §6.3.2.4 | PUCCH Format 1 (OCC, spreading) |
|
||||
| TS 38.211 §6.3.2.5 | PUCCH Format 2 |
|
||||
| TS 38.211 §6.3.2.6 | PUCCH Format 3 |
|
||||
| TS 38.211 §6.4.1.3 | PUCCH DM-RS |
|
||||
| TS 38.212 §6.3 | UCI channel coding (polar, Reed-Muller) |
|
||||
| TS 38.213 §9 | PUCCH procedures and resource allocation |
|
||||
|
||||
Key tables used in the implementation:
|
||||
|
||||
| Symbol | Standard table |
|
||||
|--------|---------------|
|
||||
| `table_5_2_2_2_2` | Base sequences (TS 38.211 Table 5.2.2.2-2) |
|
||||
| `table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop` | OCC spreading factors, no hop (TS 38.211 Table 6.3.2.4.1-1) |
|
||||
| `table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop` | OCC spreading factors, hop $m'=0$ |
|
||||
| `table_6_3_2_4_1_2_Wi` | OCC weights (TS 38.211 Table 6.3.2.4.1-2) |
|
||||
@@ -1191,7 +1191,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
nr_uci_encoding(pusch_pdu->pusch_uci.harq_payload,
|
||||
pusch_pdu->pusch_uci.harq_ack_bit_length,
|
||||
pucch_pdu->prb_size,
|
||||
true,
|
||||
rm_info.E_uci_ACK,
|
||||
mod_order,
|
||||
@@ -1211,7 +1210,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
if (pusch_pdu->pusch_uci.csi_payload.p1_bits != 0) {
|
||||
nr_uci_encoding(pusch_pdu->pusch_uci.csi_payload.part1_payload,
|
||||
pusch_pdu->pusch_uci.csi_payload.p1_bits,
|
||||
pucch_pdu->prb_size,
|
||||
true,
|
||||
rm_info.E_uci_CSI1,
|
||||
mod_order,
|
||||
@@ -1221,7 +1219,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
if (pusch_pdu->pusch_uci.csi_payload.p2_bits > 0)
|
||||
nr_uci_encoding(pusch_pdu->pusch_uci.csi_payload.part2_payload,
|
||||
pusch_pdu->pusch_uci.csi_payload.p2_bits,
|
||||
pucch_pdu->prb_size,
|
||||
true,
|
||||
rm_info.E_uci_CSI2,
|
||||
mod_order,
|
||||
|
||||
@@ -420,7 +420,7 @@ void nr_generate_pucch1(c16_t **txdataF,
|
||||
}
|
||||
|
||||
if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band
|
||||
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6;
|
||||
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) - 6;
|
||||
}
|
||||
|
||||
if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC
|
||||
@@ -436,8 +436,8 @@ void nr_generate_pucch1(c16_t **txdataF,
|
||||
if (l%2 == 1) { // mapping PUCCH according to TS38.211 subclause 6.4.1.3.1
|
||||
txdataF[0][re_offset] = z[i + n];
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n",
|
||||
amp, frame_parms->ofdm_symbol_size, frame_parms->N_RB_DL, frame_parms->first_carrier_offset, i + n, re_offset,
|
||||
printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%u/%u)=(x_n(l=%d,n=%d)=(%d,%d))\n",
|
||||
amp, frame_parms->ofdm_symbol_size, frame_parms->N_RB_DL, frame_parms->first_carrier_offset, i + n, re_offset, re_offset - ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size),
|
||||
l, n, txdataF[0][re_offset].r, txdataF[0][re_offset].i);
|
||||
#endif
|
||||
}
|
||||
@@ -445,8 +445,8 @@ void nr_generate_pucch1(c16_t **txdataF,
|
||||
if (l % 2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1
|
||||
txdataF[0][re_offset] = z_dmrs[i + n];
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n",
|
||||
amp, frame_parms->ofdm_symbol_size, frame_parms->N_RB_DL, frame_parms->first_carrier_offset, i+n, re_offset,
|
||||
printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u/%u)=(x_n(l=%d,n=%d)=(%d,%d))\n",
|
||||
amp, frame_parms->ofdm_symbol_size, frame_parms->N_RB_DL, frame_parms->first_carrier_offset, i+n, re_offset, re_offset - ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size),
|
||||
l, n, txdataF[0][re_offset].r, txdataF[0][re_offset].i);
|
||||
#endif
|
||||
// printf("gNb l=%d\ti=%d\treoffset=%d\tre=%d\tim=%d\n",l,i,re_offset,z_dmrs_re[i+n],z_dmrs_im[i+n]);
|
||||
@@ -505,7 +505,7 @@ static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit, uint16_t rnti, uint1
|
||||
const int roundedSz = (M_bit + 31) / 32;
|
||||
uint32_t *seq = gold_cache((rnti << 15) + n_id, roundedSz);
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%x, M_bit %d\n", *seq, M_bit);
|
||||
printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence (%x) s=%x, M_bit %d\n", (rnti << 15) + n_id, *seq, M_bit);
|
||||
#endif
|
||||
|
||||
uint8_t *btildep = btilde;
|
||||
@@ -535,7 +535,7 @@ static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit, uint16_t rnti, uint1
|
||||
#endif
|
||||
}
|
||||
|
||||
void nr_uci_encoding(uint64_t payload, uint8_t nr_bit, uint8_t nrofPRB, bool uci_on_pusch, uint16_t E, uint8_t Qm, uint64_t *b)
|
||||
void nr_uci_encoding(uint64_t payload, uint8_t nr_bit, bool uci_on_pusch, uint16_t E, uint8_t Qm, uint64_t *b)
|
||||
{
|
||||
/*
|
||||
* Implementing TS 38.212 Subclause 6.3.1.2 and 6.3.2
|
||||
@@ -548,7 +548,7 @@ void nr_uci_encoding(uint64_t payload, uint8_t nr_bit, uint8_t nrofPRB, bool uci
|
||||
// E is the rate matching output sequence length as given in TS 38.212 subclause 6.3.1.4.1
|
||||
// int I_seg;
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t\t [nr_uci_encoding] start function with encoding A=%d bits into M_bit=%d (where nrofPRB=%d)\n", A, E, nrofPRB);
|
||||
printf("\t\t [nr_uci_encoding] start function with encoding A=%d bits into M_bit=%d (E)\n", A, E);
|
||||
#endif
|
||||
|
||||
// For A=1 case (single bit UCI)
|
||||
@@ -659,7 +659,7 @@ void nr_uci_encoding(uint64_t payload, uint8_t nr_bit, uint8_t nrofPRB, bool uci
|
||||
b[i] = 0;
|
||||
}
|
||||
} else {
|
||||
// repetition for rate-matching up to 16 PRB
|
||||
// repetition for rate-matching up to 256 channel bits
|
||||
b[0] = b0 | (b0<<32);
|
||||
b[1] = b[0];
|
||||
b[2] = b[0];
|
||||
@@ -668,16 +668,15 @@ void nr_uci_encoding(uint64_t payload, uint8_t nr_bit, uint8_t nrofPRB, bool uci
|
||||
b[5] = b[0];
|
||||
b[6] = b[0];
|
||||
b[7] = b[0];
|
||||
AssertFatal(nrofPRB<=16,"Number of PRB >16\n");
|
||||
//AssertFatal(E<=256,"Number of channelbits >32\n");
|
||||
}
|
||||
} else if (A >= 12) {
|
||||
// Encoder reversal
|
||||
payload = reverse_bits(payload, A);
|
||||
|
||||
polar_encoder_fast(&payload, b, 0,0,
|
||||
NR_POLAR_UCI_PUCCH_MESSAGE_TYPE,
|
||||
A,
|
||||
nrofPRB);
|
||||
E);
|
||||
}
|
||||
|
||||
if (uci_on_pusch) {
|
||||
@@ -692,7 +691,7 @@ void nr_uci_encoding(uint64_t payload, uint8_t nr_bit, uint8_t nrofPRB, bool uci
|
||||
N = 32;
|
||||
} else {
|
||||
// For polar-coded UCI, output depends on nrofPRB
|
||||
N = 16 * nrofPRB;
|
||||
N = E;
|
||||
}
|
||||
|
||||
if ((nr_bit == 1 || nr_bit == 2) && Qm > 1) {
|
||||
@@ -740,7 +739,7 @@ void nr_generate_pucch2(c16_t **txdataF,
|
||||
uint64_t b[16] = {0}; // limit to 1024-bit encoded length
|
||||
// M_bit is the number of bits of block b (payload after encoding)
|
||||
uint16_t M_bit = nr_pucch_output_sequence_length(pucch_pdu->format_type, pucch_pdu->nr_of_symbols, pucch_pdu->prb_size, 0, 0, 0);
|
||||
nr_uci_encoding(pucch_pdu->payload, pucch_pdu->n_bit, pucch_pdu->prb_size, false, M_bit, 0, &b[0]);
|
||||
nr_uci_encoding(pucch_pdu->payload, pucch_pdu->n_bit, false, M_bit, 0, &b[0]);
|
||||
/*
|
||||
* Implementing TS 38.211
|
||||
* Subclauses 6.3.2.5.1 Scrambling (PUCCH format 2)
|
||||
@@ -810,9 +809,10 @@ void nr_generate_pucch2(c16_t **txdataF,
|
||||
// int32_t *txptr;
|
||||
int outSample = 0;
|
||||
uint8_t startingSymbolIndex = pucch_pdu->start_symbol_index;
|
||||
uint16_t startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start;
|
||||
int secondHopPRB = pucch_pdu->freq_hop_flag ? pucch_pdu->second_hop_prb : pucch_pdu->prb_start;
|
||||
|
||||
for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
|
||||
uint16_t startingPRB = ((l==0) ? pucch_pdu->prb_start : secondHopPRB) + pucch_pdu->bwp_start;
|
||||
// c_init calculation according to TS38.211 subclause
|
||||
uint64_t temp_x2 = 1ll << 17;
|
||||
temp_x2 *= 14UL * nr_slot_tx + l + startingSymbolIndex + 1;
|
||||
@@ -827,22 +827,9 @@ void nr_generate_pucch2(c16_t **txdataF,
|
||||
const bool nb_rb_is_even = frame_parms->N_RB_DL & 1;
|
||||
const int halfRBs = frame_parms->N_RB_DL / 2;
|
||||
const int baseRB = rb + startingPRB;
|
||||
int re_offset = (l + startingSymbolIndex) * frame_parms->ofdm_symbol_size + 12 * baseRB;
|
||||
if (nb_rb_is_even) {
|
||||
if (baseRB < halfRBs) // if number RBs in bandwidth is even and current PRB is lower band
|
||||
re_offset += frame_parms->first_carrier_offset;
|
||||
else
|
||||
re_offset -= halfRBs;
|
||||
} else {
|
||||
if (baseRB < halfRBs) // if number RBs in bandwidth is odd and current PRB is lower band
|
||||
re_offset += frame_parms->first_carrier_offset;
|
||||
else if (baseRB > halfRBs) // if number RBs in bandwidth is odd and current PRB is upper band
|
||||
re_offset += -halfRBs + 6;
|
||||
else
|
||||
re_offset += frame_parms->first_carrier_offset;
|
||||
}
|
||||
int re_offset = (l + startingSymbolIndex) * frame_parms->ofdm_symbol_size;
|
||||
re_offset += ((12 * baseRB + frame_parms->first_carrier_offset)% frame_parms->ofdm_symbol_size);
|
||||
|
||||
//txptr = &txdataF[0][re_offset];
|
||||
int k=0;
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
int kk=0;
|
||||
@@ -949,6 +936,28 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
uint16_t nrofPRB = pucch_pdu->prb_size;
|
||||
uint16_t startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start;
|
||||
uint8_t add_dmrs = pucch_pdu->add_dmrs_flag;
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
int ndmrs=0;
|
||||
#endif
|
||||
uint8_t table_6_4_1_3_3_2_1_dmrs_positions[11][14] = {
|
||||
{(intraSlotFrequencyHopping==0)?0:1,(intraSlotFrequencyHopping==0)?1:0,(intraSlotFrequencyHopping==0)?0:1,0,0,0,0,0,0,0,0,0,0,0}, // PUCCH length = 4
|
||||
{1,0,0,1,0,0,0,0,0,0,0,0,0,0}, // PUCCH length = 5
|
||||
{0,1,0,0,1,0,0,0,0,0,0,0,0,0}, // PUCCH length = 6
|
||||
{0,1,0,0,1,0,0,0,0,0,0,0,0,0}, // PUCCH length = 7
|
||||
{0,1,0,0,0,1,0,0,0,0,0,0,0,0}, // PUCCH length = 8
|
||||
{0,1,0,0,0,0,1,0,0,0,0,0,0,0}, // PUCCH length = 9
|
||||
{0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),(add_dmrs==0?0:1),0,0,0,0,0}, // PUCCH length = 10
|
||||
{0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,0,0}, // PUCCH length = 11
|
||||
{0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,0}, // PUCCH length = 12
|
||||
{0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0}, // PUCCH length = 13
|
||||
{0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0} // PUCCH length = 14
|
||||
};
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
for (int l=0;l<nrofSymbols;l++)
|
||||
if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 1) ndmrs++;
|
||||
|
||||
printf("\t [nr_generate_pucch3_4] nrofSymbols %d, nrofPRB %d, startingPRB %d, add_dmrs %d is_pi_over_2_bpsk_enabled %d\n",nrofSymbols,nrofPRB,startingPRB,add_dmrs,is_pi_over_2_bpsk_enabled);
|
||||
#endif
|
||||
|
||||
M_bit = nr_pucch_output_sequence_length(pucch_pdu->format_type,
|
||||
nrofSymbols,
|
||||
@@ -957,7 +966,10 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
is_pi_over_2_bpsk_enabled,
|
||||
add_dmrs);
|
||||
|
||||
nr_uci_encoding(pucch_pdu->payload, pucch_pdu->n_bit, nrofPRB, false, M_bit, 0, b);
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t [nr_generate_pucch3_4] nrofSymbols %d, nrofPRB %d, startingPRB %d, add_dmrs %d, ndmrs %d, is_pi_over_2_bpsk_enabled %d, M_bit %d\n",nrofSymbols,nrofPRB,startingPRB,add_dmrs,ndmrs,is_pi_over_2_bpsk_enabled,M_bit);
|
||||
#endif
|
||||
nr_uci_encoding(pucch_pdu->payload, pucch_pdu->n_bit, false, M_bit, 0, b);
|
||||
/*
|
||||
* Implementing TS 38.211
|
||||
* Subclauses 6.3.2.6.1 Scrambling (PUCCH formats 3 and 4)
|
||||
@@ -997,7 +1009,7 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
|
||||
if (is_pi_over_2_bpsk_enabled == 0) {
|
||||
// using QPSK if PUCCH format 3,4 and pi/2-BPSK is not configured, according to subclause 6.3.2.6.2
|
||||
c16_t qpskSymbols[4] = {{baseVal, baseVal}, {-baseVal, baseVal}, {-baseVal, baseVal}, {-baseVal, -baseVal}};
|
||||
c16_t qpskSymbols[4] = {{baseVal, baseVal}, {baseVal, -baseVal}, {-baseVal, baseVal}, {-baseVal, -baseVal}};
|
||||
for (int i=0; i < m_symbol; i++) { // QPSK modulation subclause 5.1.3
|
||||
int tmp = (btilde[2 * i] & 1) * 2 + (btilde[(2 * i) + 1] & 1);
|
||||
d[i] = qpskSymbols[tmp];
|
||||
@@ -1141,9 +1153,10 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
c16_t *yPtr = y_n + l * 12 * nrofPRB;
|
||||
c16_t *zPtr = z + l * 12 * nrofPRB + k;
|
||||
*zPtr = (c16_t){0};
|
||||
for (int m = l * 12 * nrofPRB; m < (l + 1) * 12 * nrofPRB; m++) {
|
||||
// for (int m = l * 12 * nrofPRB; m < (l + 1) * 12 * nrofPRB; m++) {
|
||||
for (int m = 0; m < (12 * nrofPRB); m++) {
|
||||
const c16_t angle = {lround(32767 * cos(2 * M_PI * m * k / (12 * nrofPRB))),
|
||||
lround(32767 * sin(2 * M_PI * m * k / (12 * nrofPRB)))};
|
||||
lround(-32767 * sin(2 * M_PI * m * k / (12 * nrofPRB)))};
|
||||
c16_t tmp = c16mulShift(yPtr[m], angle, 15);
|
||||
csum(*zPtr, *zPtr, c16mulRealShift(tmp, base, 15));
|
||||
}
|
||||
@@ -1195,19 +1208,6 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
int N_ZC = 12 * nrofPRB;
|
||||
c16_t r_u_v_base[N_ZC];
|
||||
uint32_t re_offset = 0;
|
||||
uint8_t table_6_4_1_3_3_2_1_dmrs_positions[11][14] = {
|
||||
{(intraSlotFrequencyHopping==0)?0:1,(intraSlotFrequencyHopping==0)?1:0,(intraSlotFrequencyHopping==0)?0:1,0,0,0,0,0,0,0,0,0,0,0}, // PUCCH length = 4
|
||||
{1,0,0,1,0,0,0,0,0,0,0,0,0,0}, // PUCCH length = 5
|
||||
{0,1,0,0,1,0,0,0,0,0,0,0,0,0}, // PUCCH length = 6
|
||||
{0,1,0,0,1,0,0,0,0,0,0,0,0,0}, // PUCCH length = 7
|
||||
{0,1,0,0,0,1,0,0,0,0,0,0,0,0}, // PUCCH length = 8
|
||||
{0,1,0,0,0,0,1,0,0,0,0,0,0,0}, // PUCCH length = 9
|
||||
{0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),(add_dmrs==0?0:1),0,0,0,0,0}, // PUCCH length = 10
|
||||
{0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,0,0}, // PUCCH length = 11
|
||||
{0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,0}, // PUCCH length = 12
|
||||
{0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0}, // PUCCH length = 13
|
||||
{0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0} // PUCCH length = 14
|
||||
};
|
||||
int k = 0;
|
||||
|
||||
for (int l=0; l<nrofSymbols; l++) {
|
||||
@@ -1218,7 +1218,7 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,n_hop,nr_slot_tx,&u,&v); // calculating u and v value
|
||||
|
||||
// Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33
|
||||
if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies
|
||||
if (l==0 && nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies
|
||||
int i = 4;
|
||||
|
||||
while (list_of_prime_numbers[i] < (12*nrofPRB)) i++;
|
||||
@@ -1242,7 +1242,7 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
}
|
||||
}
|
||||
|
||||
if (nrofPRB == 2) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-4) applies
|
||||
if (l==0 && nrofPRB == 2) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-4) applies
|
||||
for (int n = 0; n < 12 * nrofPRB; n++) {
|
||||
c16_t table = {table_5_2_2_2_4_Re[u][n], table_5_2_2_2_4_Im[u][n]};
|
||||
r_u_v_base[n] = c16mulRealShift(table, amp, 15);
|
||||
@@ -1256,7 +1256,7 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
}
|
||||
}
|
||||
|
||||
if (nrofPRB == 1) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-2) applies
|
||||
if (l==0 && nrofPRB == 1) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-2) applies
|
||||
for (int n = 0; n < 12 * nrofPRB; n++) {
|
||||
c16_t table = {table_5_2_2_2_2_Re[u][n], table_5_2_2_2_2_Im[u][n]};
|
||||
r_u_v_base[n] = c16mulRealShift(table, amp, 15);
|
||||
@@ -1275,12 +1275,12 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,m0,mcs,l,startingSymbolIndex,nr_slot_tx);
|
||||
|
||||
for (int rb=0; rb<nrofPRB; rb++) {
|
||||
const bool nb_rb_is_even = frame_parms->N_RB_DL & 1;
|
||||
const bool nb_rb_is_even = (frame_parms->N_RB_DL & 1)==0;
|
||||
const int halfRBs = frame_parms->N_RB_DL / 2;
|
||||
const int baseRB = rb + startingPRB;
|
||||
if ((intraSlotFrequencyHopping == 1) && (l<floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new offset PRB
|
||||
startingPRB = startingPRB + pucch_pdu->second_hop_prb;
|
||||
if ((intraSlotFrequencyHopping == 1) && (l>=floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new offset PRB
|
||||
startingPRB = pucch_pdu->second_hop_prb;
|
||||
}
|
||||
const int baseRB = rb + startingPRB;
|
||||
re_offset = ((l + startingSymbolIndex) * frame_parms->ofdm_symbol_size);
|
||||
//startingPRB = startingPRB + rb;
|
||||
if (nb_rb_is_even) {
|
||||
@@ -1304,7 +1304,7 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
printf("3 ");
|
||||
#endif
|
||||
} else if (baseRB > halfRBs) { // if number RBs in bandwidth is odd and current PRB is upper band
|
||||
re_offset += 12 * (baseRB - halfRBs) + 6;
|
||||
re_offset += 12 * (baseRB - halfRBs) - 6;
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("4 ");
|
||||
#endif
|
||||
@@ -1317,7 +1317,7 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
}
|
||||
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("re_offset=%u,baseRB=%d\n", re_offset, baseRB);
|
||||
printf("re_offset=%u,baseRB=%d\n", re_offset-((l + startingSymbolIndex) * frame_parms->ofdm_symbol_size), baseRB);
|
||||
#endif
|
||||
|
||||
//txptr = &txdataF[0][re_offset];
|
||||
@@ -1332,10 +1332,10 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
txdataF[0][re_offset] = z[n + k];
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf(
|
||||
"\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,k=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d "
|
||||
"\tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%u)=(z(l=%d,n=%d)=(%d,%d))\n",
|
||||
"\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,k=%d) mapping PUCCH DATA to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d "
|
||||
"\tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%u)=(z(l=%d,n=%d)=(%d,%d))[%d]\n",
|
||||
l,
|
||||
rb,
|
||||
startingPRB+rb,
|
||||
n,
|
||||
k,
|
||||
amp,
|
||||
@@ -1347,7 +1347,8 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
l,
|
||||
n,
|
||||
txdataF[0][re_offset].r,
|
||||
txdataF[0][re_offset].i);
|
||||
txdataF[0][re_offset].i,
|
||||
re_offset-(l + startingSymbolIndex) * frame_parms->ofdm_symbol_size);
|
||||
#endif
|
||||
}
|
||||
if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 1) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.2
|
||||
@@ -1355,12 +1356,13 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
txdataF[0][re_offset] = c16mulShift(angle, r_u_v_base[n + j], 15);
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf(
|
||||
"\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,j=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d "
|
||||
"\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,j=%d,alpha %f) mapping PUCCH DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d "
|
||||
"\tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u)=(r_u_v(l=%d,n=%d)=(%d,%d))\n",
|
||||
l,
|
||||
rb,
|
||||
rb+startingPRB,
|
||||
n,
|
||||
j,
|
||||
alpha,
|
||||
amp,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
frame_parms->N_RB_DL,
|
||||
@@ -1370,7 +1372,8 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
l,
|
||||
n,
|
||||
txdataF[0][re_offset].r,
|
||||
txdataF[0][re_offset].i);
|
||||
txdataF[0][re_offset].i,
|
||||
re_offset-(l + startingSymbolIndex) * frame_parms->ofdm_symbol_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ void nr_generate_pucch3_4(c16_t **txdataF,
|
||||
const int nr_slot_tx,
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu);
|
||||
|
||||
void nr_uci_encoding(uint64_t payload, uint8_t nr_bit, uint8_t nrofPRB, bool uci_on_pusch, uint16_t E, uint8_t Qm, uint64_t *b);
|
||||
void nr_uci_encoding(uint64_t payload, uint8_t nr_bit, bool uci_on_pusch, uint16_t E, uint8_t Qm, uint64_t *b);
|
||||
|
||||
static const uint8_t list_of_prime_numbers[46] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
|
||||
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
|
||||
|
||||
@@ -133,7 +133,7 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n
|
||||
bitmap);
|
||||
|
||||
nr_generate_pss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||
nr_generate_sss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg->cell_config.phy_cell_id.value, fp);
|
||||
nr_generate_sss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg->cell_config.phy_cell_id.value, fp);
|
||||
|
||||
uint16_t slots_per_hf = (fp->slots_per_frame) >> 1;
|
||||
int n_hf = slot < slots_per_hf ? 0 : 1;
|
||||
@@ -681,8 +681,10 @@ nr_srs_info_t nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
|
||||
*srs_est = nr_get_srs_signal(gNB, rxdataF, slot_rx, srs_pdu, &nr_srs_info, srs_received_signal, srs_received_noise);
|
||||
stop_meas(&gNB->get_srs_signal_stats);
|
||||
|
||||
uint32_t signal_power_avg = 0;
|
||||
c16_t srs_ls_estimated_channel[nb_antennas_rx][N_ap][ofdm_symbol_size * N_symb_SRS];
|
||||
uint32_t signal_power_avg = 0;
|
||||
int16_t noise_power_per_rb[srs_pdu->bwp_size];
|
||||
memset(noise_power_per_rb, 0, srs_pdu->bwp_size * sizeof(int16_t));
|
||||
|
||||
if (*srs_est >= 0) {
|
||||
start_meas(&gNB->srs_channel_estimation_stats);
|
||||
@@ -732,7 +734,7 @@ nr_srs_info_t nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
|
||||
T_INT(gNB->Mod_id),
|
||||
T_INT(srs_pdu->rnti),
|
||||
T_INT(frame_rx),
|
||||
T_INT(0),
|
||||
T_INT(slot_rx),
|
||||
T_INT(ant_rx_ind),
|
||||
T_INT(p_ind),
|
||||
T_BUFFER(srs_estimated_channel_freq[ant_rx_ind][p_ind], N_symb_SRS * ofdm_symbol_size * sizeof(c16_t)));
|
||||
@@ -741,14 +743,13 @@ nr_srs_info_t nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
|
||||
T_INT(gNB->Mod_id),
|
||||
T_INT(srs_pdu->rnti),
|
||||
T_INT(frame_rx),
|
||||
T_INT(0),
|
||||
T_INT(slot_rx),
|
||||
T_INT(ant_rx_ind),
|
||||
T_INT(p_ind),
|
||||
T_BUFFER(srs_estimated_channel_time_shifted[ant_rx_ind][p_ind],
|
||||
NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size * sizeof(c16_t)));
|
||||
}
|
||||
}
|
||||
|
||||
signal_power_avg /= (nb_antennas_rx * N_ap);
|
||||
signal_power_avg = max(signal_power_avg, 1);
|
||||
|
||||
@@ -931,10 +932,11 @@ static void handle_pucch(PHY_VARS_gNB *gNB, c16_t **rxdataF, const NR_gNB_PUCCH_
|
||||
nr_decode_pucch0(gNB, rxdataF, pucch->frame, pucch->slot, uci_pdu_format0, pucch_pdu);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
uci->pdu_type = NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE;
|
||||
uci->pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_2_3_4_t);
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu_format2 = &uci->pucch_pdu_format_2_3_4;
|
||||
nr_decode_pucch2(gNB, rxdataF, pucch->frame, pucch->slot, uci_pdu_format2, pucch_pdu);
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu_format2_3_4 = &uci->pucch_pdu_format_2_3_4;
|
||||
nr_decode_pucch2_3(gNB, rxdataF, pucch->frame, pucch->slot, uci_pdu_format2_3_4, pucch_pdu);
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Only PUCCH formats 0 and 2 are currently supported\n");
|
||||
|
||||
@@ -86,7 +86,7 @@ int main(int argc, char **argv)
|
||||
__attribute__((unused)) struct sigaction oldaction;
|
||||
sigaction(SIGINT, &sigint_action, &oldaction);
|
||||
|
||||
int i;
|
||||
int i;
|
||||
double SNR, snr0 = -2.0, snr1 = 2.0;
|
||||
double cfo = 0;
|
||||
uint8_t snr1set = 0;
|
||||
@@ -100,7 +100,7 @@ int main(int argc, char **argv)
|
||||
channel_desc_t *UE2gNB;
|
||||
int format = 0;
|
||||
FILE *input_fd = NULL;
|
||||
int16_t amp = 0x7FFF;
|
||||
int16_t amp = 0x1000;
|
||||
int nr_slot_tx = 0;
|
||||
int nr_frame_tx = 0;
|
||||
uint64_t actual_payload = 0, payload_received = 0;
|
||||
@@ -108,11 +108,8 @@ int main(int argc, char **argv)
|
||||
int nr_bit = 1; // maximum value possible is 2
|
||||
uint8_t m0 = 0; // higher layer paramater initial cyclic shift
|
||||
uint8_t nrofSymbols = 1; // number of OFDM symbols can be 1-2 for format 1
|
||||
// resource allocated see 9.2.1, 38.213 for more info.should be actually present in the resource set provided
|
||||
uint8_t startingSymbolIndex = 0;
|
||||
uint16_t startingPRB = 0;
|
||||
// PRB number not sure see 9.2.1, 38.213 for more info. Should be actually present in the resource set provided
|
||||
uint16_t startingPRB_intraSlotHopping = 0;
|
||||
uint8_t startingSymbolIndex = 0;
|
||||
uint16_t startingPRB = 0, startingPRB_intraSlotHopping = 0;
|
||||
uint16_t nrofPRB = 2;
|
||||
uint8_t timeDomainOCC = 0;
|
||||
SCM_t channel_model = AWGN; // Rayleigh1_anticorr;
|
||||
@@ -123,7 +120,9 @@ int main(int argc, char **argv)
|
||||
int N_RB_DL = 273, mu = 1;
|
||||
float target_error_rate = 0.001;
|
||||
int frame_length_complex_samples;
|
||||
// int frame_length_complex_samples_no_prefix;
|
||||
NR_DL_FRAME_PARMS *frame_parms;
|
||||
// unsigned char frame_type = 0;
|
||||
int loglvl = OAILOG_WARNING;
|
||||
int sr_flag = 0;
|
||||
int pucch_DTX_thres = 0;
|
||||
@@ -139,7 +138,8 @@ int main(int argc, char **argv)
|
||||
|
||||
int c;
|
||||
int nrofSymbols_set = 0;
|
||||
while ((c = getopt(argc, argv, "--:O:f:hA:f:g:i:I:P:B:b:t:T:m:n:r:o:s:S:x:y:z:N:F:GR:IL:q:cd:C")) != -1) {
|
||||
int freq_hop_flag=0;
|
||||
while ((c = getopt(argc, argv, "--:O:f:hA:f:g:i:I:P:B:b:t:T:m:n:r:o:s:S:x:y:z:N:F:GR:IL:q:cd:CH:")) != -1) {
|
||||
/* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */
|
||||
/* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */
|
||||
if (c == 1 || c == '-' || c == 'O')
|
||||
@@ -299,6 +299,9 @@ int main(int argc, char **argv)
|
||||
if ((format == 1 || format == 3) && nrofSymbols_set == 0)
|
||||
nrofSymbols = 14;
|
||||
break;
|
||||
case 'H':
|
||||
freq_hop_flag = 1;
|
||||
break;
|
||||
case 'm':
|
||||
m0 = atoi(optarg);
|
||||
break;
|
||||
@@ -374,12 +377,14 @@ int main(int argc, char **argv)
|
||||
|
||||
printf("Initializing gNodeB for mu %d, N_RB_DL %d, n_rx %d\n", mu, N_RB_DL, n_rx);
|
||||
|
||||
if ((format != 0) && (format != 1) && (format != 2)) {
|
||||
if ((format != 0) && (format != 1) && (format != 2) && (format != 3)) {
|
||||
printf("PUCCH format %d not supported\n", format);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
AssertFatal(((format < 2) && (nr_bit < 3) && (actual_payload < 5)) || ((format == 2) && (nr_bit > 2) && (nr_bit < 65)),
|
||||
AssertFatal(((format < 2) && (nr_bit < 3) && (actual_payload < 5)) ||
|
||||
((format == 2) && (nr_bit > 2) && (nr_bit < 65)) ||
|
||||
((format == 3) && (nr_bit > 2) && (nr_bit < 65)),
|
||||
"illegal combination format %d, nr_bit %d\n",
|
||||
format,
|
||||
nr_bit);
|
||||
@@ -463,7 +468,7 @@ int main(int argc, char **argv)
|
||||
AssertFatal(1 == 0, "Either nr_bit %d or sr_flag %d must be non-zero\n", nr_bit, sr_flag);
|
||||
}
|
||||
|
||||
startingPRB_intraSlotHopping = N_RB_DL - 1;
|
||||
startingPRB_intraSlotHopping = N_RB_DL - 1;
|
||||
uint32_t hopping_id = Nid_cell;
|
||||
uint32_t dmrs_scrambling_id = 0;
|
||||
uint32_t data_scrambling_id = 0;
|
||||
@@ -488,7 +493,6 @@ int main(int argc, char **argv)
|
||||
pucch_tx_pdu.hopping_id = hopping_id;
|
||||
pucch_tx_pdu.group_hop_flag = 0;
|
||||
pucch_tx_pdu.sequence_hop_flag = 0;
|
||||
pucch_tx_pdu.freq_hop_flag = 0;
|
||||
pucch_tx_pdu.mcs = mcs;
|
||||
pucch_tx_pdu.initial_cyclic_shift = 0;
|
||||
pucch_tx_pdu.second_hop_prb = startingPRB_intraSlotHopping;
|
||||
@@ -503,8 +507,6 @@ int main(int argc, char **argv)
|
||||
pucch_tx_pdu.prb_start = startingPRB;
|
||||
pucch_tx_pdu.hopping_id = hopping_id;
|
||||
pucch_tx_pdu.group_hop_flag = 0;
|
||||
pucch_tx_pdu.sequence_hop_flag = 0;
|
||||
pucch_tx_pdu.freq_hop_flag = 1;
|
||||
pucch_tx_pdu.initial_cyclic_shift = m0;
|
||||
pucch_tx_pdu.second_hop_prb = startingPRB_intraSlotHopping;
|
||||
pucch_tx_pdu.time_domain_occ_idx = timeDomainOCC;
|
||||
@@ -521,11 +523,33 @@ int main(int argc, char **argv)
|
||||
pucch_tx_pdu.hopping_id = hopping_id;
|
||||
pucch_tx_pdu.group_hop_flag = 0;
|
||||
pucch_tx_pdu.sequence_hop_flag = 0;
|
||||
pucch_tx_pdu.freq_hop_flag = 0;
|
||||
pucch_tx_pdu.dmrs_scrambling_id = dmrs_scrambling_id;
|
||||
pucch_tx_pdu.data_scrambling_id = data_scrambling_id;
|
||||
pucch_tx_pdu.second_hop_prb = startingPRB_intraSlotHopping;
|
||||
}
|
||||
if (format == 3) {
|
||||
pucch_tx_pdu.format_type = 3;
|
||||
pucch_tx_pdu.rnti = 0x1234;
|
||||
pucch_tx_pdu.n_bit = nr_bit;
|
||||
pucch_tx_pdu.payload = actual_payload;
|
||||
pucch_tx_pdu.nr_of_symbols = nrofSymbols;
|
||||
pucch_tx_pdu.start_symbol_index = startingSymbolIndex;
|
||||
pucch_tx_pdu.bwp_start = 0;
|
||||
pucch_tx_pdu.prb_start = startingPRB;
|
||||
pucch_tx_pdu.prb_size = nrofPRB;
|
||||
pucch_tx_pdu.hopping_id = hopping_id;
|
||||
pucch_tx_pdu.sequence_hop_flag = 0;
|
||||
pucch_tx_pdu.freq_hop_flag = 1;
|
||||
pucch_tx_pdu.dmrs_scrambling_id = dmrs_scrambling_id;
|
||||
pucch_tx_pdu.data_scrambling_id = data_scrambling_id;
|
||||
pucch_tx_pdu.second_hop_prb = startingPRB_intraSlotHopping;
|
||||
}
|
||||
|
||||
if (freq_hop_flag > 0 && nrofSymbols > 1) {
|
||||
pucch_tx_pdu.freq_hop_flag = 1;
|
||||
pucch_tx_pdu.second_hop_prb = N_RB_DL - nrofPRB;
|
||||
} else
|
||||
pucch_tx_pdu.freq_hop_flag = 0;
|
||||
|
||||
pucch_GroupHopping_t PUCCH_GroupHopping = pucch_tx_pdu.group_hop_flag + (pucch_tx_pdu.sequence_hop_flag << 1);
|
||||
double tx_level_fp = 100.0;
|
||||
@@ -542,8 +566,10 @@ int main(int argc, char **argv)
|
||||
nr_generate_pucch0(txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu);
|
||||
} else if (format == 1 && do_DTX == 0) {
|
||||
nr_generate_pucch1(txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu);
|
||||
} else if (do_DTX == 0) {
|
||||
} else if (format == 2 && do_DTX == 0) {
|
||||
nr_generate_pucch2(txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu);
|
||||
} else if (format == 3 && do_DTX == 0) {
|
||||
nr_generate_pucch3_4(txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu);
|
||||
}
|
||||
|
||||
// SNR Computation
|
||||
@@ -576,7 +602,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
random_channel(UE2gNB, 0);
|
||||
freq_channel(UE2gNB, N_RB_DL, 2 * N_RB_DL + 1, 15 << mu);
|
||||
freq_channel(UE2gNB, N_RB_DL, 12 * N_RB_DL + 1, 15 << mu);
|
||||
for (int symb = 0; symb < nrofSymbols; symb++) {
|
||||
int i0 = (startingSymbolIndex + symb) * gNB->frame_parms.ofdm_symbol_size;
|
||||
for (int re = 0; re < N_RB_DL * 12; re++) {
|
||||
@@ -588,10 +614,10 @@ int main(int argc, char **argv)
|
||||
double txr = (double)(((int16_t *)txdataF[0])[(i << 1)]);
|
||||
double txi = (double)(((int16_t *)txdataF[0])[1 + (i << 1)]);
|
||||
double rxr = {0}, rxi = {0};
|
||||
for (int l = 0; l < UE2gNB->channel_length; l++) {
|
||||
rxr = txr * UE2gNB->chF[aarx][l].r - txi * UE2gNB->chF[aarx][l].i;
|
||||
rxi = txr * UE2gNB->chF[aarx][l].i + txi * UE2gNB->chF[aarx][l].r;
|
||||
}
|
||||
//for (int l = 0; l < UE2gNB->channel_length; l++) {
|
||||
rxr = txr * UE2gNB->chF[aarx][re].r - txi * UE2gNB->chF[aarx][re].i;
|
||||
rxi = txr * UE2gNB->chF[aarx][re].i + txi * UE2gNB->chF[aarx][re].r;
|
||||
//}
|
||||
double rxr_tmp = rxr * phasor.r - rxi * phasor.i;
|
||||
rxi = rxr * phasor.i + rxi * phasor.r;
|
||||
rxr = rxr_tmp;
|
||||
@@ -686,7 +712,8 @@ int main(int argc, char **argv)
|
||||
pucch_pdu.prb_size = 1;
|
||||
pucch_pdu.bwp_start = 0;
|
||||
pucch_pdu.bwp_size = N_RB_DL;
|
||||
if (nrofSymbols > 1) {
|
||||
|
||||
if (freq_hop_flag > 0 && nrofSymbols > 1) {
|
||||
pucch_pdu.freq_hop_flag = 1;
|
||||
pucch_pdu.second_hop_prb = N_RB_DL - 1;
|
||||
} else
|
||||
@@ -730,8 +757,11 @@ int main(int argc, char **argv)
|
||||
pucch_pdu.prb_size = 1;
|
||||
pucch_pdu.bwp_start = 0;
|
||||
pucch_pdu.bwp_size = N_RB_DL;
|
||||
pucch_pdu.freq_hop_flag = 1;
|
||||
pucch_pdu.second_hop_prb = N_RB_DL - 2;
|
||||
if (freq_hop_flag > 0)
|
||||
pucch_pdu.freq_hop_flag = 1;
|
||||
else
|
||||
pucch_pdu.freq_hop_flag = 0;
|
||||
pucch_pdu.second_hop_prb = N_RB_DL - 1;
|
||||
pucch_pdu.time_domain_occ_idx = timeDomainOCC;
|
||||
|
||||
nr_decode_pucch1(gNB, rxdataF, nr_frame_tx, nr_slot_tx, &uci_pdu, &pucch_pdu);
|
||||
@@ -748,11 +778,11 @@ int main(int argc, char **argv)
|
||||
else if ((!confidence_lvl && !harq_list[0].harq_value) || (!confidence_lvl && nr_bit == 2 && !harq_list[1].harq_value))
|
||||
ack_nack_errors++;
|
||||
}
|
||||
|
||||
} else if (format == 2) {
|
||||
} else if (format == 2 || format == 3) {
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t uci_pdu = {0};
|
||||
nfapi_nr_pucch_pdu_t pucch_pdu = {0};
|
||||
pucch_pdu.rnti = 0x1234;
|
||||
pucch_pdu.format_type = format;
|
||||
pucch_pdu.subcarrier_spacing = 1;
|
||||
pucch_pdu.group_hop_flag = PUCCH_GroupHopping & 1;
|
||||
pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping >> 1) & 1;
|
||||
@@ -768,12 +798,12 @@ int main(int argc, char **argv)
|
||||
pucch_pdu.prb_start = startingPRB;
|
||||
pucch_pdu.dmrs_scrambling_id = dmrs_scrambling_id;
|
||||
pucch_pdu.data_scrambling_id = data_scrambling_id;
|
||||
if (nrofSymbols > 1) {
|
||||
if (freq_hop_flag > 0 && nrofSymbols > 1) {
|
||||
pucch_pdu.freq_hop_flag = 1;
|
||||
pucch_pdu.second_hop_prb = N_RB_DL - 1;
|
||||
pucch_pdu.second_hop_prb = N_RB_DL - nrofPRB;
|
||||
} else
|
||||
pucch_pdu.freq_hop_flag = 0;
|
||||
nr_decode_pucch2(gNB, rxdataF, nr_frame_tx, nr_slot_tx, &uci_pdu, &pucch_pdu);
|
||||
nr_decode_pucch2_3(gNB, rxdataF, nr_frame_tx, nr_slot_tx, &uci_pdu, &pucch_pdu);
|
||||
int csi_part1_bytes = pucch_pdu.bit_len_csi_part1 >> 3;
|
||||
if ((pucch_pdu.bit_len_csi_part1 & 7) > 0)
|
||||
csi_part1_bytes++;
|
||||
|
||||
@@ -632,7 +632,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
chan_desc->ch[i] = calloc(chan_desc->channel_length, sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->chF[i] = calloc(1200, sizeof(struct complexd));
|
||||
chan_desc->chF[i] = calloc(273*12, sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<chan_desc->nb_taps; i++)
|
||||
chan_desc->a[i] = calloc(nb_tx*nb_rx, sizeof(struct complexd));
|
||||
@@ -694,7 +694,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
chan_desc->ch[i] = (struct complexd *) malloc(chan_desc->channel_length * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(1200 * sizeof(struct complexd));
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(273*12 * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<chan_desc->nb_taps; i++)
|
||||
chan_desc->a[i] = (struct complexd *) malloc(nb_tx*nb_rx * sizeof(struct complexd));
|
||||
@@ -791,7 +791,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
chan_desc->ch[i] = (struct complexd *) malloc(chan_desc->channel_length * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(1200 * sizeof(struct complexd));
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(273*12 * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<chan_desc->nb_taps; i++)
|
||||
chan_desc->a[i] = (struct complexd *) malloc(nb_tx*nb_rx * sizeof(struct complexd));
|
||||
@@ -847,7 +847,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
chan_desc->ch[i] = (struct complexd *) malloc(chan_desc->channel_length * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(1200 * sizeof(struct complexd));
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(273*12 * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<chan_desc->nb_taps; i++)
|
||||
chan_desc->a[i] = (struct complexd *) malloc(nb_tx*nb_rx * sizeof(struct complexd));
|
||||
@@ -902,7 +902,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
chan_desc->ch[i] = (struct complexd *) malloc(chan_desc->channel_length * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(1200 * sizeof(struct complexd));
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(273*12 * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<chan_desc->nb_taps; i++)
|
||||
chan_desc->a[i] = (struct complexd *) malloc(nb_tx*nb_rx * sizeof(struct complexd));
|
||||
@@ -957,7 +957,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
chan_desc->ch[i] = (struct complexd *) malloc(chan_desc->channel_length * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(1200 * sizeof(struct complexd));
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(273*12 * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<chan_desc->nb_taps; i++)
|
||||
chan_desc->a[i] = (struct complexd *) malloc(nb_tx*nb_rx * sizeof(struct complexd));
|
||||
@@ -1012,7 +1012,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
chan_desc->ch[i] = (struct complexd *) malloc(chan_desc->channel_length * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(1200 * sizeof(struct complexd));
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(273*12 * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<chan_desc->nb_taps; i++)
|
||||
chan_desc->a[i] = (struct complexd *) malloc(nb_tx*nb_rx * sizeof(struct complexd));
|
||||
@@ -1068,7 +1068,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
chan_desc->ch[i] = (struct complexd *) malloc(chan_desc->channel_length * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(1200 * sizeof(struct complexd));
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(273*12 * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<chan_desc->nb_taps; i++)
|
||||
chan_desc->a[i] = (struct complexd *) malloc(nb_tx*nb_rx * sizeof(struct complexd));
|
||||
@@ -1124,7 +1124,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
chan_desc->ch[i] = (struct complexd *) malloc(chan_desc->channel_length * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<nb_tx*nb_rx; i++)
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(1200 * sizeof(struct complexd));
|
||||
chan_desc->chF[i] = (struct complexd *) malloc(273*12 * sizeof(struct complexd));
|
||||
|
||||
for (i = 0; i<chan_desc->nb_taps; i++)
|
||||
chan_desc->a[i] = (struct complexd *) malloc(nb_tx*nb_rx * sizeof(struct complexd));
|
||||
|
||||
@@ -236,53 +236,56 @@ add_physim_test(physim.5g.nr_ulschsim.test4 "106 PRBs 4-layer MIMO" nr_ulschsim
|
||||
###### nr_pucchsim unit test ######
|
||||
####################################################################################
|
||||
|
||||
add_physim_test(physim.5g.nr_pucchsim.test1 "Format 0 1-bit ACK miss 106 PRB" nr_pucchsim -R 106 -i 1 -P 0 -b 1 -s-2 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test2 "Format 0 2-bit ACK miss 106 PRB" nr_pucchsim -R 106 -i 1 -P 0 -b 2 -s-2 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test3 "Format 0 2-bit ACK miss, 1-bit SR 106 PRB" nr_pucchsim -R 106 -i 1 -P 0 -b 2 -s-2 -c -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test4 "Format 2 3-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 3 -s0 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test5 "Format 2 4-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 4 -s0 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test6 "Format 2 5-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 5 -s1 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test7 "Format 2 6-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 6 -s2 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test8 "Format 2 7-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 7 -s3 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test9 "Format 2 8-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 8 -s4 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test10 "Format 2 9-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 9 -s5 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test11 "Format 2 10-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 10 -s6 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test12 "Format 2 11-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 11 -s6 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test13 "Format 2 12-bit 4/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q4 -b 12 -s-3 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test14 "Format 2 19-bit 4/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q4 -b 19 -s-3 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test15 "Format 2 12-bit 8/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q8 -b 12 -s-3 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test16 "Format 2 19-bit 8/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q8 -b 19 -s-3 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test17 "Format 2 32-bit 8/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q8 -b 32 -s-3 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test18 "Format 2 32-bit 16/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q16 -b 32 -s-3 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test19 "Format 2 64-bit 16/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q16 -b 64 -s-3 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test20 "Format 0 1-bit Ack miss 273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 0 -b 1 -s-2 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test21 "Format 0 2-bit Ack miss 273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 0 -b 2 -s-2 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test22 "Format 0 2-bit Ack miss+SR 273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 0 -b 2 -s-2 -c -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test23 "Format 2 4-bit 2/273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 2 -b 4 -s-8 -S0 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test24 "Format 2 7-bit 2/273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 2 -b 7 -s3 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test25 "Format 2 11-bit 2/273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 2 -b 11 -s6 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test26 "Format 2 12-bit 8/273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 2 -q8 -b 12 -s-3 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test27 "Format 2 19-bit 8/273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 2 -q8 -b 19 -s-3 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test28 "Format 2 64-bit 16/273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 2 -q16 -b 64 -s-3 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test29 "Format 2 64-bit 16/273 PRB Delay 2us" nr_pucchsim -R 273 -z8 -i 1 -P 2 -q16 -b 64 -s0 -S7 -d 2 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test30 "Format 1 NACK number of symbols = 4 273PRB" nr_pucchsim -R 273 -z8 -i 4 -P 1 -b 1 -B 0 -s-8 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test31 "Format 1 ACK number of symbols = 4 273PRB" nr_pucchsim -R 273 -z8 -i 4 -P 1 -b 1 -B 1 -s-8 -n3000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test32 "Format 1 (NACK,NACK) number of symbols = 4, 273PRB" nr_pucchsim -R 273 -z8 -i 4 -P 1 -b 2 -B 0 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test33 "Format 1 (ACK,NACK) number of symbols = 4, 273PRB with SR" nr_pucchsim -R 273 -z8 -i 4 -P 1 -b 2 -B 1 -s-8 -c -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test34 "Format 1 (NACK,ACK) number of symbols = 4, 273PRB" nr_pucchsim -R 273 -z8 -i 4 -P 1 -b 2 -B 2 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test35 "Format 1 (ACK,ACK) number of symbols = 4, 273PRB" nr_pucchsim -R 273 -z8 -i 4 -P 1 -b 2 -B 3 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test36 "Format 1 NACK number of symbols = 8, 273PRB" nr_pucchsim -R 273 -z8 -i 8 -P 1 -b 1 -B 0 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test37 "Format 1 ACK number of symbols = 8, 273PRB" nr_pucchsim -R 273 -z8 -i 8 -P 1 -b 1 -B 1 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test38 "Format 1 (NACK,NACK) number of symbols = 8, 273PRB" nr_pucchsim -R 273 -z8 -i 8 -P 1 -b 2 -B 0 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test39 "Format 1 (ACK,NACK) number of symbols = 8, 273PRB" nr_pucchsim -R 273 -z8 -i 8 -P 1 -b 2 -B 1 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test40 "Format 1 (NACK,ACK) number of symbols = 8, 273PRB with SR" nr_pucchsim -R 273 -z8 -i 8 -P 1 -b 2 -B 2 -s-8 -c -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test41 "Format 1 (ACK,ACK) number of symbols = 8, 273PRB" nr_pucchsim -R 273 -z8 -i 8 -P 1 -b 2 -B 3 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test42 "Format 1 NACK number of symbols = 14, 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 1 -b 1 -B 0 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test43 "Format 1 ACK number of symbols = 14, 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 1 -b 1 -B 1 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test44 "Format 1 (NACK,NACK) number of symbols = 14, 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 1 -b 2 -B 0 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test45 "Format 1 (ACK,NACK) number of symbols = 14, 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 1 -b 2 -B 1 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test46 "Format 1 (NACK,ACK) number of symbols = 14, 273PRB with SR" nr_pucchsim -R 273 -z8 -i 14 -P 1 -b 2 -B 2 -s-8 -c -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test47 "Format 1 (ACK,ACK) number of symbols = 14, 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 1 -b 2 -B 3 -s-8 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test1 "Format 0 1-bit ACK miss 106 PRB" nr_pucchsim -R 106 -i 1 -P 0 -b 1 -s-2 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test2 "Format 0 2-bit ACK miss 106 PRB" nr_pucchsim -R 106 -i 1 -P 0 -b 2 -s-2 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test3 "Format 0 2-bit ACK miss, 1-bit SR 106 PRB" nr_pucchsim -R 106 -i 1 -P 0 -b 2 -s-2 -c -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test4 "Format 2 3-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 3 -s0 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test5 "Format 2 4-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 4 -s0 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test6 "Format 2 5-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 5 -s1 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test7 "Format 2 6-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 6 -s2 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test8 "Format 2 7-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 7 -s3 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test9 "Format 2 8-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 8 -s4 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test10 "Format 2 9-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 9 -s5 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test11 "Format 2 10-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 10 -s6 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test12 "Format 2 11-bit 2/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -b 11 -s6 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test13 "Format 2 12-bit 4/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q4 -b 12 -s-3 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test14 "Format 2 19-bit 4/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q4 -b 19 -s-3 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test15 "Format 2 12-bit 8/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q8 -b 12 -s-3 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test16 "Format 2 19-bit 8/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q8 -b 19 -s-3 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test17 "Format 2 32-bit 8/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q8 -b 32 -s-3 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test18 "Format 2 32-bit 16/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q16 -b 32 -s-3 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test19 "Format 2 64-bit 16/106 PRB" nr_pucchsim -R 106 -i 1 -P 2 -q16 -b 64 -s-3 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test20 "Format 0 1-bit Ack miss 273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 0 -b 1 -s-2 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test21 "Format 0 2-bit Ack miss 273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 0 -b 2 -s-2 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test22 "Format 0 2-bit Ack miss+SR 273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 0 -b 2 -s-2 -c -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test23 "Format 2 4-bit 2/273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 2 -b 4 -s-8 -S0 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test24 "Format 2 7-bit 2/273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 2 -b 7 -s3 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test25 "Format 2 11-bit 2/273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 2 -b 11 -s6 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test26 "Format 2 12-bit 8/273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 2 -q8 -b 12 -s-3 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test27 "Format 2 19-bit 8/273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 2 -q8 -b 19 -s-3 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test28 "Format 2 64-bit 16/273 PRB" nr_pucchsim -R 273 -z8 -i 1 -P 2 -q16 -b 64 -s-3 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test29 "Format 2 64-bit 16/273 PRB Delay 2us" nr_pucchsim -R 273 -z8 -i 1 -P 2 -q16 -b 64 -s0 -S7 -d 2 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test30 "Format 1 NACK number of symbols = 4 273PRB" nr_pucchsim -R 273 -z8 -i 4 -P 1 -b 1 -B 0 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test31 "Format 1 ACK number of symbols = 4 273PRB" nr_pucchsim -R 273 -z8 -i 4 -P 1 -b 1 -B 1 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test32 "Format 1 (NACK,NACK) number of symbols = 4 273PRB" nr_pucchsim -R 273 -z8 -i 4 -P 1 -b 2 -B 0 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test33 "Format 1 (ACK,NACK) number of symbols = 4 273PRB with SR" nr_pucchsim -R 273 -z8 -i 4 -P 1 -b 2 -B 1 -s-10 -c -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test34 "Format 1 (NACK,ACK) number of symbols = 4 273PRB" nr_pucchsim -R 273 -z8 -i 4 -P 1 -b 2 -B 2 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test35 "Format 1 (ACK,ACK) number of symbols = 4 273PRB" nr_pucchsim -R 273 -z8 -i 4 -P 1 -b 2 -B 3 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test36 "Format 1 NACK number of symbols = 8 273PRB" nr_pucchsim -R 273 -z8 -i 8 -P 1 -b 1 -B 0 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test37 "Format 1 ACK number of symbols = 8 273PRB" nr_pucchsim -R 273 -z8 -i 8 -P 1 -b 1 -B 1 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test38 "Format 1 (NACK,NACK) number of symbols = 8 273PRB" nr_pucchsim -R 273 -z8 -i 8 -P 1 -b 2 -B 0 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test39 "Format 1 (ACK,NACK) number of symbols = 8 273PRB" nr_pucchsim -R 273 -z8 -i 8 -P 1 -b 2 -B 1 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test40 "Format 1 (NACK,ACK) number of symbols = 8 273PRB with SR" nr_pucchsim -R 273 -z8 -i 8 -P 1 -b 2 -B 2 -s-10 -c -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test41 "Format 1 (ACK,ACK) number of symbols = 8 273PRB" nr_pucchsim -R 273 -z8 -i 8 -P 1 -b 2 -B 3 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test42 "Format 1 NACK number of symbols = 14 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 1 -b 1 -B 0 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test43 "Format 1 ACK number of symbols = 14 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 1 -b 1 -B 1 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test44 "Format 1 (NACK,NACK) number of symbols = 14 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 1 -b 2 -B 0 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test45 "Format 1 (ACK,NACK) number of symbols = 14 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 1 -b 2 -B 1 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test46 "Format 1 (NACK,ACK) number of symbols = 14 273PRB with SR" nr_pucchsim -R 273 -z8 -i 14 -P 1 -b 2 -B 2 -s-10 -c -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test47 "Format 1 (ACK,ACK) number of symbols = 14 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 1 -b 2 -B 3 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test48 "Format 3 4-bits number of symbols = 14 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 3 -q1 -b 3 -B 3 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test49 "Format 3 7-bits number of symbols = 14 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 3 -q1 -b 7 -B 3 -s-10 -n1000)
|
||||
add_physim_test(physim.5g.nr_pucchsim.test50 "Format 3 11-bits number of symbols = 14 273PRB" nr_pucchsim -R 273 -z8 -i 14 -P 3 -q1 -b 7 -B 3 -s-10 -n1000)
|
||||
|
||||
####################################################################################
|
||||
###### nr_ulsim unit test ######
|
||||
|
||||
Reference in New Issue
Block a user