1pub mod bitvector;
36pub mod errors;
37pub mod history;
38pub mod real;
39pub mod vector;
40
41use std::cmp::Ordering;
42use std::collections::HashMap;
43
44use crate::bitvector::BitVector;
45use crate::errors::*;
46use crate::real::*;
47use crate::vector::*;
48
49#[derive(Clone, Debug, PartialEq, Eq)]
50pub enum WaveformSearchMode {
51 Before,
52 After,
53 Closest,
54 Exact,
55}
56
57pub enum WaveformSignalResult<'a> {
58 Vector(&'a WaveformSignalVector),
59 Real(&'a WaveformSignalReal),
60}
61
62#[derive(Clone, Debug, PartialEq)]
63pub enum WaveformValueResult {
64 Vector(BitVector, usize), Real(f64, usize), }
67
68impl WaveformValueResult {
69 pub fn is_unknown(&self) -> bool {
70 match self {
71 Self::Vector(bv, _) => bv.is_unknown(),
72 _ => false,
73 }
74 }
75
76 pub fn is_high_impedance(&self) -> bool {
77 match self {
78 Self::Vector(bv, _) => bv.is_high_impedance(),
79 _ => false,
80 }
81 }
82
83 pub fn get_timestamp_index(&self) -> usize {
84 match self {
85 Self::Vector(_, index) | Self::Real(_, index) => *index,
86 }
87 }
88}
89
90pub struct Waveform {
91 timestamps: Vec<u64>,
92 vector_signals: HashMap<usize, WaveformSignalVector>,
93 real_signals: HashMap<usize, WaveformSignalReal>,
94}
95
96impl Waveform {
97 pub fn new() -> Self {
98 Self {
99 timestamps: Vec::new(),
100 vector_signals: HashMap::default(),
101 real_signals: HashMap::default(),
102 }
103 }
104
105 pub fn shard(self, num_shards: usize) -> Vec<Self> {
106 let mut shards = Vec::new();
107 for _ in 0..num_shards {
108 let mut shard = Self::new();
109 shard.timestamps = self.timestamps.clone();
110 shards.push(shard);
111 }
112 for (id, signal) in self.vector_signals {
113 shards[id % num_shards].vector_signals.insert(id, signal);
114 }
115 for (id, signal) in self.real_signals {
116 shards[id % num_shards].real_signals.insert(id, signal);
117 }
118 shards
119 }
120
121 pub fn unshard(shards: Vec<Self>) -> WaveformResult<Self> {
122 let timestamps = if let Some(shard) = shards.first() {
123 shard.timestamps.clone()
124 } else {
125 Vec::new()
126 };
127 for shard in &shards {
128 if shard.timestamps != timestamps {
129 return Err(WaveformError::MismatchedTimestamps);
130 }
131 }
132 let mut merged = Self::new();
133 merged.timestamps = timestamps;
134 for shard in shards {
135 merged.vector_signals.extend(shard.vector_signals);
136 merged.real_signals.extend(shard.real_signals);
137 }
138 Ok(merged)
139 }
140
141 pub fn initialize_vector(&mut self, id: usize, width: usize) {
142 self.vector_signals
143 .insert(id, WaveformSignalVector::new(width));
144 }
145
146 pub fn initialize_real(&mut self, id: usize) {
147 self.real_signals.insert(id, WaveformSignalReal::new());
148 }
149
150 pub fn get_vector_signal(&self, id: usize) -> Option<&WaveformSignalVector> {
151 self.vector_signals.get(&id)
152 }
153
154 pub fn get_real_signal(&self, id: usize) -> Option<&WaveformSignalReal> {
155 self.real_signals.get(&id)
156 }
157
158 pub fn get_signal(&self, id: usize) -> Option<WaveformSignalResult<'_>> {
159 if let Some(signal) = self.vector_signals.get(&id) {
160 Some(WaveformSignalResult::Vector(signal))
161 } else {
162 self.real_signals.get(&id).map(WaveformSignalResult::Real)
163 }
164 }
165
166 pub fn get_timestamps(&self) -> &Vec<u64> {
167 &self.timestamps
168 }
169
170 pub fn insert_timestamp(&mut self, timestamp: u64) -> WaveformResult<()> {
171 let Some(last) = self.timestamps.last() else {
172 self.timestamps.push(timestamp);
173 return Ok(());
174 };
175 match timestamp.cmp(last) {
176 Ordering::Less => return Err(WaveformError::DecreasingTimestamp { timestamp }),
177 Ordering::Greater => self.timestamps.push(timestamp),
178 Ordering::Equal => {}
179 }
180 Ok(())
181 }
182
183 pub fn update_vector(&mut self, id: usize, value: BitVector) -> WaveformResult<()> {
184 let signal = if let Some(signal) = self.vector_signals.get_mut(&id) {
185 signal
186 } else {
187 return Err(WaveformError::InvalidId { id });
188 };
189 if signal.get_width() < value.get_bit_width() {
190 return Err(WaveformError::InvalidWidth {
191 id,
192 expected: signal.get_width(),
193 actual: value.get_bit_width(),
194 });
195 }
196 signal.update(self.timestamps.len() - 1, value);
197 Ok(())
198 }
199
200 pub fn update_real(&mut self, id: usize, value: f64) -> WaveformResult<()> {
201 let signal = if let Some(signal) = self.real_signals.get_mut(&id) {
202 signal
203 } else {
204 return Err(WaveformError::InvalidId { id });
205 };
206 signal.update(self.timestamps.len() - 1, value);
207 Ok(())
208 }
209
210 pub fn timestamps_count(&self) -> usize {
211 self.timestamps.len()
212 }
213
214 pub fn get_block_size(&self) -> usize {
215 let mut size = 0;
216 for signal in self.vector_signals.values() {
217 size += signal.get_history().get_block_size();
218 }
219 for signal in self.real_signals.values() {
220 size += signal.get_history().get_block_size();
221 }
222 size
223 }
224
225 pub fn get_vector_size(&self) -> usize {
226 let mut size = 0;
227 for signal in self.vector_signals.values() {
228 size += signal.get_vector_size();
229 }
230 for signal in self.real_signals.values() {
231 size += signal.get_vector_size();
232 }
233 size
234 }
235
236 pub fn count_empty(&self) -> usize {
237 let mut empty = 0;
238 for signal in self.vector_signals.values() {
239 if signal.is_empty() {
240 empty += 1;
241 }
242 }
243 for signal in self.real_signals.values() {
244 if signal.is_empty() {
245 empty += 1;
246 }
247 }
248 empty
249 }
250
251 pub fn count_one(&self) -> usize {
252 let mut empty = 0;
253 for signal in self.vector_signals.values() {
254 if signal.len() == 1 {
255 empty += 1;
256 }
257 }
258 for signal in self.real_signals.values() {
259 if signal.len() == 1 {
260 empty += 1;
261 }
262 }
263 empty
264 }
265
266 pub fn get_timestamp_range(&self) -> std::ops::Range<u64> {
269 match (self.get_timestamps().first(), self.get_timestamps().last()) {
270 (Some(start), Some(end)) => *start..*end,
271 _ => 0..0,
272 }
273 }
274
275 pub fn search_timestamp(
281 &self,
282 timestamp: u64,
283 search_mode: WaveformSearchMode,
284 ) -> Option<usize> {
285 let (mut start, mut end) = (0, self.timestamps.len() - 1);
287 if timestamp < self.timestamps[start] {
289 return match search_mode {
290 WaveformSearchMode::Exact | WaveformSearchMode::Before => None,
291 WaveformSearchMode::After | WaveformSearchMode::Closest => Some(start),
292 };
293 } else if self.timestamps[end] < timestamp {
294 return match search_mode {
295 WaveformSearchMode::Exact | WaveformSearchMode::After => None,
296 WaveformSearchMode::Before | WaveformSearchMode::Closest => Some(end),
297 };
298 }
299 while start <= end {
301 let mid = (start + end) / 2;
302 let mid_value = self.timestamps[mid];
303 match timestamp.cmp(&mid_value) {
304 Ordering::Less => end = mid - 1,
305 Ordering::Greater => start = mid + 1,
306 Ordering::Equal => return Some(mid),
307 }
308 }
309 match search_mode {
311 WaveformSearchMode::Exact => None,
312 WaveformSearchMode::Before => Some(end),
313 WaveformSearchMode::After => Some(start),
314 WaveformSearchMode::Closest => {
315 if (self.timestamps[start] - timestamp) < (timestamp - self.timestamps[end]) {
316 Some(start)
317 } else {
318 Some(end)
319 }
320 }
321 }
322 }
323
324 pub fn search_value_bit_index(
325 &self,
326 idcode: usize,
327 timestamp_index: usize,
328 search_mode: WaveformSearchMode,
329 bit_index: Option<usize>,
330 ) -> Option<WaveformValueResult> {
331 if let Some(signal) = self.vector_signals.get(&idcode) {
332 let Some(index) = signal.get_history().search_timestamp_index(timestamp_index, search_mode) else {
333 return None
334 };
335 let bv = signal.get_bitvector(index.get_value_index());
336 let bv = if let Some(index) = bit_index {
337 BitVector::from(bv.get_bit(index))
338 } else {
339 bv
340 };
341 Some(WaveformValueResult::Vector(bv, index.get_timestamp_index()))
342 } else if let Some(signal) = self.real_signals.get(&idcode) {
343 let Some(index) = signal.get_history().search_timestamp_index(timestamp_index, search_mode) else {
344 return None
345 };
346 let r = signal.get_real(index.get_value_index());
347 Some(WaveformValueResult::Real(r, index.get_timestamp_index()))
348 } else {
349 None
350 }
351 }
352
353 pub fn search_value(
354 &self,
355 idcode: usize,
356 timestamp_index: usize,
357 search_mode: WaveformSearchMode,
358 ) -> Option<WaveformValueResult> {
359 self.search_value_bit_index(idcode, timestamp_index, search_mode, None)
360 }
361}
362
363impl Default for Waveform {
364 fn default() -> Self {
365 Self::new()
366 }
367}