Issie logo Issie

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

Type Description

BinaryTransition

Whether a binary waveform changes at the start of a clock cycle, and what it changes between.

NonBinaryTransition

Whether a non-binary waveform changes value at the start of a clock cycle.

Samples

Where a slice's samples live. Dense today - see the note above on runs. `Base` is the index of sample 0 and `Stride` the distance between samples, so sample i is at Base + i*Stride: local step data is read in place at the sampling multiplier, and a sidecar reply, already sampled, at a stride of one.

WaveSlice

Window

The window a slice covers: `SampleCount` samples, one every `Multiplier` clock cycles, the first at clock cycle `StartSample * Multiplier`. **StartSample counts samples, not clock cycles**, which is the waveform simulator's own convention and the easiest thing here to get wrong: `WaveSimModel.StartCycle` is a DISPLAY position, and the cycle it refers to is `StartCycle * SamplingZoom` - as `lastCycleNeeded = (ShownCycles + StartCycle) * SamplingZoom` and `CursorExactClkCycle = CursorDisplayCycle * SamplingZoom` both attest. The field is named for what it counts so that a reader has to notice.

Functions and values

Function or value Description

bigAt slice i

Full Usage: bigAt slice i

Parameters:
Returns: bigint
Modifiers: inline

Sample i as a bigint, for a slice of width > 32.

slice : WaveSlice
i : int
Returns: bigint

binaryTransitions slice

Full Usage: binaryTransitions slice

Parameters:
Returns: BinaryTransition array

The transitions of a binary (one-bit) waveform, one per drawn cycle.

slice : WaveSlice
Returns: BinaryTransition array

nonBinaryTransitionsBigs slice

Full Usage: nonBinaryTransitionsBigs slice

Parameters:
Returns: NonBinaryTransition array * bigint array

nonBinaryTransitionsWords for a slice wider than 32 bits.

slice : WaveSlice
Returns: NonBinaryTransition array * bigint array

nonBinaryTransitionsWords slice

Full Usage: nonBinaryTransitionsWords slice

Parameters:
Returns: NonBinaryTransition array * uint32 array

The transitions of a wider waveform, with the sampled values beside them - the values are what the viewer writes into each run, so they come back together rather than being read twice.

slice : WaveSlice
Returns: NonBinaryTransition array * uint32 array

ofFetchedBigs data rowBase wordsPerSample width window leadIn

Full Usage: ofFetchedBigs data rowBase wordsPerSample width window leadIn

Parameters:
    data : uint32 array
    rowBase : int
    wordsPerSample : int
    width : int
    window : Window
    leadIn : bool

Returns: WaveSlice

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.

data : uint32 array
rowBase : int
wordsPerSample : int
width : int
window : Window
leadIn : bool
Returns: WaveSlice

ofFetchedWords data rowBase wordsPerSample width window leadIn

Full Usage: ofFetchedWords data rowBase wordsPerSample width window leadIn

Parameters:
    data : uint32 array
    rowBase : int
    wordsPerSample : int
    width : int
    window : Window
    leadIn : bool

Returns: WaveSlice

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.

data : uint32 array
rowBase : int
wordsPerSample : int
width : int
window : Window
leadIn : bool
Returns: WaveSlice

ofLocalDriver io clockTick window

Full Usage: ofLocalDriver io clockTick window

Parameters:
Returns: WaveSlice option

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.

io : IOArray
clockTick : int
window : Window
Returns: WaveSlice option

sampleValue slice i

Full Usage: sampleValue slice i

Parameters:
Returns: bigint

Sample i whatever the width, for the value readouts - the cursor column and the hover tooltip - which want a number and not a representation.

slice : WaveSlice
i : int
Returns: bigint

wordAt slice i

Full Usage: wordAt slice i

Parameters:
Returns: uint32
Modifiers: inline

Sample i as a uint32, for a slice of width <= 32. Index -1 is the lead-in sample, which is sample 0 where the window starts at cycle 0.

slice : WaveSlice
i : int
Returns: uint32

Type something to start searching.