|
SimulationBudget
|
How much memory a simulation may take, and of which kind.
Here rather than beside the code that spends it because two different parts of the simulator
spend it: GraphMerger, which expands the design into a graph, and FastCreate, which allocates
the step arrays. Both come out of the same memory and GraphMerger is compiled first.
Sizes are float and not int64 on purpose. Fable compiles int64 to BigInt, so every comparison
here would allocate one - a poor thing to spend on deciding whether a design is too big. A float
carries integers exactly to 2^53 and the largest number reached here is a few hundred GB.
|
|
BigIntState
|
Used for efficiency reasons.
For a given normal simulation these arrays show whether the corresponding
component input or output is a bigint or a unint32 type bus, and therefore
show IOArray array is used for the data.
|
|
Driver
|
Convenience array used so that waveform simulation can access
component outputs (drivers) without a Map lookup
|
|
FData
|
|
|
FastComponent
|
FastComponent represents a physical component in a simulation. Because sheets can be
instantiated in multiple places a given sheet component can have multiple FastComponents
in the simulation.
Arrays on FastComponent are filled up with simulation data per clock step as a clocked
simulation progresses.
Equality is by reference: a FastComponent is a mutable object with an identity, holding
step arrays that can run to megabytes, so comparing two of them field by field would be
both meaningless and ruinous. It also carries its own reducers, which are functions and
so have no structural equality at all.
|
|
FastSimulation
|
|
|
GatherData
|
Scaffolding for building a FastSimulation, and alive only while one is built: the flattened
design indexed the several ways createInitFastCompPhase and linkFastComponents need it. It is
deliberately not kept afterwards - AllComps holds a SimulationComponent per component INSTANCE,
so on a large design it is one of the biggest things the simulator ever allocates, and a
FastSimulation left holding one made every later edit slower by giving each major GC all of it
to trace. What the built simulation still needs is copied out: FCustomOutputCompLookup.
|
|
GatherTemp
|
GatherTemp is the output type used to accumulate lists of data links when recursively exploring SimulationGraph
as first step in flattening it.
Each list of pairs is converted into a map at the end in the final GatherData structure
The cost of creating maps makes it important to use lists here as the intermediate structures
|
|
IOArray
|
This type represents an array of time steps of simulation data.
In any simulation, for a given IOArray, only one of the three 'Step' arrays will be used.
For (very strong) efficiency reasons this cannot be implemented as a disjoint union:
the code that reads and writes IOArray array elements will access the appropriate array.
Truthtable simulations use FDataStep everywhere.
Normal simulations use UInt32step or BigIntStep according to the size of the relevant bus.
|
|
SheetPort
|
Type used to tie component ports to simulation data
for advanved wavefor simulation features.
|
|
SimulationData
|
- Top level data tracking a simulation
|
|
SimulationRunStatus
|
document current status of a simulation as used by waveform simulator
|
|
StepArray<'T>
|
Wrapper to allow arrays to be resized for longer simulations while keeping the links between inputs
and outputs
|
|
StepCost
|
What one clock cycle of a design costs in step arrays, kept apart by which memory it comes from.
The two are not interchangeable, and measurably so - though not in the way performance.memory
suggests. usedJSHeapSize counts Uint32Arrays at every size, so it cannot tell the two apart;
what separates them is the LIMIT. Uint32Array allocation ran to 15.5GB on a 32GB machine
against a jsHeapSizeLimit of 3.7GB, so those are bounded by the machine and not by V8's pointer
compression cage. Buses wider than 32 bits are held as a plain array of BigInt, which is
ordinary heap - 400MB of values cost 454MB - inside that 4GB cage, shared with the model, the
design and the waveforms. So a design can be refused for the second while nowhere near the first.
FastCreate.stepBytesForWidth works out one port's share; FastCreate.stepCostOfDesign totals it.
|
|
StepIndex
|
Where one clock step sits in the circular simulation arrays: the step number itself, its
index into the arrays, and the index of the step before it. All three follow from the step
number, so the simulation loop works them out once per step and hands the same value to
every component - numStep % maxArraySize is an integer division, and it used to be redone
for every component of every step. A struct so that passing it costs nothing.
|