Build for an FPGA#
SiliconCompiler compiles to FPGA bitstreams as well as to GDSII, through the same schema, the same flowgraph and the same run. What changes is the project type, the thing you target, and the artifact you get back.
For a lot of readers this is the easier on-ramp: an FPGA flow needs no PDK, no foundry agreement and no tapeout budget, and the open-source toolchain for Lattice iCE40 parts is a package-manager install away.
ASIC |
FPGA |
|
|---|---|---|
Project type |
||
What you target |
a PDK and standard cell libraries |
an |
How you target it |
|
|
Extra constraints |
SDC timing constraints |
SDC, plus a pin-assignment file (PCF/XDC) |
Output |
GDSII |
a bitstream |
Check your install first#
The FPGA equivalent of the ASIC demo builds an 8-bit counter onto a small open architecture called z1000:
python -m siliconcompiler.demos.fpga_demo
It runs Yosys for synthesis, VPR for place-and-route and OpenSTA for timing, so a clean run tells you that half of your toolchain is working. z1000 is a demo architecture – 2K LUTs, no hard macros – and exists to be a self-test, not a part you would ship to.
A real part: blinky on an iCE40#
examples/blinky builds a bitstream for a Lattice iCE40 UP5K, the part on an iCEBreaker board:
design = Design("blinky")
# Set up a 'dataroot' to easily reference local files.
design.set_dataroot("blinky", __file__)
# Configure the "rtl" (Register-Transfer Level) fileset.
with design.active_dataroot("blinky"), design.active_fileset("rtl"):
design.set_topmodule("blinky")
design.add_file("blinky.v")
# Configure the "pcf" (Physical Constraints File) fileset.
# This is a crucial file for FPGAs. It maps the ports in the Verilog
# design (e.g., 'clk', 'led') to the physical pins on the FPGA.
with design.active_dataroot("blinky"), design.active_fileset("pcf"):
design.add_file("icebreaker.pcf")
# --- Project Setup ---
# Create an FPGA, which is tailored for FPGA-specific needs.
project = FPGA(design)
# Tell the project which filesets are required for this compilation.
project.add_fileset("rtl")
project.add_fileset("pcf")
# --- FPGA Target Configuration ---
# Apply this FPGA configuration to the project.
project.set_fpga(ICE40Up5k_sg48())
# --- Flow Loading ---
# Set the compilation flow. The FPGANextPNRFlow is a pre-built flow
# that uses open-source tools like Yosys for synthesis and nextpnr
# for place-and-route.
project.set_flow(fpgaflow.FPGANextPNRFlow())
Three things differ from an ASIC script:
A second constraint fileset.
pcfis a fileset holding the pin-constraint file, which maps ports in your Verilog onto physical pins on the package. Without it the tools have no idea whereledgoes.A device instead of a target.
FPGA.set_fpga()takes anFPGADevice– hereICE40Up5k_sg48, shipped insiliconcompiler.fpgas. The device carries the architecture description, the primitives Yosys may map to and the timing models, which is what a PDK plus a cell library does on the ASIC side.An FPGA flow. FPGANextPNRFlow is Yosys plus nextpnr plus
icepack.
Run it:
cd examples/blinky
python blinky.py
The summary reports resource utilisation – LUTs, flip-flops, carry cells – rather than cell area, because those are the numbers that decide whether a design fits.
Which flow#
Flow |
Tools |
For |
|---|---|---|
yosys, nextpnr, icepack |
Lattice iCE40 and similar open-toolchain parts |
|
yosys, VPR |
Research and custom architectures described in VPR’s XML |
|
the above, plus OpenSTA |
The same, when you also want timing analysis |
|
Vivado |
Xilinx parts; needs a Vivado licence |
examples/heartbeat carries a Xilinx target alongside its ASIC ones, so the
same design goes to an Artix-7 with smake fpga.
Installing the tools#
sc-install has an FPGA group:
sc-install -group fpga
That covers sv2v, yosys, wildebeest, vpr and opensta – the
VPR path. It does not include nextpnr or icepack, which the iCE40
example above needs; install those from your package manager or the
nextpnr and
icestorm projects.
See External Tools for what is script-installable on your platform, and Docker to skip installing entirely. Vivado is a vendor tool and has to be installed and licensed separately.
Defining your own device#
FPGADevice is a library – it derives from the same base as a standard
cell library – so describing a new part is the job covered by
Defining a Library, and packaging one to share is
Packaging an External Library.
For a complete worked device, read siliconcompiler/demos/fpga_demo.py: Z1000
sets the LUT size, the register types Yosys may infer, the VPR architecture and
routing-graph files, and the Liberty models OpenSTA reads.
Next#
Lint your RTL – faster still, and needs nothing installed.
Example designs –
blinkyand the rest, with what each one needs.Compilation Process – how a flow is put together, if you want to build your own.