Defining a Target#
A target in SiliconCompiler is a reusable “build configuration” for a specific type of project. Think of it as a master recipe that bundles together everything needed to compile a design for a particular goal, such as creating a low-power IoT chip on the Skywater 130nm process or a high-performance block on FreePDK45.
Targets are implemented as simple Python functions that configure a Project object. They are loaded by directly calling the function and passing in the project to configure, making it incredibly easy to set up a complex build.
A full list of built-in targets can be found on the targets page.
Why Create a Target?#
While you can configure a project’s PDK, flow, and libraries manually, creating a target is the recommended approach for any serious project. The benefits include:
Encapsulation: It bundles all technology-specific and flow-specific settings into one place.
Reusability: The same target can be used across multiple designs, ensuring consistency.
Simplicity: It reduces a complex setup process to a single line of code in your build script.
Anatomy of a Target Function#
A target is a Python function that accepts a Project object as its first argument. Inside this function, you will typically perform the following actions:
Load Core Components: Set the fundamental building blocks of your compilation:
PDK: The process design kit for the manufacturing technology.
Flow: The sequence of EDA tool steps to run (e.g., synthesis, place-and-route).
Libraries: The standard cell libraries and/or macros to use.
Set Default Constraints: Define the default goals and physical constraints for the design.
Timing Constraints: Clock speeds, I/O delays, and other performance goals.
Physical Constraints: Desired die area, core utilization (density), and pin placement.
Configure Tool Options: Set default options for specific tools in the flow, such as the number of cores to use for a given step.
Example: A Target for a Simple ASIC#
Let’s create a target for a generic ASIC design. This function will load a standard ASIC flow, a fictional PDK and library, and set some common physical and timing constraints.
from siliconcompiler import ASIC
from siliconcompiler.flows import asicflow
from siliconcompiler.tools.yosys import syn_asic
# It's common practice to import the PDK and library schemas
# that your target will use.
from my_designs.pdks import my_freepdk45
from my_designs.libs import my_nangate45
def my_asic_target(project: ASIC,
# Targets can be parameterized. Here, we allow the user
# to specify the number of cores for parallelizable steps.
place_np=1,
route_np=1):
'''
A simple target for a generic 45nm ASIC design.
'''
# 1. Load Core Components
# The order is important: load libraries and PDK first, then the flow.
project.set_mainlib(my_nangate45.Nangate45())
project.set_pdk(my_freepdk45.FreePDK45())
project.set_flow(asicflow.ASICFlow(place_np=place_np, route_np=route_np))
# 2. Set Default Constraints
# Timing Constraints: Define a "typical" corner for setup/hold analysis.
# This sets the performance goals for the design.
scenario = project.constraint.timing.make_scenario("typical")
scenario.add_libcorner("typical")
scenario.set_pexcorner("typical")
scenario.add_check(["setup", "hold"])
# Physical Constraints: Define the physical layout goals.
# Here, we aim for 40% core utilization and a 1-micron margin.
area = project.constraint.area
area.set_density(40)
area.set_coremargin(1)
# 3. Configure Tool Options
syn_asic.ASICSynthesis.find_task(project).set_strategy("AREA3")
How to Use the Target#
Once the target function is defined, you can load it into your project like this:
import siliconcompiler
# Create a project
project = siliconcompiler.ASIC()
# Load the entire configuration by calling the target function.
# We can also pass values for the parameterized arguments.
my_asic_target(project, place_np=4, route_np=4)
# Now the project is fully configured and ready to run!
# project.run()
Next Steps#
A target is composed of other SiliconCompiler modules. To build effective targets, you will need to understand how to define these components: