feat(nr): implement rank-8 PDSCH
This commit is contained in:
@@ -16,13 +16,14 @@ extern "C" {
|
||||
|
||||
#include "openair1/PHY/TOOLS/tools_defs.h" // c16_t
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h" // fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
//#include "openair1/PHY/MODULATION/nr_modulation.h" // nr_layer_precoder_simd_[cm, simd]
|
||||
|
||||
// Forward declare the function but hide the Variable-Length Array (VLA) feature from C not available in C++
|
||||
c16_t nr_layer_precoder_cm(int n_layers,
|
||||
int symbol_size,
|
||||
c16_t (*dataF_in)[/*symbol_size*/], // c16_t dataF_in[n_layers][symbol_size]
|
||||
const c16_t (*dataF_in)[/*symbol_size*/], // c16_t dataF_in[n_layers][symbol_size]
|
||||
int ant,
|
||||
c16_t weights[NR_MAX_NB_LAYERS][NR_MAX_CSI_PORTS],
|
||||
int offset);
|
||||
@@ -37,6 +38,14 @@ void nr_layer_precoder_simd(int n_layers,
|
||||
int re_cnt,
|
||||
c16_t *dataF_out);
|
||||
|
||||
// Forward declare the layer mapper while hiding its C VLA dimension.
|
||||
void nr_layer_mapping(int nb_codewords,
|
||||
const c16_t *const mod_symbols[2],
|
||||
const uint32_t n_symbols_per_codeword[2],
|
||||
uint8_t n_layers,
|
||||
int layer_size,
|
||||
c16_t (*tx_layers)[/*layer_size*/]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -185,11 +194,50 @@ TEST(NrLayerPrecoderTest, Compare_CM_SIMD)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NrLayerMappingTest, Rank8UsesTwoCodewordsAcrossEightDistinctLayers)
|
||||
{
|
||||
constexpr int n_codewords = 2;
|
||||
constexpr int n_layers = 8;
|
||||
constexpr int layers_per_codeword = 4;
|
||||
constexpr int symbols_per_layer = 7;
|
||||
constexpr int symbols_per_codeword = layers_per_codeword * symbols_per_layer;
|
||||
|
||||
std::vector<c16_t> cw0(symbols_per_codeword);
|
||||
std::vector<c16_t> cw1(symbols_per_codeword);
|
||||
for (int i = 0; i < symbols_per_codeword; ++i) {
|
||||
cw0[i] = {static_cast<int16_t>(100 + i), static_cast<int16_t>(-100 - i)};
|
||||
cw1[i] = {static_cast<int16_t>(1000 + i), static_cast<int16_t>(-1000 - i)};
|
||||
}
|
||||
|
||||
const c16_t *mod_symbols[2] = {cw0.data(), cw1.data()};
|
||||
const uint32_t n_symbols_per_codeword[2] = {symbols_per_codeword, symbols_per_codeword};
|
||||
std::vector<c16_t> layer_storage(n_layers * symbols_per_layer, c16_t{SHRT_MIN, SHRT_MIN});
|
||||
c16_t(*tx_layers)[symbols_per_layer] = reinterpret_cast<c16_t(*)[symbols_per_layer]>(layer_storage.data());
|
||||
|
||||
nr_layer_mapping(n_codewords,
|
||||
mod_symbols,
|
||||
n_symbols_per_codeword,
|
||||
n_layers,
|
||||
symbols_per_layer,
|
||||
tx_layers);
|
||||
|
||||
for (int re = 0; re < symbols_per_layer; ++re) {
|
||||
for (int layer = 0; layer < n_layers; ++layer) {
|
||||
const int cw = layer / layers_per_codeword;
|
||||
const int cw_layer = layer % layers_per_codeword;
|
||||
const c16_t expected = mod_symbols[cw][re * layers_per_codeword + cw_layer];
|
||||
EXPECT_EQ(tx_layers[layer][re].r, expected.r) << "real mismatch at layer " << layer << ", RE " << re;
|
||||
EXPECT_EQ(tx_layers[layer][re].i, expected.i) << "imag mismatch at layer " << layer << ", RE " << re;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize random seed
|
||||
srand(time(0));
|
||||
|
||||
logInit();
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user