Skip to content

Commit 529ca01

Browse files
committed
reconfigure steps and flow as a librelane plugin
(+ i attempted to fold resizing the floorplan into PlaceRAM and failed)
1 parent efc67de commit 529ca01

File tree

16 files changed

+124
-85
lines changed

16 files changed

+124
-85
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ venv/manifest.txt: ./requirements_dev.txt
1616
PYTHONPATH= ./venv/bin/python3 -m pip install --upgrade pip
1717
PYTHONPATH= ./venv/bin/python3 -m pip install --upgrade wheel
1818
PYTHONPATH= ./venv/bin/python3 -m pip install --upgrade\
19-
-r ./requirements_dev.txt
19+
-r ./requirements_dev.txt -r ./requirements.txt
2020
PYTHONPATH= ./venv/bin/python3 -m pip freeze > $@
2121
touch venv/manifest.txt
2222

@@ -30,4 +30,4 @@ clean:
3030
rm -rf build/
3131
rm -rf logs/
3232
rm -rf dist/
33-
rm -rf *.egg-info
33+
rm -rf *.egg-info

Readme.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
<h1 align="center"> DFFRAM Compiler</h1>
2-
<p align="center">
3-
<a href="https://colab.research.google.com/github/Cloud-V/DFFRAM/blob/main/dffram.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open in Google Colab"/></a>
4-
</p>
52
<p align="center">
63
<a href="https://opensource.org/licenses/Apache-2.0"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache 2.0"/></a>
74
<img src="https://github.com/AUCOHL/DFFRAM/actions/workflows/main.yml/badge.svg?branch=main" alt="CI Status" />
8-
<a href="https://invite.skywater.tools"><img src="https://img.shields.io/badge/Community-Skywater%20PDK%20Slack-ff69b4?logo=slack" alt="Invite to the Skywater PDK Slack"/></a>
5+
<a href="https://fossi-chat.org"><img src="https://img.shields.io/badge/Community-FOSSi%20Chat-1bb378?logo=element" alt="Invite to FOSSi Chat"/></a>
96
<a href="https://github.com/psf/black"><img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code Style: Black"/></a>
107
</p>
118

@@ -21,11 +18,12 @@ but it is a bit out-of-date at this point.
2118

2219
## Platform Support Status
2320

24-
| Configured Platform | Working | Silicon-proven\* |
21+
| Configured Platform | Signoff-clean | Silicon-proven\* |
2522
| - | - | - |
26-
| `sky130A` | Yes | Yes |
27-
| `sky130B` | Yes | No |
28-
| `gf180mcuD` | No\* (Hold violations in the Netlist) | No |
23+
| `sky130A` (Latches) | Yes | Yes |
24+
| `sky130A` (DFF) | Yes | No |
25+
| `sky130B` (Latches/DFF) | Yes | No |
26+
| `gf180mcuD` (Latches/DFF) | No\* (Hold violations in the Netlist) | No |
2927

3028
> \* Silicon proven does not imply that you should use it without whole-system,
3129
> timing-annotated simulation to make sure that it works for your circuit.
@@ -76,7 +74,11 @@ blocks are as follows:
7674
7775
Currently, the can compiler generate the layout of the following configurations:
7876

79-
> 1RW1R variants are temporarily disabled due to a bug.
77+
> We currently do not recommend the use of 1RW1R. See this discussion for more
78+
> info:
79+
>
80+
> https://github.com/AUCOHL/DFFRAM/issues/198
81+
8082

8183
* RAM
8284
* 32 words with byte write enable (1RW and 1RW1R).
@@ -116,8 +118,8 @@ using different means.
116118
<th rowspan="2">Size<sup>1</sup></th>
117119
<th colspan="2">OpenRAM<sup>2</sup></th>
118120
<th colspan="2">DFFRAM Compiler</th>
119-
<th colspan="2">DFFRAM/OpenLane</th>
120-
<th colspan="2">RTL/OpenLane</th>
121+
<th colspan="2">DFFRAM Netlist + OpenROAD Placer</th>
122+
<th colspan="2">Memory RTL with OpenLane</th>
121123
</tr>
122124
<tr style="border-top:4px solid darkblue;">
123125
<td> Dim WxH (μm) </td> <td> Bit Density (bits/mm<sup>2</sup>) </td>

dffram.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
type=Decimal,
4848
help="Minimum height in µm",
4949
)
50+
@cloup.option("--latch/--dff", default=True, help="Whether to use latches or dffs")
5051
@cloup_flow_opts(accept_config_files=False)
5152
@cloup.argument("size", default="32x32", nargs=1)
5253
def main(
@@ -67,6 +68,7 @@ def main(
6768
min_height,
6869
flow_name,
6970
pdk_root,
71+
latch,
7072
**kwargs,
7173
):
7274
if variant == "DEFAULT":
@@ -123,7 +125,9 @@ def main(
123125
}
124126
)
125127

126-
build_dir = os.path.join("build", design)
128+
build_dir = os.path.join(
129+
"build", f"{pdk}-{scl}-{'latch' if latch else 'dff'}", design
130+
)
127131
mkdirp(build_dir)
128132

129133
tech_info_path = os.path.join(".", "platforms", pdk, scl, "tech.yml")
@@ -163,7 +167,7 @@ def main(
163167
],
164168
"SYNTH_ELABORATE_ONLY": True,
165169
"SYNTH_ELABORATE_FLATTEN": True,
166-
"SYNTH_PARAMETERS": [f"WSIZE={logical_width}"],
170+
"SYNTH_PARAMETERS": [f"WSIZE={logical_width}", f"USE_LATCH={int(latch)}"],
167171
"GRT_REPAIR_ANTENNAS": False,
168172
"MINIMUM_HEIGHT": min_height,
169173
"VERTICAL_HALO": vertical_halo,

placeram/__init__.py renamed to librelane_plugin_dffram/scripts/odbpy/placeram/__init__.py

File renamed without changes.

placeram/__main__.py renamed to librelane_plugin_dffram/scripts/odbpy/placeram/__main__.py

File renamed without changes.

placeram/cli.py renamed to librelane_plugin_dffram/scripts/odbpy/placeram/cli.py

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ def create_fill(name, sites=1):
107107
fill_cell = self.fill_cells_by_sites[sites]
108108
return odb.dbInst_create(self.block, fill_cell, name)
109109

110-
self.micron_in_units = self.block.getDefUnits()
111-
tap_distance = self.micron_in_units * tap_distance
110+
self.micron_in_dbus: int = self.block.getDefUnits()
111+
tap_distance = self.micron_in_dbus * tap_distance
112112

113113
self.rows = Row.from_odb(
114114
self.block.getRows(),
@@ -132,22 +132,49 @@ def represent(self, file):
132132

133133
def place(self):
134134
eprint("Starting placement…")
135-
print(f"Placing across {len(self.rows)} rows...")
135+
print(f"Placing across {len(self.rows)} rows")
136136
last_row = self.hierarchy.place(self.rows)
137-
print(f"Placement concluded with {last_row} rows...")
137+
138+
print(f"Placement concluded with {last_row} rows…")
138139
Row.fill_rows(self.rows, 0, last_row)
139140

140141
# We can't rely on the fact that a placeable will probably fill
141142
# before returning and pick the width of the nth row or whatever.
142-
width_units = 0
143+
width_dbus: int = 0
143144
for row in self.rows:
144-
width_units = max(row.width, width_units)
145+
width_dbus = max(row.width, width_dbus)
145146

146-
self.core_width = width_units / self.micron_in_units
147+
height_dbus: int = self.rows[last_row - 1].ymax - self.rows[0].y
147148

148-
height_units = self.rows[last_row - 1].ymax - self.rows[0].y
149+
self.core_width = width_dbus / self.micron_in_dbus
150+
self.core_height = height_dbus / self.micron_in_dbus
149151

150-
self.core_height = height_units / self.micron_in_units
152+
utl.metric_float("dffram__suggested__core_width", self.core_width)
153+
utl.metric_float("dffram__suggested__core_height", self.core_height)
154+
155+
eprint(
156+
"Placement concluded with core area of %fµm x %fµm."
157+
% (self.core_width, self.core_height)
158+
)
159+
160+
# resizing doesn't work - rows widths are immutable from python
161+
# # resize
162+
# width_margin: int = self.rows[0].x
163+
# height_margin: int = self.rows[0].y
164+
# die_height_dbus = height_dbus + height_margin * 2
165+
# die_width_dbus = width_dbus + width_margin * 2
166+
167+
# die_rect = odb.Rect(0, 0, die_width_dbus, die_height_dbus)
168+
# self.block.setDieArea(die_rect)
169+
# for row in self.block.getRows():
170+
# _, row_y = row.getOrigin()
171+
# if row_y >= width_dbus + width_margin:
172+
# odb.dbRow.destroy(row)
173+
174+
# calculate density
175+
die_width = self.block.getDieArea().dx() / self.micron_in_dbus
176+
die_height = self.block.getDieArea().dy() / self.micron_in_dbus
177+
die_area = die_width * die_height
151178

152179
logical_area: float = 0
153180
for cell in self.block.getInsts():
@@ -160,24 +187,13 @@ def place(self):
160187
break
161188
if type not in ["nonfiller"]:
162189
continue
163-
width = master.getWidth() / self.micron_in_units
164-
height = master.getHeight() / self.micron_in_units
190+
width = master.getWidth() / self.micron_in_dbus
191+
height = master.getHeight() / self.micron_in_dbus
165192
logical_area += width * height
166193

167-
eprint(
168-
"Placement concluded with core area of %fµm x %fµm."
169-
% (self.core_width, self.core_height)
170-
)
171-
172-
utl.metric_float("dffram__suggested__core_width", self.core_width)
173-
utl.metric_float("dffram__suggested__core_height", self.core_height)
174-
175-
die_width = self.block.getDieArea().dx() / self.micron_in_units
176-
die_height = self.block.getDieArea().dy() / self.micron_in_units
177-
die_area = die_width * die_height
178-
179194
self.density = logical_area / die_area
180195
utl.metric_float("dffram__logic__density", self.density)
196+
181197
eprint("Density: %.2f%%" % (self.density * 100))
182198
eprint("Done.")
183199

placeram/common_data.py renamed to librelane_plugin_dffram/scripts/odbpy/placeram/common_data.py

File renamed without changes.

placeram/data.py renamed to librelane_plugin_dffram/scripts/odbpy/placeram/data.py

File renamed without changes.

placeram/placeable.py renamed to librelane_plugin_dffram/scripts/odbpy/placeram/placeable.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,22 @@ def dbInst__repr__(self):
1818

1919
Instance.__repr__ = dbInst__repr__
2020

21-
RegExp = str
21+
22+
def _load_regexes():
23+
compiled = {}
24+
with open(os.path.join(os.path.dirname(__file__), "rx.yml"), encoding="utf8") as f:
25+
_loading: Dict[str, Dict[str, str]] = yaml.safe_load(f)
26+
for cls, patterns in _loading.items():
27+
compiled.setdefault(cls, {})
28+
for variable, rx in patterns.items():
29+
compiled[cls][variable] = re.compile(rx)
30+
return compiled
2231

2332

2433
class Placeable(object):
25-
RegexDictionary: Dict[str, Dict[str, RegExp]] = yaml.safe_load(
26-
open(os.path.join(os.path.dirname(__file__), "rx.yml"))
27-
)
34+
RegexDictionary: Dict[str, Dict[str, re.Pattern]] = _load_regexes()
2835

29-
def regex_dict(self) -> Dict[str, RegExp]:
36+
def regex_dict(self) -> Dict[str, re.Pattern]:
3037
return Placeable.RegexDictionary[self.__class__.__name__]
3138

3239
class Sieve(object):
@@ -44,7 +51,6 @@ def __init__(
4451

4552
def sieve(self, instances: List[Instance], sieves: List[Sieve]):
4653
regexes = self.regex_dict()
47-
compiled_regexes = {k: re.compile(v) for k, v in regexes.items()}
4854
for sieve in sieves:
4955
depth = len(sieve.groups)
5056
if depth == 0:
@@ -56,7 +62,7 @@ def sieve(self, instances: List[Instance], sieves: List[Sieve]):
5662
n = instance.getName()
5763
found = False
5864
for sieve in sieves:
59-
rx = compiled_regexes[sieve.variable]
65+
rx = regexes[sieve.variable]
6066
result = rx.search(n)
6167
if result is None:
6268
continue

placeram/reg_data.py renamed to librelane_plugin_dffram/scripts/odbpy/placeram/reg_data.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@
77
from .placeable import Placeable
88
from .common_data import Decoder5x32
99

10-
from odb import dbInst
10+
from odb import dbInst as Instance
1111
from typing import Dict, List
1212

13-
Instance = dbInst
14-
1513
P = Placeable
1614
S = Placeable.Sieve
1715

0 commit comments

Comments
 (0)