-
Notifications
You must be signed in to change notification settings - Fork 34
Home
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).
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.
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
- Pilot symbols:
-
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 sizeUE_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
(processingzf_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
- Uplink:
- 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