feat(nr): implement rank-8 PDSCH

This commit is contained in:
2026-09-15 00:36:01 +09:00
parent 04ee4ea8e5
commit c50fe1af53
42 changed files with 3244 additions and 648 deletions
+20 -1
View File
@@ -71,9 +71,28 @@ static inline const char *rnti_types(nr_rnti_type_t rr)
#define MAX_GSCN_BAND 620 // n78 has the highest GSCN range of 619
#define NR_SYMBOLS_PER_SLOT 14
#define NR_SYMBOLS_PER_SLOT_EXTENDED_CP 12
#define NR_MAX_NB_LAYERS 4 // 8
#define NR_MAX_NB_LAYERS 8
#define NR_MAX_NB_CODEWORDS 2
#define NR_MAX_CSI_PORTS 12
/* TS 38.211 Table 7.3.1.3-1: PDSCH uses one codeword up to rank four and
* two codewords from rank five onward. Keep this split in one shared helper
* so MAC and PHY cannot silently disagree about the 4+4 rank-eight mapping. */
static inline uint8_t nr_pdsch_num_codewords(uint8_t layers)
{
AssertFatal(layers >= 1 && layers <= NR_MAX_NB_LAYERS, "Invalid PDSCH layer count %u\n", layers);
return layers > 4 ? 2 : 1;
}
static inline uint8_t nr_pdsch_layers_per_codeword(uint8_t layers, uint8_t codeword)
{
const uint8_t n_codewords = nr_pdsch_num_codewords(layers);
AssertFatal(codeword < n_codewords, "Invalid codeword %u for %u PDSCH layers\n", codeword, layers);
if (n_codewords == 1)
return layers;
return layers / 2 + (codeword == 1 ? layers % 2 : 0);
}
// Since the IQ samples are represented by SQ15 R+I (see https://en.wikipedia.org/wiki/Q_(number_format)) we need to compensate when
// calcualting signal energy. Instead of shifting each sample right by 15, we can normalize the result in dB scale once its
// calcualted. Signal energy is calculated using RMS^2, where each sample is squared before taking the average of the sum, therefore
+16
View File
@@ -21,6 +21,22 @@ TEST(nr_common, nr_timer) {
EXPECT_TRUE(nr_timer_expired(&timer));
}
TEST(nr_common, pdsch_codeword_layer_split)
{
constexpr uint8_t expected_codewords[] = {1, 1, 1, 1, 2, 2, 2, 2};
constexpr uint8_t expected_cw0_layers[] = {1, 2, 3, 4, 2, 3, 3, 4};
constexpr uint8_t expected_cw1_layers[] = {0, 0, 0, 0, 3, 3, 4, 4};
for (uint8_t layers = 1; layers <= NR_MAX_NB_LAYERS; layers++) {
const int index = layers - 1;
EXPECT_EQ(nr_pdsch_num_codewords(layers), expected_codewords[index]);
EXPECT_EQ(nr_pdsch_layers_per_codeword(layers, 0), expected_cw0_layers[index]);
if (expected_codewords[index] == 2) {
EXPECT_EQ(nr_pdsch_layers_per_codeword(layers, 1), expected_cw1_layers[index]);
}
}
}
int main(int argc, char **argv)
{