# OFDM Carrier Allocator

This block turns a stream of complex, scalar modulation symbols into vectors which are the input for an IFFT in an OFDM transmitter. It also supports the possibility of placing pilot symbols onto the carriers.

The carriers can be allocated freely, if a carrier is not allocated, it is set to zero. This allows doing OFDMA-style carrier allocations.

- Input
- A tagged stream of complex scalars. The first item must have a tag containing the number of complex symbols in this frame.
- Output
- A tagged stream of complex vectors of length fft_len. This can directly be connected to an FFT block. Make sure to set this block to 'reverse' for the IFFT. If output_is_shifted is true, the FFT block must activate FFT shifting, otherwise, set shifting to false. If given, sync words are prepended to the output. Note that sync words are prepended verbatim, make sure they are shifted (or not).

Carrier indexes are always such that index 0 is the DC carrier (note: you should not allocate this carrier). The carriers below the DC carrier are either indexed with negative numbers, or with indexes larger than fft_len/2. Index -1 and index fft_len-1 both identify the carrier below the DC carrier.

There are some basic checks in place during initialization which check that the carrier allocation table is valid. However, it is possible to overwrite data symbols with pilot symbols, or provide a carrier allocation that has mismatching pilot symbol positions and -values.

Tags are propagated such that a tag on an incoming complex symbol is mapped to the corresponding OFDM symbol. There is one exception: If a tag is on the first OFDM symbol, it is assumed that this tag should stay there, so it is moved to the front even if a sync word is included (any other tags will never be attached to the sync word). This allows tags to control the transmit timing to pass through in the correct position.

## Parameters

- FFT length
- FFT length, is also the maximum width of the OFDM symbols, the output vector size and maximum value for elements in occupied_carriers and pilot_carriers.

- Occupied Carriers
- A vector of vectors of indexes. Example: if occupied_carriers = ((1, 2, 3), (1, 2, 4)), the first three input symbols will be mapped to carriers 1, 2 and 3. After that, a new OFDM symbol is started. The next three input symbols will be placed onto carriers 1, 2 and 4 of the second OFDM symbol. The allocation then starts from the beginning. Order matters! The first input symbol is always mapped onto occupied_carriers[0][0].

- Pilot Carriers
- The position of the pilot symbols. Same as occupied_carriers, but the actual symbols are taken from pilot_symbols instead of the input stream.

- Pilot Symbols
- The pilot symbols which are placed onto the pilot carriers. pilot_symbols[0][0] is placed onto the first OFDM symbol, on carrier index pilot_carriers[0][0] etc.

- Sync Words
- OFDM symbols that are prepended to the OFDM frame (usually for synchronisation purposes, e.g. OFDM symbols with every second sub-carrier being idle). Is a vector of complex vectors of length fft_len

- Length tag key
- The key of the tag identifying the length of the input packet.

- Shift Output
- Whether to 'fftshift' the output OFDM symbols. If used, the followup FFT should be instantaited such that it knows that the input is shifted. Default is true.

## Example Flowgraph

This flowgraph can be found at [1].

## Source Files

- C++ files
- ofdm_carrier_allocator_cvc_impl.cc

- Header files
- ofdm_carrier_allocator_cvc_impl.h

- Public header files
- ofdm_carrier_allocator_cvc.h

- Block definition
- digital_ofdm_carrier_allocator_cvc.block.yml