Platforms
A platform is the target a design is built and measured against. It has two halves:
- identity — an FPGA part, a synthesis clock, and the resource counters that technology is measured in.
- library — everything fit or measured for that target: the bus-transfer law, timing residuals, and area records.
It is the pairing that makes it work. A cycle count or a LUT count is only meaningful for a particular part at a particular clock, so the numbers and the identity they were taken under are stored together and confirmed on use.
Waveflow ships one reference platform, so an installed user inherits working measurements for the framework’s own modules with no toolchain run at all; a project then creates its own seeded from it.
It is not just a calibration concept
Four things consume a platform, and only one of them is calibration:
| consumer | what it takes |
|---|---|
| the build | part and the clock period → the csynth set_part / create_clock |
| timing models | the component residual fit for this target |
| resource models | the measured area records, and the counter vocabulary |
| calibration | where a new fit is written |
The first is the one that is easy to miss. BuildConfig(platform=…) resolves a Platform, and codegen
reads part off it to emit the synthesis TCL — so someone who never calibrates anything still needs
a platform to synthesize against the right device. That is why this is its own section rather than a
chapter of model fitting: it is shared infrastructure, and putting it under either the timing or the
resource axis would make the other a second-class citizen of it.
The payoff is a property worth stating plainly:
The part a design is synthesized for and the part its models were fit for come from the same object, so they cannot drift. Naming a platform on a build is a create-or-confirm gate: a new one is seeded from the build’s part/clock, an existing one is checked against them, and a mismatch is an error rather than a silently reused number.
In this section
- Platform identity — what identifies one: part, synthesis clock, memory system, and the counter vocabulary; plus the mismatch gate that keeps a fit from being used off-target.
- Creating a platform — one per project: where the directory goes, why you seed it from
an upstream platform rather than recalibrating the framework, and what to
.gitignore. - Directory layout — what ends up inside, the two content trees and their keys, and the search order across roots.
- Managing a platform — inspecting one, and the two-tier work → publish flow that is the only writer of a tracked library.
See also
- Model calibration — how the fits stored here are produced.
BuildConfig— theplatform/part/clk_freqselector.
Table of contents
- Platform identity - What identifies a platform, in two parts. THE TARGET — an FPGA part, a synthesis clock and the memory system — decides what a cycle count means: the part fixes primitive latencies, the synthesis clock fixes the HLS schedule (and is not the sim clock), and the memory system fixes the bus law without appearing in the part number. THE RESOURCE TYPES decide what an area number even is; they default to the FPGA counters and are declared per platform, which is the seam a non-FPGA technology enters through and what makes counter names validated rather than conventional.
-
Creating a platform - One platform per project, not per module. Where the directory goes (
/calib/platforms/ , one subdirectory per target); why you seed it from an upstream platform rather than recalibrating the framework components your design composes; how a build names one and creates-or-confirms it against a stored identity; and the .gitignore lines — without the re-include, a project publishing exactly as documented writes into a directory git silently drops. - Directory layout - What is inside a platform directory and where platform directories live. Two content trees under one identity — components/ holds timing residuals keyed by task configuration, modules/ holds resource records keyed by module structure — and three homes: an untracked work tier that sweeps churn freely, a project's own tracked library, and the read-only reference shipped inside the package.
-
Managing a platform - Calibration storage is two-tier: sweeps write a churny untracked calib/work/
/; the publish_calib command promotes the stable artifacts (platform.json, mm_bus.json, points/, component params + corpus -- never the raw firing trees) into the shipped, in-package library waveflow/calib/platforms/ /. publish is dry-run by default, a byte-compare no-op on unchanged files, and refuses a coverage regression (a thinner re-fit) unless forced. The reference zynq7020_bfm_100mhz platform is built end-to-end by examples/mem_copy/calibrate_platform.py and reproduces the writer RTL period to 0.0%.