Skip to content

Commit

Permalink
ber: add interleaver
Browse files Browse the repository at this point in the history
  • Loading branch information
daniestevez committed Sep 5, 2023
1 parent 7f96edd commit 46ab0e9
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 6 deletions.
7 changes: 7 additions & 0 deletions src/cli/ber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ pub struct Args {
/// Puncturing pattern (format "1,1,1,0")
#[structopt(long)]
puncturing: Option<String>,
/// Interleaving columns (negative for backwards read)
#[structopt(long)]
interleaving: Option<isize>,
/// Minimum Eb/N0 (dB)
#[structopt(long)]
min_ebn0: f64,
Expand Down Expand Up @@ -94,6 +97,7 @@ impl Run for Args {
decoder_implementation: self.decoder,
modulation: self.modulation,
puncturing_pattern: puncturing_pattern.as_ref().map(|v| &v[..]),
interleaving_columns: self.interleaving,
max_frame_errors: self.frame_errors,
max_iterations: self.max_iter,
ebn0s_db: &ebn0s,
Expand Down Expand Up @@ -132,6 +136,9 @@ impl Args {
if let Some(puncturing) = self.puncturing.as_ref() {
writeln!(f, " - Puncturing pattern: {puncturing}")?;
}
if let Some(interleaving) = self.interleaving.as_ref() {
writeln!(f, " - Interleaving columns: {interleaving}")?;
}
writeln!(f, " - Information bits (k): {}", test.k())?;
writeln!(f, " - Codeword size (N_cw): {}", test.n_cw())?;
writeln!(f, " - Frame size (N): {}", test.n())?;
Expand Down
28 changes: 22 additions & 6 deletions src/simulation/ber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use super::{
channel::{AwgnChannel, Channel},
factory::Ber,
interleaving::Interleaver,
modulation::{Demodulator, Modulation, Modulator},
puncturing::Puncturer,
};
Expand Down Expand Up @@ -36,6 +37,7 @@ pub struct BerTest<Mod: Modulation> {
rate: f64,
encoder: Encoder,
puncturer: Option<Puncturer>,
interleaver: Option<Interleaver>,
modulator: Mod::Modulator,
ebn0s_db: Vec<f32>,
statistics: Vec<Statistics>,
Expand All @@ -52,6 +54,7 @@ struct Worker<Mod: Modulation> {
k: usize,
encoder: Encoder,
puncturer: Option<Puncturer>,
interleaver: Option<Interleaver>,
modulator: Mod::Modulator,
channel: AwgnChannel,
demodulator: Mod::Demodulator,
Expand Down Expand Up @@ -169,17 +172,19 @@ impl<Mod: Modulation> BerTest<Mod> {
///
/// The parameters required to define the test are the parity check matrix
/// `h`, an optional puncturing pattern (which uses the semantics of
/// [`Puncturer`]), the maximum number of frame errors at which to stop the
/// simulation for each Eb/N0, the maximum number of iterations of the LDPC
/// decoder, a list of Eb/N0's in dB units, and an optional [`Reporter`] to
/// send messages about the test progress.
/// [`Puncturer`]), an optional interleaving pattern, the maximum number of
/// frame errors at which to stop the simulation for each Eb/N0, the maximum
/// number of iterations of the LDPC decoder, a list of Eb/N0's in dB units,
/// and an optional [`Reporter`] to send messages about the test progress.
///
/// This function only defines the BER test. To run it it is necessary to
/// call the [`BerTest::run`] method.
#[allow(clippy::too_many_arguments)]
pub fn new(
h: SparseMatrix,
decoder_implementation: DecoderImplementation,
puncturing_pattern: Option<&[bool]>,
interleaving_columns: Option<isize>,
max_frame_errors: u64,
max_iterations: usize,
ebn0s_db: &[f32],
Expand All @@ -188,6 +193,7 @@ impl<Mod: Modulation> BerTest<Mod> {
let k = h.num_cols() - h.num_rows();
let n_cw = h.num_cols();
let puncturer = puncturing_pattern.map(Puncturer::new);
let interleaver = interleaving_columns.map(|n| Interleaver::new(n.unsigned_abs(), n < 0));
let puncturer_rate = if let Some(p) = puncturer.as_ref() {
p.rate()
} else {
Expand All @@ -205,6 +211,7 @@ impl<Mod: Modulation> BerTest<Mod> {
encoder: Encoder::from_h(&h)?,
h,
puncturer,
interleaver,
modulator: Mod::Modulator::default(),
ebn0s_db: ebn0s_db.to_owned(),
statistics: Vec::with_capacity(ebn0s_db.len()),
Expand Down Expand Up @@ -300,6 +307,7 @@ impl<Mod: Modulation> BerTest<Mod> {
k: self.k,
encoder: self.encoder.clone(),
puncturer: self.puncturer.clone(),
interleaver: self.interleaver.clone(),
modulator: self.modulator.clone(),
channel: AwgnChannel::new(noise_sigma),
demodulator: Mod::Demodulator::from_noise_sigma(noise_sigma),
Expand Down Expand Up @@ -362,13 +370,21 @@ impl<Mod: Modulation> Worker<Mod> {
Some(p) => p.puncture(&codeword)?,
None => codeword,
};
let transmitted = match self.interleaver.as_ref() {
Some(i) => i.interleave(&transmitted),
None => transmitted,
};
let mut symbols = self.modulator.modulate(&transmitted);
self.channel.add_noise(rng, &mut symbols);
let llrs_demod = self.demodulator.demodulate(&symbols);
let llrs_decoder = match self.puncturer.as_ref() {
Some(p) => p.depuncture(&llrs_demod)?,
let llrs_decoder = match self.interleaver.as_ref() {
Some(i) => i.deinterleave(&llrs_demod),
None => llrs_demod,
};
let llrs_decoder = match self.puncturer.as_ref() {
Some(p) => p.depuncture(&llrs_decoder)?,
None => llrs_decoder,
};

let (decoded, iterations, success) =
match self.decoder.decode(&llrs_decoder, self.max_iterations) {
Expand Down
6 changes: 6 additions & 0 deletions src/simulation/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub struct BerTestBuilder<'a> {
pub modulation: Modulation,
/// Codeword puncturing pattern.
pub puncturing_pattern: Option<&'a [bool]>,
/// Codeword interleaving.
///
/// A negative value indicates that the columns should be read backwards.
pub interleaving_columns: Option<isize>,
/// Maximum number of frame errors per Eb/N0.
pub max_frame_errors: u64,
/// Maximum number of iterations per codeword.
Expand Down Expand Up @@ -107,6 +111,7 @@ impl<'a> BerTestBuilder<'a> {
self.h,
self.decoder_implementation,
self.puncturing_pattern,
self.interleaving_columns,
self.max_frame_errors,
self.max_iterations,
self.ebn0s_db,
Expand All @@ -116,6 +121,7 @@ impl<'a> BerTestBuilder<'a> {
self.h,
self.decoder_implementation,
self.puncturing_pattern,
self.interleaving_columns,
self.max_frame_errors,
self.max_iterations,
self.ebn0s_db,
Expand Down

0 comments on commit 46ab0e9

Please sign in to comment.