diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index ca387cda32..7e632636ec 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -18,7 +18,7 @@ HWs="" BUILD_DIR=ran_build CMAKE_BUILD_TYPE="RelWithDebInfo" CMAKE_CMD="$CMAKE" -OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_aal ldpc_xdma websrv oai_iqplayer imscope imscope_record" +OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_aal websrv oai_iqplayer imscope imscope_record" TARGET_LIST="" BUILD_TOOL_OPT="-j$(nproc)" diff --git a/doc/LDPC_XDMA_offload_setup.md b/doc/LDPC_XDMA_offload_setup.md deleted file mode 100644 index a0270db6b0..0000000000 --- a/doc/LDPC_XDMA_offload_setup.md +++ /dev/null @@ -1,163 +0,0 @@ - - -# LDPC offload with the XDMA driver - -[TOC] - -This documentation aims to provide a tutorial for using Xilinx PCIe-XDMA based FPGA LDPC decoding within OAI. LDPC decoding is offloaded to FPGA. - -## XDMA Driver Build & Install - -- Get XDMA driver source -```bash -git clone https://github.com/Xilinx/dma_ip_drivers.git -cd dma_ip_drivers/XDMA/linux-kernel -``` -The *xdma_driver* directory contains the following: - -```bash -dma_ip_drivers/XDMA/linux-kernel/ -├── COPYING -├── include -├── LICENSE -├── readme.txt -├── RELEASE -├── tests -├── tools -└── xdma -``` - -Before building the driver, ensure that your system recognizes the Xilinx device. You can check this using the `lspci` command: - -```bash -$ lspci | grep Xilinx -01:00.0 Serial controller: Xilinx Corporation Device 8038 -``` - -Building and Installing the Driver - -```bash -cd ~/dma_ip_drivers/XDMA/linux-kernel/xdma -make clean -make -# install to make the driver loading automatically at system startup -sudo make install -``` - -Load the Driver - -```bash -cd ~/dma_ip_drivers/XDMA/linux-kernel/tests -sudo ./load_driver.sh -``` - -## OAI Build - -```bash -# Get openairinterface5g source code -git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g -cd ~/openairinterface5g - -# Install OAI dependencies -cd ~/openairinterface5g/cmake_targets -./build_oai -I - -# Build OAI gNB & UE -cd ~/openairinterface5g -source oaienv -cd cmake_targets -./build_oai --ninja -w SIMU --gNB --nrUE -P --build-lib "ldpc_xdma" -C -c -``` - -Shared object file *libldpc_xdma.so* is created during the compilation. This object is conditionally compiled. Selection of the library to compile is done using `--build-lib ldpc_xdma`. - -## 5G PHY simulators - -The simulated test uses the option `--loader.ldpc.shlibversion _xdma` to select the XDMA version for loading into the LDPC interface. Additionally, the option `--nrLDPC_coding_xdma.num_threads_prepare` is used to specify the number of threads for preparing data before the LDPC processing, specifically for the deinterleaving and rate matching parts. - -Another way to activate the feature is to add the `xdma.conf` file with the following content: - -``` -nrLDPC_coding_xdma : { - num_threads_prepare : 2; -}; - -loader : { - ldpc : { - shlibversion : "_xdma"; - }; -}; - -``` - -and use option `-O xdma.conf`. - -### nr_ulsim test - -Example command for running nr_ulsim with LDPC decoding offload to the FPGA: - -```bash -cd ~/openairinterface5g/cmake_targets/ran_build/build -sudo ./nr_ulsim -n100 -m28 -r273 -R273 -s22 -I10 -C8 -P --loader.ldpc.shlibversion _xdma --nrLDPC_coding_xdma.num_threads_prepare 2 -``` - -or - -``` -sudo ./nr_ulsim -n100 -m28 -r273 -R273 -s22 -I10 -C8 -P -O xdma.conf -``` - -## Run - -Both gNB and nrUE use the option `--loader.ldpc.shlibversion _xdma` to select the XDMA version for loading into the LDPC interface and `--nrLDPC_coding_xdma.num_threads_prepare` to specify the number of threads for preparing data before the LDPC processing, specifically for the deinterleaving and rate matching parts. - -Another way to activate the feature is to add the following content to the `.conf` file you want to use: - -``` -nrLDPC_coding_xdma : { - num_threads_prepare : 2; -}; - -loader : { - ldpc : { - shlibversion : "_xdma"; - }; -}; - -``` - -and use option `-O *.conf`. - -### gNB - -Example command using rfsim: - -```bash -cd ~/openairinterface5g/cmake_targets/ran_build/build -sudo ./nr-softmodem --rfsim --log_config.global_log_options level,nocolor,time -O ../../../ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.conf --loader.ldpc.shlibversion _xdma --nrLDPC_coding_xdma.num_threads_prepare 2 -``` - -or - -```bash -sudo ./nr-softmodem --rfsim --log_config.global_log_options level,nocolor,time -O ../../../ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.conf -``` - -if you have added the configuration to the `.conf` file. - -### UE - -Example command using rfsim: - -```bash -cd ~/openairinterface5g/cmake_targets/ran_build/build -sudo ./nr-uesoftmodem --rfsim -r 106 --numerology 1 --band 78 -C 3319680000 --ue-nb-ant-tx 1 --ue-nb-ant-rx 1 -O ../../../ci-scripts/conf_files/nrue1.uicc.cluCN.conf --rfsimulator.[0].serveraddr 10.201.1.100 --loader.ldpc.shlibversion _xdma --nrLDPC_coding_xdma.num_threads_prepare 2 -``` - -or - -```bash -sudo ./nr-uesoftmodem --rfsim -r 106 --numerology 1 --band 78 -C 3319680000 --ue-nb-ant-tx 1 --ue-nb-ant-rx 1 -O ../../../ci-scripts/conf_files/nrue1.uicc.cluCN.conf --rfsimulator.[0].serveraddr 10.201.1.100 -``` - -if you have added the configuration to the `.conf` file. diff --git a/openair1/PHY/CODING/DOC/LDPCImplementation.md b/openair1/PHY/CODING/DOC/LDPCImplementation.md index aaf1dfa190..8bda7c90bf 100644 --- a/openair1/PHY/CODING/DOC/LDPCImplementation.md +++ b/openair1/PHY/CODING/DOC/LDPCImplementation.md @@ -48,30 +48,6 @@ Please refer to the dedicated documentation at [LDPC_OFFLOAD_SETUP.md](file://.. `libldpc_aal.so` has its decoder and its encoder implemented in [nrLDPC_coding_aal.c](file://../nrLDPC_coding/nrLDPC_coding_aal/nrLDPC_coding_aal.c). -loading `libldpc_xdma.so` instead of `libldpc.so`: - -`make ldpc_xdma` or `ninja ldpc_xdma` - -This command creates the `libldpc_xdma.so` shared library. - -``` -ninja ldpc_xdma -[2/2] Linking C shared module libldpc_xdma.so -``` - -At runtime, to successfully use the xdma, you need to install vendor specific drivers and tools.\ -Please refer to the dedicated documentation at [LDPC_XDMA_OFFLOAD_SETUP.md](file://../../../../doc/LDPC_XDMA_OFFLOAD_SETUP.md). - -``` -./nr-softmodem -O libconfig:gnb.band78.sa.fr1.106PRB.usrpb210.conf:dbgl5 --rfsim --rfsimulator.[0].serveraddr server --log_config.gtpu_log_level info --loader.ldpc.shlibversion _xdma --nrLDPC_coding_xdma.num_threads_prepare 2 -``` - -`libldpc_xdma.so` has its decoder implemented in [nrLDPC_coding_xdma.c](file://../nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c).\ -Its encoder is implemented in [nrLDPC_coding_segment_encoder.c](file://../nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c). - -*Note: `libldpc_xdma.so` relies on a segment coding library for encoding.* -*The segment coding library is `libldpc.so` by default but it can be chosen with option `--nrLDPC_coding_xdma.encoder_shlibversion` followed by the library version - like with `--loder.ldpc.shlibversion` in the segment coding case above -* - #### Examples of ldpc shared lib selection when running ldpctest: Slot coding libraries cannot be used yet within ldpctest. @@ -86,8 +62,6 @@ Libraries implementing the slotwise LDPC coding must be named `libldpc<_version> `libldpc_aal.so` is completed. -`libldpc_xdma.so` is completed. - ## LDPC segment coding The interface of the library is defined in [nrLDPC_defs.h](file://../nrLDPC_defs.h) as typedefs of the functions of the interface. The name of the functions implementing these typedefs can be found in [nrLDPC_extern.h](file://../nrLDPC_extern.h). diff --git a/openair1/PHY/CODING/nrLDPC_coding/CMakeLists.txt b/openair1/PHY/CODING/nrLDPC_coding/CMakeLists.txt index 193bf8d3b9..8a9f7d8353 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/CMakeLists.txt +++ b/openair1/PHY/CODING/nrLDPC_coding/CMakeLists.txt @@ -1,5 +1,4 @@ # SPDX-License-Identifier: LicenseRef-CSSL-1.0 add_subdirectory(nrLDPC_coding_segment) -add_subdirectory(nrLDPC_coding_xdma) add_subdirectory(nrLDPC_coding_aal) diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/CMakeLists.txt b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/CMakeLists.txt deleted file mode 100644 index 6cce8434fc..0000000000 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -# SPDX-License-Identifier: LicenseRef-CSSL-1.0 - -########################################################## - -# LDPC offload library - XDMA -########################################################## - -add_boolean_option(ENABLE_LDPC_XDMA OFF "Build support for LDPC Offload to XDMA library" OFF) - -if (ENABLE_LDPC_XDMA) - - add_library(ldpc_xdma MODULE - nrLDPC_coding_xdma_offload.c - nrLDPC_coding_xdma.c - ../nrLDPC_coding_segment/nr_rate_matching.c - ../nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c - ../../nrLDPC_encoder/ldpc_encoder_optim8segmulti.c - ) - target_include_directories(ldpc_xdma PRIVATE ../nrLDPC_coding_segment) - - target_link_libraries(ldpc_xdma PRIVATE ldpc_gen_HEADERS log_headers) - set_target_properties(ldpc_xdma PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) - - add_dependencies(nr-softmodem ldpc_xdma) - add_dependencies(nr-uesoftmodem ldpc_xdma) - add_dependencies(nr_ulsim ldpc_xdma) - add_dependencies(nr_ulschsim ldpc_xdma) - add_dependencies(nr_dlsim ldpc_xdma) - add_dependencies(nr_dlschsim ldpc_xdma) - -endif() diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c deleted file mode 100644 index 1a136b6c02..0000000000 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - * SPDX-License-Identifier: LicenseRef-CSSL-1.0 - */ - -/*! \file PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c - * \brief Top-level routines for decoding LDPC (ULSCH) transport channels - * decoding implemented using a FEC IP core on FPGA through XDMA driver - */ - -// [from gNB coding] -#include - -#include -#include "PHY/CODING/coding_defs.h" -#include "PHY/CODING/coding_extern.h" -#include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma_offload.h" -#include "PHY/CODING/nrLDPC_extern.h" -#include "common/utils/LOG/log.h" -#include "defs.h" -// #define DEBUG_ULSCH_DECODING -// #define gNB_DEBUG_TRACE - -#define OAI_UL_LDPC_MAX_NUM_LLR 27000 // 26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384 -// #define DEBUG_CRC -#ifdef DEBUG_CRC -#define PRINT_CRC_CHECK(a) a -#else -#define PRINT_CRC_CHECK(a) -#endif - -#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h" -#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" - -#include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h" - -// Global var to limit the rework of the dirty legacy code -int num_threads_prepare_max = 0; -char *user_device = NULL; -char *enc_read_device = NULL; -char *enc_write_device = NULL; -char *dec_read_device = NULL; -char *dec_write_device = NULL; - -/*! - * \typedef args_fpga_decode_prepare_t - * \struct args_fpga_decode_prepare_s - * \brief arguments structure for passing arguments to the nr_ulsch_FPGA_decoding_prepare_blocks function - */ -typedef struct args_fpga_decode_prepare_s { - nrLDPC_TB_decoding_parameters_t *TB_params; /*!< transport blocks parameters */ - - uint8_t *multi_indata; /*!< pointer to the head of the block destination array that is then passed to the FPGA decoding */ - int no_iteration_ldpc; /*!< pointer to the number of iteration set by this function */ - uint32_t r_first; /*!< index of the first block to be prepared within this function */ - uint32_t r_span; /*!< number of blocks to be prepared within this function */ - int r_offset; /*!< r index expressed in bits */ - int input_CBoffset; /*!< */ - int Kc; /*!< ratio between the number of columns in the parity check graph and the lifting size */ - int Kprime; /*!< size of payload and CRC bits in a code block */ - task_ans_t *ans; /*!< pointer to the answer that is used by thread pool to detect job completion */ -} args_fpga_decode_prepare_t; - -int32_t nrLDPC_coding_init(void); -int32_t nrLDPC_coding_shutdown(void); -int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *slot_params, int frame_rx, int slot_rx); -// int32_t nrLDPC_coding_encoder(void); -int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, int frame_rx, int slot_rx, tpool_t *ldpc_threadPool); -void nr_ulsch_FPGA_decoding_prepare_blocks(void *args); - -int32_t nrLDPC_coding_init(void) -{ - paramdef_t LoaderParams[] = { - {"num_threads_prepare", NULL, 0, .iptr = &num_threads_prepare_max, .defintval = 0, TYPE_INT, 0, NULL}, - {"user_device", NULL, 0, .strptr = &user_device, .defstrval = DEVICE_NAME_DEFAULT_USER, TYPE_STRING, 0, NULL}, - {"enc_read_device", NULL, 0, .strptr = &enc_read_device, .defstrval = DEVICE_NAME_DEFAULT_ENC_READ, TYPE_STRING, 0, NULL}, - {"enc_write_device", NULL, 0, .strptr = &enc_write_device, .defstrval = DEVICE_NAME_DEFAULT_ENC_WRITE, TYPE_STRING, 0, NULL}, - {"dec_read_device", NULL, 0, .strptr = &dec_read_device, .defstrval = DEVICE_NAME_DEFAULT_DEC_READ, TYPE_STRING, 0, NULL}, - {"dec_write_device", NULL, 0, .strptr = &dec_write_device, .defstrval = DEVICE_NAME_DEFAULT_DEC_WRITE, TYPE_STRING, 0, NULL}}; - config_get(config_get_if(), LoaderParams, sizeofArray(LoaderParams), "nrLDPC_coding_xdma"); - AssertFatal(num_threads_prepare_max != 0, "nrLDPC_coding_xdma.num_threads_prepare was not provided"); - - return 0; -} - -int32_t nrLDPC_coding_shutdown(void) -{ - return 0; -} - -int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *slot_params, int frame_rx, int slot_rx) -{ - int nbDecode = 0; - for (int ULSCH_id = 0; ULSCH_id < slot_params->nb_TBs; ULSCH_id++) - nbDecode += decoder_xdma(&slot_params->TBs[ULSCH_id], frame_rx, slot_rx, slot_params->threadPool); - return nbDecode; -} - -/* -int32_t nrLDPC_coding_encoder(void) -{ - return 0; -} -*/ - -int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params, int frame_rx, int slot_rx, tpool_t *ldpc_threadPool) -{ - const uint32_t K = TB_params->K; - const int Kc = TB_params->BG == 2 ? 52 : 68; - int r_offset = 0, offset = 0; - int Kprime = K - TB_params->F; - - // FPGA parameter preprocessing - static uint8_t multi_indata[27000 * 25]; // FPGA input data - static uint8_t multi_outdata[1100 * 25]; // FPGA output data - - int bg_len = TB_params->BG == 1 ? 22 : 10; - - // Calc input CB offset - int input_CBoffset = TB_params->Z * Kc * 8; - if ((input_CBoffset & 0x7F) == 0) - input_CBoffset = input_CBoffset / 8; - else - input_CBoffset = 16 * ((input_CBoffset / 128) + 1); - - DecIFConf dec_conf = {0}; - dec_conf.Zc = TB_params->Z; - dec_conf.BG = TB_params->BG; - dec_conf.max_iter = TB_params->max_ldpc_iterations; - dec_conf.numCB = TB_params->C; - // input soft bits length, Zc x 66 - length of filler bits - dec_conf.numChannelLls = (Kprime - 2 * TB_params->Z) + (Kc * TB_params->Z - K); - // filler bits length - dec_conf.numFillerBits = TB_params->F; - dec_conf.max_schedule = 0; - dec_conf.SetIdx = 12; - dec_conf.nRows = (dec_conf.BG == 1) ? 46 : 42; - - dec_conf.user_device = user_device; - dec_conf.enc_read_device = enc_read_device; - dec_conf.enc_write_device = enc_write_device; - dec_conf.dec_read_device = dec_read_device; - dec_conf.dec_write_device = dec_write_device; - - int out_CBoffset = dec_conf.Zc * bg_len; - if ((out_CBoffset & 0x7F) == 0) - out_CBoffset = out_CBoffset / 8; - else - out_CBoffset = 16 * ((out_CBoffset / 128) + 1); - -#ifdef LDPC_DATA - printf("\n------------------------\n"); - printf("BG:\t\t%d\n", dec_conf.BG); - printf("TB_params->C: %d\n", TB_params->C); - printf("TB_params->K: %d\n", TB_params->K); - printf("TB_params->Z: %d\n", TB_params->Z); - printf("TB_params->F: %d\n", TB_params->F); - printf("numChannelLls:\t %d = (%d - 2 * %d) + (%d * %d - %d)\n", - dec_conf.numChannelLls, - Kprime, - TB_params->Z, - Kc, - TB_params->Z, - K); - printf("numFillerBits:\t %d\n", TB_params->F); - printf("------------------------\n"); - // =================================== - // debug mode - // =================================== - FILE *fptr_llr, *fptr_ldpc; - fptr_llr = fopen("../../../cmake_targets/log/ulsim_ldpc_llr.txt", "w"); - fptr_ldpc = fopen("../../../cmake_targets/log/ulsim_ldpc_output.txt", "w"); - // =================================== -#endif - - int length_dec = lenWithCrc(TB_params->C, TB_params->A); - uint8_t crc_type = crcType(TB_params->C, TB_params->A); - int no_iteration_ldpc = 2; - - uint32_t num_threads_prepare = 0; - - // calculate required number of jobs - uint32_t r_while = 0; - while (r_while < TB_params->C) { - // calculate number of segments processed in the new job - uint32_t modulus = (TB_params->C - r_while) % (num_threads_prepare_max - num_threads_prepare); - uint32_t quotient = (TB_params->C - r_while) / (num_threads_prepare_max - num_threads_prepare); - uint32_t r_span_max = modulus == 0 ? quotient : quotient + 1; - - // saturate to be sure to not go above C - uint32_t r_span = TB_params->C - r_while < r_span_max ? TB_params->C - r_while : r_span_max; - - // increment - num_threads_prepare++; - r_while += r_span; - } - - args_fpga_decode_prepare_t arr[num_threads_prepare]; - task_ans_t ans[num_threads_prepare]; - memset(ans, 0, num_threads_prepare * sizeof(task_ans_t)); - thread_info_tm_t t_info = {.buf = (uint8_t *)arr, .len = 0, .cap = num_threads_prepare, .ans = ans}; - - // start the prepare jobs - uint32_t r_remaining = 0; - for (uint32_t r = 0; r < TB_params->C; r++) { - nrLDPC_segment_decoding_parameters_t *segment_params = &TB_params->segments[r]; - if (r_remaining == 0) { - // TODO: int nr_tti_rx = 0; - - args_fpga_decode_prepare_t *args = &((args_fpga_decode_prepare_t *)t_info.buf)[t_info.len]; - DevAssert(t_info.len < t_info.cap); - args->ans = &t_info.ans[t_info.len]; - t_info.len += 1; - - args->TB_params = TB_params; - args->multi_indata = multi_indata; - args->no_iteration_ldpc = no_iteration_ldpc; - args->r_first = r; - - uint32_t modulus = (TB_params->C - r) % (num_threads_prepare_max - num_threads_prepare); - uint32_t quotient = (TB_params->C - r) / (num_threads_prepare_max - num_threads_prepare); - uint32_t r_span_max = modulus == 0 ? quotient : quotient + 1; - - uint32_t r_span = TB_params->C - r < r_span_max ? TB_params->C - r : r_span_max; - args->r_span = r_span; - args->r_offset = r_offset; - args->input_CBoffset = input_CBoffset; - args->Kc = Kc; - args->Kprime = Kprime; - - r_remaining = r_span; - - task_t t = {.func = &nr_ulsch_FPGA_decoding_prepare_blocks, .args = args}; - pushTpool(ldpc_threadPool, t); - - LOG_D(PHY, "Added %d block(s) to prepare for decoding, in pipe: %d to %d\n", r_span, r, r + r_span - 1); - } - r_offset += segment_params->E; - offset += ((K >> 3) - (TB_params->F >> 3) - ((TB_params->C > 1) ? 3 : 0)); - r_remaining -= 1; - } - - // reset offset in order to properly fill the output array later - offset = 0; - - DevAssert(num_threads_prepare == t_info.len); - - // wait for the prepare jobs to complete - join_task_ans(t_info.ans); - - for (uint32_t job = 0; job < num_threads_prepare; job++) { - args_fpga_decode_prepare_t *args = &arr[job]; - if (args->no_iteration_ldpc >= TB_params->max_ldpc_iterations) - no_iteration_ldpc = TB_params->max_ldpc_iterations; - } - - // launch decode with FPGA - LOG_I(PHY, "Run the LDPC ------[FPGA version]------\n"); - //================================================================== - // Xilinx FPGA LDPC decoding function -> nrLDPC_decoder_FPGA_PYM() - //================================================================== - start_meas(&TB_params->segments[0].ts_ldpc_decode); - nrLDPC_decoder_FPGA_PYM(&multi_indata[0], &multi_outdata[0], dec_conf); - // printf("Xilinx FPGA -> CB = %d\n", harq_process->C); - stop_meas(&TB_params->segments[0].ts_ldpc_decode); - - *TB_params->processedSegments = 0; - for (uint32_t r = 0; r < TB_params->C; r++) { - // ------------------------------------------------------------ - // --------------------- copy FPGA output --------------------- - // ------------------------------------------------------------ - nrLDPC_segment_decoding_parameters_t *segment_params = &TB_params->segments[r]; - if (check_crc(multi_outdata, length_dec, crc_type)) { -#ifdef DEBUG_CRC - LOG_I(PHY, "Segment %d CRC OK\n", r); -#endif - no_iteration_ldpc = 2; - } else { -#ifdef DEBUG_CRC - LOG_I(PHY, "segment %d CRC NOK\n", r); -#endif - no_iteration_ldpc = TB_params->max_ldpc_iterations; - } - for (int i = 0; i < out_CBoffset; i++) { - segment_params->c[i] = multi_outdata[i + r * out_CBoffset]; - } - segment_params->decodeSuccess = (no_iteration_ldpc < TB_params->max_ldpc_iterations); - if (segment_params->decodeSuccess) { - *TB_params->processedSegments = *TB_params->processedSegments + 1; - } - } - - return 0; -} - -/*! - * \fn nr_ulsch_FPGA_decoding_prepare_blocks(void *args) - * \brief prepare blocks for LDPC decoding on FPGA - * - * \param args pointer to the arguments of the function in a structure of type args_fpga_decode_prepare_t - */ -void nr_ulsch_FPGA_decoding_prepare_blocks(void *args) -{ - // extract the arguments - args_fpga_decode_prepare_t *arguments = (args_fpga_decode_prepare_t *)args; - - nrLDPC_TB_decoding_parameters_t *TB_params = arguments->TB_params; - - uint8_t Qm = TB_params->Qm; - - uint8_t BG = TB_params->BG; - uint8_t rv_index = TB_params->rv_index; - uint8_t max_ldpc_iterations = TB_params->max_ldpc_iterations; - - uint32_t tbslbrm = TB_params->tbslbrm; - uint32_t K = TB_params->K; - uint32_t Z = TB_params->Z; - uint32_t F = TB_params->F; - - uint32_t C = TB_params->C; - - nrLDPC_segment_decoding_parameters_t *segment_params = &TB_params->segments[0]; - - short *ulsch_llr = segment_params->llr; - - uint8_t *multi_indata = arguments->multi_indata; - int no_iteration_ldpc = arguments->no_iteration_ldpc; - uint32_t r_first = arguments->r_first; - uint32_t r_span = arguments->r_span; - int r_offset = arguments->r_offset; - int input_CBoffset = arguments->input_CBoffset; - int Kc = arguments->Kc; - int Kprime = arguments->Kprime; - - int16_t z[68 * 384 + 16] __attribute__((aligned(16))); - simde__m128i *pv = (simde__m128i *)&z; - - // the function processes r_span blocks starting from block at index r_first in ulsch_llr - for (uint32_t r = r_first; r < (r_first + r_span); r++) { - nrLDPC_segment_decoding_parameters_t *segment_params = &TB_params->segments[r]; - // ----------------------- FPGA pre process ------------------------ - simde__m128i ones = simde_mm_set1_epi8(255); // Generate a vector with all elements set to 255 - simde__m128i *temp_multi_indata = (simde__m128i *)&multi_indata[r * input_CBoffset]; - // ----------------------------------------------------------------- - - // code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) - int16_t harq_e[segment_params->E]; - // ------------------------------------------------------------------------------------------- - // deinterleaving - // ------------------------------------------------------------------------------------------- - start_meas(&segment_params->ts_deinterleave); - nr_deinterleaving_ldpc(segment_params->E, Qm, harq_e, ulsch_llr + r_offset); - stop_meas(&segment_params->ts_deinterleave); - // ------------------------------------------------------------------------------------------- - // dematching - // ------------------------------------------------------------------------------------------- - start_meas(&segment_params->ts_rate_unmatch); - if (nr_rate_matching_ldpc_rx(tbslbrm, - BG, - Z, - segment_params->d, - harq_e, - C, - rv_index, - *segment_params->d_to_be_cleared, - segment_params->E, - F, - K - F - 2 * Z) - == -1) { - stop_meas(&segment_params->ts_rate_unmatch); - LOG_E(PHY, "ulsch_decoding.c: Problem in rate_matching\n"); - no_iteration_ldpc = max_ldpc_iterations; - arguments->no_iteration_ldpc = no_iteration_ldpc; - return; - } else { - stop_meas(&segment_params->ts_rate_unmatch); - } - - *segment_params->d_to_be_cleared = false; - - memset(segment_params->c, 0, K >> 3); - - // set first 2*Z_c bits to zeros - memset(&z[0], 0, 2 * Z * sizeof(int16_t)); - // set Filler bits - memset((&z[0] + Kprime), 127, F * sizeof(int16_t)); - // Move coded bits before filler bits - memcpy((&z[0] + 2 * Z), segment_params->d, (Kprime - 2 * Z) * sizeof(int16_t)); - // skip filler bits - memcpy((&z[0] + K), segment_params->d + (K - 2 * Z), (Kc * Z - K) * sizeof(int16_t)); - - // Saturate coded bits before decoding into 8 bits values - for (int i = 0, j = 0; j < ((Kc * Z) >> 4); i += 2, j++) { - temp_multi_indata[j] = - simde_mm_xor_si128(simde_mm_packs_epi16(pv[i], pv[i + 1]), - simde_mm_cmpeq_epi32(ones, - ones)); // Perform NOT operation and write the result to temp_multi_indata[j] - } - - // the last bytes before reaching "Kc * harq_process->Z" should not be written 128 bits at a time to avoid overwritting the - // following block in multi_indata - simde__m128i tmp = - simde_mm_xor_si128(simde_mm_packs_epi16(pv[2 * ((Kc * Z) >> 4)], pv[2 * ((Kc * Z) >> 4) + 1]), - simde_mm_cmpeq_epi32(ones, - ones)); // Perform NOT operation and write the result to temp_multi_indata[j] - uint8_t *tmp_p = (uint8_t *)&tmp; - for (int i = 0, j = ((Kc * Z) & 0xfffffff0); j < Kc * Z; i++, j++) { - multi_indata[r * input_CBoffset + j] = tmp_p[i]; - } - - r_offset += segment_params->E; - } - - arguments->no_iteration_ldpc = no_iteration_ldpc; -} diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma_offload.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma_offload.c deleted file mode 100644 index 0673ad2c73..0000000000 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma_offload.c +++ /dev/null @@ -1,783 +0,0 @@ -/* - * Copyright (c) 2016-present, Xilinx, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license - * the terms of the BSD Licence are reported below: - * - * BSD License - * - * For Xilinx DMA IP software - * - * Copyright (c) 2016-present, Xilinx, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Xilinx nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _DEFAULT_SOURCE -#define _XOPEN_SOURCE 500 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "xdma_diag.h" -#include "nrLDPC_coding_xdma_offload.h" - -#include "common/utils/assertions.h" - -typedef unsigned long long U64; -void* map_base; -int fd; -int fd_enc_write, fd_enc_read; -char *dev_enc_write, *dev_enc_read; -int fd_dec_write, fd_dec_read; -char *dev_dec_write, *dev_dec_read; -char allocated_write[24 * 1024] __attribute__((aligned(4096))); -char allocated_read[24 * 1024 * 3] __attribute__((aligned(4096))); - -// dma_from_device.c - -// [Start] #include "dma_utils.c" =================================== - -/* - * man 2 write: - * On Linux, write() (and similar system calls) will transfer at most - * 0x7ffff000 (2,147,479,552) bytes, returning the number of bytes - * actually transferred. (This is true on both 32-bit and 64-bit - * systems.) - */ - -#define RW_MAX_SIZE 0x7ffff000 - -int verbose = 0; - -uint64_t getopt_integer(char* optarg) -{ - int rc; - uint64_t value; - - rc = sscanf(optarg, "0x%lx", &value); - if (rc <= 0) - rc = sscanf(optarg, "%lu", &value); - - return value; -} - -ssize_t read_to_buffer(char* fname, int fd, char* buffer, uint64_t size, uint64_t base) -{ - ssize_t rc; - uint64_t count = 0; - char* buf = buffer; - off_t offset = base; - - while (count < size) { - uint64_t bytes = size - count; - - if (bytes > RW_MAX_SIZE) - bytes = RW_MAX_SIZE; - - if (offset) { - rc = lseek(fd, offset, SEEK_SET); - if (rc != offset) { - fprintf(stderr, "%s, seek off 0x%lx != 0x%lx.\n", fname, rc, offset); - perror("seek file"); - return -EIO; - } - } - /* read data from file into memory buffer */ - rc = read(fd, buf, bytes); - - if (rc != bytes) { - fprintf(stderr, "%s, R off 0x%lx, 0x%lx != 0x%lx.\n", fname, count, rc, bytes); - perror("read file"); - return -EIO; - } - - count += bytes; - buf += bytes; - offset += bytes; - } - - if (count != size) { - fprintf(stderr, "%s, R failed 0x%lx != 0x%lx.\n", fname, count, size); - return -EIO; - } - return count; -} - -ssize_t write_from_buffer(char* fname, int fd, char* buffer, uint64_t size, uint64_t base) -{ - ssize_t rc; - uint64_t count = 0; - char* buf = buffer; - off_t offset = base; - - while (count < size) { - uint64_t bytes = size - count; - - if (bytes > RW_MAX_SIZE) - bytes = RW_MAX_SIZE; - - if (offset) { - rc = lseek(fd, offset, SEEK_SET); - if (rc != offset) { - fprintf(stderr, "%s, seek off 0x%lx != 0x%lx.\n", fname, rc, offset); - perror("seek file"); - return -EIO; - } - } - - /* write data to file from memory buffer */ - rc = write(fd, buf, bytes); - if (rc != bytes) { - fprintf(stderr, "%s, W off 0x%lx, 0x%lx != 0x%lx.\n", fname, offset, rc, bytes); - perror("write file"); - return -EIO; - } - - count += bytes; - buf += bytes; - offset += bytes; - } - - if (count != size) { - fprintf(stderr, "%s, R failed 0x%lx != 0x%lx.\n", fname, count, size); - return -EIO; - } - return count; -} - -// [End] #include "dma_utils.c" =================================== - -int test_dma_enc_read(char* EncOut, EncIPConf Confparam) -{ - ssize_t rc; - - void* virt_addr; - - uint64_t size; - uint32_t writeval; - - uint32_t Z_val; - - uint16_t max_schedule, mb, id, bg, z_j, kb, z_a; - uint16_t z_set; - uint32_t ctrl_data; - uint32_t CB_num = CB_PROCESS_NUMBER; - - // this values should be given by Shane - max_schedule = 0; - mb = Confparam.mb; - id = CB_num; - bg = Confparam.BGSel - 1; - z_set = Confparam.z_set - 1; - z_j = Confparam.z_j; - - if (z_set == 0) - z_a = 2; - else if (z_set == 1) - z_a = 3; - else if (z_set == 2) - z_a = 5; - else if (z_set == 3) - z_a = 7; - else if (z_set == 4) - z_a = 9; - else if (z_set == 5) - z_a = 11; - else if (z_set == 6) - z_a = 13; - else - z_a = 15; - - if (bg == 0) - kb = 22; - else if (bg == 1) - kb = 10; - else if (bg == 2) - kb = 9; - else if (bg == 3) - kb = 8; - else - kb = 6; - mb = Confparam.kb_1 + kb; - Z_val = (unsigned int)(z_a << z_j); - ctrl_data = (max_schedule << 30) | ((mb - kb) << 24) | (id << 19) | (bg << 6) | (z_set << 3) | z_j; - uint32_t OutDataNUM = Z_val * mb; - uint32_t Out_dwNumItems_p128; - uint32_t Out_dwNumItems; - - if ((OutDataNUM & 0x7F) == 0) - Out_dwNumItems_p128 = OutDataNUM >> 5; - else - Out_dwNumItems_p128 = ((OutDataNUM >> 7) + 1) << 2; - Out_dwNumItems = ((Out_dwNumItems_p128 << 2) * CB_num); - size = Out_dwNumItems; - writeval = ctrl_data; - - /* calculate the virtual address to be accessed */ - virt_addr = map_base + OFFSET_ENC_OUT; - - /* swap 32-bit endianess if host is not little-endian */ - writeval = htoll(writeval); - *((uint32_t*)virt_addr) = writeval; - if (fd_enc_read < 0) { - fprintf(stderr, "unable to open device %s, %d.\n", dev_enc_read, fd_enc_read); - perror("open device"); - return -EINVAL; - } - - /* lseek & read data from AXI MM into buffer using SGDMA */ - rc = read_to_buffer(dev_enc_read, fd_enc_read, EncOut, size, 0); - if (rc < 0) - goto out; - - rc = 0; - -out: - - return rc; -} - -int test_dma_enc_write(char* data, EncIPConf Confparam) -{ - ssize_t rc; - void* virt_addr; - - uint64_t size; - uint32_t writeval; - - uint32_t Z_val; - uint16_t max_schedule, mb, id, bg, z_j, kb, z_a; - uint16_t z_set; - uint32_t ctrl_data; - uint32_t CB_num = CB_PROCESS_NUMBER; - - // this values should be given by Shane - max_schedule = 0; - - mb = Confparam.mb; - id = CB_num; - bg = Confparam.BGSel - 1; - z_set = Confparam.z_set - 1; - z_j = Confparam.z_j; - - if (z_set == 0) - z_a = 2; - else if (z_set == 1) - z_a = 3; - else if (z_set == 2) - z_a = 5; - else if (z_set == 3) - z_a = 7; - else if (z_set == 4) - z_a = 9; - else if (z_set == 5) - z_a = 11; - else if (z_set == 6) - z_a = 13; - else - z_a = 15; - - if (bg == 0) - kb = 22; - else if (bg == 1) - kb = 10; - else if (bg == 2) - kb = 9; - else if (bg == 3) - kb = 8; - else - kb = 6; - mb = Confparam.kb_1 + kb; - Z_val = (unsigned int)(z_a << z_j); - ctrl_data = (max_schedule << 30) | ((mb - kb) << 24) | (id << 19) | (bg << 6) | (z_set << 3) | z_j; - uint32_t InDataNUM = Z_val * kb; - uint32_t In_dwNumItems_p128; - uint32_t In_dwNumItems; - - if ((InDataNUM & 0x7F) == 0) - In_dwNumItems_p128 = InDataNUM >> 5; - else - In_dwNumItems_p128 = ((InDataNUM >> 7) + 1) << 2; - - In_dwNumItems = ((In_dwNumItems_p128 << 2) * CB_num); - size = In_dwNumItems; - writeval = ctrl_data; - - /* calculate the virtual address to be accessed */ - virt_addr = map_base + OFFSET_ENC_IN; - - /* swap 32-bit endianess if host is not little-endian */ - writeval = htoll(writeval); - *((uint32_t*)virt_addr) = writeval; - if (fd_enc_write < 0) { - fprintf(stderr, "unable to open device %s, %d.\n", dev_enc_write, fd_enc_write); - perror("open device"); - return -EINVAL; - } - - rc = write_from_buffer(dev_enc_write, fd_enc_write, data, size, 0); - if (rc < 0) - goto out; - rc = 0; - -out: - - return rc; -} - -// int test_dma_dec_read(unsigned int *DecOut, DecIPConf Confparam) -int test_dma_dec_read(char* DecOut, DecIPConf Confparam) -{ - ssize_t rc; - - void* virt_addr; - - uint64_t size; - uint32_t writeval; - - uint32_t Z_val; - - uint16_t max_schedule, mb, id, bg, z_j, kb, z_a, max_iter, sc_idx; - uint16_t z_set; - uint32_t ctrl_data; - uint32_t CB_num = Confparam.CB_num; - - // this values should be given by Shane - max_schedule = 0; - mb = Confparam.mb; - id = CB_num; - bg = Confparam.BGSel - 1; - z_set = Confparam.z_set - 1; - z_j = Confparam.z_j; - max_iter = 8; - sc_idx = 12; - - if (z_set == 0) - z_a = 2; - else if (z_set == 1) - z_a = 3; - else if (z_set == 2) - z_a = 5; - else if (z_set == 3) - z_a = 7; - else if (z_set == 4) - z_a = 9; - else if (z_set == 5) - z_a = 11; - else if (z_set == 6) - z_a = 13; - else - z_a = 15; - - if (bg == 0) - kb = 22; - else if (bg == 1) - kb = 10; - else if (bg == 2) - kb = 9; - else if (bg == 3) - kb = 8; - else - kb = 6; - - Z_val = (unsigned int)(z_a << z_j); - ctrl_data = - (max_schedule << 30) | ((mb - kb) << 24) | (id << 19) | (max_iter << 13) | (sc_idx << 9) | (bg << 6) | (z_set) << 3 | z_j; - - uint32_t OutDataNUM = Z_val * kb; - uint32_t Out_dwNumItems_p128; - uint32_t Out_dwNumItems; - - if (CB_num & 0x01) // odd cb number - { - if ((OutDataNUM & 0xFF) == 0) - Out_dwNumItems_p128 = OutDataNUM; - else - Out_dwNumItems_p128 = 256 * ((OutDataNUM / 256) + 1); - - Out_dwNumItems = (Out_dwNumItems_p128 * CB_num) >> 3; - } else { - if ((OutDataNUM & 0x7F) == 0) - Out_dwNumItems_p128 = OutDataNUM; - else - Out_dwNumItems_p128 = 128 * ((OutDataNUM / 128) + 1); - - Out_dwNumItems = (Out_dwNumItems_p128 * CB_num) >> 3; - if ((Out_dwNumItems & 0x1f) != 0) - Out_dwNumItems = ((Out_dwNumItems + 31) >> 5) << 5; - - } - size = Out_dwNumItems; - writeval = ctrl_data; - - /* calculate the virtual address to be accessed */ - virt_addr = map_base + OFFSET_DEC_OUT; - - /* swap 32-bit endianess if host is not little-endian */ - writeval = htoll(writeval); - *((uint32_t*)virt_addr) = writeval; - - if (fd_dec_read < 0) { - fprintf(stderr, "unable to open device %s, %d.\n", dev_dec_read, fd_dec_read); - perror("open device"); - return -EINVAL; - } - - /* lseek & read data from AXI MM into buffer using SGDMA */ - rc = read_to_buffer(dev_dec_read, fd_dec_read, DecOut, size, 0); - if (rc < 0) - goto out; - - rc = 0; - -out: - - return rc; -} - -// int test_dma_dec_write(unsigned int *data, DecIPConf Confparam) -int test_dma_dec_write(char* data, DecIPConf Confparam) -{ - ssize_t rc; - - void* virt_addr; - - uint64_t size; - uint32_t writeval; - - uint32_t Z_val; - uint16_t max_schedule, mb, id, bg, z_j, kb, z_a, max_iter, sc_idx; - uint16_t z_set; - uint32_t ctrl_data; - uint32_t CB_num = Confparam.CB_num; // CB_PROCESS_NUMBER_Dec;// - - // this values should be given by Shane - max_schedule = 0; - mb = Confparam.mb; - id = CB_num; - bg = Confparam.BGSel - 1; - z_set = Confparam.z_set - 1; - z_j = Confparam.z_j; - - max_iter = 8; - sc_idx = 12; - - if (z_set == 0) - z_a = 2; - else if (z_set == 1) - z_a = 3; - else if (z_set == 2) - z_a = 5; - else if (z_set == 3) - z_a = 7; - else if (z_set == 4) - z_a = 9; - else if (z_set == 5) - z_a = 11; - else if (z_set == 6) - z_a = 13; - else - z_a = 15; - - if (bg == 0) - kb = 22; - else if (bg == 1) - kb = 10; - else if (bg == 2) - kb = 9; - else if (bg == 3) - kb = 8; - else - kb = 6; - - Z_val = (unsigned int)(z_a << z_j); - ctrl_data = - (max_schedule << 30) | ((mb - kb) << 24) | (id << 19) | (max_iter << 13) | (sc_idx << 9) | (bg << 6) | (z_set) << 3 | z_j; - - uint32_t InDataNUM = Z_val * mb; - uint32_t In_dwNumItems_p128; - uint32_t In_dwNumItems; - - InDataNUM = Z_val * mb * 8; - if ((InDataNUM & 0x7F) == 0) - In_dwNumItems_p128 = InDataNUM; - else - In_dwNumItems_p128 = 128 * ((InDataNUM / 128) + 1); - - In_dwNumItems = (In_dwNumItems_p128 * CB_num) >> 3; - if ((In_dwNumItems & 0x1f) != 0) - In_dwNumItems = ((In_dwNumItems + 31) >> 5) << 5; - - size = In_dwNumItems; - writeval = ctrl_data; - - /* calculate the virtual address to be accessed */ - virt_addr = map_base + OFFSET_DEC_IN; - - /* swap 32-bit endianess if host is not little-endian */ - writeval = htoll(writeval); - *((uint32_t*)virt_addr) = writeval; - - if (fd_dec_write < 0) { - fprintf(stderr, "unable to open device %s, %d.\n", dev_dec_write, fd_dec_write); - perror("open device"); - return -EINVAL; - } - - rc = write_from_buffer(dev_dec_write, fd_dec_write, data, size, 0); - if (rc < 0) - goto out; - - rc = 0; - -out: - - return rc; -} - -void test_dma_init(devices_t devices) -{ - /* access width */ - char* device2 = devices.user_device; - - AssertFatal((fd = open(device2, O_RDWR | O_SYNC)) != -1, "CHARACTER DEVICE %s OPEN FAILURE\n", device2); - fflush(stdout); - - /* map one page */ - map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - AssertFatal(map_base != (void*)-1, "MEMORY MAP AT ADDRESS %p FAILED\n", map_base); - - void* virt_addr; - virt_addr = map_base + OFFSET_RESET; - *((uint32_t*)virt_addr) = 1; - - dev_enc_write = devices.enc_write_device; - dev_enc_read = devices.enc_read_device; - dev_dec_write = devices.dec_write_device; - dev_dec_read = devices.dec_read_device; - - fd_enc_write = open(dev_enc_write, O_RDWR); - fd_enc_read = open(dev_enc_read, O_RDWR); - fd_dec_write = open(dev_dec_write, O_RDWR); - fd_dec_read = open(dev_dec_read, O_RDWR); - - fflush(stdout); - -} - -void dma_reset(devices_t devices) -{ - char* device2 = devices.user_device; - - void* virt_addr; - virt_addr = map_base + PCIE_OFF; - *((uint32_t*)virt_addr) = 1; - - AssertFatal(munmap(map_base, MAP_SIZE) != -1, "munmap failure"); - close(fd_enc_write); - close(fd_enc_read); - close(fd_dec_write); - close(fd_dec_read); - close(fd); - - AssertFatal((fd = open(device2, O_RDWR | O_SYNC)) != -1, "CHARACTER DEVICE %s OPEN FAILURE\n", device2); - fflush(stdout); - - /* map one page */ - map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - AssertFatal(map_base != (void*)-1, "MEMORY MAP AT ADDRESS %p FAILED\n", map_base); - - virt_addr = map_base + PCIE_OFF; - *((uint32_t*)virt_addr) = 1; - - virt_addr = map_base + OFFSET_RESET; - *((uint32_t*)virt_addr) = 1; - - dev_enc_write = devices.enc_write_device; - dev_enc_read = devices.enc_read_device; - dev_dec_write = devices.dec_write_device; - dev_dec_read = devices.dec_read_device; - - fd_enc_write = open(dev_enc_write, O_RDWR); - fd_enc_read = open(dev_enc_read, O_RDWR); - fd_dec_write = open(dev_dec_write, O_RDWR); - fd_dec_read = open(dev_dec_read, O_RDWR); - - fflush(stdout); -} - -void test_dma_shutdown() -{ - - void* virt_addr; - virt_addr = map_base + PCIE_OFF; - *((uint32_t*)virt_addr) = 1; - - AssertFatal(munmap(map_base, MAP_SIZE) != -1, "munmap failure"); - close(fd_enc_write); - close(fd_enc_read); - close(fd_dec_write); - close(fd_dec_read); - close(fd); - -} - -// reg_rx.c -int nrLDPC_decoder_FPGA_PYM(uint8_t* buf_in, uint8_t* buf_out, DecIFConf dec_conf) -{ - struct timespec ts_start0; // evaluate time from input setting to output setting including xdma - - int Zc; - int nRows; - int baseGraph; - int CB_num; - - DecIPConf Confparam; - int z_a, z_tmp; - int z_j = 0; - - - int input_CBoffset, output_CBoffset; - - uint8_t i_LS; - - devices_t devices = { - .user_device = dec_conf.user_device, - .enc_write_device = dec_conf.enc_write_device, - .enc_read_device = dec_conf.enc_read_device, - .dec_write_device = dec_conf.dec_write_device, - .dec_read_device = dec_conf.dec_read_device - }; - - static int init_flag = 0; - if (init_flag == 0) { - /*Init*/ - test_dma_init(devices); - init_flag = 1; - } else { - dma_reset(devices); - } - - clock_gettime(CLOCK_MONOTONIC, &ts_start0); // time start0 - // LDPC input parameter - Zc = dec_conf.Zc; // shifting size - nRows = dec_conf.nRows; // number of Rows - baseGraph = dec_conf.BG; // base graph - CB_num = dec_conf.numCB; // 31 number of code block - - // calc xdma LDPC parameter - // calc i_LS - if ((Zc % 15) == 0) - i_LS = 7; - else if ((Zc % 13) == 0) - i_LS = 6; - else if ((Zc % 11) == 0) - i_LS = 5; - else if ((Zc % 9) == 0) - i_LS = 4; - else if ((Zc % 7) == 0) - i_LS = 3; - else if ((Zc % 5) == 0) - i_LS = 2; - else if ((Zc % 3) == 0) - i_LS = 1; - else - i_LS = 0; - - // calc z_a - if (i_LS == 0) - z_a = 2; - else - z_a = i_LS * 2 + 1; - - // calc z_j - z_tmp = Zc / z_a; - while (z_tmp % 2 == 0) { - z_j = z_j + 1; - z_tmp = z_tmp / 2; - } - - // calc CB_num and mb - Confparam.CB_num = CB_num; - if (baseGraph == 1) - Confparam.mb = 22 + nRows; - else - Confparam.mb = 10 + nRows; - - // set BGSel, z_set, z_j - Confparam.BGSel = baseGraph; - Confparam.z_set = i_LS + 1; - Confparam.z_j = z_j; - - // Calc input CB offset - input_CBoffset = Zc * Confparam.mb * 8; - if ((input_CBoffset & 0x7F) == 0) - input_CBoffset = input_CBoffset / 8; - else - input_CBoffset = 16 * ((input_CBoffset / 128) + 1); - - // Calc output CB offset - output_CBoffset = Zc * (Confparam.mb - nRows); - if ((output_CBoffset & 0x7F) == 0) - output_CBoffset = output_CBoffset / 8; - else - output_CBoffset = 16 * ((output_CBoffset / 128) + 1); - - // LDPC accelerator start - // write into accelerator - if (test_dma_dec_write((char *)buf_in, Confparam) != 0) { - exit(1); - printf("write exit!!\n"); - } - - // read output of accelerator - if (test_dma_dec_read((char *)buf_out, Confparam) != 0) { - exit(1); - printf("read exit!!\n"); - } - - return 0; -} - diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma_offload.h b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma_offload.h deleted file mode 100644 index 5b106e4aae..0000000000 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma_offload.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SPDX-License-Identifier: LicenseRef-CSSL-1.0 - */ - -/*! - * \briefFPGA accelerator integrated into OAI (for one and multi code block) - */ - -#ifndef __NRLDPC_CODING_XDMA_OFFLOAD__H_ - -#define __NRLDPC_CODING_XDMA_OFFLOAD__H_ - -#include - -#define DEVICE_NAME_DEFAULT_USER "/dev/xdma0_user" -#define DEVICE_NAME_DEFAULT_ENC_READ "/dev/xdma0_c2h_1" -#define DEVICE_NAME_DEFAULT_ENC_WRITE "/dev/xdma0_h2c_1" -#define DEVICE_NAME_DEFAULT_DEC_READ "/dev/xdma0_c2h_0" -#define DEVICE_NAME_DEFAULT_DEC_WRITE "/dev/xdma0_h2c_0" - -/** - \brief LDPC input parameter - \param Zc shifting size - \param Rows - \param baseGraph base graph - \param CB_num number of code block - \param numChannelLlrs input soft bits length, Zc x 66 - length of filler bits - \param numFillerBits filler bits length -*/ -typedef struct { - char *user_device, *enc_write_device, *enc_read_device, *dec_write_device, *dec_read_device; - unsigned char max_schedule; - unsigned char SetIdx; - int Zc; - unsigned char numCB; - unsigned char BG; - unsigned char max_iter; - int nRows; - int numChannelLls; - int numFillerBits; -} DecIFConf; - -int nrLDPC_decoder_FPGA_PYM(uint8_t *buf_in, uint8_t *buf_out, DecIFConf dec_conf); - -#endif // __NRLDPC_CODING_XDMA_OFFLOAD__H_ - diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/xdma_diag.h b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/xdma_diag.h deleted file mode 100644 index 8ef498c770..0000000000 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/xdma_diag.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2016-present, Xilinx, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license - * the terms of the BSD Licence are reported below: - * - * BSD License - * - * For Xilinx DMA IP software - * - * Copyright (c) 2016-present, Xilinx, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Xilinx nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef MODULES_TXCTRL_INC_XDMA_DIAG_H_ -#define MODULES_TXCTRL_INC_XDMA_DIAG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - unsigned char max_schedule; // max_schedule = 0; - unsigned char mb; // mb = 32; - unsigned char CB_num; // id = CB_num; - unsigned char BGSel; // bg = 1; - unsigned char z_set; // z_set = 0; - unsigned char z_j; // z_j = 6; - unsigned char max_iter; // max_iter = 8; - unsigned char SetIdx; // sc_idx = 12; -} DecIPConf; - -typedef struct { - int SetIdx; - int NumCBSegm; - int PayloadLen; - int Z; - int z_set; - int z_j; - int Kbmax; - int BGSel; - unsigned mb; - unsigned char CB_num; - unsigned char kb_1; -} EncIPConf; - -typedef struct { - char *user_device, *enc_write_device, *enc_read_device, *dec_write_device, *dec_read_device; -} devices_t; - -/* ltoh: little to host */ -/* htol: little to host */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define ltohl(x) (x) -#define ltohs(x) (x) -#define htoll(x) (x) -#define htols(x) (x) -#elif __BYTE_ORDER == __BIG_ENDIAN -#define ltohl(x) __bswap_32(x) -#define ltohs(x) __bswap_16(x) -#define htoll(x) __bswap_32(x) -#define htols(x) __bswap_16(x) -#endif - -#define MAP_SIZE (32 * 1024UL) -#define MAP_MASK (MAP_SIZE - 1) - -#define SIZE_DEFAULT (32) -#define COUNT_DEFAULT (1) - -#define OFFSET_DEC_IN 0x0000 -#define OFFSET_DEC_OUT 0x0004 -#define OFFSET_ENC_IN 0x0008 -#define OFFSET_ENC_OUT 0x000c -#define OFFSET_RESET 0x0020 -#define PCIE_OFF 0x0030 - -#define CB_PROCESS_NUMBER 24 // add by JW -#define CB_PROCESS_NUMBER_Dec 24 - -// dma_from_device.c - -int test_dma_enc_read(char *EncOut, EncIPConf Confparam); -int test_dma_enc_write(char *data, EncIPConf Confparam); -int test_dma_dec_read(char *DecOut, DecIPConf Confparam); -int test_dma_dec_write(char *data, DecIPConf Confparam); -void test_dma_init(devices_t devices); -void test_dma_shutdown(); -void dma_reset(devices_t devices); - -#ifdef __cplusplus -} -#endif -#endif