Skip to content
Jian Ding edited this page Jul 27, 2020 · 8 revisions

Welcome to the Millipede wiki!

Overview

Millipede is a high-performance system for massive-MIMO baseband processing. Millipede uses a queue-based master-worker model. A master thread is responsible for scheduling tasks and a pool of worker threads are responsible for executing tasks. The communication between the master thread worker threads are achieved through single-producer multi-consumer or multi-producer single-consumer shared memory FIFO queues (concurrentqueue).

overview

Flow Diagram for Baseband Processing

As shown in the figure below, Millipede has a socket interface to communicate with remote radio unit (RRU) and a MAC interface to communicate with upper layer. Baseband processing blocks are implemented as Doer functions.

code_flow_diagram

DoFFT does FFT of an OFDM symbol to convert data from time domain to frequency domain.

(Values of OFDM_CA_NUM, BS_ANT_NUM and fft_block_size are given in config.cpp)

  • Data dimension: one OFDM symbol with size OFDM_CA_NUM

  • Number of unit tasks: number of base station antennas BS_ANT_NUM

  • Task granularity is controlled by fft_block_size

  • Input: socket_buffer with 2-bytes integers (2 bytes for I and 2 bytes for Q)

  • Output: complex floats (4 bytes for I and 4 bytes for Q)

    • Pilot symbols: data_buffer
    • Uplink data symbols: data_buffer
    • Reciprocity calibration symbols: calib_buffer
  • Processing steps:

    • Convert 2-bytes integers to floats
    • Compute FFT
    • Only for pilot symbols, do channel estimation
    • Save results in a partial transposed data layout

DoZF does precoder calculation to get precoder matrix from CSI matrix with Zeroforcing method.

(Values of BS_ANT_NUM, UE_NUM, OFDM_DATA_NUM, and zf_block_size are given in config.cpp)

  • Data dimension: one CSI matrix with size BS_ANT_NUM x UE_NUM; one precoder matrix with size UE_NUM x BS_ANT_NUM (BS_ANT_NUM: number of base station antennas, UE_NUM: number of users)
  • Number of unit tasks: number of data subcarriers OFDM_DATA_NUM
  • Task granularity is controlled by zf_block_size (processing zf_block_size subcarriers in on function call)
  • Input: complex floats
    • csi_buffer
    • recip_buffer used for reciprocal calibration to get downlink precoder matrix
  • Output: complex floats
    • Uplink: ul_zf_buffer
    • Downlink: dl_zf_buffer
  • Processing steps:
    • Gather data from csi_buffer which has partial transposed data layout into csi_gather_buffer for CSI matrix with continuous layout
    • Compute matrix pseudo-inverse to get uplink precoder matrix
    • If there are downlink symbols in a frame, do reciprocal calibration to get downlink precoder matrix
Clone this wiki locally