Bringing Your Own Design#
The demo builds someone else’s design. This page is the next question: you have RTL of your own, and you want to compile it.
There are four things to tell SiliconCompiler, and nothing else is required to start.
1. Describe the design#
A Design is a top module plus the filesets holding
its sources. Sources go in rtl; timing constraints go in sdc, separately,
because they change with the technology and the RTL does not:
from siliconcompiler import Design
design = Design("mydesign")
design.set_dataroot("root", __file__)
with design.active_dataroot("root"), design.active_fileset("rtl"):
design.set_topmodule("mydesign")
design.add_file("mydesign.v")
design.add_file("submodule.v")
with design.active_dataroot("root"), design.active_fileset("sdc"):
design.add_file("mydesign.sdc")
Design.set_dataroot() with __file__ makes every path relative to the
script, so the design still builds when someone clones it somewhere else. That
is worth doing from the start – see dataroot for the other
kinds, including sources fetched from a git repository at a pinned commit.
Parameters and defines belong to the fileset too:
design.set_param("WIDTH", "32", fileset="rtl")
design.add_define("SYNTHESIS", fileset="rtl")
2. Check it before you build#
assert design.check_filepaths()
Ten seconds here saves a failed run later; unresolvable paths are the most common first failure. Then lint it, which needs no tools at all and catches the next tier of problem:
from siliconcompiler import Lint
from siliconcompiler.flows.lintflow import LintFlow
project = Lint(design)
project.add_fileset("rtl")
project.set_flow(LintFlow())
project.run()
See Lint your RTL. Do not skip this: synthesis error messages are much worse than lint error messages.
3. Pick a technology#
A target bundles the PDK, the standard cell libraries and the tool setup. Start with an open one – you can change it later without touching the design:
from siliconcompiler import ASIC
from siliconcompiler.targets import freepdk45_demo
project = ASIC(design)
project.add_fileset("rtl")
project.add_fileset("sdc")
freepdk45_demo(project)
Target |
Use when |
|---|---|
You want fast results and are not taping out. A fictional 45nm process, so timing numbers are indicative, not real. |
|
You want an open PDK that real silicon has been made in. Slower. |
|
You want to see behaviour at an advanced node. Predictive, not manufacturable. |
|
Other open PDKs with real foundry paths. |
Constraints your design will probably need:
project.constraint.area.set_dieoutline(500, 500, coremargin=10)
Without a die area the floorplanner picks one from a utilisation target, which is fine until you have macros – see Instantiating a hardened module.
4. Run it#
project.run()
project.summary()
The summary is the first thing to read, and When a run fails is the second.
Then what?#
The interesting part starts once it builds. Common next steps, in the order people usually need them:
You want to |
Go to |
|---|---|
Use RTL from another repository |
Building Your Own SoC – dataroots pinned to a commit |
Compose your design from another design |
Building Your Own SoC – |
Use an SRAM or another hard macro |
|
Try several settings and keep the best |
Parallel Job Execution – index parallelism |
Sweep a parameter and compare |
|
Compile from VHDL, Bluespec, Chisel or Migen |
|
Target an FPGA instead |
|
Not install any EDA tools |
Docker, or a remote run |
See also
Example designs – a working script for nearly every row above, and How do I…? for the one-off questions that come up along the way.