Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

README: update instructions and usage guide #23

Merged
merged 1 commit into from
Apr 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 82 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
# Bazel-orfs

This repository contains [Bazel](https://bazel.build/) rules for wrapping Physical Design Flows provided by [OpenROAD-flow-scripts](https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts).
This repository contains [Bazel](https://bazel.build/) rules for wrapping Physical Design Flows provided by [OpenROAD-flow-scripts](https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts). It provides two variants of the bazel flow:

* Docker flow - based on ORFS installed in the docker container that is used for running bazel targets
* Local flow - relies on local installation of the ORFS

## Requirements

* [Bazelisk](https://bazel.build/install/bazelisk) or [Bazel](https://bazel.build/install) - if using `bazel`, please refer to `.bazelversion` file for the recommended version of the tool.
* [OpenROAD-flow-scripts](https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts) - **Required only for running `Make` targets** - must reside under `~/OpenROAD-flow-scripts`. `bazel-orfs` intentionally does not treat OpenROAD-flow-scripts as a installable versioned tool, but prefers to rely on `~/OpenROAD-flow-scripts` such that it is easy to hack ORFS and OpenROAD.
* [Docker](https://docs.docker.com/get-docker/) - **Required only for running `Stage` targets**
* Docker image with ORFS installation - **Required only for running `Stage` targets** - can be obtained in two ways:

* running `bazel run orfs_env` which downloads the docker image from container registry and loads it to docker runtime under name: `openroad/flow-ubuntu22.04-builder:latest`
* [Building the image locally](https://openroad-flow-scripts.readthedocs.io/en/latest/user/BuildWithDocker.html#build-using-docker-from-sources)
* Pulling the image manually from the container registry with:
```
docker pull ghcr.io/antmicro/openroad-flow-scripts/ubuntu22.04:latest
```
In such case the `docker_image` attribute of `build_openroad` macro must be set to `ghcr.io/antmicro/openroad-flow-scripts/ubuntu22.04:latest`
* Providing different docker image and overriding default used in the flow through `doker_image` attribute of `build_openroad` macro

## Usage

Core functionality is implemented as `build_openroad()` bazel macro in `openroad.bzl` file.

In order to use `build_openroad()` macro in Bazel Workspace in other project it is required to pull `bazel-orfs` as external dependency through one of [Bazel Workspace Rules](https://bazel.build/reference/be/workspace). For example in project's MODULE.bazel:
In order to use `build_openroad()` macro in Bazel Workspace in other project it is required to pull `bazel-orfs` as external dependency through one of [Bazel Module Methods](https://bazel.build/rules/lib/globals/module). For example in project's MODULE.bazel:

```
bazel_dep(name = "bazel-orfs")
Expand Down Expand Up @@ -90,26 +103,34 @@ Make targets:
//:L1MetadataArray_test_grt_make_script
//:L1MetadataArray_test_generate_abstract_make
//:L1MetadataArray_test_generate_abstract_make_script
//:L1MetadataArray_test_memory_make
//:L1MetadataArray_test_memory_make_script

Config generation targets:
//:L1MetadataArray_test_config
//:L1MetadataArray_test_config.mk
//:L1MetadataArray_test_clock_period_config
//:L1MetadataArray_test_clock_period_config.mk
//:L1MetadataArray_test_synth_sdc_config
//:L1MetadataArray_test_synth_sdc_config.mk
//:L1MetadataArray_test_synth_config
//:L1MetadataArray_test_synth_config.mk
//:L1MetadataArray_test_floorplan_config
//:L1MetadataArray_test_floorplan_config.mk
//:L1MetadataArray_test_place_config
//:L1MetadataArray_test_place_config.mk
//:L1MetadataArray_test_cts_config
//:L1MetadataArray_test_cts_config.mk
//:L1MetadataArray_test_grt_config
//:L1MetadataArray_test_grt_config.mk
//:L1MetadataArray_test_generate_abstract_config
//:L1MetadataArray_test_generate_abstract_config.mk

Design config:
//:L1MetadataArray_test_config
//:L1MetadataArray_test_config.mk

Stage configs:
//:L1MetadataArray_test_clock_period_config
//:L1MetadataArray_test_clock_period_config.mk
//:L1MetadataArray_test_synth_sdc_config
//:L1MetadataArray_test_synth_sdc_config.mk
//:L1MetadataArray_test_synth_config
//:L1MetadataArray_test_synth_config.mk
//:L1MetadataArray_test_floorplan_config
//:L1MetadataArray_test_floorplan_config.mk
//:L1MetadataArray_test_place_config
//:L1MetadataArray_test_place_config.mk
//:L1MetadataArray_test_cts_config
//:L1MetadataArray_test_cts_config.mk
//:L1MetadataArray_test_grt_config
//:L1MetadataArray_test_grt_config.mk
//:L1MetadataArray_test_generate_abstract_config
//:L1MetadataArray_test_generate_abstract_config.mk
//:L1MetadataArray_test_memory_config
//:L1MetadataArray_test_memory_config.mk
```

The example comes from the `BUILD` file in this repository.
Expand All @@ -122,25 +143,53 @@ For details about targets spawned by this macro please refer to `Implementation`
This file contains simple helper functions written in starlark as well as macro `build_openroad()`.
The implementation of this macro spawns multiple `genrule` native rules which are responsible for preparing and running ORFS physical design flow targets during bazel build stage.

There are 5 kinds of genrules spawned in this macro:
These are the genrules spawend in this macro:

* Config generation targets
* Common for the whole design (named: `target_name + “_config”`)
* ORFS stage-specific config (named: `target_name + “_” + stage + “_config”`)
* Stage targets (named: `target_name + “_” + stage`)
* Special stage: Memory targets (named: `target_name + “_memory”`)
* Special mock flow: Mock Area targets (named: `target_name + “_” + stage + “_mock_area”`)
* Make targets (named: `target_name + “_” + stage + “_make”`)
* Mock Area targets (named: `target_name + “_” + stage + “_mock_area”`)
* Memory targets (named: `target_name + “_memory”`)

There are two kinds of flows available:
* docker flow (Stage targets)
* local flow (Make targets)
* Docker flow (Stage targets)
* Local flow (Make targets)

Both docker and local flow does the same thing: for each stage of the physical design flow it writes config files, sets env vars pointing to those files, builds a command line to execute in ORFS environment and runs it through the `entrypoint` script.

#### Docker flow

Docker flow uses containerized environment with preinstalled ORFS to run the physical design flow.
Example targets which run the docker flow include:

* //:L1MetadataArray_test_floorplan
* //:L1MetadataArray_test_memory
* //:tag_array_64x184_synth

It implicitly depends on a docker image with installed ORFS environment being present in docker runtime of the machine running bazel targets.
The docker image used in the flow defaults to `ghcr.io/antmicro/openroad-flow-scripts/ubuntu22.04:latest`.
The default can be overridden per `build_openroad` instance with a `docker_image` attribute.
Setting this attribute to a valid registry and image within this registry will enable docker to automatically pull the image if it's not available locally.
Users can also build the image from ORFS sources following [the guide](https://openroad-flow-scripts.readthedocs.io/en/latest/user/BuildWithDocker.html#build-using-docker-from-sources).

#### Local flow

The local flow (`_make` bazel targets) depends on the locally installed ORFS.
OpenROAD-flow-scripts installation is expected to be located specifically under `~/OpenROAD-flow-scripts`.
For the installation guide please refer to the [build instructions](https://openroad-flow-scripts.readthedocs.io/en/latest/user/BuildLocally.html).
The local flow relies on `_make` bazel targets which are used to generate shell scripts.
Those shell scripts, apart from facilitating quick tests of ORFS modifications, can be used to run ORFS stages straight from the bazel-orfs repository and to allow tweaking the "moving parts" of the flow, like e.g.:
* Design and stage configs
* Make targets patterns
* entrypoint command line

#### Config files

Docker flow uses containerized environment with preinstalled ORFS to run the physical design flow, while the local flow (`_make` bazel targets) depends on the locally installed ORFS (specifically under `~/OpenROAD-flow-scripts`).
Each stage of the physical design flow depend on two generated `config.mk` files that provide the configuration for the ORFS.
One is specific for the stage of the flow and the second one is common for the whole design being built.
Design-specific config includes the stage-specific config through `STAGE_CONFIG` environment variable that is set in the `build_openroad()` macro implementation.
Both docker and local flow does the same thing: for each stage of the physical design flow it writes config files, sets env vars pointing to those files, builds a command line to execute in ORFS environment and runs it through the `entrypoint` script.

#### Entrypoint scripts

Expand All @@ -149,18 +198,14 @@ For the local flow it is the `orfs` script and for the docker flow it's the `doc
Both of those scripts have the same responsibility of preparing and entering the ORFS build environment and then executing the build command prepared for given ORFS stage.
`orfs` does this by setting some initial environment variables and sourcing `env.sh` from ORFS.
`docker_shell` is very similar in that matter except it runs the flow in a docker container.
The input and output files for the flow stage are passed to the running container through [bind mounts](https://docs.docker.com/storage/#bind-mounts).

#### Stage Targets

Main rules for executing each ORFS stage (synthesis, floorplan, clock tree synthesis, place, route, etc.).
The outputs and inputs are different for each ORFS stage and are defined by macro arguments and the implementation of the macro.
Those targets are built with the docker flow.
Before running stage targets it is required to first fetch and load ORFS docker image into local docker runtime.
This can be done with the following `run` rule:

```
bazel run orfs_env
```
Before running stage targets it is required to first pull the ORFS docker image into local docker runtime.

#### Make Targets

Expand Down Expand Up @@ -190,7 +235,10 @@ bazel build L1MetadataArray_test_floorplan_make

#### Mock Area Targets

Those targets are used to run particular stages of the flow with a scaled area of the module evaluated in a given target.
Those targets are used to create mocked abstracts (LEF files) for macros.
The mock contains the description of macro which has its whole internal logic removed.
At the same time the mock has the same pinout as the original macro and similar size which makes it useful in early design stages.
Mocked abstracts are generated after the `floorplan` stage to be then used in builds of other parts of the design that use given macro.
Used for estimating sizes of macros with long build times and checking if they will fit in upper-level modules without running time consuming place and route flow.

#### Memory Targets
Expand Down