1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//! The blocks of a declarative link and their registry.
//!
//! A link is a list of blocks applied in order to a [`Frame`]. The first block is a
//! `source`, which draws the transmitted bits and symbols; every other block transforms
//! the current samples (a channel, a device, a DSP stage, a trained receiver) and may
//! record diagnostic values (an estimated frequency offset, the iterations of a fit).
//! [`registry`] lists every block with its parameters, their defaults and their meaning;
//! the command `comnum blocks` prints it.
//!
//! A block is written as a mapping with a `type`, an optional `label` (the prefix of the
//! values it records, the type by default) and its parameters; a block without
//! parameters can be written as its name alone. Unknown parameters are errors.
//!
//! ```yaml
//! link:
//! - {type: source, constellation: 16-QAM, n_symbols: 4096, symbol_rate: 32e9}
//! - {type: pulse_shape, sps: 2, rolloff: 0.1}
//! - {type: awgn, snr_db: $snr_db}
//! - {type: matched_filter, rolloff: 0.1}
//! - decimate
//! ```
//!
//! The wireless blocks ([`wireless`]) add antennas, fading channels, OFDM and MIMO
//! detection; the coding blocks ([`coding`]) add channel codes, mapping of coded bits
//! and soft demapping.
//!
//! # The model of a trial
//!
//! [`Frame`] carries one trial along the link. A simulated source sets the
//! transmitted symbols (`symbols`, `indices`, `bits`) and the samples; a coded link
//! starts with `fec_encode`, which draws the information bits (`coding.payload`) and
//! sets the coded bits, then `map`, which sets the symbols. With several transmit
//! antennas or two polarisations the samples of stream 0 stay in `samples` and those of
//! the others go to `antennas`, and [`Layout`] says what they are. The channel blocks
//! act on every stream and record what a genie-aided receiver knows
//! ([`ChannelState`]); a transmitter block leaves its frame to its receiver block in
//! [`InFlight`]. The receiver blocks bring the signal back to one sample per transmitted
//! symbol, aligned on the symbols, as the metrics need, and declare the noise of their
//! outputs ([`ReceiverState`]); the soft demapper and the decoder then fill
//! `coding.llr` and `coding.decoded`.
//!
//! # The families of blocks
//!
//! | Module | Blocks |
//! |---|---|
//! | [`source`] | simulated symbols, measured recordings |
//! | [`channel`] | noise, phase noise, frequency offset, linear channels, IQ imbalance |
//! | [`fiber`] | single-polarisation fibre propagation and its compensation |
//! | [`optical`] | WDM, dual-polarisation propagation, PMD, back-propagation |
//! | [`dsp`] | shaping, filtering, resampling, clock and carrier recovery, equalisation, frame synchronisation |
//! | [`wireless`] | antennas, fading, OFDM, MIMO detection |
//! | [`coding`] | channel codes, probabilistic amplitude shaping, mapping, soft demapping |
//! | [`ce_ofdm`] | constant-envelope OFDM |
//! | [`cpm`] | continuous-phase modulation (CPFSK, MSK, GMSK) |
//! | [`systems`] | the DVB-S2 chain of `comnum-systems` (ADR 0010) |
//! | [`analysis`] | probes, recordings of the samples (`dump`), the declared posterior of a receiver |
//!
//! Every module declares its blocks next to their code (`blocks`: the documentation
//! and the builder of every block, an [`Extension`] as the blocks of other crates); a test checks
//! that the parameters a block accepts and those it documents are the same.
use Rng;
use ;
use ;
use Value as Json;
pub
pub use crateparse;
pub use BuildContext;
pub use merge_fiber;
use ;
pub use ;
pub use WdmFrame;
use ;
pub use ;
pub use ;
use NumberOrList;
pub use ;
pub use ;
/// A block of a link.
block_params!
/// The value of a `constellation` parameter: a name or a [`ConstellationSpec`].
pub type ConstellationParam = ;
/// Parse a constellation, normalised to unit energy: a name of
/// [`Constellation::from_name`] (`16-QAM`, `qam16`, `QPSK`, `BPSK`, `8-PSK`, `4-PAM`,
/// `OOK`) or a mapping `{kind, m}` ([`ConstellationSpec`]).
///
/// # Errors
/// [`Error::Config`] for an unknown family or a missing or invalid order.