mirror of
https://github.com/The-OpenROAD-Project/OpenLane.git
synced 2026-05-29 00:23:55 +08:00
Documentation Restructure (#1337)
~ Documentation all moved under `docs/source`, arranged hierarchically according to the table of contents ~ `Klayout` changed to `KLayout` in all logging messages ~ Readme rewritten to just be concise, parts of it isolated into standalone documentation ~ RTD builds no longer use conda (saves some time) ~ Fixed all broken links
This commit is contained in:
269
docs/source/usage/advanced_power_grid_control.md
Normal file
269
docs/source/usage/advanced_power_grid_control.md
Normal file
@@ -0,0 +1,269 @@
|
||||
> Note: Information in this document may be out of date. It's always a good idea to take a look at the canonical documentation for OpenROAD's pdngen utility: https://openroad.readthedocs.io/en/latest/main/src/pdn/README.html
|
||||
|
||||
# Power Grid/Power Distribution Network
|
||||
|
||||
In this document we will discuss the advanced controls for power grid, and how to utilize the default PDN script to automatically power a complex design without the need to write a custom `pdn.tcl` script or learning `pdngen` tool syntax.
|
||||
|
||||
The power decision flow in this document will go top to bottom, meaning that we will start at the chip level and then go down to the internal macros.
|
||||
|
||||
An example utilizing the controls and logic provided in this documentation is [caravel](https://github.com/efabless/caravel).
|
||||
|
||||
> **Note**: When we say "your configurations" in this documentation we are refering to the `config.json` or `config.tcl` for that specific block.
|
||||
|
||||
## Chip Level
|
||||
|
||||
According to the current methodology of [OpenLane Chip Integration][0], the process goes as follows:
|
||||
1. Hardening the hard/internal macros.
|
||||
2. Hardening the core with the hard macros inside it.
|
||||
3. Hardening the full chip with the padframe and the chip core.
|
||||
|
||||
Therefore at the top level typically you only have the core block. All you need to do in that step is to verify that the power pads are in the middle of each padframe side, and then add this line to your interactive script: `power_routing` After legalization and before signal routing. However, this only supports a single power domain. Otherwise, you need to manually connect the power pads to the core ring of your core module.
|
||||
|
||||
## Core Level
|
||||
|
||||
Let's clarify here, before delving into details, that with each hierarchy level you lose one routing metal layer. For example, in the skywater pdk the metal stack has 5 layers, thus for the core level you can use all layers up to met5; however, if you have another macro inside your core, that macro can only use up to met4, and so forth.
|
||||
|
||||
The first decision to make at the core level is the core ring. So first, you need to know how many power domains do you need to use, and so how many core rings do you require. This can be easily set by the following configurations:
|
||||
|
||||
<table>
|
||||
<tr><th>JSON</th><th>Tcl</th></tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```json
|
||||
"DESIGN_IS_CORE": true,
|
||||
"FP_PDN_CORE_RING": true,
|
||||
"VDD_NETS": "vccd1 vccd2 vdda1 cdda2",
|
||||
"GND_NETS": "vssd1 vssd2 vssa1 vssa2",
|
||||
"SYNTH_USE_PG_PINS_DEFINES": "USE_POWER_PINS"
|
||||
|
||||
```
|
||||
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```tcl
|
||||
set ::env(DESIGN_IS_CORE) 1
|
||||
set ::env(FP_PDN_CORE_RING) 1
|
||||
set ::env(VDD_NETS) [list {vccd1} {vccd2} {vdda1} {vdda2}]
|
||||
set ::env(GND_NETS) [list {vssd1} {vssd2} {vssa1} {vssa2}]
|
||||
set ::env(SYNTH_USE_PG_PINS_DEFINES) "USE_POWER_PINS"
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Here we're requiring 4 power domains. For each `VDD_NETS` there is a corresponding `GND_NETS`. Those net names must also exist in the RTL and must be connected to each hard macro inside your core explicitly in the RTL, and those must be guarded with the value given to `SYNTH_USE_PG_PINS_DEFINES`. If the internal modules are going to be flattened, then there is no need to reflect this connection in the RTL for those modules that will be flattened with the core module. For the example above, Here is the required RTL reflection:
|
||||
|
||||
```verilog
|
||||
`ifdef USE_POWER_PINS
|
||||
inout vdda1, // User area 1 3.3V supply
|
||||
inout vdda2, // User area 2 3.3V supply
|
||||
inout vssa1, // User area 1 analog ground
|
||||
inout vssa2, // User area 2 analog ground
|
||||
inout vccd1, // User area 1 1.8V supply
|
||||
inout vccd2, // User area 2 1.8v supply
|
||||
inout vssd1, // User area 1 digital ground
|
||||
inout vssd2, // User area 2 digital ground
|
||||
`endif
|
||||
```
|
||||
|
||||
Then for the hard macro instatiations:
|
||||
|
||||
```verilog
|
||||
`ifdef USE_POWER_PINS
|
||||
.vdda1(vdda1), // User area 1 3.3V power
|
||||
.vdda2(vdda2), // User area 2 3.3V power
|
||||
.vssa1(vssa1), // User area 1 analog ground
|
||||
.vssa2(vssa2), // User area 2 analog ground
|
||||
.vccd1(vccd1), // User area 1 1.8V power
|
||||
.vccd2(vccd2), // User area 2 1.8V power
|
||||
.vssd1(vssd1), // User area 1 digital ground
|
||||
.vssd2(vssd2), // User area 2 digital ground
|
||||
`endif
|
||||
```
|
||||
Note that net and pin names must be matching.
|
||||
|
||||
By simply adding these you should now have 8 core rings, 4 for power and 4 for ground. To control the spacing and the power grid for these by changing the following:
|
||||
|
||||
<table>
|
||||
<tr><th>JSON</th><th>Tcl</th></tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```json
|
||||
"FP_PDN_CORE_RING_VWIDTH": 3,
|
||||
"FP_PDN_CORE_RING_HWIDTH": "expr::$FP_PDN_CORE_RING_VWIDTH",
|
||||
"FP_PDN_CORE_RING_VOFFSET": 14,
|
||||
"FP_PDN_CORE_RING_HOFFSET" "expr::$FP_PDN_CORE_RING_VOFFSET",
|
||||
"FP_PDN_CORE_RING_VSPACING": 1.7,
|
||||
"FP_PDN_CORE_RING_HSPACING": "expr::$FP_PDN_CORE_RING_VSPACING"
|
||||
```
|
||||
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```tcl
|
||||
set ::env(FP_PDN_CORE_RING_VWIDTH) 3 # The vertical sides width of the core rings
|
||||
set ::env(FP_PDN_CORE_RING_HWIDTH) $::env(FP_PDN_CORE_RING_VWIDTH) # The horizontal sides width of the core rings
|
||||
set ::env(FP_PDN_CORE_RING_VOFFSET) 14 # The vertical sides offset from the design boundaries for the core rings
|
||||
set ::env(FP_PDN_CORE_RING_HOFFSET) $::env(FP_PDN_CORE_RING_VOFFSET) # The horizontal sides offset from the design boundaries for the core rings
|
||||
set ::env(FP_PDN_CORE_RING_VSPACING) 1.7 # The vertical spacing between the core ring straps
|
||||
set ::env(FP_PDN_CORE_RING_HSPACING) $::env(FP_PDN_CORE_RING_VSPACING) # The horizontal spacing between the core ring straps
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
The next values should be added as-is to control the starting point for looping over the core rings and recalculating the new offset for each core ring:
|
||||
|
||||
<table>
|
||||
<tr><th>JSON</th><th>Tcl</th></tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```json
|
||||
"FP_PDN_VSPACING": "expr::5*$FP_PDN_CORE_RING_VWIDTH",
|
||||
"FP_PDN_HSPACING": "expr::5*$FP_PDN_CORE_RING_HWIDTH",
|
||||
```
|
||||
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```tcl
|
||||
set ::env(FP_PDN_VSPACING) [expr 5*$::env(FP_PDN_CORE_RING_VWIDTH)]
|
||||
set ::env(FP_PDN_HSPACING) [expr 5*$::env(FP_PDN_CORE_RING_HWIDTH)]
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
The next step is to control the internal power grid by changing the following variables:
|
||||
|
||||
<table>
|
||||
<tr><th>JSON</th><th>Tcl</th></tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```json
|
||||
"FP_PDN_VWIDTH": 3,
|
||||
"FP_PDN_HWIDTH": 3,
|
||||
"FP_PDN_VOFFSET": 0,
|
||||
"FP_PDN_HOFFSET": "expr::$FP_PDN_VOFFSET",
|
||||
"FP_PDN_VPITCH": 180,
|
||||
"FP_PDN_HPITCH": "expr::$FP_PDN_VPITCH"
|
||||
|
||||
```
|
||||
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```tcl
|
||||
set ::env(FP_PDN_VWIDTH) 3 # The width of the vertical straps
|
||||
set ::env(FP_PDN_HWIDTH) 3 # The width of the horizontal straps
|
||||
set ::env(FP_PDN_VOFFSET) 0 # The vertical offset for the straps
|
||||
set ::env(FP_PDN_HOFFSET) $::env(FP_PDN_VOFFSET) # The horizontal offset for the straps
|
||||
set ::env(FP_PDN_VPITCH) 180 # The pitch between the vertical straps
|
||||
set ::env(FP_PDN_HPITCH) $::env(FP_PDN_VPITCH) # The pitch between the horizontal straps
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
All values above are given in microns.
|
||||
|
||||
At this stage you have automated the power grid generation for the Core Module.
|
||||
|
||||
|
||||
## Macro Level
|
||||
|
||||
For the skywater libraries the hierarchy typically can go one level down at most otherwise you will only have two routing layers, which is usually not recommended. Therefore, although it's supported, your macros will typically have no nested macros inside them.
|
||||
|
||||
To begin the configurations for your macro, you want to announce that the design is a macro inside the core, and that it doesn't have a core ring. Also, prohibit the router from using metal layer 5 by setting the maximum routing layer to metal layer 4. This is done by setting the following configs:
|
||||
|
||||
<table>
|
||||
<tr><th>JSON</th><th>Tcl</th></tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```json
|
||||
"DESIGN_IS_CORE": false,
|
||||
"FP_PDN_CORE_RING": false,
|
||||
"RT_MAX_LAYER": "met4"
|
||||
```
|
||||
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```tcl
|
||||
set ::env(DESIGN_IS_CORE) 0
|
||||
set ::env(FP_PDN_CORE_RING) 0
|
||||
set ::env(RT_MAX_LAYER) "met4"
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Then, you should use the same `VDD_NETS` and `GND_NETS` set in the core level by adding these two lines to your configuration file:
|
||||
|
||||
<table>
|
||||
<tr><th>JSON</th><th>Tcl</th></tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```json
|
||||
"VDD_NETS": "vccd1 vccd2 vdda1 cdda2",
|
||||
"GND_NETS": "vssd1 vssd2 vssa1 vssa2"
|
||||
```
|
||||
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```tcl
|
||||
set ::env(VDD_NETS) [list {vccd1} {vccd2} {vdda1} {vdda2}]
|
||||
set ::env(GND_NETS) [list {vssd1} {vssd2} {vssa1} {vssa2}]
|
||||
```
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
This should also reflected in the module declaration in that macro's RTL in the same manner as follows:
|
||||
|
||||
```verilog
|
||||
`ifdef USE_POWER_PINS
|
||||
inout vdda1, // User area 1 3.3V supply
|
||||
inout vdda2, // User area 2 3.3V supply
|
||||
inout vssa1, // User area 1 analog ground
|
||||
inout vssa2, // User area 2 analog ground
|
||||
inout vccd1, // User area 1 1.8V supply
|
||||
inout vccd2, // User area 2 1.8v supply
|
||||
inout vssd1, // User area 1 digital ground
|
||||
inout vssd2, // User area 2 digital ground
|
||||
`endif
|
||||
```
|
||||
|
||||
These should match the names used in your core level. You don't need to use all the nets, the first two nets are used by default to power the digital cells. So you may want to only include a subset of these connections, this should be reflected in the configuration files as well as the RTL.
|
||||
|
||||
- The height of each macro must be greater than or equal to the value of `$::env(FP_PDN_HPITCH)` to allow at least two metal 5 straps on the core level to cross it and all the dropping of a via from met5 to met4 connecting the vertical straps of the macro to the horizontal straps of the core and so connect the power grid of the macro to the outer core ring.
|
||||
|
||||
|
||||
|
||||
At this stage, hardening the macros first, followed by the core, and finally connecting the core rings to the power pads, your power grids and connections should be complete.
|
||||
|
||||
|
||||
[0]: ./chip_integration.md
|
||||
140
docs/source/usage/chip_integration.md
Normal file
140
docs/source/usage/chip_integration.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# Chip Level Integration
|
||||
Using OpenLane, you can produce a GDSII from a chip RTL.
|
||||
|
||||
## The Current Methodology
|
||||
|
||||
The current methodology views the chip using the following hierarchy:
|
||||
- Chip Core
|
||||
- The hard macros
|
||||
- The rest of the design
|
||||
- Chip IO
|
||||
- IO Pads
|
||||
- Power Pads
|
||||
- Corner Pads
|
||||
|
||||
The current methodology goes as follows:
|
||||
1. Hardening the hard macros.
|
||||
2. Hardening the core with the hard macros inside it.
|
||||
3. Hardening the padframe
|
||||
4. Hardening the full chip with the padframe.
|
||||
|
||||
|
||||
## Hardening Macros
|
||||
|
||||
This is discussed in more detail [here][8].
|
||||
|
||||
## Hardening The Core
|
||||
|
||||
The chip core would usually have other macros inside it.
|
||||
|
||||
You need to set the following environment variables in your configuration file for the chip core:
|
||||
|
||||
| Key | Description |
|
||||
|-|-|
|
||||
| `VERILOG_FILES` | Space-delimited list of Verilog files*. |
|
||||
| `VERILOG_FILES_BLACKBOX` | Black-box, Verilog files where the implementation is ignored. Useful for pre-hardened macros you incorporate into your design. |
|
||||
| `EXTRA_LEFS` | LEF files for pre-hardened macros you incorporate into your design. |
|
||||
| `EXTRA_LIBS` | Specifies LIB files of pre-hardened macros used in the current design, used to improve timing analysis. (Optional) |
|
||||
| `EXTRA_GDS_FILES` | GDS files for pre-hardened macros you incorporate into your design. |
|
||||
| `SYNTH_READ_BLACKBOX_LIB` | `1/0` (Tcl), `true/false` (json): Should be set to true if you're using any standard cells directly in your design, i.e., your design does not function purely at the register transfer level. |
|
||||
| `MACRO_PLACEMENT_CFG` | A path to a file containing a line-break delimited list of instances and positions if you want to manually place the macros in specific locations, in the format `instance_name X_pos Y_pos Orientation`. The [`manual_macro_placement_test` example][9] under designs should be a good example. |
|
||||
> \* The ``` `include ``` directive is not supported.
|
||||
|
||||
You can follow the same instructions provided [here][8] for the rest of the hardenning steps.
|
||||
|
||||
[Here][0] you can find a list of all the available OpenLane configuration variables.
|
||||
|
||||
## Hardening The Full Chip
|
||||
|
||||
The full chip requires an [interactive script][2] to harden. You could take this [full chip][5] as an example.
|
||||
|
||||
First you need to harden the padframe as a separate macro, check [this flow][4] as an example on how to do so.
|
||||
|
||||
You need to set ***all environment variables mentioned in [Hardening the Core](#hardening-the-core)***, but also:
|
||||
|
||||
| Key | Description |
|
||||
|-|-|
|
||||
| `SYNTH_FLAT_TOP` | `1/0` (Tcl), `true/false` (json): Flattens the padframe if true (and presented in a chip_io module). Otherwise, you can harden it separately as indicated in [this flow][4]. |
|
||||
|
||||
The following inputs are provided to produce the final GDSII:
|
||||
|
||||
1. Padframe cfg file (provided by the user or generated by padring). [Here][6] is an example. Or a hardened chip_io.gds and chip_io.lef following [this][4].
|
||||
2. Hardened lef & GDSII for the core module, generated [here](#hardening-the-core)
|
||||
3. Top level netlist instantiating pads and core module (Could be provided by the user or generated by topModuleGen)
|
||||
|
||||
[The interactive script for the IOs][4] does the following:
|
||||
- Sources configurations.
|
||||
- Elaborates the verilog.
|
||||
- Runs floorplan.
|
||||
- Uses odbpy/padringer.py to generate the padframe.
|
||||
- Adds the obstructions to the core area, and removes core nets and pins.
|
||||
- Routes.
|
||||
- Streams out the GDSII and the LEFv view.
|
||||
|
||||
Given these inputs the following [interactive script][5] script. Mainly, it does the following steps:
|
||||
- Runs the top level netlist through yosys.
|
||||
- Runs floorplan.
|
||||
- Performs manual placement of the core macros, this sample has many cores, however for full automation you should have only a single core.
|
||||
- legalize the placement.
|
||||
- Removes Nets and Pins to a different file.
|
||||
- This stages is skipped because the design has many cores and so fully automated power routing is not possible. However if you only have a single core, you can perform automatic power routing by adding `power_routing` at this stage in your interactive script.
|
||||
- Route the design.
|
||||
- Perform power routing.
|
||||
- Generate a GDSII file of the routed design.
|
||||
- Run DRC and LVS checks [here][11].
|
||||
|
||||
## Power_routing
|
||||
|
||||
### Macros
|
||||
|
||||
This is discussed in detail [here][8].
|
||||
|
||||
### Core
|
||||
|
||||
It should have an `stdcell` section that includes a `core_ring` on met4 and met5. It should use met5 and met4 for the straps, and met1 for the rails. Thus, make sure to add these to your config file:
|
||||
|
||||
<table>
|
||||
<tr><th>JSON</th><th>Tcl</th></tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```json
|
||||
"DESIGN_IS_CORE": true,
|
||||
"FP_PDN_CORE_RING": true
|
||||
```
|
||||
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```tcl
|
||||
set ::env(DESIGN_IS_CORE) 1
|
||||
set ::env(FP_PDN_CORE_RING) 1
|
||||
```
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
You can automate the power routing process in the core and macro level by reading [this documentation][10]. Otherwise, refer to [this][3] for more details about the syntax. In case you needed to create your own `pdn.tcl` then point to it using `PDN_CFG`.
|
||||
|
||||
When you use the `power_routing` command in the chip interactive script, the power pads will be connected to the core ring, and thus the whole chip would be powered.
|
||||
|
||||
## General Notes
|
||||
|
||||
[This][2] includes more guidance on how to create an interactive script.
|
||||
|
||||
[This][0] documents all OpenLane configurations.
|
||||
|
||||
[This][1] has a description for all OpenLane commands.
|
||||
|
||||
[0]: ../reference/configuration.md
|
||||
[1]: ../reference/openlane_commands.md
|
||||
[2]: ../reference/interactive_mode.md
|
||||
[3]: https://openroad.readthedocs.io/en/latest/main/src/pdn/README.html
|
||||
[4]: https://github.com/efabless/caravel/blob/9949306c42ded3cad03e1f4566d7cd1f8215b0bb/openlane/chip_io/interactive.tcl
|
||||
[5]: https://github.com/efabless/caravel/blob/9949306c42ded3cad03e1f4566d7cd1f8215b0bb/openlane/caravel/interactive.tcl
|
||||
[6]: https://github.com/efabless/caravel/blob/9949306c42ded3cad03e1f4566d7cd1f8215b0bb/openlane/chip_io/padframe.cfg
|
||||
[8]: ./hardening_macros.md
|
||||
[9]: https://github.com/The-OpenROAD-Project/openlane/tree/master/designs/manual_macro_placement_test
|
||||
[10]: ./advanced_power_grid_control.md
|
||||
[11]: https://github.com/efabless/caravel/blob/9949306c42ded3cad03e1f4566d7cd1f8215b0bb/openlane/caravel/interactive.lvs.tcl
|
||||
45
docs/source/usage/custom_pdk_builds.md
Normal file
45
docs/source/usage/custom_pdk_builds.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Custom-Building PDKs
|
||||
The pre-built version of the sky130 PDK variants included with OpenLane includes the following standard cell libraries:
|
||||
* sky130_fd_io
|
||||
* sky130_fd_pr
|
||||
* sky130_fd_sc_hd
|
||||
* sky130_fd_sc_hvl
|
||||
* sky130 sram modules
|
||||
|
||||
If you need other libraries, you will have to resort to manual builds using [Volare](https://github.com/efabless/volare) as shown below. You will need Git 2.35+ and Docker.
|
||||
|
||||
Note that this will take a while, from 20 minutes to an hour depending on your internet speed and compute power.
|
||||
|
||||
Start a venv shell using `make start-build-env`. You should see a prompt looking kind of like this:
|
||||
|
||||
```bash
|
||||
(venv) [user@host openlane]$
|
||||
```
|
||||
|
||||
First of all, install volare:
|
||||
|
||||
```bash
|
||||
pip3 install --upgrade --no-cache-dir volare
|
||||
```
|
||||
|
||||
Then, build the PDK as follows: The `-l` options are the libraries you want to include. For example, to also include `sky130_fd_sc_hs`, you can add `-l sky130_fd_sc_hs` to the default set of libraries using the following command:
|
||||
|
||||
```bash
|
||||
volare build -j$(nproc) --pdk sky130 --clear-build-artifacts --sram -l sky130_fd_io -l sky130_fd_pr -l sky130_fd_sc_hvl -l sky130_fd_sc_hd -l sky130_fd_sc_hs
|
||||
```
|
||||
|
||||
You can also add `-l all` to just include all of them:
|
||||
|
||||
```bash
|
||||
volare build -j$(nproc) --pdk sky130 --clear-build-artifacts --sram -l all
|
||||
```
|
||||
|
||||
Either way, go grab a smoothie. This will take a while.
|
||||
|
||||
After it's done, you can then enable the resulting PDK as such:
|
||||
|
||||
```bash
|
||||
volare enable
|
||||
```
|
||||
|
||||
Et voila, your custom-built PDK is ready.
|
||||
52
docs/source/usage/designs.md
Normal file
52
docs/source/usage/designs.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Adding Your Designs
|
||||
To add a new design, the following command creates a configuration file for your design:
|
||||
|
||||
```bash
|
||||
# JSON Configuration File
|
||||
./flow.tcl -design <design_name> -init_design_config -add_to_designs
|
||||
|
||||
# Tcl Configuration File
|
||||
./flow.tcl -design <design_name> -init_design_config -add_to_designs -config_file config.tcl
|
||||
```
|
||||
|
||||
This will create the following directory structure:
|
||||
|
||||
```bash
|
||||
designs/<design_name>
|
||||
├── config.json (or config.tcl)
|
||||
```
|
||||
In the configuration file (`config.json`), you should edit the required variables and the optional variables, if needed. Further information about the variables can be found [here](../reference/configuration.md).
|
||||
> Note: config.json/config.tcl is a global configuration for all PDKs and SCLs. For more information about design configuration files, including how to set up PDK/SCL-specific variables, please see [this file](../reference/configuration_files.md).
|
||||
|
||||
It is recommended to place the design's verilog files in a `src` directory inside the design's folder as following:
|
||||
|
||||
```bash
|
||||
designs/<design_name>
|
||||
├── config.tcl
|
||||
├── src
|
||||
│ ├── design.v
|
||||
```
|
||||
|
||||
However, you can point to the src files (space-delimited) while initializing the design and they will be pointed to automatically in the configuration file and will also be automatically copied to the src directory creating the same structure shown above.
|
||||
|
||||
```bash
|
||||
./flow.tcl -design <design_name> -init_design_config -add_to_designs -src "<list_verilog_files>"
|
||||
```
|
||||
|
||||
Optionally, you can specify the configuration file name by using:
|
||||
|
||||
```bash
|
||||
./flow.tcl -design <design_name> -init_design_config -add_to_designs -config_file <custom_name.tcl/custom_name.json>
|
||||
```
|
||||
|
||||
After adding the design, you can run the design using a `-design` argument:
|
||||
|
||||
```bash
|
||||
./flow.tcl -design <design_name>
|
||||
```
|
||||
|
||||
Finally, you can specify the configuration file (belonging to that design) the flow should use:
|
||||
|
||||
```bash
|
||||
./flow.tcl -design <design_name> -config_file <path_to_config_file>
|
||||
```
|
||||
117
docs/source/usage/exploration_script.md
Normal file
117
docs/source/usage/exploration_script.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# Regression & Exploration
|
||||
## Overview
|
||||
OpenLane provides `run_designs.py`, a script that can do multiple runs in a parallel using different configurations. A run consists of a set of designs and a configuration file that contains the configuration values. It is useful to explore the design implementation using different configurations to figure out the best one(s). For examples, check the [Usage](#usage) section.
|
||||
|
||||
Also, it can be used for testing the flow by running the flow against several designs using their best configurations. For example the following has two runs: spm and xtea using their default configuration files `config.tcl.` :
|
||||
```
|
||||
python3 run_designs.py --tag test --threads 3 spm xtea des aes256
|
||||
```
|
||||
## Default Test Set Results
|
||||
|
||||
You can view the results of the run against some designs (more [here](#usage)) against any of the 5 sky130 standard cell libraries through these sheets:
|
||||
|
||||
- [sky130_fd_sc_hd](https://github.com/The-OpenROAD-Project/openlane/blob/master/regression_results/benchmark_results/SW_HD.csv)
|
||||
- [sky130_fd_sc_hs](https://github.com/The-OpenROAD-Project/openlane/blob/master/regression_results/benchmark_results/SW_HS.csv)
|
||||
- [sky130_fd_sc_ms](https://github.com/The-OpenROAD-Project/openlane/blob/master/regression_results/benchmark_results/SW_MS.csv)
|
||||
- [sky130_fd_sc_ls](https://github.com/The-OpenROAD-Project/openlane/blob/master/regression_results/benchmark_results/SW_LS.csv)
|
||||
- [sky130_fd_sc_hdll](https://github.com/The-OpenROAD-Project/openlane/blob/master/regression_results/benchmark_results/SW_HDLL.csv)
|
||||
|
||||
**Note**: `flow_failed` under `flow_status` implies that the run had failed.
|
||||
|
||||
## Usage
|
||||
|
||||
- The list of flags that could be used with run_designs.py is described here [Command line arguments](#command-line-arguments). Check [columns_defintions.md](../reference/datapoint_definitions.md) for more details on the reported configuration parameters.
|
||||
|
||||
The script can be used in two ways
|
||||
|
||||
1. Running one or more designs.
|
||||
|
||||
```bash
|
||||
python3 run_designs.py --threads 4 spm xtea PPU APU
|
||||
```
|
||||
|
||||
You can run the default test set consisting of all designs under [designs](../../../designs/) through running the following command along with any of the flags:
|
||||
|
||||
```bash
|
||||
python3 run_design.py --defaultTestSet
|
||||
```
|
||||
|
||||
2. An exploration run that generates configuration files of all possible combinations of the passed regression file and runs them on the provided designs.
|
||||
|
||||
```bash
|
||||
python3 run_designs.py --regression ./scripts/config/regression.config --threads 2 spm xtea
|
||||
```
|
||||
|
||||
These parameters must be provided in the file passed to `--regression`. Any file can be used. The file used above is just an example
|
||||
|
||||
- Basic Regression Script:
|
||||
|
||||
The parameters that have multiple values inside the brackets will form the combinations. So here all combinations of GRT_ADJUSTMENT and FP_CORE_UTIL will be tried.
|
||||
|
||||
```
|
||||
GRT_ADJUSTMENT=(0.1,0.15)
|
||||
FP_CORE_UTIL=(40,50)
|
||||
PL_TARGET_DENSITY=(0.4)
|
||||
SYNTH_STRATEGY=(1,3)
|
||||
FP_PDN_VPITCH=(153.6)
|
||||
FP_PDN_HPITCH=(153.18)
|
||||
FP_ASPECT_RATIO=(1)
|
||||
SYNTH_MAX_FANOUT=(5)
|
||||
|
||||
```
|
||||
|
||||
- Complex Expressions:
|
||||
|
||||
In addition, `extra` is appended to every configuration file generated. So it is used to add some configurations specific to this regression run. The file could also contain non-white-space-separated expressions of one or more configuration variables or alternatively this could be specified in the extra section:
|
||||
|
||||
```
|
||||
FP_CORE_UTIL=(40,50)
|
||||
PL_TARGET_DENSITY=(FP_CORE_UTIL*0.01-0.1,0.4)
|
||||
|
||||
extra="
|
||||
set ::env(SYNTH_MAX_FANOUT) { $::env(FP_ASPECT_RATIO) * 5 }
|
||||
"
|
||||
```
|
||||
|
||||
- SCL-specific section
|
||||
|
||||
You can use this section to specify information that you would like to be sourced before sourcing SCL-specific information:
|
||||
|
||||
```
|
||||
FP_CORE_UTIL=(40,50)
|
||||
PL_TARGET_DENSITY=(FP_CORE_UTIL*0.01-0.1,0.4)
|
||||
|
||||
extra="
|
||||
set ::env(SYNTH_MAX_FANOUT) { $::env(FP_ASPECT_RATIO) * 5 }
|
||||
"
|
||||
|
||||
std_cell_library="
|
||||
set ::env(STD_CELL_LIBRARY) sky130_fd_sc_hd
|
||||
set ::env(SYNTH_STRATEGY) 1
|
||||
"
|
||||
```
|
||||
In the example above, SYNTH_STRATEGY and STD_CELL_LIBRARY will be set before sourcing the SCL-specific information, and thus if SYNTH_STRATEGY is already specified under the configurations, the old value will override the value specified here.
|
||||
|
||||
This can also be used to control the used PDK and its SCL, since it is set before sourcing the SCL-specific information, so this will override the SCL set in general.tcl and allow for more control on different standard cell libraries under the same design.
|
||||
|
||||
|
||||
It's important to note that the used configuration in the expression should be assigned a value or a range of values preceding its use in the file.
|
||||
|
||||
|
||||
**Important Note:** *If you are going to launch two or more separate regression runs that include same design(s), make sure to set different tags for them using the `--tag` option. Also, put memory management into consideration while running multiple threads to avoid running out of memory to avoid any invalid pointer access.*
|
||||
|
||||
## Output
|
||||
- In addition to files produced inside `designs/<design>/runs/config_<tag>_<timestamp>` for each run on a design, three files are produced:
|
||||
1. `regression_results/<tag>_<timestamp>/<tag>_<timestamp>.log` A log file that describes start and stopping time of a given run.
|
||||
2. `regression_results/<tag>_<timestamp>/<tag>_<timestamp>.csv` A report file that provides a summary of each run. The summary contains some metrics and the configuration of that run
|
||||
3. `regression_results/<tag>_<timestamp>/<tag>_<timestamp>_best.csv` A report file that selects the best configuration per design based on number of violations
|
||||
|
||||
- If a file is provided to the --benchmark flag, the following files will also be generated:
|
||||
|
||||
6. `regression_results/<tag>_<timestamp>/<tag>_<timestamp>.rpt.yml` An incrementaly generated list of all designs in this run compared to the benchmark results and whether they PASSED or FAILED the regression test.
|
||||
7. `regression_results/<tag>_<timestamp>/<tag>_<timestamp>.rpt` A detailed report pointing out the differences between this run of the test set and the benchmark results. It divides them into three categories: Critical, Note-worthy, and Configurations.
|
||||
8. `regression_results/<tag>_<timestamp>/<tag>_<timestamp>.rpt.xlsx` A design to design comparison between benchmark results and this run of the test set. It includes whether or not a design failed or passed the test and it highlights the differences.
|
||||
|
||||
|
||||
## Command line arguments
|
||||
`python3 ./run_designs.py --help`
|
||||
225
docs/source/usage/hardening_macros.md
Normal file
225
docs/source/usage/hardening_macros.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# Hardening Macros
|
||||
Using OpenLane, you can produce a GDSII from an RTL for macros, and then use these macros to create your chip. Check [this][4] for more details about chip integration.
|
||||
|
||||
In this document we will go through the hardening steps and discuss in some detail what considerations should be made when hardening your macro.
|
||||
|
||||
> **NOTE:** For all the configurations mentioned in this documentation and any other openlane configurations, you can use the exploration script `run_designs.py` to find the optimal value for each configuration for your design. Read more [here][6].
|
||||
|
||||
## Base Requirements
|
||||
|
||||
You should start by setting the basic configuration file for your design. Check [this][5] for how to add your new design.
|
||||
|
||||
The basic configuration `config.json` or `config.tcl` file should at least contain these variables:
|
||||
|
||||
| Key | Description |
|
||||
|-|-|
|
||||
| `DESIGN_NAME` | The Verilog module name of your design. |
|
||||
| `VERILOG_FILES` | Space-delimited list of Verilog files used in your design*. |
|
||||
| `CLOCK_PORT` | List of clock ports used in your design. If your design is purely combinational, you can set this value to `""` (Tcl) or `null` (JSON). |
|
||||
| `DESIGN_IS_CORE` | `1/0` (Tcl), `true/false` (json): Whether your design is a core or a reusable macro: for macros, you want to set this to `0`/`false`<sup>**</sup>. |
|
||||
> \* The ``` `include ``` directive is not supported.
|
||||
>
|
||||
> \** If you're hardening the chip core, check [this][4] for more details about chip integration.
|
||||
|
||||
So, for example:
|
||||
|
||||
<table>
|
||||
<tr><th>JSON</th><th>Tcl</th></tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
```json
|
||||
"DESIGN_NAME": "spm",
|
||||
"VERILOG_FILES": "dir::src/*.v",
|
||||
"DESIGN_IS_CORE": false
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```tcl
|
||||
set ::env(DESIGN_NAME) {spm}
|
||||
|
||||
set ::env(VERILOG_FILES) [glob $::env(DESIGN_DIR)/src/*.v]
|
||||
set ::env(CLOCK_PORT) {clk}
|
||||
set ::env(DESIGN_IS_CORE) {0}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
These configurations should get you through the flow with the all other configurations using openlane default values, read about those [here][0]. However, in the coming sections we will take a closer look on how to determine the best values for most of the other configurations.
|
||||
|
||||
## Synthesis
|
||||
|
||||
The first decision in synthesis is determining the optimal synthesis strategy `SYNTH_STRATEGY` for your design. For that purpose there is a flag in the `flow.tcl` script, `-synth_explore` that runs a synthesis strategy exploration and reports the results in a table under `<run_path>/reports/`.
|
||||
|
||||
Then you need to consider the best values for the `SYNTH_MAX_FANOUT`.
|
||||
|
||||
If your macro is huge (200k+ cells), then you might want to try setting `SYNTH_NO_FLAT` to `1` (Tcl)/`true` (JSON), which will postpone the flattening of the design during synthesis until the very end.
|
||||
|
||||
Other configurations like `SYNTH_SIZING`, `SYNTH_BUFFERING`, and other synthesis configurations don't have to be changed. However, the advanced user can check [this][0] documentation for more details about those configurations and their values.
|
||||
|
||||
## Static Timing Analysis
|
||||
|
||||
Static Timing Analysis happens multiple times during the flow. However, they all use the same base.sdc file. You can control the outcome of the static timing analysis by setting those values:
|
||||
|
||||
1. The clock ports in the design, explained in the base requirements section `CLOCK_PORT`.
|
||||
|
||||
2. The clock period that you prefer the design to run with. This could be set using `CLOCK_PERIOD` and the unit is ns. It's important to note that the flow will use this value to calculate the worst and total negative slack, also if timing optimizations are enabled, it will try to optimize for it and give suggested clock period at the end of the run in `<run-path>/reports/metrics.csv` This value should be used in the future to speed up the optimization process and it will be the estimated value at which the design should run.
|
||||
|
||||
3. The IO delay percentage from the clock period `IO_PCT`. More about that [here][0].
|
||||
|
||||
4. You may want to write a custom SDC file to be used in STA and CTS. The default SDC file in the flow is [this file][11]. However, you can change that by pointing to a new file with the environment variable `BASE_SDC_FILE`. More about that [here][0].
|
||||
|
||||
Other values are set based on the (PDK, STD_CELL_LIBRARY) used. You can read more about those configurations [here][0].
|
||||
|
||||
Static Timing Analysis are done after:
|
||||
|
||||
1. Synthesis using the verilog netlist.
|
||||
|
||||
2. Placement using OpenROAD's estimate_parasitics.
|
||||
|
||||
3. Timing optimizations using the verilog netlist.
|
||||
|
||||
4. Global Routing using OpenROAD's estimate_parasitics.
|
||||
|
||||
5. Detailed Routing using SPEF extraction and the verilog netlist.
|
||||
|
||||
For SPEF extraction, you can control the wire model and the edge capacitance factor through these variables `SPEF_WIRE_MODEL` and `SPEF_EDGE_CAP_FACTOR`.
|
||||
|
||||
More about that [here][0].
|
||||
|
||||
## Floorplan
|
||||
|
||||
During Floor plan, you have one of three options:
|
||||
|
||||
1. Let the tools determine the area relative to the size and number of cells. This is done by setting `FP_SIZING` to `relative` (the default value), and setting `FP_CORE_UTIL` as the core utilization percentage. Also, you can change the aspect ratio by changing `FP_ASPECT_RATIO`.
|
||||
|
||||
2. Set a specific DIE AREA by making `FP_SIZING` set to `absolute` and then giving the size as four coordinates to `DIE_AREA`.
|
||||
|
||||
3. Use a template DEF and apply the same DIE AREA and dimensions of that DEF. Note that this option will also force the flow to use the same PIN locations and PIN names (they are copied over from the template DEF). To use this option set: `FP_DEF_TEMPLATE` to point to that DEF file.
|
||||
|
||||
You can read more about how to control these variables [here][0].
|
||||
|
||||
|
||||
## IO Placement
|
||||
|
||||
For IO placement, you currently have four options:
|
||||
|
||||
1. Using a template DEF file and applying the same PIN locations and PIN names (they are copied over from the template DEF). Note that this will force the flow to apply the same exact DIE AREA and dimensions of the template DEF. To use that option set: `FP_DEF_TEMPLATE` to point to that DEF file.
|
||||
|
||||
2. Manually setting the direction of each pin using a configuration file such as [this one][7]. Then you need to set `FP_PIN_ORDER_CFG` to point to that file.
|
||||
|
||||
3. Using contextualized pin placement, which will automatically optimize the placement of the pins based on their context in the larger design that includes them. This relevant for macros since they will be included inside a core, and also relevant for the core since it will be part of a bigger chip. For this to happen, you need to point to the LEF and DEF of the container/parent design using these two variables: `FP_CONTEXT_DEF` and `FP_CONTEXT_LEF`. Note that currently this script can only handle the existance of a single instance of that macro.
|
||||
|
||||
4. To let the tool randomly assign IOs using the random equidistant mode. This is the default way.
|
||||
|
||||
The options are prioritized based on the order mentioned above. This means that if you set a value for `FP_DEF_TEMPLATE` it will be used and the rest - if they exist - will be ignored.
|
||||
|
||||
You can read more about those configurations [here][0].
|
||||
|
||||
## Placement
|
||||
|
||||
Placement is done in three steps: Global Placement, Optimizations, and Detailed Placement.
|
||||
|
||||
### Global Placement
|
||||
|
||||
For Global Placement, the most important value would be `PL_TARGET_DENSITY` which should be easy to set.
|
||||
|
||||
- If your design is not a tiny design, then `PL_TARGET_DENSITY` should have a value that is `FP_CORE_UTIL` + 1~5%. Note that `FP_CORE_UTIL` has a value from 0 to 100, while `PL_TARGET_DENSITY` has a value from 0 to 1.0.
|
||||
|
||||
- If your design is a tiny design, then you may need to set `PL_RANDOM_GLB_PLACEMENT` to `1` or `PL_RANDOM_INITIAL_PLACEMENT` to 1. Also, `PL_TARGET_DENSITY` should have high value, while `FP_CORE_UTIL` should have a low value. (i.e `PL_TARGET_DENSITY` set to 0.5 and `FP_CORE_UTIL` set to 5). In very tiny designs (i.e. 1 std cell designs), the approximated DIE AREA in the floorplan stage may not leave enough room to insert tap cells in the design. Thus, it's recommended to use `FP_SIZING` as `absolute` and manually setting an appropriate `DIE_AREA`, check [the floorplan section](#floorplan) for more details. You may also want to reduce the values for `FP_PDN_HORIZONTAL_HALO` and `FP_PDN_VERTICAL_HALO`. You can read more about those [here][0].
|
||||
|
||||
Other values to be considered are `PL_BASIC_PLACEMENT` and `PL_SKIP_INITIAL_PLACEMENT`, you can read more about those [here][0].
|
||||
|
||||
### Optimizations
|
||||
|
||||
For this step we rely on Resizer and OpenPhySyn.
|
||||
|
||||
#### Resizer optimizations
|
||||
|
||||
The only optimization we use from resizer is the wire length optimization which is used to reduce the antenna violations. This is disabled by default since the diode insertion strategies should cover that purpose.
|
||||
|
||||
However, you can enable that by setting `PL_RESIZER_OVERBUFFER` to `1` and then determine the maximum wire length by setting this value `MAX_WIRE_LENGTH`.
|
||||
|
||||
### Detailed Placement
|
||||
|
||||
The only value to consider here is the `DPL_CELL_PADDING` which is usually selected for each (PDK,STD_CELL_LIBRARY) and should mostly be left as is. However, typically for the skywater libraries the value should be 4~6.
|
||||
|
||||
You can read more about that [here][0].
|
||||
|
||||
## Clock Tree Synthesis
|
||||
|
||||
Most of the values for clock tree synthesis are (PDK, STD_CELL_LIBRARY) specific and you can read more about those [here][8].
|
||||
|
||||
You can disable it by setting `CLOCK_TREE_SYNTH` to `0`.
|
||||
|
||||
If you don't want all the clock ports to be used in clock tree synthesis, then you can use set `CLOCK_NET` to specify those ports. Otherwise, `CLOCK_NET` will be defaulted to the value of `CLOCK_PORT`.
|
||||
|
||||
## Power Grid/Power Distribution Network
|
||||
See [here][9].
|
||||
|
||||
## Diode Insertion
|
||||
|
||||
Here, you have four options to choose from and they are controlled by setting `DIODE_INSERTION_STRATEGY` to one of the following values: (0, 1, 2, 3, 4, 5)
|
||||
|
||||
0. No diode insertion is done.
|
||||
|
||||
1. A diode is inserted for each PIN and connected to it.
|
||||
|
||||
2. A fake diode is inserted for each PIN and connected to it, then after an antenna check is run and the fake diodes are replaced with real ones if the pin is violated.
|
||||
|
||||
3. Rely on OpenROAD:FastRoute antenna avoidance flow to insert the diodes during global routing by using the Antenna Rule Checker and fixing violations. You can execute this iteratively by setting `GRT_MAX_DIODE_INS_ITERS`, it is capable to detect any divergence, so, you'll probably end up with the lowest # of Antenna violations possible.
|
||||
|
||||
4. A smarter version of strategy 1 that attempts to reduce the number of inserted diodes and places a diode at each design pin.
|
||||
|
||||
5. A variant of 2 utilizing the script used in strategy 4.
|
||||
|
||||
You can read more about those configurations [here][0].
|
||||
|
||||
## Routing
|
||||
|
||||
The configurations here were optimized based on a large design set and are best left as is, however the advanced user could refer to [this documentation][0] to learn more about each used configuration and how to change it.
|
||||
|
||||
You are advised to change `ROUTING_CORES` based on your CPU capacity to specify the number of threads that TritonRoute can run with to perform Detailed Routing in the least runtime possible.
|
||||
|
||||
## GDS Streaming
|
||||
|
||||
The configurations here were selected based on a large design test set and the consulation of the magic sources; therefore they are best left as is. However, for the curious user, refer to [this documentation][0] to learn more about each used configuration and how to change it.
|
||||
|
||||
## Final Reports and Checks
|
||||
|
||||
Finally, the flow ends with physical verification. This begins by streaming out the GDS followed by running DRC, LVS, and Antenna checks on the design. Then, it produces a final summary report in csv format to summarize all the reports.
|
||||
|
||||
You can control whether the magic DRC should be done on GDSII or on LEF/DEF abstract views. We recommend using GDSII on macros while using LEF/DEF on the chip level. This should speed up the run process and still give results as accurate as possible. This is controlled by `MAGIC_DRC_USE_GDS`.
|
||||
|
||||
You can run Antenna Checks using OpenROAD ARC or magic. This is controlled by `USE_ARC_ANTENNA_CHECK`. The magic antenna checker was more reliable at the time of writing this documentation but it comes with a huge runtime trade-off and the accuracy gain is not significant enough to accept that tradeoff; thus, the default is OpenROAD's ARC.
|
||||
|
||||
You can control whether LVS should be run down to the device level or the cell level based on the type of the extraction. If you perform extraction on GDSII then it's going to be down to the device/transistor level, otherwise using the LEF/DEF views then it's going to be down to the cell/block level. This is controlloed by `MAGIC_EXT_USE_GDS`.
|
||||
|
||||
You can enable LEC on the different netlists by setting `LEC_ENABLE` to one, which should run logic verification after writing each intermediate netlist.
|
||||
|
||||
A final summary report is produced by default as `<run-path>/reports/metrics.csv`, for more details about the contents of the report check [this documentation][10].
|
||||
|
||||
A final manufacturability report is produced by default as `<run-path>/reports/manufacturability_report.csv`, this report contains the magic DRC, the LVS, and the antenna violations summaries.
|
||||
|
||||
The final GDSII file can be found under `<run-path>/results/final/gds`.
|
||||
|
||||
To integrate that macro into a core or a chip, check this [documentation on chip integration][4].
|
||||
|
||||
If you want to create further tweaks in the flow that the abundant configurations don't allow, make sure to check [this][2] for more details about the interactive mode of the OpenLane flow.
|
||||
|
||||
[0]: ../reference/configuration.md
|
||||
[1]: ../reference/openlane_commands.md
|
||||
[2]: ../reference/interactive_mode.md
|
||||
[3]: https://github.com/The-OpenROAD-Project/OpenROAD/blob/master/src/pdn/doc/PDN.md
|
||||
[4]: ./chip_integration.md
|
||||
[5]: ./designs.md
|
||||
[6]: ./exploration_script.md
|
||||
[7]: https://github.com/The-OpenROAD-Project/openlane/blob/master/designs/spm/pin_order.cfg
|
||||
[8]: ../for_developers/pdk_structure.md
|
||||
[9]: ./advanced_power_grid_control.md
|
||||
[10]: ../reference/datapoint_definitions.md
|
||||
[11]: ./../../../scripts/base.sdc
|
||||
12
docs/source/usage/index.rst
Normal file
12
docs/source/usage/index.rst
Normal file
@@ -0,0 +1,12 @@
|
||||
Using OpenLane
|
||||
---------------
|
||||
.. toctree::
|
||||
:glob:
|
||||
|
||||
designs
|
||||
exploration_script
|
||||
hardening_macros
|
||||
chip_integration
|
||||
advanced_power_grid_control
|
||||
custom_pdk_builds
|
||||
|
||||
Reference in New Issue
Block a user