WaveSlice Module
One waveform over one view window: what the waveform viewer asks for, draws from, and - when the simulator is the .NET sidecar - fetches across the wire. **Why a slice rather than an array.** The viewer never wants a whole waveform. It wants `ShownCycles` samples taken every `SamplingZoom` cycles from `StartCycle`, which is exactly what `SidecarClient.simRead` asks the sidecar for and exactly what the local step arrays can be read as. Making that window a value with a name gives the two simulators one shape to meet in: a slice from the local `FastSimulation` and a slice fetched from the sidecar are the same thing to everything downstream, so the drawing code neither knows nor cares which simulator ran. **Why the drawing code goes through the operations here and not the array.** What a waveform actually needs is its *transitions* - where the value changes - which is a run-length encoding of the samples in all but name. Today a slice holds dense samples and the operations below compute runs from them; the intended next step is for the sidecar to send runs, for a slice to hold runs, and for these same operations to return them with no work at all. That change should not reach the SVG code, so the SVG code must not index samples itself. Point access (a cursor value, a hover tooltip) is a handful of calls per render and can afford to go through a function; the drawing path asks for transitions once per waveform. **Reading costs nothing extra.** A slice does not copy: it names the array its samples already live in, where sample 0 starts, and how far apart samples are. Local step arrays are read with a stride of the sampling multiplier; a sidecar response is already sampled, so its stride is one and its base is the start of that signal's row in the reply.
Types
Functions and values
| Function or value | Description |
|
|
|
|
Full Usage:
nonBinaryTransitionsBigs slice
Parameters:
WaveSlice
Returns: NonBinaryTransition array * bigint array
|
|
Full Usage:
nonBinaryTransitionsWords slice
Parameters:
WaveSlice
Returns: NonBinaryTransition array * uint32 array
|
|
A slice over one signal's row of a sidecar reply, for a signal too wide for a uint32. This one copies, because a bigint is not a view over anything: each sample's words are joined into a number. It is the only copying reader here and it is affordable for the same reason the width is unusual - a view draws tens of samples, not thousands.
|
|
A slice over one signal's row of a sidecar reply, which is already sampled. A reply carries `wordsPerSample` uint32s per sample, least significant word first, so a signal of 32 bits or less is read in place at that stride - word 0 of each sample - and nothing is copied. `rowBase` is the index of the row's first WORD, and `leadIn` says whether the fetch asked for the extra sample before the window, in which case that sample is first and sample 0 is the next one.
|
|
|
A slice over a driver's local step data. Nothing is copied: the step arrays are read where they lie, at the sampling stride. `None` when the window is not inside what the simulation HOLDS - which is a question about `clockTick`, not about the array's size. Those are different numbers and using the wrong one is silent: an array long enough for a cycle the simulation has not reached yet holds zeros there, and a slice over them draws zeros as confidently as data. This guarded on the array length alone, and was right only because the caller happened to run the simulation first. The step arrays are a circular buffer, and this reads them with a stride and no modulo, which is only correct while the simulation has not wrapped. It never has here: the waveform simulator sizes its arrays for the whole configured run. Rather than leave that as an assumption two files apart, a wrapped simulation is refused - so if this is ever pointed at the step simulator's arrays it says no instead of returning somebody else's cycles.
|
|
|
|