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

ASIC

FPGA

What you target

a PDK and standard cell libraries

an FPGADevice – one part

How you target it

target(project)

project.set_fpga(...)

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. pcf is 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 where led goes.

  • A device instead of a target. FPGA.set_fpga() takes an FPGADevice – here ICE40Up5k_sg48, shipped in siliconcompiler.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

FPGANextPNRFlow

yosys, nextpnr, icepack

Lattice iCE40 and similar open-toolchain parts

FPGAVPRFlow

yosys, VPR

Research and custom architectures described in VPR’s XML

FPGAVPROpenSTAFlow

the above, plus OpenSTA

The same, when you also want timing analysis

FPGAXilinxFlow

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#