Skip to content

Commit 20f5713

Browse files
committed
openroad: basic OpenROAD build and readme
Signed-off-by: Øyvind Harboe <[email protected]>
1 parent 9e73e11 commit 20f5713

15 files changed

+4206
-0
lines changed

.bazelversion

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
7.4.0

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
bazel-bin
2+
bazel-serv
3+
bazel-out
4+
bazel-testlogs

BUILD.bazel

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Top level Bazel module, allows access to files by other modules."""
2+
3+
exports_files(
4+
glob([
5+
"rtl/**/*.v",
6+
]),
7+
visibility = [":__subpackages__"],
8+
)
9+
10+
filegroup(
11+
name = "verilog",
12+
srcs = glob(
13+
["rtl/**/*.v"],
14+
exclude = ["rtl/serv_top.v"],
15+
),
16+
visibility = [":__subpackages__"],
17+
)

MODULE.bazel

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""Bazel depedencies"""
2+
3+
module(
4+
name = "serv",
5+
version = "0.0.1",
6+
compatibility_level = 1,
7+
)
8+
9+
bazel_dep(name = "rules_python", version = "1.2.0")
10+
11+
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
12+
python.toolchain(
13+
ignore_root_user_error = True,
14+
is_default = True,
15+
python_version = "3.12",
16+
)
17+
18+
bazel_dep(name = "bazel-orfs")
19+
git_override(
20+
module_name = "bazel-orfs",
21+
commit = "e153c70cebe9416db4e2de33d0bcee2749d0e539",
22+
remote = "https://github.com/The-OpenROAD-Project/bazel-orfs.git",
23+
)
24+
25+
orfs = use_extension("@bazel-orfs//:extension.bzl", "orfs_repositories")
26+
orfs.default(
27+
# To update, find latest at https://hub.docker.com/r/openroad/orfs/tags
28+
image = "docker.io/openroad/orfs:v3.0-2591-g9bca87d7",
29+
sha256 = "673181c3b49235cf5b43e386e4cf478d676b797c8b7736a3ed79fc90f4c8acb7",
30+
)
31+
use_repo(orfs, "com_github_nixos_patchelf_download")
32+
use_repo(orfs, "docker_orfs")

MODULE.bazel.lock

+3,945
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

openroad/BUILD.bazel

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
load("@bazel-orfs//:openroad.bzl", "orfs_flow")
2+
load("@bazel-orfs//:ppa.bzl", "orfs_ppa")
3+
4+
FASTER = {
5+
# ignore timing repair for now
6+
#"SETUP_SLACK_MARGIN": "-1000",
7+
"SKIP_REPORT_METRICS": "1",
8+
"SKIP_LAST_GASP": "1",
9+
# skip checks for now, faster
10+
"PWR_NETS_VOLTAGES": "",
11+
"GND_NETS_VOLTAGES": "",
12+
}
13+
14+
filegroup(
15+
name = "io",
16+
srcs = [":io.tcl"],
17+
data = [":util.tcl"],
18+
)
19+
20+
WIDTHS = [1 << i for i in range(0, 6)]
21+
22+
PDKS = [
23+
"sky130hd",
24+
"asap7",
25+
]
26+
27+
[orfs_flow(
28+
name = "serv_top",
29+
arguments = FASTER | {
30+
"SYNTH_HIERARCHICAL": "1",
31+
"CORE_UTILIZATION": "5",
32+
"PLACE_DENSITY": "0.8",
33+
"CORE_MARGIN": "1",
34+
} |
35+
(
36+
{
37+
"IO_PLACER_H": "M2 M4",
38+
"IO_PLACER_V": "M3 M5",
39+
} if pdk == "asa7" else {
40+
}
41+
),
42+
pdk = "@docker_orfs//:{}".format(pdk),
43+
sources = {
44+
"SDC_FILE": [":constraints_{}.sdc".format(pdk)],
45+
"IO_CONSTRAINTS": [":io"],
46+
},
47+
variant = "{pdk}_{width}".format(
48+
pdk = pdk,
49+
width = width,
50+
),
51+
verilog_files = [
52+
":serv_top_{width}".format(width = width),
53+
"//:verilog",
54+
],
55+
) for width in WIDTHS for pdk in PDKS]
56+
57+
# FIXME workaround for https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts/pull/2943
58+
[genrule(
59+
name = "serv_top_{width}".format(width = width),
60+
srcs = ["//:rtl/serv_top.v"],
61+
outs = ["serv_top_{width}.v".format(width = width)],
62+
# parameter W = 1,
63+
cmd = """
64+
sed -E 's/parameter\\s+W = 1,/parameter W = {width},/' < $< > $@
65+
""".format(width = width),
66+
) for width in WIDTHS]
67+
68+
[orfs_ppa(
69+
name = "ppa_" + pdk,
70+
plot = ["serv_top_{pdk}_{width}_cts".format(
71+
pdk = pdk,
72+
width = width,
73+
) for width in WIDTHS],
74+
title = "serv_top vs. bit width (W)",
75+
) for pdk in PDKS]

openroad/README.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
OpenROAD ASAP7 PDK configuration
2+
================================
3+
4+
TL;DR Install Bazelisk and run command below to build and view darksocv in the GUI, Bazelisk handles all depedencies.
5+
6+
Demonstrates how to set up an [bazel-orfs](https://github.com/The-OpenROAD-Project/bazel-orfs) to build darksocv with [OpenROAD-flow-scripts](https://github.com/The-OpenROAD-Project/OpenROAD-flow-scripts)
7+
8+
To build and view [Install Bazelisk](https://bazel.build/install/bazelisk) and run:
9+
10+
bazel run //openroad:serv_top_asap7_1_cts /tmp/cts gui_cts
11+
12+
Register to register histogram
13+
------------------------------
14+
15+
![alt text](reg2reghistogram.png)
16+
17+
Estimated routing congestion
18+
----------------------------
19+
20+
![alt text](estimatedroutingcongestion.png)
21+
22+
Detailed routing and congestion
23+
-------------------------------
24+
25+
bazel run //openroad:serv_top_asap7_1_route /tmp/route gui_route
26+
27+
![alt text](route.png)
28+
29+
sky130hd
30+
--------
31+
32+
bazel run serv_top_sky130hd_32_cts /tmp/cts gui_cts
33+
34+
PPA plots
35+
=========
36+
37+
View sky130hd PPA plots:
38+
39+
bazel run //openroad:ppa_sky130hd
40+
41+
![alt text](ppa_sky130hd.png)
42+
43+
Ideas for future work
44+
=====================
45+
46+
- reduce clock period
47+
- adjust input/output delays
48+
- add IO constraints to place pins on one edge of the SRAMs and top level
49+
- reduce area
50+
51+
[MegaBoom](https://github.com/The-OpenROAD-Project/megaboom) demonstrates a number of techniques to study a design and set up mock SRAMs.

openroad/constraints_asap7.sdc

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
set clk_name clk
2+
set clk_port_name clk
3+
set clk_period 500
4+
5+
source $::env(PLATFORM_DIR)/constraints.sdc

openroad/constraints_sky130hd.sdc

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
set clk_name clk
2+
set clk_port_name clk
3+
set clk_period 10
4+
5+
set clk_port [get_ports $clk_port_name]
6+
create_clock -period $clk_period -waveform [list 0 [expr $clk_period / 2]] -name $clk_name $clk_port
7+
8+
set non_clk_inputs [lsearch -inline -all -not -exact [all_inputs] $clk_port]
9+
set all_register_outputs [get_pins -of_objects [all_registers] -filter {direction == output}]
10+
set_max_delay [expr {[info exists in2reg_max] ? $in2reg_max : 80}] -from $non_clk_inputs -to [all_registers]
11+
set_max_delay [expr {[info exists reg2out_max] ? $reg2out_max : 80}] -from $all_register_outputs -to [all_outputs]
12+
set_max_delay [expr {[info exists in2out_max] ? $in2out_max : 80}] -from $non_clk_inputs -to [all_outputs]
13+
group_path -name in2reg -from $non_clk_inputs -to [all_registers]
14+
group_path -name reg2out -from [all_registers] -to [all_outputs]
15+
group_path -name reg2reg -from [all_registers] -to [all_registers]
16+
group_path -name in2out -from $non_clk_inputs -to [all_outputs]
454 KB
Loading

openroad/io.tcl

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
source openroad/util.tcl
2+
3+
set_io_pin_constraint -region bottom:* -pin_names [match_pins .*]
4+

openroad/ppa_sky130hd.png

52.9 KB
Loading

openroad/reg2reghistogram.png

49.8 KB
Loading

openroad/route.png

1000 KB
Loading

openroad/util.tcl

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Helper function to split a string into a list of strings and numbers
2+
proc split_strings_and_numbers {str} {
3+
set result {}
4+
foreach {all letters numbers} [regexp -all -inline {(\D*)(\d*)} $str] {
5+
if {$letters ne ""} {
6+
lappend result $letters
7+
}
8+
if {$numbers ne ""} {
9+
lappend result [expr {$numbers + 0}] ;# Convert to integer
10+
}
11+
}
12+
return $result
13+
}
14+
15+
# Custom comparison function
16+
proc natural_compare {str1 str2} {
17+
set list1 [split_strings_and_numbers $str1]
18+
set list2 [split_strings_and_numbers $str2]
19+
set len [expr {min([llength $list1], [llength $list2])}]
20+
for {set i 0} {$i < $len} {incr i} {
21+
set part1 [lindex $list1 $i]
22+
set part2 [lindex $list2 $i]
23+
if {$part1 ne $part2} {
24+
if {[string is integer -strict $part1] && [string is integer -strict $part2]} {
25+
return [expr {$part1 - $part2}]
26+
} else {
27+
return [string compare $part1 $part2]
28+
}
29+
}
30+
}
31+
return [expr {[llength $list1] - [llength $list2]}] ;# If all parts are equal, compare by length
32+
}
33+
34+
proc natural_sort {list} {
35+
return [lsort -command natural_compare $list]
36+
}
37+
38+
proc match_pins { regex {direction .*} {is_clock 0}} {
39+
set pins {}
40+
# The regex for get_ports is not the tcl regex
41+
foreach pin [get_ports -regex .*] {
42+
set input [get_property $pin name]
43+
# We want the Tcl regex
44+
if {![regexp $regex $input]} {
45+
continue
46+
}
47+
if {![regexp $direction [get_property $pin direction]]} {
48+
continue
49+
}
50+
if {[expr $is_clock != [sta::is_clock_src [sta::get_port_pin $pin]]]} {
51+
continue
52+
}
53+
lappend pins [get_property $pin name]
54+
}
55+
return [natural_sort $pins]
56+
}

0 commit comments

Comments
 (0)