The OpenLane Directory Structure
With OpenLane and the PDK installed, the temptation is to point the flow at some RTL immediately and see what happens. Resist it for one more article. Knowing where things live before you run anything means every log message, output path and error the course throws at you later will make sense in terms of a tree you built yourself, not a structure a tool generated.
Three places that matter
An OpenLane install has three locations worth knowing cold:
designs/: every design you point OpenLane at lives here, one subfolder per design, each holding that design’s RTL and itsconfig.json.- The PDK root, wherever
volare enableinstalled it, referenced through thePDK_ROOTenvironment variable: the SKY130 data from the previous article, libraries, rule decks, models. runs/<run-tag>/, created fresh inside a design’s folder each time you run the flow, holding that run’s outputs by stage (synthesis/,floorplan/and so on, as introduced in the orchestrator article of Section 1.2).
The separation this enforces is useful. Your design’s input (RTL, config) is in one place, the process data (PDK) is in a shared location every design references but none owns, and each run’s output is in its own fresh folder. Re-running never overwrites your source, and you can keep several run tags side by side to compare.
Build a design folder by hand
Rather than let OpenLane’s scaffolding create this, build it once yourself so the shape is something you typed rather than something that appeared:
cd designs
mkdir -p my_first_design/src
touch my_first_design/src/my_first_design.v
touch my_first_design/config.json
That is the whole expected shape:
designs/my_first_design/
├── src/
│ └── my_first_design.v # RTL source
└── config.json # design-specific OpenLane configuration
src/ holds the Verilog for the design; in the next article it becomes a small counter. config.json tells OpenLane everything about this design: its name, which RTL files to read, timing constraints, and the physical design knobs you previewed in Section 1.3 (STD_CELL_LIBRARY) and will build in Section 1.5.
This two-piece structure, a src/ folder plus one config.json, is what every design in the course uses, including the ALU, UART and RISC core in Module 10. A common “why won’t my design even start” problem for newcomers is RTL placed in the design’s top folder instead of src/, or config.json named something else. The default flow expects this structure, and deviating from it without reconfiguring the relevant fields will stop the flow before it begins.
Practice Exercise
You want to keep two versions of a design’s RTL, the original and an experimental rewrite, without OpenLane confusing which one a run used. Using the three-location structure, describe a clean way to organise this.
Solution
Two separate design folders under designs/, say designs/my_first_design/ and designs/my_first_design_v2/, each with its own src/ and config.json, even if the configs are nearly identical apart from DESIGN_NAME. Because runs/<run-tag>/ is created per design, running the flow on each produces two cleanly separate run trees with no risk of one design’s outputs being confused with the other’s. This is better than keeping two RTL files in one src/ and switching between them by config edits, which invites exactly the “which version produced this run” ambiguity the separate folders avoid.
In the next article we take the design folder you just built and run a real design through the complete, unmodified OpenLane flow, start to finish.