Skip to main content

comnum_spec/blocks/wireless/
mod.rs

1//! Wireless blocks: several antennas, fading channels, OFDM and MIMO detection.
2//!
3//! | Block | Does |
4//! |---|---|
5//! | `mimo_tx` | spreads the symbols over $n_{t}$ antennas: spatial multiplexing (one layer per antenna, power $1/n_{t}$ each) or Alamouti's code |
6//! | `rayleigh` | flat Rayleigh or Rician fading, $n_{r} \times n_{t}$, constant over the trial or over coherence blocks, with exponential antenna correlation |
7//! | `tdl` | a tapped delay line (EPA, EVA, ETU, ITU Pedestrian A and Vehicular A, exponential) with Doppler |
8//! | `cdl` | a clustered delay line of 3GPP TR 38.901 (CDL-A to CDL-E) between uniform linear arrays, with the Doppler of a moving receiver |
9//! | `ofdm_tx` | maps every antenna's symbols on a resource grid with pilots and modulates it |
10//! | `ofdm_rx` | demodulates, estimates the channel (perfect, LS or LMMSE) and detects every resource element |
11//! | `mimo_rx` | detects a single-carrier link over flat fading with the known channel |
12//!
13//! # Scales
14//!
15//! The OFDM modulator gives the samples the power $K/(L N)$ ($K$ active subcarriers,
16//! IFFT of size $L N$), so that a resource element of unit energy spreads over
17//! $L N / K$ samples: `ofdm_tx` sets the samples per symbol to $L N / K$ and the symbol
18//! rate to the rate of the resource elements $K \Delta f$. The noise blocks then set the
19//! SNR per resource element: `awgn` with `snr_db` gives $E_{s}/N_{0}$ on every data
20//! resource element of unit energy, and the noise of every demodulated resource
21//! element has the variance of the noise per sample. Spatial multiplexing divides the
22//! power among the antennas, so that the SNR is the total transmitted energy per
23//! resource element over the noise of one receive antenna.
24//!
25//! # Example
26//!
27//! ```yaml
28//! link:
29//!   - {type: source, constellation: 16-QAM, n_symbols: 4800}
30//!   - {type: mimo_tx, n_tx: 2}
31//!   - {type: ofdm_tx, n_fft: 256, n_subcarriers: 200, n_cp: 18, n_symbols: 14}
32//!   - {type: tdl, profile: EPA, doppler_hz: 5, n_rx: 2}
33//!   - {type: awgn, snr_db: $snr_db}
34//!   - {type: ofdm_rx, estimation: lmmse, detector: mmse}
35//! ```
36//!
37//! # References
38//!
39//! 1. S. M. Alamouti, "A simple transmit diversity technique for wireless
40//!    communications," *IEEE J. Sel. Areas Commun.*, 16(8), 1451–1458, 1998.
41//! 2. O. Edfors, M. Sandell, J.-J. van de Beek, S. K. Wilson and P. O. Börjesson, "OFDM
42//!    channel estimation by singular value decomposition," *IEEE Trans. Commun.*,
43//!    46(7), 931–939, 1998.
44//! 3. 3GPP TS 36.101, *E-UTRA; User Equipment radio transmission and reception*,
45//!    Annex B.2 (EPA, EVA, ETU).
46
47use super::Extension;
48use comnum_channel::multipath::Taps;
49use comnum_math::linalg::CMat;
50
51mod fading;
52mod mimo;
53mod ofdm;
54
55use fading::{CdlBlock, CdlSpec, Rayleigh, RayleighSpec, TdlBlock, TdlSpec};
56use mimo::{Detection, DetectorSpec, MimoRx, MimoTx, MimoTxSpec};
57use ofdm::{OfdmRx, OfdmRxSpec, OfdmTx, OfdmTxSpec};
58
59/// The channel of a trial, as a genie-aided receiver knows it.
60#[derive(Clone, Debug)]
61pub enum Csi {
62    /// Flat fading: one matrix $n_{r} \times n_{t}$ per block of `coherence` samples.
63    Flat {
64        /// The matrices, block after block.
65        h: Vec<CMat>,
66        /// Samples per block.
67        coherence: usize,
68    },
69    /// The taps of a tapped delay line.
70    Taps(Taps),
71}
72
73impl Csi {
74    /// The flat channel at sample `n`.
75    fn flat(&self, n: usize) -> Option<&CMat> {
76        match self {
77            Csi::Flat { h, coherence } => h.get(n / (*coherence).max(1)).or_else(|| h.last()),
78            Csi::Taps(_) => None,
79        }
80    }
81}
82
83pub use comnum_waveform::ofdm::link::OfdmFrame;
84
85/// The blocks of this module: their documentation and their builders.
86pub(super) fn blocks() -> Vec<Extension> {
87    vec![
88        builtin!(
89            "mimo_tx",
90            "Spread the symbols over n_tx antennas: spatial multiplexing (power 1/n_tx per antenna) or Alamouti's code.",
91            MimoTxSpec,
92            needs [Samples],
93            gives [],
94            |q, _, _| Ok(Box::new(MimoTx::new(&q)?)),
95        ),
96        builtin!(
97            "rayleigh",
98            "Flat fading y = H x on every antenna; records the channel for a genie-aided receiver.",
99            RayleighSpec,
100            needs[Samples],
101            gives[Csi],
102            |q, _, _| Ok(Box::new(Rayleigh { p: q })),
103        ),
104        builtin!(
105            "tdl",
106            "Tapped-delay-line multipath fading with Clarke/Jakes Doppler; records the taps for a genie-aided receiver.",
107            TdlSpec,
108            needs[Samples],
109            gives[Csi],
110            |q, _, _| Ok(Box::new(TdlBlock::new(&q)?)),
111        ),
112        builtin!(
113            "cdl",
114            "Clustered delay line of 3GPP TR 38.901 between uniform linear arrays (one tap per cluster, random ray phases and coupling); records the taps for a genie-aided receiver.",
115            CdlSpec,
116            needs[Samples],
117            gives[Csi],
118            |q, _, _| Ok(Box::new(CdlBlock::new(&q)?)),
119        ),
120        builtin!(
121            "ofdm_tx",
122            "Map every antenna's symbols on resource grids with pilots and OFDM-modulate them (power K/(LN) per sample).",
123            OfdmTxSpec,
124            needs[Samples],
125            gives[Ofdm],
126            |q, _, _| Ok(Box::new(OfdmTx::new(&q)?)),
127        ),
128        builtin!(
129            "ofdm_rx",
130            "Demodulate the OFDM grids, estimate the channel and detect every data resource element; output the symbols and their noise variances.",
131            OfdmRxSpec,
132            needs [Samples, Constellation, Ofdm],
133            gives [Noise, Llr],
134            |q, _, _| Ok(Box::new(OfdmRx::new(&q)?)),
135        ),
136        builtin!(
137            "mimo_rx",
138            "Detect a single-carrier link over flat fading with the known channel; output the symbols and their noise variances.",
139            DetectorSpec,
140            needs [Samples, Constellation, Csi],
141            gives [Noise, Llr],
142            |q, _, _| Ok(Box::new(MimoRx(Detection::new(&q)?))),
143        ),
144    ]
145}
146
147#[cfg(test)]
148mod tests;