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:

  1. Instantiate Flowgraph: For simple or dynamically generated flows, you can create an object directly from the Flowgraph class and configure it.

  2. 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.

node

Creates or updates a flowgraph node.

edge

Creates a directed edge from a tail node to a head node.

Modifying a Flowgraph#

These methods allow you to alter an existing flowgraph, which is useful for dynamically adjusting a pre-defined flow.

remove_node

Removes a flowgraph node and reconnects its inputs to its outputs.

insert_node

Inserts a new node in the graph immediately before a specified node.

graph

Instantiates a sub-flowgraph within the current flowgraph.

Inspecting a Flowgraph#

These methods help you understand the structure and execution order of your flow.

get_nodes

Returns a sorted tuple of all nodes defined in this flowgraph.

get_entry_nodes

Collects all nodes that are entry points to the flowgraph.

get_exit_nodes

Collects all nodes that are exit points of the flowgraph.

get_execution_order

Generates a topologically sorted list of nodes for execution.

get_node_outputs

Returns the nodes that the given node provides input to (its children).

validate

Checks if the flowgraph is valid.

get_task_module

Returns the imported Python Task class for a given task node.

get_all_tasks

Returns all unique task classes used in this flowgraph.

write_flowgraph

Renders and saves the compilation flowgraph to a file.

Documentation#

This method helps you generate documentation for your custom flow.

make_docs

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

Flowgraph.edge

Creates a directed edge from a tail node to a head node.

Flowgraph.get_all_tasks

Returns all unique task classes used in this flowgraph.

Flowgraph.get_entry_nodes

Collects all nodes that are entry points to the flowgraph.

Flowgraph.get_execution_order

Generates a topologically sorted list of nodes for execution.

Flowgraph.get_exit_nodes

Collects all nodes that are exit points of the flowgraph.

Flowgraph.get_graph_node

Get the flowgraph node for this step and index

Flowgraph.get_node_outputs

Returns the nodes that the given node provides input to (its children).

Flowgraph.get_nodes

Returns a sorted tuple of all nodes defined in this flowgraph.

Flowgraph.get_task_module

Returns the imported Python Task class for a given task node.

Flowgraph.graph

Instantiates a sub-flowgraph within the current flowgraph.

Flowgraph.insert_node

Inserts a new node in the graph immediately before a specified node.

Flowgraph.node

Creates or updates a flowgraph node.

Flowgraph.remove_node

Removes a flowgraph node and reconnects its inputs to its outputs.

Flowgraph.validate

Checks if the flowgraph is valid.

Flowgraph.write_flowgraph

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

FlowgraphNodeSchema.add_args

Adds command-line arguments specific to this node.

FlowgraphNodeSchema.add_goal

Sets a goal for a specific metric for this node.

FlowgraphNodeSchema.add_weight

Sets a weight for a specific metric for this node.

FlowgraphNodeSchema.get_args

Gets the list of command-line arguments for this node.

FlowgraphNodeSchema.get_goal

Gets the goal for a specific metric for this node.

FlowgraphNodeSchema.get_input

Gets the list of input nodes (dependencies) for this node.

FlowgraphNodeSchema.get_task

Gets the task associated with this node.

FlowgraphNodeSchema.get_taskmodule

Gets the fully qualified Python module/class for this node's task.

FlowgraphNodeSchema.get_tool

Gets the tool associated with this node.

FlowgraphNodeSchema.get_weight

Gets the weight for a specific metric for this node.

FlowgraphNodeSchema.has_input

Checks if this node has any inputs.

RuntimeFlowgraph#

Class siliconcompiler.flowgraph.RuntimeFlowgraph

RuntimeFlowgraph.get_completed_nodes

Finds all nodes in this runtime graph that have successfully completed.

RuntimeFlowgraph.get_entry_nodes

Returns the entry nodes for this runtime graph.

RuntimeFlowgraph.get_execution_order

Returns the execution order of the nodes in this runtime graph.

RuntimeFlowgraph.get_exit_nodes

Returns the exit nodes for this runtime graph.

RuntimeFlowgraph.get_node_inputs

Gets the inputs for a specific node in the runtime graph.

RuntimeFlowgraph.get_nodes

Returns the nodes that are part of this runtime graph.

RuntimeFlowgraph.get_nodes_starting_at

Returns all nodes reachable from a given starting node in this runtime graph.

RuntimeFlowgraph.validate

Validates runtime options against a flowgraph.