Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add signal builders interface #29

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# released under BSD 3-Clause License
# author: Kevin Laeufer <[email protected]>


[workspace]
resolver = "2"
members = ["wellen", "pywellen"]
Expand All @@ -10,35 +11,40 @@ default-members = ["wellen"]
[workspace.package]
version = "0.12.1"
edition = "2021"
# we require the `div_ceil` method on integers
rust-version = "1.73.0"
authors = ["Kevin Laeufer <[email protected]>"]
description = "Fast VCD and FST library for waveform viewers written in Rust."
repository = "https://github.com/ekiwi/wellen"
license = "BSD-3-Clause"
keywords = ["vcd", "fst", "waveform", "wavedump"]


[workspace.dependencies]
bytesize = "1.3.0"
fst-reader = "0.8.7"
leb128 = "0.2.5"

lz4_flex = "0.11.3"
memmap2 = "0.9.5"
rayon = "1.10.0"
num_enum = "0.7.3"
thiserror = "1.0"
serde = { version = "1.0", features = ["derive"] }


# dev dependencies
itertools = "0.13.0"
vcd = "0.7.0"
clap = { version = "4.4.6", features = ["derive"] }
criterion = "0.5"
indicatif = "0.17.8"
proptest = "1.4.0"
wellen = { path = "wellen" }

[workspace.dependencies.wellen]
path = "wellen"
version = "0.12.1"

[workspace.dependencies.pywellen]
path = "pywellen"
version = "0.12.1"

[profile.release]
debug = true
2 changes: 1 addition & 1 deletion pywellen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ authors = ["James Connolly <[email protected]>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "pywellen"
crate-type = ["cdylib"]
crate-type = ["cdylib", "rlib"]

[dependencies]
bytemuck = "1.18.0"
Expand Down
21 changes: 21 additions & 0 deletions pywellen/pywellen/pywellen.pyi
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
from typing import Optional, Tuple, Union
from pywellen.signal_builder import SignalBuilder

class Hierarchy:
def all_vars(self) -> VarIter: ...
def top_scopes(self) -> ScopeIter: ...

class Scope:
"""
One variable from a VCD/FST/GHW waveform
"""

def name(self, hier: Hierarchy) -> str: ...
def full_name(self, hier: Hierarchy) -> str: ...
def vars(self, hier: Hierarchy) -> VarIter: ...
Expand All @@ -15,6 +20,10 @@ class ScopeIter:
def __next__(self) -> Scope: ...

class Var:
"""
One variable from a VCD/FST/GHW waveform
"""

def name(self, hier: Hierarchy) -> str: ...
def full_name(self, hier: Hierarchy) -> str: ...
def bitwidth(self) -> Optional[int]: ...
Expand All @@ -27,6 +36,10 @@ class TimeTable:
def __getitem__(self, idx: int) -> int: ...

class Waveform:
"""
One VCD/FST/GHW waveform
"""

hierarchy: Hierarchy
time_table: TimeTable

Expand All @@ -40,10 +53,18 @@ class Waveform:
def get_signal_from_path(self, abs_hierarchy_path: str) -> Signal: ...

class Signal:
"""
Single signal in a VCD/GHW/FST

"""

def value_at_time(self, time: int) -> Union[int, str]: ...
def value_at_idx(self, idx: int) -> Union[int, str]: ...
def all_changes(self) -> SignalChangeIter: ...
def width(self) -> int: ...

class SignalChangeIter:
def __iter__(self) -> SignalChangeIter: ...
def __next__(self) -> Tuple[int, str]: ...

def create_derived_signal(builds: SignalBuilder) -> Signal: ...
72 changes: 72 additions & 0 deletions pywellen/pywellen/signal_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import abc
from typing import Dict, List, Optional, Union
from pywellen import Signal, Waveform, create_derived_signal


class SignalBuilder(abc.ABC):
def get_all_signals(self) -> List[Signal]:
raise NotImplementedError()

def get_value_at_index(self, time_table_idx: int) -> Optional[Union[int, str]]:
"""
Returns the value at the index -- wellen interprets this as an unsigned
width of size `self.width`
"""
raise NotImplementedError()

def width(self):
"""
Width of the generated signal in bits

It MUST be static -- width is not allowed to change function of
timetable index
"""

def to_signal(self) -> Signal:
return create_derived_signal(self)


class PassThrough(SignalBuilder):
signal: Signal

def __init__(self, signal: Signal, lsb: int, msb: int):

self.signal = signal

def get_all_signals(self) -> List[Signal]:
return [self.signal]

def get_value_at_index(self, time_table_idx: int) -> Optional[Union[int, str]]:
return self.signal.value_at_idx(time_table_idx)

def width(self):
return self.signal.width


class SlicedSignal(SignalBuilder):
signal: Signal
lsb: int
msb: int

def __init__(self, signal: Signal, lsb: int, msb: int):

self.signal = signal
self.lsb = lsb
self.msb = msb

def get_all_signals(self) -> List[Signal]:
return [self.signal]

def get_value_at_index(self, time_table_idx: int) -> Optional[Union[int, str]]:
current_value = self.signal.value_at_idx(time_table_idx)
if isinstance(current_value, int):
mask = (1 << (self.msb - self.lsb)) - 1
return (current_value >> self.lsb) & mask
else:
return None

def width(self):
return self.msb - self.lsb


def get_signals(wave: Waveform) -> Dict[str, SignalBuilder]: ...
10 changes: 10 additions & 0 deletions pywellen/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ pub trait Mappable: Sized {
}
}

/// Trait to convert a data type into a `wellen::SignalValue`
///
pub trait ToValue: Sized {
fn as_signal_value(&self) -> SignalValue;
}

macro_rules! impl_mappable_basic {
($t:ty) => {
impl Mappable for $t {
Expand Down Expand Up @@ -52,6 +58,10 @@ impl Mappable for BigUint {
}
}

pub fn bytes_as_signal_value(bytes: &Vec<u8>, bit_width: u32) -> SignalValue {
SignalValue::Binary(bytes.as_slice(), bit_width)
}

#[cfg(test)]
mod tests {
use super::Mappable;
Expand Down
Loading
Loading