PortView Module
The ports of one elaborated sheet instance that a waveform can be taken of. **This is the narrow question the renderer should be asking a simulator**, and the one `SimInterface` describes: not "give me every wave in the design" - which is proportional to the expansion and is what a remote simulator exists to keep out of the renderer - but "which ports does THIS instance offer", asked of the handful of instances on screen. Everything here that a design could answer is answered from the design instead; what is left is what only an elaborated simulation knows. That is two things, and they are the reason this cannot be a design-time query: the WIDTH of a port, because parameters are resolved when a design is elaborated, so two instances of one sheet are meant to differ; where the port's data LIES - its driver and its step array - which is a fact about one build and is invalidated by the next. Below the UI for the same reason `RamView` and `WaveNames` are: the .NET sidecar has a FastSimulation of its own and must answer this from exactly this code, or the two agree until they do not.
Types
Functions and values
| Function or value | Description |
Full Usage:
drawnComponentOf design waveId
Parameters:
SimulatedDesign
waveId : WaveIndexT
Returns: ComponentId
|
The component a wave should take the user TO, which is not always the one it comes from. A wave on one of an array component's copies comes from a component the EXPANSION made - the copy, which is a custom component on a sheet nobody drew - so there is no symbol anywhere to go to, and the waveform viewer's "show me this" button did nothing at all. What the user means by it is the join, or the input or output, that this port IS: that is drawn on the array component's own sheet, and the body sheet keeps the ids of what is drawn there, so the body's IO component for this port is the drawn one. Found by port NUMBER and not by label. A copy's port labels are the channels that copy is joined by, which is the whole point of them, and those are not the body's labels - see ArrayElaborate's copyPortNames.
|
|
|
Full Usage:
ofInstance fs instance
Parameters:
FastSimulation
instance : InstancePath
Returns: InstanceView
|
The ports of one instance that carry a waveform, from the simulation in this process. The DERIVATION is `ofSlice`'s - the design plus two ints a port - and this is only the local composition of it with the local slice. A renderer whose simulator is in another process runs the same `ofSlice` over a slice that arrived on the wire, and the two must be the same function or the two modes drift; that is why there is no second derivation here.
|
Full Usage:
ofInstanceCached fs instance
Parameters:
FastSimulation
instance : InstancePath
Returns: InstanceView
|
|
Full Usage:
ofSlice design instance slice
Parameters:
SimulatedDesign
instance : InstancePath
slice : ComponentSlots list
Returns: InstanceView
|
|
Full Usage:
sheetSliceOf fs instance
Parameters:
FastSimulation
instance : InstancePath
Returns: ComponentSlots list
|
Width and driver of every port of every component on one instance's sheet. ALL ports, positionally - not the wave-carrying subset. Filtering would mean naming what was kept, which costs more than the entries it saves, and the rule for what carries a wave is a design fact the caller already has - the IOLabel election included, which is read off the design's connections (see `ofSlice`). A group's members share their arrays here, so the DATA is the same whichever member is asked about. A width of 0 is a port with no signal: an unconnected input, still holding the dummy array it was created with. This is the sidecar's answer to "what does this instance offer" and the renderer's local answer to the same question, from one body of code - which is the point.
|
Full Usage:
sliceSource
Returns: (FastSimulation -> InstancePath -> ComponentSlots list option) option
|
Where wire-fetched slices are read from, when the simulation is NOT in this process. Installed ONCE, at startup, by the renderer's PortData - and never under .NET, where it stays None and every slice is computed locally. It is consulted only for a CARRIER build, and it answers from what has arrived for exactly that build: None means "this instance is not described YET" - a different thing from an empty slice, and the distinction is what lets a selection loaded before the wire answers pass through unresolved instead of being dropped. A hook rather than a parameter because slices are read from view code through the memo below, at call sites that have no business knowing which process simulates. Which build the hook is asked about travels WITH the ask - the same fs the caller holds - so there is no lifecycle here: nothing activates it, nothing clears it, and a stale answer is impossible because the store inside keys what it holds by the build it holds it for.
|
|
The ports of an instance, remembered for as long as the simulation is. `ofInstance` costs one sheet. That is the right cost to pay once for an instance and the wrong cost to pay per selected wave: reconciling a hundred waves walked their sheet a hundred times, and the test suite went from 27 seconds to 43 when it started to. Only instances actually asked about are held - the ones the selector is showing, and the ones selected waves are in - so what this holds is bounded by what the UI touches rather than by the expansion. Keyed on the simulation, which is rebuilt rather than mutated, so a new one is the signal that all of it is stale; emptied when a simulation ends, by Helpers.clearIdentityMemos. None while the sidecar simulates and this instance's slice has not arrived - the case every display site answers with nothing-yet, and reconciliation answers by keeping the wave unresolved. A described instance is memoised; an undescribed one is asked again, because the answer changes when the slice lands.
|
Full Usage:
waveIndexOf instance port
Parameters:
InstancePath
port : InstancePort
Returns: WaveIndexT
|
|
Full Usage:
waveIndicesOfDesign design instance
Parameters:
SimulatedDesign
instance : InstancePath
Returns: WaveIndexT list
|
The wave-carrying ports of one instance, from the DESIGN alone - no simulation, no slices. Every wave comes back UNRESOLVED (SimArrayIndex = DriverIndex -1): where its data lies is a build fact this deliberately does not know. Reconciliation resolves them against whichever simulator runs - which is what makes this enumeration mode-agnostic, and what the dev harness selects with. Port counts and numbering are the design's own; the carries-a-wave rule is the same one ofSlice applies, election by connection included. The one thing a slice adds - dropping an unconnected input's width-0 port - is left to resolution, where the fetch already records such a wave as having no driver.
|