rules_vivado: FPGA Synthesis and Place-and-Route in Bazel
rules_vivado drives the AMD/Xilinx Vivado FPGA toolchain from
Bazel: VHDL and Verilog compile, elaborate, simulate, synthesize,
place-and-route, generate a bitstream, and program the device, all as hermetic
Bazel build actions rather than clicks in a GUI or a pile of ad-hoc TCL. This
is the module that turns the Cocoapuffs board flow into bazel build.
This post kicks off a short series. Over the Cocoapuffs project and
its parent repo a200t_examples I ended up writing a fair number of Bazel
modules to make an FPGA-based RISC-V system reproducible from source. I have
written about some already (rules_ghdl, rules_shar,
fshlib, bazel-ebook, and build-in-docker); over the coming
months I will cover the rest, one module per post: this one, then grlib,
rules_fusesoc, rules_dtc, OpenSBI, rules_osvvm, rules_vunit, vhdl_ls_gen, and
gotopt2.
What it does
Vivado is a large, license-encumbered, GUI-and-TCL-centric tool, which is
exactly the kind of thing Bazel usually cannot touch. rules_vivado runs the
Vivado tools inside a locally-built Docker container (the same
“build-in-docker” idea behind my bid rules; the container image setup
itself is delegated to Andrew Goessling’s rules_vivado), so an otherwise
monolithic EDA flow becomes reproducible and incremental.
The rule set is broad. The ones I lean on most:
vivado_librarycompiles VHDL/Verilog sources into a named Vivado logical library, with a selectable VHDL standard anddepson other libraries.vivado_simulationandvivado_testrun an XSim behavioral simulation, the latter wired as a self-checking Bazeltest.vivado_synthesisandvivado_place_and_routetake RTL to a routed design and a bitstream.vivado_program_deviceandvivado_program_flashpush the result onto an attached FPGA over the hw_server.vivado_ipconfigures a parameterized AMD IP block, andvivado_unisims_librarybuilds the Xilinx UNISIM primitives for simulation.
There are also niceties like vivado_ila/vivado_read_ila for an Integrated
Logic Analyzer, and vivado_repl/vivado_gui for an interactive TCL prompt
inside the container.
In a200t_examples
This is the primary synthesis and simulation backend for the Artix-7
xc7a200t. The board flow lives in boards/noelv/tool.vivado: vivado_library
targets assemble the SoC from grlib and local IP, then :sim, :synth,
:pnr, and :prog form the sim to bitstream to programming chain. Board-level
generics splice the firmware images (the SERV loader and NOEL-V boot images)
into the RTL. Across the repo there are dozens of vivado_library targets and
a couple dozen vivado_simulation runs, many of them boot-debug traces from
the Zircon bring-up.
Prior art and references
- agoessling/rules_vivado is the predecessor that requires a host Vivado install; my rules build on it for the container setup.
- hw-bzl/rules_vivado is an independent set of Vivado Bazel rules.
- bazel_rules_hdl is the broad “EDA under Bazel” precedent (Verilator, Yosys, OpenROAD).
- FuseSoC and Edalize solve the same “assemble and drive an FPGA flow” problem outside Bazel.
For the payoff, see From zero to RISC-V in hardware in 6 minutes and the Cocoapuffs post. The source is at filmil/bazel_rules_vivado, published through my Bazel registry.