Skip to content

Commit

Permalink
wip: compress signal
Browse files Browse the repository at this point in the history
  • Loading branch information
ekiwi committed Jan 21, 2025
1 parent a23633e commit e14ca40
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 2 deletions.
69 changes: 69 additions & 0 deletions wellen/src/compressed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright 2025 Cornell University
// released under BSD 3-Clause License
// author: Kevin Laeufer <[email protected]>

//! Compression for individual signals.
use crate::{Signal, SignalRef, SignalValue, TimeTableIdx};

/// A compressed version of a Signal. Uses a compression scheme very similar to what [crate::wavemem] uses.
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct CompressedSignal {
idx: SignalRef,
/// variable length encoded signal data
data: Vec<u8>,
/// additional compression performed on the data
compression: Compression,
}

#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Compression {
None,
Lz4(usize),
}

impl CompressedSignal {
fn new(idx: SignalRef) -> Self {
Self {
idx,
data: vec![],
compression: Compression::None,
}
}

fn add_value_change(&mut self, time: TimeTableIdx, change: SignalValue) {
debug_assert_eq!(
self.compression,
Compression::None,
"signal is already compressed!"
);
todo!()
}

fn compress_lz4(&mut self) {
assert_eq!(
self.compression,
Compression::None,
"signal is already compressed"
);
todo!()
}
}

impl From<&Signal> for CompressedSignal {
fn from(value: &Signal) -> Self {
let mut out = CompressedSignal::new(value.idx());
for (time, change) in value.iter_changes() {
out.add_value_change(time, change);
}
out.compress_lz4();
out
}
}

impl From<&CompressedSignal> for Signal {
fn from(value: &CompressedSignal) -> Self {
todo!()
}
}
1 change: 1 addition & 0 deletions wellen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// released under BSD 3-Clause License
// author: Kevin Laeufer <[email protected]>

mod compressed;
mod fst;
mod ghw;
mod hierarchy;
Expand Down
29 changes: 28 additions & 1 deletion wellen/src/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,19 @@ pub enum FixedWidthEncoding {
Real,
}

impl FixedWidthEncoding {
pub fn signal_encoding(&self) -> SignalEncoding {
match self {
FixedWidthEncoding::BitVector { bits, .. } => {
SignalEncoding::BitVector(NonZeroU32::new(*bits).unwrap())
}
FixedWidthEncoding::Real => SignalEncoding::Real,
}
}
}

#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub struct Signal {
#[allow(unused)]
idx: SignalRef,
time_indices: Vec<TimeTableIdx>,
data: SignalChangeData,
Expand Down Expand Up @@ -255,6 +265,14 @@ impl Signal {
pub fn iter_changes(&self) -> SignalChangeIterator {
SignalChangeIterator::new(self)
}

pub(crate) fn idx(&self) -> SignalRef {
self.idx
}

pub(crate) fn signal_encoding(&self) -> SignalEncoding {
self.data.signal_encoding()
}
}

pub struct SignalChangeIterator<'a> {
Expand Down Expand Up @@ -546,6 +564,15 @@ enum SignalChangeData {
VariableLength(Vec<String>),
}

impl SignalChangeData {
fn signal_encoding(&self) -> SignalEncoding {
match self {
SignalChangeData::FixedLength { encoding, .. } => encoding.signal_encoding(),
SignalChangeData::VariableLength(_) => SignalEncoding::String,
}
}
}

impl Debug for SignalChangeData {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Expand Down
18 changes: 17 additions & 1 deletion wellen/src/wavemem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ use crate::hierarchy::{Hierarchy, SignalRef};
use crate::signals::{
FixedWidthEncoding, Real, Signal, SignalSource, SignalSourceImplementation, Time, TimeTableIdx,
};
use crate::{SignalEncoding, TimeTable};
use crate::{SignalEncoding, SignalValue, TimeTable};
use num_enum::TryFromPrimitive;
use rayon::prelude::*;
use std::any::Any;
use std::borrow::Cow;
use std::cmp::Ordering;
use std::io::Read;
Expand Down Expand Up @@ -878,6 +879,21 @@ impl SignalEncoder {
}
}

/// Compress a Signal by replaying all changes on our SignalEncoder.
pub(crate) fn compress_signal(signal: &Signal) -> Option<(Vec<u8>, SignalEncodingMetaData)> {
let mut enc = SignalEncoder::new(signal.signal_encoding(), signal.idx().index());
for (time, value) in signal.iter_changes() {
match value {
SignalValue::Binary(data, bits) => enc.add_n_bit_change(time as u16, data, States::Two),
SignalValue::FourValue(data, bits) => {}
SignalValue::NineValue(data, bits) => {}
SignalValue::String(_) => {}
SignalValue::Real(_) => {}
}
}
enc.finish()
}

#[inline]
fn expand_special_vector_cases(value: &[u8], len: usize) -> Option<Vec<u8>> {
// if the value is actually longer than expected, there is nothing we can do
Expand Down

0 comments on commit e14ca40

Please sign in to comment.