Building a Flowgraph#
A flowgraph in SiliconCompiler defines the sequence of steps (or tasks) required to transform your hardware design from source code into a physical layout. Think of it as a recipe for your project, where each step is a specific tool run (like synthesis or place-and-route).
Flowgraphs are highly flexible and allow you to create custom compilation flows tailored to your specific needs. You can build them in two primary ways:
Instantiate Flowgraph: For simple or dynamically generated flows, you can create an object directly from the
Flowgraphclass and configure it.Subclass Flowgraph: For creating reusable, complex flows, you can define your own Python class that inherits from
Flowgraph.
Once defined, you load your flowgraph into a project using the Project.set_flow() method before starting a run. This tells SiliconCompiler which set of tasks to execute.
A complete set of supported builtin flows can be found in flows.
Key Concepts#
Before we build a flowgraph, let’s define the core components:
Node: A node represents a single task or step in the flow. Each node is typically an instance of a Task class, which wraps a specific EDA tool (e.g., Yosys for synthesis, OpenROAD for place-and-route).
Edge: An edge defines a dependency between two nodes. If you create an edge from nodeA to nodeB, it means that nodeA must complete successfully before nodeB can begin. This creates the directed, acyclic graph that SiliconCompiler executes.
Example: A Basic Synthesis Flow#
Here’s how to build a simple flow that elaborates Verilog, runs synthesis, and then performs a timing analysis.
This example demonstrates the fundamental node() and edge() API calls.
We’ll create a new class called SynthesisFlow that inherits from Flowgraph.
# Import the base class and the specific tool tasks we need.
from siliconcompiler import Flowgraph
from siliconcompiler.tools.yosys import syn_asic
from siliconcompiler.tools.opensta import timing
from siliconcompiler.tools.slang import elaborate
class SynthesisFlow(Flowgraph):
"""
A simple synthesis flow that demonstrates the basic principles
of creating a SiliconCompiler flowgraph.
"""
def __init__(self):
# It's important to call the parent constructor and give the flow a name.
super().__init__("synthesis_flow")
# Step 1: Create the nodes for our flow.
# Each node is given a name (e.g., "elaborate") and is associated
# with a Task object that knows how to run a specific tool.
self.node("elaborate", elaborate.Elaborate())
self.node("synthesis", syn_asic.ASICSynthesis())
self.node("timing", timing.TimingTask())
# Step 2: Create the edges to define the execution order.
# This tells SiliconCompiler that 'elaborate' must run before 'synthesis',
# and 'synthesis' must run before 'timing'.
self.edge("elaborate", "synthesis")
self.edge("synthesis", "timing")
To use this flow, you would instantiate it and set it in your project:
import siliconcompiler
# Create a project
project = siliconcompiler.Project()
# Instantiate and set the flow
flow = SynthesisFlow()
project.set_flow(flow)
# Now you can configure the rest of your project and run it.
# project.run()
Useful APIs#
The Flowgraph class provides a rich API for creating, modifying, and inspecting flowgraphs.
Create a Flowgraph#
These are the fundamental methods for building the graph structure.
Modifying a Flowgraph#
These methods allow you to alter an existing flowgraph, which is useful for dynamically adjusting a pre-defined flow.
Removes a flowgraph node and reconnects its inputs to its outputs. |
|
Inserts a new node in the graph immediately before a specified node. |
|
Instantiates a sub-flowgraph within the current flowgraph. |
Inspecting a Flowgraph#
These methods help you understand the structure and execution order of your flow.
Returns a sorted tuple of all nodes defined in this flowgraph. |
|
Collects all nodes that are entry points to the flowgraph. |
|
Collects all nodes that are exit points of the flowgraph. |
|
Generates a topologically sorted list of nodes for execution. |
|
Returns the nodes that the given node provides input to (its children). |
|
Checks if the flowgraph is valid. |
|
Returns the imported Python Task class for a given task node. |
|
Returns all unique task classes used in this flowgraph. |
|
Renders and saves the compilation flowgraph to a file. |
Documentation#
This method helps you generate documentation for your custom flow.
Generate the documentation representation for this schema. |
Class Reference#
For more detailed information, refer to the full API documentation for the primary classes involved in creating and managing flowgraphs.
Flowgraph#
Class siliconcompiler.Flowgraph
Creates a directed edge from a tail node to a head node. |
|
Returns all unique task classes used in this flowgraph. |
|
Collects all nodes that are entry points to the flowgraph. |
|
Generates a topologically sorted list of nodes for execution. |
|
Collects all nodes that are exit points of the flowgraph. |
|
Get the flowgraph node for this step and index |
|
Returns the nodes that the given node provides input to (its children). |
|
Returns a sorted tuple of all nodes defined in this flowgraph. |
|
Returns the imported Python Task class for a given task node. |
|
Instantiates a sub-flowgraph within the current flowgraph. |
|
Inserts a new node in the graph immediately before a specified node. |
|
Creates or updates a flowgraph node. |
|
Removes a flowgraph node and reconnects its inputs to its outputs. |
|
Checks if the flowgraph is valid. |
|
Renders and saves the compilation flowgraph to a file. |
Supporting Classes#
These classes are used internally by the flowgraph but can be useful to understand.
FlowgraphNodeSchema#
Class siliconcompiler.flowgraph.FlowgraphNodeSchema
Adds command-line arguments specific to this node. |
|
Sets a goal for a specific metric for this node. |
|
Sets a weight for a specific metric for this node. |
|
Gets the list of command-line arguments for this node. |
|
Gets the goal for a specific metric for this node. |
|
Gets the list of input nodes (dependencies) for this node. |
|
Gets the task associated with this node. |
|
Gets the fully qualified Python module/class for this node's task. |
|
Gets the tool associated with this node. |
|
Gets the weight for a specific metric for this node. |
|
Checks if this node has any inputs. |
RuntimeFlowgraph#
Class siliconcompiler.flowgraph.RuntimeFlowgraph
Finds all nodes in this runtime graph that have successfully completed. |
|
Returns the entry nodes for this runtime graph. |
|
Returns the execution order of the nodes in this runtime graph. |
|
Returns the exit nodes for this runtime graph. |
|
Gets the inputs for a specific node in the runtime graph. |
|
Returns the nodes that are part of this runtime graph. |
|
Returns all nodes reachable from a given starting node in this runtime graph. |
|
Validates runtime options against a flowgraph. |