FastCreate Module
Functions and values
| Function or value | Description |
Full Usage:
addComponentWaveDrivers f fc pType
Parameters:
FastSimulation
fc : FastComponent
pType : PortType
Returns: WaveIndexT[] array
|
|
Full Usage:
addWaveIndexAndDrivers comps f
Parameters:
FastComponent array
f : FastSimulation
Returns: WaveIndexT array
|
Called after the fs.Drivers array is created. waveComps must contain all components that can be viewed in the wave simulation. This function mutates fs.Drivers adding the correct arrays where these are used. In some cases an array may never be used and therefore is not added. In parallel with this, the function returns an array of WaveIndexT records that reference component ports which can be viewed in a wave simulation. Every WaveIndex references an element of fs.Drivers from which the simulation data is found.
|
Full Usage:
addWavesToFastSimulation comps fs
Parameters:
FastComponent array
fs : FastSimulation
Returns: FastSimulation
|
Adds the Drivers and WaveIndex fields to a fast simulation. For use by waveform Simulator. Needs to be run after widths are calculated. **What a simulation needs only in order to be DRAWN**, and all of it sized by the expansion: a map of every component of every instance, an entry per step array, and an entry per wave-carrying port. `WaveTables` is what decides whether a build pays for them; a simulator that runs and answers reads by name does not.
|
Full Usage:
assertThat cond msg
Parameters:
bool
msg : string
Modifiers: inline |
|
Full Usage:
checkSimulationFits arraySize cost
Parameters:
int
cost : StepCost
Returns: Result<unit, SimulationError>
|
Refuse a simulation whose step arrays would not fit, before a byte of them is allocated. Before rather than after, because the arrays ARE what exhausts memory: a check that had to build them first would be the thing it is meant to prevent. Everything it needs is known by then - the flattened design gives every width, and the caller has said how many cycles it wants - so the answer is exact rather than a guess. A Result and not an exception: this is a limit an ordinary user reaches by asking for a long waveform simulation of a big design, so it travels the same path as any other simulation error and is shown the same way, saying what would fit instead. The line enforced here is the budget times SimulationBudget.runtimeHeadroom, not the budget: this check is the crash guard of last resort, and the configuration dialog - which holds users to the budgets exactly - is the advertised limit. The gap is for the simulation that arrives without passing that dialog, a LastClock saved into a sheet on a larger machine above all, which should run if it safely can rather than fail the moment Start is pressed. The advice in the refusal still quotes the dialog's own bound, so following it always works.
|
|
|
|
What one clock cycle of this design will cost, read straight off the merged SimulationGraph - before it is flattened, before a FastComponent exists, and allocating nothing itself. One step array is allocated per output port of every component of every INSTANCE, so that is what is counted: the graph is walked the way the flatten walks it, descending into each custom component's own graph, so a sheet used ten times is charged ten times. It is deliberately taken from the graph and not from the flattened design. The flatten now creates the step arrays as it goes, so a cost worked out from its output would be worked out after the memory it is meant to refuse had been taken - see checkSimulationFits below, whose whole point is to come first. Reading the graph keeps the check where it belongs and, as a bonus, is what lets the waveform simulator's configuration dialog price a design (ModelHelpers.waveSimStepCost) without building any of it. Custom components are counted, not skipped: their output arrays are allocated and then replaced by links to the arrays inside them (linkFastCustomComponentsToDriverArrays), and the replaced ones stay in the step-array arena for the simulation's whole life. So this count is exactly what a built simulation occupies, the replaced quarter included, not an estimate of it. The per-step State array is counted too. Only RAMs ever write it, but createFastComponent allocates one for every component that could be synchronous - customs included - so on a register-heavy design it is real memory, and the estimate that omitted it said a design was smaller than it is. The count comes back alongside the cost because both are wanted at the same moment, by the same caller, from the same walk: the build sizes its component store from the count so that the store never has to grow, and refuses the design outright on the cost.
|
Full Usage:
createFastComponent maxArraySize sComp accessPath fullName
Parameters:
int
sComp : SimulationComponent
accessPath : ComponentId list
fullName : string
Returns: FastComponent
|
create a FastComponent data structure with data arrays from a SimulationComponent. numSteps is the number of past clocks data kept - arrays are managed as circular buffers. fullName is given rather than filled in afterwards: the flatten stores this object in its index space, and `{ fc with FullName = ... }` afterwards would put a DIFFERENT object there than the one the caller kept - a copy of a 23-field record per component, and a reference-equal identity broken, for a string that is known when it is made.
|
Full Usage:
createInitFastCompPhase simulationArraySize g f
Parameters:
int
g : GatherData
f : FastSimulation
Returns: FastSimulation
|
The door between the build's index space and the rest of the program. It used to create the FastComponents as well; the flatten does that now, so what is left of it is the boundary. What a built simulation offers is the STORE - FCompsByIndex, in gather order - and one map, FIndexOf, from the design-time name a caller arrives with to a place in it. The name is what survives a rebuild and so what the renderer holds; the index is what everything inside the simulation works in. Custom against ordinary is decided here, by a predicate over the one store. It is not a second index space and must not become one: the links the flatten resolved are positions in this store, and splitting it would make the same integer mean two different things.
|
Full Usage:
determineBigIntState comps f
Parameters:
FastComponent array
f : FastSimulation
Returns: FastSimulation
|
|
Full Usage:
emptyFastSimulation diagramName
Parameters:
string
Returns: FastSimulation
|
|
|
|
Full Usage:
finishStepArena ()
Parameters:
unit
|
|
Full Usage:
gatherSimulation maxArraySize size graph
Parameters:
int
size : int
graph : SimulationGraph
Returns: GatherData
|
Flatten the SimulationGraph into the one index space the rest of the build works in, creating every FastComponent - and so every step array - as it goes. size is how many components the expanded design has, from costAndSizeOfGraph, so the store is made at exactly the right size and never grows. That same walk is what priced the design and refused it if it would not fit, which is why this may allocate at all: by the time it runs the budget has been checked and the step-array arena opened for what it said.
|
Full Usage:
getFid cid ap
Parameters:
ComponentId
ap : ComponentId list
Returns: ComponentId * ComponentId list
|
|
|
|
Full Usage:
linkCustomComponentPorts comps fs
Parameters:
FastComponent array
fs : FastSimulation
Returns: FastSimulation
|
Point every custom component's ports at the arrays of the Input and Output components inside it, so that reading a custom component's port reads the signal it actually carries. Not optional, and not part of the wave tables below even though it used to be in the same phase: a port that points at the dummy array it was created with reads as nothing. Cheap - one re-pointing per port of each custom component, and there are far fewer of those than of ordinary ones. `comps` is every component of the build in creation order - the array the gather filled, not the maps. See the note on createFastArrays: walking the maps here means walking the components in a different order from the one they were allocated in, and on a design of any size that is most of what this phase costs.
|
Full Usage:
linkFastComponents g f
Parameters:
GatherData
f : FastSimulation
Returns: FastSimulation
|
Use the links the flatten resolved to tie the FastComponents' data arrays together. InputLinks[i] is set equal to the driving Outputs array, so that input i reads the data reduced by the correct output of the component that drives it. The main work is dealing with custom components, which represent whole design sheets with recursively defined component graphs. The custom component itself is not linked and does not exist as a simulatable FastComponent - instead its graph's Input and Output components are linked to whatever connects to the corresponding ports of the custom component. Note: custom components are linked in later as unsimulatable placeholders, to let the wave simulation reach their ports. Everything here works in store indices. It used to work in (ComponentId, access path) pairs against four maps, and that was the build's shape problem: a structural key costs a boxed comparison of a GUID-like id and a list per tree level, and this function does one per link of every component of the expanded design.
|
Full Usage:
linkFastCustomComponentsToDriverArrays fs (arg2, arg3) fc
Parameters:
FastSimulation
arg1 : ComponentId
arg2 : ComponentId list
fc : FastComponent
Returns: Unit
|
|
|
|
|
|
|
|
|
|
|
The largest WSConfig.LastClock a design costing this much can be configured to. maxCyclesFor bounds the step ARRAYS, and the arrays carry a zoom margin past the last clock - up to CommonTypes.waveSimMaxArrayMargin - so the two numbers differ by exactly that margin. Every message that tells the user what may be ASKED for must quote this one: quoting the array bound as a configuration value told the user to set a number that was itself refused.
|
Full Usage:
portCarriesWave f fc pType
Parameters:
FastSimulation
fc : FastComponent
pType : PortType
Returns: bool
|
Add one driver changing the fs.Driver array reference. Return a WaveIndex reference. WaveIndex refrences are bound to specific component ports and not unique per driver. Whether a port of a component carries a waveform the user can watch. The rules the wave index is built from, said once. They used to live only inside addComponentWaveDrivers, which walks every port of every component of the whole expanded simulation; anything wanting to know which ports one INSTANCE offers - without walking the expansion to find out - has to decide it the same way, and two copies of a rule like this drift. The builder below now asks this, so there is one answer. What is excluded, and why each: the input side of components whose input is not a signal of its own (an IOLabel, an Input1, a Viewer, a NotConnected, an Output); a Constant1, whose output drives but is not worth watching; every IOLabel of a same-named group except the one elected to drive it, since they are all one net; the wiring components, which carry no signal distinct from what they are wired to; and the Input1 and Output components INSIDE a subsheet, whose signal is the enclosing custom component's port and is offered there instead.
|
|
|
|
Start drawing step regions from arena slabs, sized for what this build is about to need. The size matters more than it looks. A slab used to be a fixed 256MB whatever was being built, so EVERY simulation - a three-component test circuit as much as a CPU - allocated and zeroed 256MB before it could hold its first cycle. Under .NET that is a large-object allocation per build, and a test suite that builds a few thousand small simulations spent eight minutes of its twelve doing nothing else. The cost of a build is now the cost of what it holds. The numbers come from `stepCostOfGraph`, which is computed for the memory budget before the arrays are allocated and charges for exactly what the arena keeps - so the first slab is the whole of an ordinary build. A build that needs more than a slab, or more than was planned for, simply takes another; nothing depends on the estimate being right. Callers must pair this with finishStepArena however the build ends, or the next truth-table build would draw from a slab nobody meant it to share.
|
Full Usage:
stepArrayIndex
Returns: int
|
|
Full Usage:
stepBytesForWidth w
Parameters:
int
Returns: int
|
|
|
|