Home · ASPLOS 2022 · Accelerators & Hardware Design

PLD: fast FPGA compilation to make reconfigurable acceleration compatible with modern incremental refinement software development

Yuanlong Xiao, Eric Micallef, Andrew Butt, Matthew Hofmann, Marc Alston, Matthew Goldsmith and 2 others

Conference
ASPLOS 2022
Published
2022
Pages
933-945
Citations
18

FPGAs are chips you reprogram into custom accelerators for big speedups, and you can now describe them in C — but compiling one is brutally slow, tens of hours, because the tools do a MONOLITHIC compile that solves a giant NP-hard puzzle of arranging millions of gates in space, and any tiny edit means recompiling the whole thing, so FPGA development feels like the 1960s instead of the seconds-long edit-compile-debug loop software engineers expect; this paper (Penn) brings the software-compiler playbook to FPGAs — separate compilation, linking, and fast-versus-quality optimization levels — by describing the app as a graph of streaming "operators" whose FIFO links make each one independent, cutting the FPGA into separately-compilable "pages" wired by an on-chip network you can re-link with a few packets, and offering three modes — compile every operator to a fast soft-CPU in SECONDS for functional debugging, to a small FPGA page in MINUTES for incremental refinement on real hardware, or into one optimized design in HOURS for full speed — so a developer always has a running accelerator and only recompiles what changed, making the fast path 4 to 7x quicker than the monolithic flow.

The argument in one glance

  1. Problem

    FPGA accelerators are powerful, but compiling one takes hours

    An FPGA is a chip whose logic you can reprogram, so you can build a custom hardware accelerator for your algorithm and get large performance and energy wins over a CPU — and data centers now offer FPGA cards you can target from C. The catch is the build step. Compiling a design onto an FPGA is agonizingly slow: mapping a whole accelerator can take tens of hours. Every time you change one line and want to test it, you wait — because the tools recompile the entire design from scratch. Software engineers, by contrast, live in a seconds-long edit-compile-debug loop and refine their programs incrementally. Programming an FPGA today feels like stepping back to the batch-processing era of the 1960s, and that mismatch keeps most software engineers away from FPGA acceleration.

  2. What people did

    Use the vendor tools to compile the whole design for maximum quality

    The standard path is a commercial high-level-synthesis toolchain (Xilinx Vitis): write the accelerator in C, and let the tool compile the whole thing monolithically into hardware, optimizing across the entire design to produce the highest-quality result. Because it sees everything at once, it can place logic well and squeeze out performance. This is the right tool when you want a finished, fully-optimized accelerator.

  3. Why it fell short

    A monolithic compile is slow, all-or-nothing, and has no fast mode

    That monolithic compile is exactly what makes iteration impossible. It solves hard SPATIAL optimization problems — placing and routing millions of individual gates on the chip — using super-linear, NP-hard algorithms, so it takes one to two hours for a small design and ten or more for a large one, and any small change forces a full recompile. There is no separate compilation (recompile only the part that changed) and no linking. Worse, there is no fast-and-rough mode: a software compiler offers optimization levels from -O0 (compile fast, do not optimize) to -O3 (compile slow, optimize hard), so you can iterate quickly during development and optimize only at the end. FPGA tools offer essentially only the slow, high-quality path. So during development, when you just want to check whether a change works, you still wait hours — which is why the fast, incremental refinement that defines modern software engineering is simply unavailable.

  4. This paper's idea

    Bring separate compilation, linking, and optimization levels to FPGAs

    This paper (University of Pennsylvania — Xiao, DeHon, and colleagues) builds PLD, which adapts the software-compiler model to FPGAs: separate compilation, linking, and distinct fast-versus-quality optimization levels, from single-source C. The application is described as a dataflow graph of OPERATORS connected by streaming FIFO links; because those links are latency-INSENSITIVE (an operator's timing does not change functional behavior), each operator is an independent module that can be compiled, placed, relocated, and re-linked on its own. PLD cuts the FPGA into independent "pages" — atomic regions of about 18,000 look-up tables, created with partial reconfiguration — so each operator compiles SEPARATELY and in PARALLEL, and only the changed pages are recompiled; the pages are wired by an on-chip packet-switched linking network that you re-link just by sending a few control packets. On top of this, PLD offers three levels: -O0 maps every operator to a fast-compiling RISC-V SOFTCORE overlay (build in seconds, run slowly — for functional debugging), -O1 maps each operator to a small FPGA page (build in minutes — for incremental refinement on real hardware), and -O3 links everything into one monolithic optimized design (build in hours — for full performance). The developer always has a running application and climbs the ladder as they refine. The -O1 path compiles in ten to twenty minutes, 4.2 to 7.3x faster than monolithic, and -O3 matches or beats native quality.

Why this problem is worth solving

FPGAs are one of the most promising ways to accelerate computing as general-purpose scaling stalls, but their adoption is gated less by hardware and more by a developer experience stuck decades behind software. Understanding why the build is so slow comes first. A

an FPGA (field-programmable gate array) is a chip made of a sea of tiny configurable logic elements (look-up tables), memories, and arithmetic blocks, plus a programmable mesh of wires, that you configure to implement any digital circuit — letting you build a custom accelerator in reconfigurable hardware. You can now describe the computation in C and use HIGH-LEVEL SYNTHESIS (HLS) to turn it into a circuit. But turning that circuit into a configuration the chip can load is a monolithic, whole-design COMPILE that must solve placement and routing: deciding where each of millions of gates physically sits on the chip and how to route the wires between them. These are NP-hard spatial optimization problems solved by super-linear heuristics with no runtime guarantee, so the compile takes hours to tens of hours, and because it optimizes the whole design at once, any change means redoing all of it
is the root cause. The compile time directly sets the edit-compile-debug cycle, and hours-long cycles make the incremental refinement software engineers rely on impossible.

The idea PLD borrows to fix this is one software compilers have used for decades. A

in software, a program is split into modules that are compiled SEPARATELY, then LINKED together, so changing one module only requires recompiling that module and re-linking — not rebuilding the whole program. Compilers also offer OPTIMIZATION LEVELS (fast -O0 through slow -O3) trading compile time for quality. PLD brings both to FPGAs, and the enabler is a streaming DATAFLOW model: the application is a graph of OPERATORS (modular compute units, each described in C) connected by LATENCY-INSENSITIVE stream links — FIFO channels where a read blocks until data arrives and back-pressure stalls a too-fast producer. The crucial property is that this timing does NOT change the functional result: an operator can be made faster or slower, moved to a different location, or even run on a processor instead of the fabric, and the computation still produces the same answer. That timing- independence is exactly what lets operators be compiled, placed, and re-linked as independent modules, the way software objects are
is the conceptual core. A stable, timing-insensitive interface is what turns a monolithic hardware compile into a modular, incremental one.

What people did before, and where it broke

  • Monolithic HLS compilation (Vitis). Compile the whole accelerator at once for the best quality. Excellent final designs, but one to two hours (ten or more for large designs), all-or-nothing, with no fast iteration mode.
  • FPGA optimization “levels” (as they existed). Vendor tools have limited fast-versus-quality strategies, nothing like a software compiler’s -O0 to -O3, so there was no way to trade a little quality for a fast build during development.
  • Coarse-grained overlays. Pre-build a fixed, higher-level architecture on the FPGA and target it, compiling faster. But overlays waste FPGA resources (3 to 10x capacity cost), are often domain-specific, and use their own instruction set rather than the same C that also runs on a processor.
  • Prior separate-compilation attempts. Earlier work hinted at separate compilation for FPGAs but ran only on embedded boards (no data-center or OpenCL support), required operators pre-sized to fixed regions, and left the developer with no running design during refinement.
  • The gap. No approach gave software engineers the full model — separate compilation, linking, optimization levels, and single-source C that runs on both fabric and processor — always leaving a running, testable application. That is the gap PLD fills.

How PLD makes FPGA compiles fast

Model the app as operators, split the FPGA into pages, link them, and offer optimization levels

  1. Why FPGA compiles are slow

    A whole-accelerator compile solves NP-hard placement and routing of millions of gates with super-linear heuristics, taking hours, and any change forces a full recompile. There is no separate compilation, no linking, and no fast-and-rough optimization level.

  2. Describe the app as streaming operators new

    PLD expresses the computation as a dataflow graph of operators connected by latency-insensitive FIFO stream links. Because an operator's timing does not affect the functional result, each operator is an independent module that can be compiled, placed, relocated, and re-linked on its own — the precondition for separate compilation.

  3. Cut the FPGA into independent pages new

    Using partial reconfiguration, PLD divides the fabric into "pages" — atomic regions of about 18,000 look-up tables that can be compiled and loaded independently while the rest of the chip runs. Each operator maps to a page, so the one huge place-and-route becomes many small ones that run separately and in parallel, and only changed pages are recompiled.

  4. Wire pages with a re-linkable network new

    A packet-switched on-chip network (a Butterfly Fat Tree) connects the pages and implements the latency-insensitive stream links. "Linking" is setting routing registers in each page's network interface, so operators can be re-linked — connected differently — by sending a few control packets, with no recompilation.

  5. Offer three optimization levels new

    Guided by a per-operator target pragma, PLD compiles each operator to one of three targets: -O0 maps it to a fast RISC-V softcore overlay (built in seconds, runs slowly); -O1 maps it to a small FPGA page (built in minutes, runs on real fabric through the network); -O3 links all operators into one monolithic, natively place-and-routed design (built in hours, full performance).

  6. Always keep a running artifact and climb the ladder new

    A developer can start with everything at -O0 for near-instant functional debugging, move individual operators to -O1 pages to refine them on real hardware in minutes (recompiling only what changed), and finish at -O3 when they want peak performance — always holding a running, testable application, exactly like software development.

Built on Xilinx Vitis and Vitis HLS, evaluated on an Alveo U50 data-center FPGA (22 user pages, a 200 MHz packet-switched network, a PicoRV32 softcore per page) on the Rosetta benchmark suite. Open-sourced.

The idea

Borrow the software-compiler model — separate compilation, linking, and optimization levels. The whole paper is an act of translation: take ideas that made software development fast and productive — compiling modules separately, linking them, and offering a fast-to-slow optimization dial — and bring them to FPGA hardware, where compilation had none of them. Porting a proven model from an adjacent domain onto an unfamiliar problem is a move the site rewards repeatedly, whether it is casting a scheduling problem onto max-flow or a search onto ray-tracing cores, and it pairs with the raise-the-abstraction discipline the in-memory-computing and high-level-synthesis pages use to give hardware a software-like interface. Here the payoff is a familiar mental model: the FPGA developer edits a module, recompiles just that module, and re-links — and gets the seconds- to-minutes turnaround that software engineers take for granted, instead of an hours-long monolithic rebuild.

Decompose the monolithic NP-hard compile into independent parallel pieces. The reason a whole-design compile is slow is that placement and routing are super-linear in the design size, so one giant problem is far worse than many small ones. PLD divides the FPGA into pages so each operator is a small, independent place-and-route that runs in parallel with the others, and only the pages that changed are recompiled. Breaking a coupled monolithic super-linear problem into independent sub-problems is the same divide-into-independent-pieces discipline the high-level-synthesis page uses when it decomposes a dataflow optimization by hierarchy to drop from exponential to polynomial cost — and the independence is only possible because the latency-insensitive links let the pieces be compiled without knowing each other’s internals. The monolithic -O3 path still exists for when peak quality matters; the point is that development no longer requires paying its cost on every edit.

Give a ladder of cost-versus-quality points, and always keep something running. PLD’s deepest idea for developer experience is that you should never be stuck waiting with nothing to test. Its three levels form a ladder — seconds on a softcore for functional debugging, minutes on FPGA pages for hardware refinement, hours for the final optimized design — and at every rung the developer holds a running application they can validate and measure, moving up only as they invest more time. Offering a spectrum of cost-versus-quality operating points, and always retaining a working artifact, is the same graceful-ladder discipline the site’s scheduling and approximate-query pages use when they degrade to a cheaper mode under pressure or run a fast path first — and here the slow, flexible RISC-V overlay plays the role of the interpreter you run for fast iteration before you compile for speed. The compiler can always produce a more performant version later; it never leaves the developer without a testable one now.

From an hours-long recompile to a seconds-long loop

Making FPGA development iterate like software

Bringing separate compilation and optimization levels to FPGAs. Numbers from the paper's Alveo U50 evaluation on the Rosetta benchmarks.

Step 1 of 5

The compile wall

A whole-accelerator compile is a monolithic, NP-hard place-and-route of millions of gates, taking one to two hours (ten or more for large designs), and every edit forces a full recompile. There is no way to recompile just the part that changed, and no fast-and-rough mode for development.

placement and routing are solved by super-linear heuristics with no runtime guarantee, so cost grows fast with design size
programming an FPGA this way feels like the batch-processing era, not a modern edit-compile-debug loop

Why it works

  • Placement and routing are super-linear in design size → dividing the FPGA into independent pages turns one giant place-and-route into many small parallel ones → the incremental (-O1) build drops from hours to ten to twenty minutes.
  • An operator’s timing does not change its functional result (latency- insensitive links) → operators are independent modules that can be compiled, placed, and re-linked separately → separate compilation and linking become possible, so only changed pages are rebuilt.
  • Re-linking is only a routing change → setting a few control registers in the network interfaces reconnects operators → the connection graph can be changed by sending packets, with no recompilation.
  • Software engineers need a running artifact to iterate → a fast RISC-V softcore overlay compiles an operator in seconds → the developer always has a working application for functional debugging, before any FPGA build.
  • Peak performance still needs whole-design optimization → the monolithic -O3 path remains for the final build → the developer pays the hours-long cost only once, at the end, not on every edit.

What it costs (trade-offs and scope)

  • The fast modes trade performance for compile speed. -O1 runs through the shared linking network at 1.5 to 10x slower than the monolithic design, and -O0 on the softcore runs three to five orders of magnitude slower. Full performance still requires the -O3 build, which is as slow to compile as Vitis — this is a compile-versus-performance ladder, not a free lunch.
  • It demands a streaming-operator programming discipline. Operators must communicate only through stream FIFOs, avoid dynamic allocation and recursion, use compatible fixed-point and integer types, and not use global shared memory — real restrictions — and decomposing and sizing a program into pages is manual, with auto-partitioning left as future work.
  • Pages fragment the fabric and cost area. Pages are a fixed size on a heterogeneous fabric (memory and arithmetic columns, hardcoded blocks break the regular grid), so an operator smaller than a page wastes the rest, and the per-page network interface and FIFO links make -O1 and -O3 use more area than monolithic Vitis.
  • The linking network is a shared bottleneck. The general packet- switched overlay is tuned for broad compatibility over peak bandwidth, so an operator needing more than one network port’s throughput is limited — -O1 leaves performance on the table by design.
  • It is demonstrated on one vendor’s stack. PLD relies on Xilinx partial-reconfiguration features (hierarchical DFX, the abstract shell) and the Vitis toolchain, and its softcore is a small, slow PicoRV32, so the results and the exact mechanisms are tied to that ecosystem.

The evaluation

PLD on a Xilinx Alveo U50 (a Virtex UltraScale+ FPGA with about 751,000 look-up tables across two die regions), with 22 user pages, a 200 MHz packet-switched Butterfly-Fat-Tree network, and a PicoRV32 softcore per page, using Vitis and Vitis HLS as the backend, compiling on a Slurm cluster, on the Rosetta benchmark suite (3D rendering, digit recognition, spam filtering, optical flow, face detection, and a binarized neural network), against monolithic Vitis and against software emulation.

Compiling an FPGA accelerator

PropertyMonolithic compile (Vitis)PLD -O1 (FPGA pages)PLD -O0 (softcore)
Compile time
What recompiles
Runs on
Performance
Use
Monolithic compilation gives the best design but takes hours and rebuilds everything on any change. PLD adds a ladder: -O1 compiles changed FPGA pages in minutes (4.2 to 7.3x faster) for incremental refinement on real hardware, and -O0 compiles operators to a softcore in seconds for instant functional debugging. A full-quality -O3 path (not shown) still compiles monolithically in hours, matching or beating native quality — so the developer always has a running application and pays the hours-long cost only at the end.Underlined values explain themselves when clicked.

Check yourself

Check your understanding

  1. 1. PLD divides the FPGA into independent "pages" and compiles each separately. Predict why this makes the build so much faster than compiling the whole design at once.

  2. 2. PLD's separate compilation relies on the operators being connected by "latency-insensitive" FIFO links. Predict why that timing-insensitivity is the essential enabler.

  3. 3. PLD offers three optimization levels (-O0 seconds, -O1 minutes, -O3 hours) and stresses that the developer always has a running application. Predict why that "always running" property matters so much.

  4. 4. The core of PLD is importing ideas from software compilers — separate compilation, linking, optimization levels — into FPGA tooling. Predict what makes this kind of cross-domain borrowing powerful.

Sources

Related papers on Accelerators & Hardware Design

See all 118 →