From efc67decbbd03958e14327df3a6d4c58f3a0182f Mon Sep 17 00:00:00 2001
From: Mohamed Gaber
Date: Fri, 3 Oct 2025 15:36:08 +0300
Subject: [PATCH 1/5] chore: update to librelane 2.4.2, cleanup
---
.github/workflows/main.yml | 54 ++---
Contributing.md | 14 +-
Readme.md | 2 +-
dffram.py | 192 +-----------------
docs/Usage.md | 47 +----
docs/md/Getting Sky130.md | 19 --
flake.lock | 125 ++++++++++++
flake.nix | 14 ++
librelane_plugin_dffram/__init__.py | 2 +
librelane_plugin_dffram/flows.py | 47 +++++
librelane_plugin_dffram/steps.py | 132 ++++++++++++
models/ram/model.v | 20 +-
models/rf/model.v | 24 +--
placeram/__init__.py | 18 +-
placeram/__main__.py | 18 +-
placeram/cli.py | 23 +--
placeram/common_data.py | 18 +-
placeram/data.py | 18 +-
placeram/placeable.py | 3 +
placeram/reg_data.py | 18 +-
placeram/row.py | 18 +-
placeram/util.py | 18 +-
.../block_definitions.v | 23 +--
.../sky130_fd_sc_hd/block_definitions.v | 23 +--
requirements.txt | 2 +-
rtl/gen_rtl.py | 18 +-
scripts/python/render.py | 18 +-
scripts/python/sky130_hd_hack.py | 2 +-
scripts/python/unplace.py | 18 +-
shell.nix | 23 ---
verification/gen_tb.py | 18 +-
verification/tb_template.py | 18 +-
32 files changed, 410 insertions(+), 597 deletions(-)
delete mode 100644 docs/md/Getting Sky130.md
create mode 100644 flake.lock
create mode 100644 flake.nix
create mode 100644 librelane_plugin_dffram/__init__.py
create mode 100644 librelane_plugin_dffram/flows.py
create mode 100644 librelane_plugin_dffram/steps.py
delete mode 100644 shell.nix
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 53e70c7..751e141 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -8,10 +8,10 @@ name: CI
jobs:
lint_models:
name: Lint All Models
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
steps:
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v5
- name: Get IcarusVerilog
run: |
sudo apt-get install -y iverilog
@@ -24,7 +24,7 @@ jobs:
done
lint_python:
name: Lint Python Code
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
steps:
- name: Check out Git repository
uses: actions/checkout@v2
@@ -32,7 +32,7 @@ jobs:
run: make lint
verify_models:
name: Verify (${{ matrix.count }}x${{ matrix.width }}_${{ matrix.variant }})
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
needs: [lint_models]
strategy:
matrix:
@@ -53,7 +53,7 @@ jobs:
- { count: "2048", width: "32", variant: "1RW1R" }
steps:
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v5
- name: Get IcarusVerilog
run: |
sudo apt-get install -y iverilog
@@ -68,7 +68,7 @@ jobs:
/bin/bash -c "! make | grep -c FATAL"
harden:
name: Harden (${{ matrix.count }}x${{ matrix.width }}_${{ matrix.variant }})
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
needs: [lint_models, lint_python]
strategy:
fail-fast: false
@@ -90,15 +90,15 @@ jobs:
#- { count: "256", width: "32", variant: "1RW1R" } # Timeout
steps:
- name: Checkout code
- uses: actions/checkout@v3
- - name: Setup Nix
- uses: cachix/install-nix-action@v22
- with:
- nix_path: nixpkgs=channel:nixos-23.05
- - name: Setup Cachix
- uses: cachix/cachix-action@v12
- with:
- name: openlane
+ uses: actions/checkout@v5
+ - name: Install Lix
+ run: |
+ curl --proto '=https' --tlsv1.2 -sSf -L https://install.lix.systems/lix | sh -s -- install --no-confirm --extra-conf "
+ access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
+ experimental-features = nix-command flakes
+ "
+ echo "extra-substituters = https://nix-cache.fossi-foundation.org" | sudo tee -a /etc/nix/nix.conf
+ echo "extra-trusted-public-keys = nix-cache.fossi-foundation.org:3+K59iFwXqKsL7BNu6Guy0v+uTlwsxYQxjspXzqLYQs=" | sudo tee -a /etc/nix/nix.conf
- name: Run
run: |
building_blocks=ram
@@ -106,12 +106,12 @@ jobs:
building_blocks=rf
fi
- nix-shell --pure --run "\
+ nix develop --command "\
./dffram.py ${{ matrix.count }}x${{ matrix.width }}\
- -p sky130A\
- -s sky130_fd_sc_hd\
- -v ${{ matrix.variant }}\
- -b $building_blocks\
+ -p sky130A\
+ -s sky130_fd_sc_hd\
+ -v ${{ matrix.variant }}\
+ -b $building_blocks\
"
echo "PRODUCTS_PATH=$(echo products/*)" >> $GITHUB_ENV
@@ -122,7 +122,7 @@ jobs:
# name: BUILD_${{ matrix.count }}x${{ matrix.width }}_${{ matrix.variant }}
# path: ./build
- name: Upload Final Views
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: ${{ matrix.count }}x${{ matrix.width }}_${{ matrix.variant }}
path: ${{ env.PRODUCTS_PATH }}
@@ -130,9 +130,9 @@ jobs:
name: Publish Release
if: always()
needs: [harden, verify_models]
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Export Repo URL
@@ -147,8 +147,12 @@ jobs:
if [ "${{ github.event_name }}" != "pull_request" ] && [ "${{ env.BRANCH_NAME }}" = "main" ]; then
python3 ./.github/scripts/generate_tag.py
fi
- - name: Download All Artifacts
- uses: actions/download-artifact@v3
+ - name: Merge Artifacts
+ uses: actions/upload-artifact/merge@v4
+ with:
+ delete-merged: true
+ - name: Download Artifacts
+ uses: actions/download-artifact@v4
with:
path: ./artifacts
- name: Create Release
diff --git a/Contributing.md b/Contributing.md
index 1ee49bb..442036d 100644
--- a/Contributing.md
+++ b/Contributing.md
@@ -15,7 +15,7 @@ Ensure that your local git clone also has an `upstream` remote. You can add it v
```sh
git remote get-url upstream
> fatal: No such remote 'upstream'
-git remote add upstream https://github.com/Cloud-V/DFFRAM`
+git remote add upstream https://github.com/AUCOHL/DFFRAM`
```
You can start a rebase by typing:
@@ -39,17 +39,7 @@ git push -fu origin main
Then, create your pull request. If all went well, the CI should pass.
## Note to maintainers
+
If the number of commits is low, rebase and merge, but if it is high (5 commits or more), squash and merge.
Squash and merge makes for a cleaner commit history, but will require pretty much everyone to rebase any work they've had off the main branch with a great degree more difficulty.
-
-# Legal
-By submitting a pull request, you (the Contributor) hereby grant The American University in Cairo a world-wide, royalty-free, non-exclusive license under intellectual property rights (other than patent or trademark) licensable by such Contributor to:
-
-* use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work;
-
-* under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version.
-
-Copyright notice: above text adapted from the Mozilla Public License, version 2.0.
-
-You are entitled and encouraged to add your name and email to the AUTHORS document at the root of the repository under 'Other Contributors', as well as include your name in any modified or created file.
\ No newline at end of file
diff --git a/Readme.md b/Readme.md
index 355700d..5cd6ea1 100644
--- a/Readme.md
+++ b/Readme.md
@@ -4,7 +4,7 @@
-
+
diff --git a/dffram.py b/dffram.py
index 907351d..337f128 100755
--- a/dffram.py
+++ b/dffram.py
@@ -1,194 +1,18 @@
#!/usr/bin/env python3
# -*- coding: utf8 -*-
-# Copyright ©2020-2023 The American University in Cairo
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2025, The American University in Cairo
# Copyright ©2023 Efabless Corporation
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
import os
import re
-import math
-from typing import List
from fnmatch import fnmatch
from decimal import Decimal
import yaml
import cloup
-from openlane.common import mkdirp
-from openlane.config import Variable
-from openlane.logging import warn, err
-from openlane.state import DesignFormat
-from openlane.flows import SequentialFlow, cloup_flow_opts, Flow
-from openlane.steps import Yosys, OpenROAD, Magic, KLayout, Netgen, Odb, Checker, Misc
-
-
-class PlaceRAM(Odb.OdbpyStep):
- id = "DFFRAM.PlaceRAM"
-
- config_vars = [
- Variable(
- "RAM_SIZE",
- str,
- "The size of the RAM macro being hardened the format {words}x{bits}",
- ),
- Variable(
- "BUILDING_BLOCKS",
- str,
- "The set of building blocks being used.",
- default="ram",
- ),
- ]
-
- def get_script_path(self):
- return "placeram"
-
- def get_command(self) -> List[str]:
- raw = super().get_command() + [
- "--building-blocks",
- f"{self.config['PDK']}:{self.config['STD_CELL_LIBRARY']}:{self.config['BUILDING_BLOCKS']}",
- "--size",
- self.config["RAM_SIZE"],
- ]
- raw.insert(raw.index("placeram"), "-m")
- return raw
-
-
-class Floorplan(OpenROAD.Floorplan):
- id = "DFFRAM.Floorplan"
-
- outputs = [
- DesignFormat.ODB,
- ]
-
- config_vars = [
- var
- for var in OpenROAD.Floorplan.config_vars
- if var.name not in ["FP_SIZING", "CORE_AREA", "DIE_AREA"]
- ] + [
- Variable(
- "HORIZONTAL_HALO",
- type=Decimal,
- description="The space between the horizontal edges of the die area and the core area in microns.",
- units="µm",
- default=2.5,
- ),
- Variable(
- "VERTICAL_HALO",
- type=Decimal,
- description="The space between the vertical edges of the die area and the core area in microns.",
- units="µm",
- default=2.5,
- ),
- Variable(
- "MINIMUM_HEIGHT",
- type=Decimal,
- description="A minimum height to be applied",
- default=0,
- units="µm",
- ),
- ]
-
- def run(self, state_in, **kwargs):
- min_height = self.config["MINIMUM_HEIGHT"]
-
- core_width = Decimal(
- state_in.metrics.get("dffram__suggested__core_width") or 20000
- )
- core_height = Decimal(
- state_in.metrics.get("dffram__suggested__core_height") or 20000
- )
-
- horizontal_halo = self.config["HORIZONTAL_HALO"]
- vertical_halo = self.config["VERTICAL_HALO"]
-
- pdk = self.config["PDK"]
- scl = self.config["STD_CELL_LIBRARY"]
-
- tech_info_path = os.path.join(".", "platforms", pdk, scl, "tech.yml")
- tech_info = yaml.safe_load(open(tech_info_path))
- site_info = tech_info.get("site")
-
- site_width = Decimal(1)
- site_height = Decimal(1)
-
- if site_info is not None:
- site_width = Decimal(site_info["width"])
- site_height = Decimal(site_info["height"])
-
- horizontal_halo = math.ceil(horizontal_halo / site_width) * site_width
- vertical_halo = math.ceil(vertical_halo / site_height) * site_height
- else:
- if horizontal_halo != 0.0 or vertical_halo != 0.0:
- warn(
- "Note: This platform does not have site information. The halo will not be rounded up to the nearest number of sites. This may cause off-by-one issues with some tools."
- )
-
- die_width = core_width + horizontal_halo * 2
- die_height = core_height + vertical_halo * 2
- if die_height < min_height:
- die_height = min_height
- vertical_halo = (die_height - core_height) / 2
- vertical_halo = math.ceil(vertical_halo / site_height) * site_height
-
- kwargs, env = self.extract_env(kwargs)
-
- env["DIE_AREA"] = f"0 0 {die_width} {die_height}"
- env[
- "CORE_AREA"
- ] = f"{horizontal_halo} {vertical_halo} {horizontal_halo + core_width} {vertical_halo + core_height}"
- env["FP_SIZING"] = "absolute"
- return super().run(state_in, env=env, **kwargs)
-
-
-@Flow.factory.register()
-class DFFRAM(SequentialFlow):
- Steps = [
- Yosys.Synthesis,
- Misc.LoadBaseSDC,
- OpenROAD.STAPrePNR,
- Floorplan,
- PlaceRAM,
- Floorplan,
- PlaceRAM,
- OpenROAD.IOPlacement,
- Odb.CustomIOPlacement,
- OpenROAD.GeneratePDN,
- OpenROAD.STAMidPNR,
- OpenROAD.GlobalRouting,
- OpenROAD.STAMidPNR,
- OpenROAD.DetailedRouting,
- Checker.TrDRC,
- Odb.ReportDisconnectedPins,
- Checker.DisconnectedPins,
- Odb.ReportWireLength,
- Checker.WireLength,
- OpenROAD.RCX,
- OpenROAD.STAPostPNR,
- OpenROAD.IRDropReport,
- Magic.StreamOut,
- Magic.WriteLEF,
- KLayout.StreamOut,
- KLayout.XOR,
- Checker.XOR,
- Magic.DRC,
- Checker.MagicDRC,
- Magic.SpiceExtraction,
- Checker.IllegalOverlap,
- Netgen.LVS,
- Checker.LVS,
- ]
+from librelane.common import mkdirp
+from librelane.logging import err
+from librelane.flows import cloup_flow_opts, Flow
@cloup.command()
@@ -319,7 +143,7 @@ def main(
rt_max_layer = tech_info["metal_layers"]["rt-max-layer"]
- TargetFlow = Flow.factory.get(flow_name) or DFFRAM
+ TargetFlow = Flow.factory.get(flow_name) or Flow.factory.get("DFFRAMFlow")
dffram_flow = TargetFlow(
{
"DESIGN_NAME": design,
@@ -339,8 +163,6 @@ def main(
],
"SYNTH_ELABORATE_ONLY": True,
"SYNTH_ELABORATE_FLATTEN": True,
- "SYNTH_READ_BLACKBOX_LIB": True,
- "SYNTH_EXCLUSION_CELL_LIST": "/dev/null",
"SYNTH_PARAMETERS": [f"WSIZE={logical_width}"],
"GRT_REPAIR_ANTENNAS": False,
"MINIMUM_HEIGHT": min_height,
@@ -356,7 +178,7 @@ def main(
"FP_IO_VLENGTH": 2,
"FP_IO_HLENGTH": 2,
# PDN
- "DESIGN_IS_CORE": False,
+ "FP_PDN_MULTILAYER": False,
},
design_dir=os.path.abspath(build_dir),
pdk_root=pdk_root,
diff --git a/docs/Usage.md b/docs/Usage.md
index 854a9e3..5e27ce0 100644
--- a/docs/Usage.md
+++ b/docs/Usage.md
@@ -14,53 +14,14 @@ the RAM modules from elaboration to GDS-II stream out. It incorporates `placeram
* The Nix Package Manager
## Installing Nix
-You can install Nix by following the instructions at https://nixos.org/download.html.
-Or more simply, on Ubuntu, run the following in your Terminal:
-
-```sh
-sudo apt-get install -y curl
-sh <(curl -L https://nixos.org/nix/install) --daemon --yes
-```
-> On not systemd-based Linux systems, replace `--daemon` with `--no-daemon`.
-
-Or on macOS:
-
-```sh
-sh <(curl -L https://nixos.org/nix/install) --yes
-```
-
-Enter your password if prompted. This hsould take around 5 minutes.
-
-Make sure to close all terminals after you're done with this step.
-
-### Setting up the binary cache
-Cachix allows the reproducible Nix builds to be stored on a cloud server so you
-do not have to build OpenLane's dependencies from scratch on every computer,
-which will take a long time.
-
-First, you want to install Cachix by running the following in your terminal:
-
-```sh
-nix-env -f "" -iA cachix
-```
-
-Then set up the OpenLane binary cache as follows:
-
-```sh
-cachix use openlane
-```
-If `cachix use openlane` fails, re-run it as follows:
-
-```sh
-sudo env PATH="$PATH" cachix use openlane
-```
+Follow the guide at https://librelane.readthedocs.io/en/latest/getting_started/common/nix_installation/index.html
# Basic
```sh
-git clone https://github.com/Cloud-V/DFFRAM
+git clone https://github.com/AUCOHL/DFFRAM
cd DFFRAM
-nix-shell
+nix develop
./dffram.py 8x32 # <8-2048>x<8-64>
```
@@ -97,4 +58,4 @@ FORCE_DESIGN_NAME|Design names are found based on the size. If you'd like to for
# Appendices
- [Appendix A: Using Opendbpy](./md/Using%20Opendbpy.md)
-- [Appendix B: How PlaceRAM Works](./md/How%20PlaceRAM%20Works.md)
\ No newline at end of file
+- [Appendix B: How PlaceRAM Works](./md/How%20PlaceRAM%20Works.md)
diff --git a/docs/md/Getting Sky130.md b/docs/md/Getting Sky130.md
deleted file mode 100644
index 651d0e8..0000000
--- a/docs/md/Getting Sky130.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Getting Sky130
-The best way to get it is via [Openlane](https://github.com/The-OpenROAD-Project/OpenLane): you clone that repo then run:
-
-```sh
-export PDK_ROOT=/usr/local/pdk
-make pdk
-```
-
-Another option is to get a pre-built:
-
-```sh
-export PDK_ROOT=$(realpath ~/pdklite)
-git clone --depth 1 https://github.com/olofk/pdklite $PDK_ROOT
-```
-
-I would really recommend adding whichever you exported as `PDK_ROOT` to your shell's profile.
-
-## I don't have `realpath` on macOS!
-`brew install coreutils`
\ No newline at end of file
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000..cabadfe
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,125 @@
+{
+ "nodes": {
+ "ciel": {
+ "inputs": {
+ "nix-eda": [
+ "librelane",
+ "nix-eda"
+ ]
+ },
+ "locked": {
+ "lastModified": 1751196116,
+ "narHash": "sha256-y6w1MYMsgfSUPdJoKc+k+4xg0Zi1dUQtv+z71vyCLDU=",
+ "owner": "fossi-foundation",
+ "repo": "ciel",
+ "rev": "1260b5f7d752e457d0bef3b1d9ab7fd044ad9c83",
+ "type": "github"
+ },
+ "original": {
+ "owner": "fossi-foundation",
+ "repo": "ciel",
+ "type": "github"
+ }
+ },
+ "devshell": {
+ "inputs": {
+ "nixpkgs": [
+ "librelane",
+ "nix-eda",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1741473158,
+ "narHash": "sha256-kWNaq6wQUbUMlPgw8Y+9/9wP0F8SHkjy24/mN3UAppg=",
+ "owner": "numtide",
+ "repo": "devshell",
+ "rev": "7c9e793ebe66bcba8292989a68c0419b737a22a0",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "devshell",
+ "type": "github"
+ }
+ },
+ "flake-compat": {
+ "locked": {
+ "lastModified": 1733328505,
+ "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
+ "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
+ "revCount": 69,
+ "type": "tarball",
+ "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.1.0/01948eb7-9cba-704f-bbf3-3fa956735b52/source.tar.gz"
+ },
+ "original": {
+ "type": "tarball",
+ "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"
+ }
+ },
+ "librelane": {
+ "inputs": {
+ "ciel": "ciel",
+ "devshell": "devshell",
+ "flake-compat": "flake-compat",
+ "nix-eda": "nix-eda"
+ },
+ "locked": {
+ "lastModified": 1756988446,
+ "narHash": "sha256-3V4+1Pbhd2Q69IiTHqJjtPxh+vp+bNGydKhSj3eKsmE=",
+ "owner": "librelane",
+ "repo": "librelane",
+ "rev": "4dc53448d98f3688e0096873a88200b04d268c6c",
+ "type": "github"
+ },
+ "original": {
+ "owner": "librelane",
+ "ref": "2.4.2",
+ "repo": "librelane",
+ "type": "github"
+ }
+ },
+ "nix-eda": {
+ "inputs": {
+ "nixpkgs": "nixpkgs"
+ },
+ "locked": {
+ "lastModified": 1749403175,
+ "narHash": "sha256-+VKZ7ZrVpJxVGA0ULHO4GkDwXNFx2kZvw9TeBTpuqqA=",
+ "owner": "fossi-foundation",
+ "repo": "nix-eda",
+ "rev": "abf388eeae6e55da82adefb9e74e21acea9e5888",
+ "type": "github"
+ },
+ "original": {
+ "owner": "fossi-foundation",
+ "ref": "2.1.3",
+ "repo": "nix-eda",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1717144377,
+ "narHash": "sha256-F/TKWETwB5RaR8owkPPi+SPJh83AQsm6KrQAlJ8v/uA=",
+ "owner": "nixos",
+ "repo": "nixpkgs",
+ "rev": "805a384895c696f802a9bf5bf4720f37385df547",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nixos",
+ "ref": "nixos-24.05",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "librelane": "librelane"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 0000000..003531c
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,14 @@
+# The nix-eda flake template
+{
+ inputs = {
+ librelane.url = "github:librelane/librelane/2.4.2";
+ };
+
+ outputs = {
+ self,
+ librelane,
+ ...
+ }: {
+ devShells = librelane.devShells;
+ };
+}
diff --git a/librelane_plugin_dffram/__init__.py b/librelane_plugin_dffram/__init__.py
new file mode 100644
index 0000000..b5db667
--- /dev/null
+++ b/librelane_plugin_dffram/__init__.py
@@ -0,0 +1,2 @@
+from . import steps as DFFRAM # noqa: F401
+from . import flows # noqa: F401
diff --git a/librelane_plugin_dffram/flows.py b/librelane_plugin_dffram/flows.py
new file mode 100644
index 0000000..6ae9a6b
--- /dev/null
+++ b/librelane_plugin_dffram/flows.py
@@ -0,0 +1,47 @@
+# -*- coding: utf8 -*-
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2025, The American University in Cairo
+# Copyright ©2023 Efabless Corporation
+from librelane.flows import SequentialFlow, Flow
+from librelane.steps import Yosys, OpenROAD, Magic, KLayout, Netgen, Odb, Checker, Misc
+
+from . import steps as DFFRAM
+
+
+@Flow.factory.register()
+class DFFRAMFlow(SequentialFlow):
+ Steps = [
+ Yosys.Synthesis,
+ Misc.LoadBaseSDC,
+ OpenROAD.STAPrePNR,
+ DFFRAM.Floorplan,
+ DFFRAM.PlaceRAM,
+ DFFRAM.Floorplan,
+ DFFRAM.PlaceRAM,
+ OpenROAD.IOPlacement,
+ Odb.CustomIOPlacement,
+ OpenROAD.GeneratePDN,
+ OpenROAD.STAMidPNR,
+ OpenROAD.GlobalRouting,
+ OpenROAD.STAMidPNR,
+ OpenROAD.DetailedRouting,
+ Checker.TrDRC,
+ Odb.ReportDisconnectedPins,
+ Checker.DisconnectedPins,
+ Odb.ReportWireLength,
+ Checker.WireLength,
+ OpenROAD.RCX,
+ OpenROAD.STAPostPNR,
+ OpenROAD.IRDropReport,
+ Magic.StreamOut,
+ Magic.WriteLEF,
+ KLayout.StreamOut,
+ KLayout.XOR,
+ Checker.XOR,
+ Magic.DRC,
+ Checker.MagicDRC,
+ Magic.SpiceExtraction,
+ Checker.IllegalOverlap,
+ Netgen.LVS,
+ Checker.LVS,
+ ]
diff --git a/librelane_plugin_dffram/steps.py b/librelane_plugin_dffram/steps.py
new file mode 100644
index 0000000..2d6f4fd
--- /dev/null
+++ b/librelane_plugin_dffram/steps.py
@@ -0,0 +1,132 @@
+# -*- coding: utf8 -*-
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2025, The American University in Cairo
+# Copyright ©2023 Efabless Corporation
+import os
+import math
+from typing import List
+from decimal import Decimal
+
+import yaml
+from librelane.config import Variable
+from librelane.logging import warn
+from librelane.state import DesignFormat
+from librelane.steps import OpenROAD, Odb
+
+
+class PlaceRAM(Odb.OdbpyStep):
+ id = "DFFRAM.PlaceRAM"
+
+ config_vars = [
+ Variable(
+ "RAM_SIZE",
+ str,
+ "The size of the RAM macro being hardened the format {words}x{bits}",
+ ),
+ Variable(
+ "BUILDING_BLOCKS",
+ str,
+ "The set of building blocks being used.",
+ default="ram",
+ ),
+ ]
+
+ def get_script_path(self):
+ return "placeram"
+
+ def get_command(self) -> List[str]:
+ raw = super().get_command() + [
+ "--building-blocks",
+ f"{self.config['PDK']}:{self.config['STD_CELL_LIBRARY']}:{self.config['BUILDING_BLOCKS']}",
+ "--size",
+ self.config["RAM_SIZE"],
+ ]
+ raw.insert(raw.index("placeram"), "-m")
+ return raw
+
+
+class Floorplan(OpenROAD.Floorplan):
+ id = "DFFRAM.Floorplan"
+
+ outputs = [
+ DesignFormat.ODB,
+ ]
+
+ config_vars = [
+ var
+ for var in OpenROAD.Floorplan.config_vars
+ if var.name not in ["FP_SIZING", "CORE_AREA", "DIE_AREA"]
+ ] + [
+ Variable(
+ "HORIZONTAL_HALO",
+ type=Decimal,
+ description="The space between the horizontal edges of the die area and the core area in microns.",
+ units="µm",
+ default=2.5,
+ ),
+ Variable(
+ "VERTICAL_HALO",
+ type=Decimal,
+ description="The space between the vertical edges of the die area and the core area in microns.",
+ units="µm",
+ default=2.5,
+ ),
+ Variable(
+ "MINIMUM_HEIGHT",
+ type=Decimal,
+ description="A minimum height to be applied",
+ default=0,
+ units="µm",
+ ),
+ ]
+
+ def run(self, state_in, **kwargs):
+ min_height = self.config["MINIMUM_HEIGHT"]
+
+ core_width = Decimal(
+ state_in.metrics.get("dffram__suggested__core_width") or 20000
+ )
+ core_height = Decimal(
+ state_in.metrics.get("dffram__suggested__core_height") or 20000
+ )
+
+ horizontal_halo = self.config["HORIZONTAL_HALO"]
+ vertical_halo = self.config["VERTICAL_HALO"]
+
+ pdk = self.config["PDK"]
+ scl = self.config["STD_CELL_LIBRARY"]
+
+ tech_info_path = os.path.join(".", "platforms", pdk, scl, "tech.yml")
+ tech_info = yaml.safe_load(open(tech_info_path))
+ site_info = tech_info.get("site")
+
+ site_width = Decimal(1)
+ site_height = Decimal(1)
+
+ if site_info is not None:
+ site_width = Decimal(site_info["width"])
+ site_height = Decimal(site_info["height"])
+
+ horizontal_halo = math.ceil(horizontal_halo / site_width) * site_width
+ vertical_halo = math.ceil(vertical_halo / site_height) * site_height
+ else:
+ if horizontal_halo != 0.0 or vertical_halo != 0.0:
+ warn(
+ "Note: This platform does not have site information. The halo will not be rounded up to the nearest number of sites. This may cause off-by-one issues with some tools."
+ )
+
+ die_width = core_width + horizontal_halo * 2
+ die_height = core_height + vertical_halo * 2
+ if die_height < min_height:
+ die_height = min_height
+ vertical_halo = (die_height - core_height) / 2
+ vertical_halo = math.ceil(vertical_halo / site_height) * site_height
+
+ kwargs, env = self.extract_env(kwargs)
+
+ env["DIE_AREA"] = f"0 0 {die_width} {die_height}"
+ env["CORE_AREA"] = (
+ f"{horizontal_halo} {vertical_halo} {horizontal_halo + core_width} {vertical_halo + core_height}"
+ )
+ env["FP_SIZING"] = "absolute"
+ return super().run(state_in, env=env, **kwargs)
diff --git a/models/ram/model.v b/models/ram/model.v
index 943711f..b33d03f 100644
--- a/models/ram/model.v
+++ b/models/ram/model.v
@@ -1,21 +1,5 @@
-/*
- Copyright ©2020-2022 The American University in Cairo
-
- This file is part of the DFFRAM Memory Compiler.
- See https://github.com/Cloud-V/DFFRAM for further info.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
+// SPDX-License-Identifier: Apache-2.0
+// Copyright ©2020-2022, The American University in Cairo
// Add 1x2 binary decoder
`default_nettype none
diff --git a/models/rf/model.v b/models/rf/model.v
index 6736b15..34fb9d5 100644
--- a/models/rf/model.v
+++ b/models/rf/model.v
@@ -1,24 +1,8 @@
-/*
- Copyright ©2020-2022 The American University in Cairo
-
- This file is part of the DFFRAM Memory Compiler.
- See https://github.com/Cloud-V/DFFRAM for further info.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
+// SPDX-License-Identifier: Apache-2.0
+// Copyright ©2020-2022, The American University in Cairo
/*
- DFFRFile
- Mohamed Shalan (mshalan@aucegypt.edu)
+ Module: DFFRF_2R1W
+ Author: Mohamed Shalan (mshalan@aucegypt.edu)
32x32 Register File with 2RW1W ports and clock gating for SKY130A
~ 3550 Cells
< 2ns (no input or output delays)
diff --git a/placeram/__init__.py b/placeram/__init__.py
index 38e688e..9d92d15 100644
--- a/placeram/__init__.py
+++ b/placeram/__init__.py
@@ -1,19 +1,5 @@
# -*- coding: utf8 -*-
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
__version__ = "0.0.1"
diff --git a/placeram/__main__.py b/placeram/__main__.py
index c78b24e..5358079 100644
--- a/placeram/__main__.py
+++ b/placeram/__main__.py
@@ -1,21 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf8 -*-
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
from .cli import main
diff --git a/placeram/cli.py b/placeram/cli.py
index b5cbd95..1aa5b94 100644
--- a/placeram/cli.py
+++ b/placeram/cli.py
@@ -1,20 +1,6 @@
# -*- coding: utf8 -*-
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2025, The American University in Cairo
import os
import re
@@ -23,6 +9,7 @@
try:
import odb
import utl
+ from openroad import Tech, Design
except ImportError:
print(
"""
@@ -63,7 +50,9 @@ def __init__(
tap_distance,
):
# Initialize Database
- self.db = odb.dbDatabase.create()
+ self.ord_tech = Tech()
+ self.design = Design(self.ord_tech)
+ self.db = self.ord_tech.getDB()
odb.read_db(self.db, odb_in)
diff --git a/placeram/common_data.py b/placeram/common_data.py
index bc4faea..91003ac 100644
--- a/placeram/common_data.py
+++ b/placeram/common_data.py
@@ -1,20 +1,6 @@
# -*- coding: utf8 -*-
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
from .row import Row
from .util import d2a
from .placeable import Placeable
diff --git a/placeram/data.py b/placeram/data.py
index 49ee648..a45679a 100644
--- a/placeram/data.py
+++ b/placeram/data.py
@@ -1,20 +1,6 @@
# -*- coding: utf8 -*-
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
from .util import d2a
from .row import Row
from .placeable import Placeable, DataError
diff --git a/placeram/placeable.py b/placeram/placeable.py
index 7340387..959fb59 100644
--- a/placeram/placeable.py
+++ b/placeram/placeable.py
@@ -1,3 +1,6 @@
+# -*- coding: utf8 -*-
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
import os
import re
import sys
diff --git a/placeram/reg_data.py b/placeram/reg_data.py
index 2a33362..3321a34 100644
--- a/placeram/reg_data.py
+++ b/placeram/reg_data.py
@@ -1,20 +1,6 @@
# -*- coding: utf8 -*-
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
from .row import Row
from .util import d2a
diff --git a/placeram/row.py b/placeram/row.py
index d45c925..8ad682c 100644
--- a/placeram/row.py
+++ b/placeram/row.py
@@ -1,20 +1,6 @@
# -*- coding: utf8 -*-
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
from odb import dbRow, dbInst, dbSite
from typing import List, Callable
diff --git a/placeram/util.py b/placeram/util.py
index 2a6ff0b..b17c68d 100644
--- a/placeram/util.py
+++ b/placeram/util.py
@@ -1,20 +1,6 @@
# -*- coding: utf8 -*-
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
import sys
import collections
diff --git a/platforms/gf180mcuD/gf180mcu_fd_sc_mcu7t5v0/block_definitions.v b/platforms/gf180mcuD/gf180mcu_fd_sc_mcu7t5v0/block_definitions.v
index 7fd5583..50fecff 100644
--- a/platforms/gf180mcuD/gf180mcu_fd_sc_mcu7t5v0/block_definitions.v
+++ b/platforms/gf180mcuD/gf180mcu_fd_sc_mcu7t5v0/block_definitions.v
@@ -1,22 +1,5 @@
-/*
- Copyright ©2020-2021 The American University in Cairo and the Cloud V Project.
-
- This file is part of the DFFRAM Memory Compiler.
- See https://github.com/Cloud-V/DFFRAM for further info.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
+// SPDX-License-Identifier: Apache-2.0
+// Copyright ©2020-2022, The American University in Cairo
// Add 1x2 binary decoder
`default_nettype none
@@ -468,4 +451,4 @@ module RFWORD0 #(parameter WSIZE=32)
gf180mcu_fd_sc_mcu7t5v0__bufz_1 OBUF2 ( .I(lo[4+i/8]), .Z(D2[i]), .EN(SEL2_B_N[i/8]) );
end
endgenerate
-endmodule
\ No newline at end of file
+endmodule
diff --git a/platforms/sky130A/sky130_fd_sc_hd/block_definitions.v b/platforms/sky130A/sky130_fd_sc_hd/block_definitions.v
index a0f1325..5994f5a 100644
--- a/platforms/sky130A/sky130_fd_sc_hd/block_definitions.v
+++ b/platforms/sky130A/sky130_fd_sc_hd/block_definitions.v
@@ -1,22 +1,5 @@
-/*
- Copyright ©2020-2022 The American University in Cairo
-
- This file is part of the DFFRAM Memory Compiler.
- See https://github.com/Cloud-V/DFFRAM for further info.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
+// SPDX-License-Identifier: Apache-2.0
+// Copyright ©2020-2022, The American University in Cairo
// Add 1x2 binary decoder
`default_nettype none
@@ -417,4 +400,4 @@ module RFWORD0 #(parameter WSIZE=32)
sky130_fd_sc_hd__ebufn_2 OBUF2 ( .A(lo[4+i/8]), .Z(D2[i]), .TE_B(SEL2_B[i/8]) );
end
endgenerate
-endmodule
\ No newline at end of file
+endmodule
diff --git a/requirements.txt b/requirements.txt
index 640b328..579ec73 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,3 @@
-openlane==2.0.0b16
+librelane>=2.4.0,<3
pyyaml
cloup
diff --git a/rtl/gen_rtl.py b/rtl/gen_rtl.py
index 25b4519..5c11675 100755
--- a/rtl/gen_rtl.py
+++ b/rtl/gen_rtl.py
@@ -1,21 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf8 -*-
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
import os
import pathlib
import traceback
diff --git a/scripts/python/render.py b/scripts/python/render.py
index 6c446c1..4c46cf3 100644
--- a/scripts/python/render.py
+++ b/scripts/python/render.py
@@ -1,21 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf8 -*-
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
import gdstk
import subprocess
diff --git a/scripts/python/sky130_hd_hack.py b/scripts/python/sky130_hd_hack.py
index dd2a659..e05162b 100755
--- a/scripts/python/sky130_hd_hack.py
+++ b/scripts/python/sky130_hd_hack.py
@@ -3,7 +3,7 @@
# Copyright ©2021 The American University in Cairo
#
# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
+# See https://github.com/AUCOHL/DFFRAM for further info.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/scripts/python/unplace.py b/scripts/python/unplace.py
index ddbafb8..404225e 100644
--- a/scripts/python/unplace.py
+++ b/scripts/python/unplace.py
@@ -1,21 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf8 -*-
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
import os
import re
diff --git a/shell.nix b/shell.nix
deleted file mode 100644
index 142f0f7..0000000
--- a/shell.nix
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2023 Efabless Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-{
- pkgs ? import {}
-}:
-
-let openlane-src = pkgs.fetchFromGitHub {
- owner = "efabless";
- repo = "openlane2";
- rev = "83ec6c32add40006cc70d951745667d30193f51d";
- sha256 = "sha256-9Xms6eRf3yyaFJVVjk+uPYYM+EDRl4GYAYYUK5QhiLc=";
-}; in import "${openlane-src}/shell.nix" {}
diff --git a/verification/gen_tb.py b/verification/gen_tb.py
index 232da62..e3f1e59 100755
--- a/verification/gen_tb.py
+++ b/verification/gen_tb.py
@@ -1,20 +1,6 @@
#!/usr/bin/env python3
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
import tb_template as RAM_tb
import sys
diff --git a/verification/tb_template.py b/verification/tb_template.py
index 8b4da52..32b2ece 100644
--- a/verification/tb_template.py
+++ b/verification/tb_template.py
@@ -1,20 +1,6 @@
# -*- coding: utf8 -*-
-# Copyright ©2020-2022 The American University in Cairo
-#
-# This file is part of the DFFRAM Memory Compiler.
-# See https://github.com/Cloud-V/DFFRAM for further info.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# Copyright ©2020-2022, The American University in Cairo
RAM_instantiation = """
/*
From 529ca010ac213852ce959521808b22ee80ced551 Mon Sep 17 00:00:00 2001
From: Mohamed Gaber
Date: Sat, 4 Oct 2025 08:40:04 +0300
Subject: [PATCH 2/5] reconfigure steps and flow as a librelane plugin
(+ i attempted to fold resizing the floorplan into PlaceRAM and failed)
---
Makefile | 4 +-
Readme.md | 24 ++++---
dffram.py | 8 ++-
.../scripts/odbpy/placeram}/__init__.py | 0
.../scripts/odbpy/placeram}/__main__.py | 0
.../scripts/odbpy/placeram}/cli.py | 62 ++++++++++------
.../scripts/odbpy/placeram}/common_data.py | 0
.../scripts/odbpy/placeram}/data.py | 0
.../scripts/odbpy/placeram}/placeable.py | 20 ++++--
.../scripts/odbpy/placeram}/reg_data.py | 4 +-
.../scripts/odbpy/placeram}/row.py | 0
.../scripts/odbpy/placeram}/rx.yml | 0
.../scripts/odbpy/placeram}/util.py | 0
librelane_plugin_dffram/steps.py | 71 +++++++++++--------
models/ram/config.yml | 2 +-
.../gf180mcu_fd_sc_mcu7t5v0/tech.yml | 14 ++--
16 files changed, 124 insertions(+), 85 deletions(-)
rename {placeram => librelane_plugin_dffram/scripts/odbpy/placeram}/__init__.py (100%)
rename {placeram => librelane_plugin_dffram/scripts/odbpy/placeram}/__main__.py (100%)
rename {placeram => librelane_plugin_dffram/scripts/odbpy/placeram}/cli.py (86%)
rename {placeram => librelane_plugin_dffram/scripts/odbpy/placeram}/common_data.py (100%)
rename {placeram => librelane_plugin_dffram/scripts/odbpy/placeram}/data.py (100%)
rename {placeram => librelane_plugin_dffram/scripts/odbpy/placeram}/placeable.py (89%)
rename {placeram => librelane_plugin_dffram/scripts/odbpy/placeram}/reg_data.py (99%)
rename {placeram => librelane_plugin_dffram/scripts/odbpy/placeram}/row.py (100%)
rename {placeram => librelane_plugin_dffram/scripts/odbpy/placeram}/rx.yml (100%)
rename {placeram => librelane_plugin_dffram/scripts/odbpy/placeram}/util.py (100%)
diff --git a/Makefile b/Makefile
index 1ec8f7a..d35d103 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ venv/manifest.txt: ./requirements_dev.txt
PYTHONPATH= ./venv/bin/python3 -m pip install --upgrade pip
PYTHONPATH= ./venv/bin/python3 -m pip install --upgrade wheel
PYTHONPATH= ./venv/bin/python3 -m pip install --upgrade\
- -r ./requirements_dev.txt
+ -r ./requirements_dev.txt -r ./requirements.txt
PYTHONPATH= ./venv/bin/python3 -m pip freeze > $@
touch venv/manifest.txt
@@ -30,4 +30,4 @@ clean:
rm -rf build/
rm -rf logs/
rm -rf dist/
- rm -rf *.egg-info
\ No newline at end of file
+ rm -rf *.egg-info
diff --git a/Readme.md b/Readme.md
index 5cd6ea1..744a209 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1,11 +1,8 @@
DFFRAM Compiler
-
-
-
-
+
@@ -21,11 +18,12 @@ but it is a bit out-of-date at this point.
## Platform Support Status
-| Configured Platform | Working | Silicon-proven\* |
+| Configured Platform | Signoff-clean | Silicon-proven\* |
| - | - | - |
-| `sky130A` | Yes | Yes |
-| `sky130B` | Yes | No |
-| `gf180mcuD` | No\* (Hold violations in the Netlist) | No |
+| `sky130A` (Latches) | Yes | Yes |
+| `sky130A` (DFF) | Yes | No |
+| `sky130B` (Latches/DFF) | Yes | No |
+| `gf180mcuD` (Latches/DFF) | No\* (Hold violations in the Netlist) | No |
> \* Silicon proven does not imply that you should use it without whole-system,
> timing-annotated simulation to make sure that it works for your circuit.
@@ -76,7 +74,11 @@ blocks are as follows:
Currently, the can compiler generate the layout of the following configurations:
-> 1RW1R variants are temporarily disabled due to a bug.
+> We currently do not recommend the use of 1RW1R. See this discussion for more
+> info:
+>
+> https://github.com/AUCOHL/DFFRAM/issues/198
+
* RAM
* 32 words with byte write enable (1RW and 1RW1R).
@@ -116,8 +118,8 @@ using different means.
Size1 |
OpenRAM2 |
DFFRAM Compiler |
- DFFRAM/OpenLane |
- RTL/OpenLane |
+ DFFRAM Netlist + OpenROAD Placer |
+ Memory RTL with OpenLane |
| Dim WxH (μm) | Bit Density (bits/mm2) |
diff --git a/dffram.py b/dffram.py
index 337f128..a21763c 100755
--- a/dffram.py
+++ b/dffram.py
@@ -47,6 +47,7 @@
type=Decimal,
help="Minimum height in µm",
)
+@cloup.option("--latch/--dff", default=True, help="Whether to use latches or dffs")
@cloup_flow_opts(accept_config_files=False)
@cloup.argument("size", default="32x32", nargs=1)
def main(
@@ -67,6 +68,7 @@ def main(
min_height,
flow_name,
pdk_root,
+ latch,
**kwargs,
):
if variant == "DEFAULT":
@@ -123,7 +125,9 @@ def main(
}
)
- build_dir = os.path.join("build", design)
+ build_dir = os.path.join(
+ "build", f"{pdk}-{scl}-{'latch' if latch else 'dff'}", design
+ )
mkdirp(build_dir)
tech_info_path = os.path.join(".", "platforms", pdk, scl, "tech.yml")
@@ -163,7 +167,7 @@ def main(
],
"SYNTH_ELABORATE_ONLY": True,
"SYNTH_ELABORATE_FLATTEN": True,
- "SYNTH_PARAMETERS": [f"WSIZE={logical_width}"],
+ "SYNTH_PARAMETERS": [f"WSIZE={logical_width}", f"USE_LATCH={int(latch)}"],
"GRT_REPAIR_ANTENNAS": False,
"MINIMUM_HEIGHT": min_height,
"VERTICAL_HALO": vertical_halo,
diff --git a/placeram/__init__.py b/librelane_plugin_dffram/scripts/odbpy/placeram/__init__.py
similarity index 100%
rename from placeram/__init__.py
rename to librelane_plugin_dffram/scripts/odbpy/placeram/__init__.py
diff --git a/placeram/__main__.py b/librelane_plugin_dffram/scripts/odbpy/placeram/__main__.py
similarity index 100%
rename from placeram/__main__.py
rename to librelane_plugin_dffram/scripts/odbpy/placeram/__main__.py
diff --git a/placeram/cli.py b/librelane_plugin_dffram/scripts/odbpy/placeram/cli.py
similarity index 86%
rename from placeram/cli.py
rename to librelane_plugin_dffram/scripts/odbpy/placeram/cli.py
index 1aa5b94..6e7e4ee 100644
--- a/placeram/cli.py
+++ b/librelane_plugin_dffram/scripts/odbpy/placeram/cli.py
@@ -107,8 +107,8 @@ def create_fill(name, sites=1):
fill_cell = self.fill_cells_by_sites[sites]
return odb.dbInst_create(self.block, fill_cell, name)
- self.micron_in_units = self.block.getDefUnits()
- tap_distance = self.micron_in_units * tap_distance
+ self.micron_in_dbus: int = self.block.getDefUnits()
+ tap_distance = self.micron_in_dbus * tap_distance
self.rows = Row.from_odb(
self.block.getRows(),
@@ -132,22 +132,49 @@ def represent(self, file):
def place(self):
eprint("Starting placement…")
- print(f"Placing across {len(self.rows)} rows...")
+ print(f"Placing across {len(self.rows)} rows…")
last_row = self.hierarchy.place(self.rows)
- print(f"Placement concluded with {last_row} rows...")
+
+ print(f"Placement concluded with {last_row} rows…")
Row.fill_rows(self.rows, 0, last_row)
# We can't rely on the fact that a placeable will probably fill
# before returning and pick the width of the nth row or whatever.
- width_units = 0
+ width_dbus: int = 0
for row in self.rows:
- width_units = max(row.width, width_units)
+ width_dbus = max(row.width, width_dbus)
- self.core_width = width_units / self.micron_in_units
+ height_dbus: int = self.rows[last_row - 1].ymax - self.rows[0].y
- height_units = self.rows[last_row - 1].ymax - self.rows[0].y
+ self.core_width = width_dbus / self.micron_in_dbus
+ self.core_height = height_dbus / self.micron_in_dbus
- self.core_height = height_units / self.micron_in_units
+ utl.metric_float("dffram__suggested__core_width", self.core_width)
+ utl.metric_float("dffram__suggested__core_height", self.core_height)
+
+ eprint(
+ "Placement concluded with core area of %fµm x %fµm."
+ % (self.core_width, self.core_height)
+ )
+
+ # resizing doesn't work - rows widths are immutable from python
+ # # resize
+ # width_margin: int = self.rows[0].x
+ # height_margin: int = self.rows[0].y
+ # die_height_dbus = height_dbus + height_margin * 2
+ # die_width_dbus = width_dbus + width_margin * 2
+
+ # die_rect = odb.Rect(0, 0, die_width_dbus, die_height_dbus)
+ # self.block.setDieArea(die_rect)
+ # for row in self.block.getRows():
+ # _, row_y = row.getOrigin()
+ # if row_y >= width_dbus + width_margin:
+ # odb.dbRow.destroy(row)
+
+ # calculate density
+ die_width = self.block.getDieArea().dx() / self.micron_in_dbus
+ die_height = self.block.getDieArea().dy() / self.micron_in_dbus
+ die_area = die_width * die_height
logical_area: float = 0
for cell in self.block.getInsts():
@@ -160,24 +187,13 @@ def place(self):
break
if type not in ["nonfiller"]:
continue
- width = master.getWidth() / self.micron_in_units
- height = master.getHeight() / self.micron_in_units
+ width = master.getWidth() / self.micron_in_dbus
+ height = master.getHeight() / self.micron_in_dbus
logical_area += width * height
- eprint(
- "Placement concluded with core area of %fµm x %fµm."
- % (self.core_width, self.core_height)
- )
-
- utl.metric_float("dffram__suggested__core_width", self.core_width)
- utl.metric_float("dffram__suggested__core_height", self.core_height)
-
- die_width = self.block.getDieArea().dx() / self.micron_in_units
- die_height = self.block.getDieArea().dy() / self.micron_in_units
- die_area = die_width * die_height
-
self.density = logical_area / die_area
utl.metric_float("dffram__logic__density", self.density)
+
eprint("Density: %.2f%%" % (self.density * 100))
eprint("Done.")
diff --git a/placeram/common_data.py b/librelane_plugin_dffram/scripts/odbpy/placeram/common_data.py
similarity index 100%
rename from placeram/common_data.py
rename to librelane_plugin_dffram/scripts/odbpy/placeram/common_data.py
diff --git a/placeram/data.py b/librelane_plugin_dffram/scripts/odbpy/placeram/data.py
similarity index 100%
rename from placeram/data.py
rename to librelane_plugin_dffram/scripts/odbpy/placeram/data.py
diff --git a/placeram/placeable.py b/librelane_plugin_dffram/scripts/odbpy/placeram/placeable.py
similarity index 89%
rename from placeram/placeable.py
rename to librelane_plugin_dffram/scripts/odbpy/placeram/placeable.py
index 959fb59..065cfc9 100644
--- a/placeram/placeable.py
+++ b/librelane_plugin_dffram/scripts/odbpy/placeram/placeable.py
@@ -18,15 +18,22 @@ def dbInst__repr__(self):
Instance.__repr__ = dbInst__repr__
-RegExp = str
+
+def _load_regexes():
+ compiled = {}
+ with open(os.path.join(os.path.dirname(__file__), "rx.yml"), encoding="utf8") as f:
+ _loading: Dict[str, Dict[str, str]] = yaml.safe_load(f)
+ for cls, patterns in _loading.items():
+ compiled.setdefault(cls, {})
+ for variable, rx in patterns.items():
+ compiled[cls][variable] = re.compile(rx)
+ return compiled
class Placeable(object):
- RegexDictionary: Dict[str, Dict[str, RegExp]] = yaml.safe_load(
- open(os.path.join(os.path.dirname(__file__), "rx.yml"))
- )
+ RegexDictionary: Dict[str, Dict[str, re.Pattern]] = _load_regexes()
- def regex_dict(self) -> Dict[str, RegExp]:
+ def regex_dict(self) -> Dict[str, re.Pattern]:
return Placeable.RegexDictionary[self.__class__.__name__]
class Sieve(object):
@@ -44,7 +51,6 @@ def __init__(
def sieve(self, instances: List[Instance], sieves: List[Sieve]):
regexes = self.regex_dict()
- compiled_regexes = {k: re.compile(v) for k, v in regexes.items()}
for sieve in sieves:
depth = len(sieve.groups)
if depth == 0:
@@ -56,7 +62,7 @@ def sieve(self, instances: List[Instance], sieves: List[Sieve]):
n = instance.getName()
found = False
for sieve in sieves:
- rx = compiled_regexes[sieve.variable]
+ rx = regexes[sieve.variable]
result = rx.search(n)
if result is None:
continue
diff --git a/placeram/reg_data.py b/librelane_plugin_dffram/scripts/odbpy/placeram/reg_data.py
similarity index 99%
rename from placeram/reg_data.py
rename to librelane_plugin_dffram/scripts/odbpy/placeram/reg_data.py
index 3321a34..836e3ff 100644
--- a/placeram/reg_data.py
+++ b/librelane_plugin_dffram/scripts/odbpy/placeram/reg_data.py
@@ -7,11 +7,9 @@
from .placeable import Placeable
from .common_data import Decoder5x32
-from odb import dbInst
+from odb import dbInst as Instance
from typing import Dict, List
-Instance = dbInst
-
P = Placeable
S = Placeable.Sieve
diff --git a/placeram/row.py b/librelane_plugin_dffram/scripts/odbpy/placeram/row.py
similarity index 100%
rename from placeram/row.py
rename to librelane_plugin_dffram/scripts/odbpy/placeram/row.py
diff --git a/placeram/rx.yml b/librelane_plugin_dffram/scripts/odbpy/placeram/rx.yml
similarity index 100%
rename from placeram/rx.yml
rename to librelane_plugin_dffram/scripts/odbpy/placeram/rx.yml
diff --git a/placeram/util.py b/librelane_plugin_dffram/scripts/odbpy/placeram/util.py
similarity index 100%
rename from placeram/util.py
rename to librelane_plugin_dffram/scripts/odbpy/placeram/util.py
diff --git a/librelane_plugin_dffram/steps.py b/librelane_plugin_dffram/steps.py
index 2d6f4fd..9eebb34 100644
--- a/librelane_plugin_dffram/steps.py
+++ b/librelane_plugin_dffram/steps.py
@@ -4,17 +4,21 @@
# Copyright ©2023 Efabless Corporation
import os
import math
+from pathlib import Path
from typing import List
from decimal import Decimal
import yaml
-from librelane.config import Variable
+from librelane.config import Variable, Config
from librelane.logging import warn
from librelane.state import DesignFormat
-from librelane.steps import OpenROAD, Odb
+from librelane.steps import OpenROAD, OdbpyStep, Step
+__file_dir__ = Path(__file__).absolute().parent
-class PlaceRAM(Odb.OdbpyStep):
+
+@Step.factory.register()
+class PlaceRAM(OdbpyStep):
id = "DFFRAM.PlaceRAM"
config_vars = [
@@ -44,7 +48,40 @@ def get_command(self) -> List[str]:
raw.insert(raw.index("placeram"), "-m")
return raw
+ def run(self, state_in, **kwargs):
+ kwargs, env = self.extract_env(kwargs)
+ env["PYTHONPATH"] = str(__file_dir__ / "scripts" / "odbpy")
+ return super().run(state_in, env=env, **kwargs)
+
+
+def calculate_halo(config: Config):
+ pdk = config["PDK"]
+ scl = config["STD_CELL_LIBRARY"]
+ horizontal_halo = config["HORIZONTAL_HALO"]
+ vertical_halo = config["VERTICAL_HALO"]
+
+ tech_info_path = os.path.join(".", "platforms", pdk, scl, "tech.yml")
+ tech_info = yaml.safe_load(open(tech_info_path))
+ site_info = tech_info.get("site")
+
+ site_width = Decimal(1)
+ site_height = Decimal(1)
+
+ if site_info is not None:
+ site_width = Decimal(site_info["width"])
+ site_height = Decimal(site_info["height"])
+
+ horizontal_halo = math.ceil(horizontal_halo / site_width) * site_width
+ vertical_halo = math.ceil(vertical_halo / site_height) * site_height
+ else:
+ if horizontal_halo != 0.0 or vertical_halo != 0.0:
+ warn(
+ "Note: This platform does not have site information. The halo will not be rounded up to the nearest number of sites. This may cause off-by-one issues with some tools."
+ )
+ return horizontal_halo, vertical_halo, site_width, site_height
+
+@Step.factory.register()
class Floorplan(OpenROAD.Floorplan):
id = "DFFRAM.Floorplan"
@@ -81,8 +118,6 @@ class Floorplan(OpenROAD.Floorplan):
]
def run(self, state_in, **kwargs):
- min_height = self.config["MINIMUM_HEIGHT"]
-
core_width = Decimal(
state_in.metrics.get("dffram__suggested__core_width") or 20000
)
@@ -90,33 +125,11 @@ def run(self, state_in, **kwargs):
state_in.metrics.get("dffram__suggested__core_height") or 20000
)
- horizontal_halo = self.config["HORIZONTAL_HALO"]
- vertical_halo = self.config["VERTICAL_HALO"]
-
- pdk = self.config["PDK"]
- scl = self.config["STD_CELL_LIBRARY"]
-
- tech_info_path = os.path.join(".", "platforms", pdk, scl, "tech.yml")
- tech_info = yaml.safe_load(open(tech_info_path))
- site_info = tech_info.get("site")
-
- site_width = Decimal(1)
- site_height = Decimal(1)
-
- if site_info is not None:
- site_width = Decimal(site_info["width"])
- site_height = Decimal(site_info["height"])
-
- horizontal_halo = math.ceil(horizontal_halo / site_width) * site_width
- vertical_halo = math.ceil(vertical_halo / site_height) * site_height
- else:
- if horizontal_halo != 0.0 or vertical_halo != 0.0:
- warn(
- "Note: This platform does not have site information. The halo will not be rounded up to the nearest number of sites. This may cause off-by-one issues with some tools."
- )
+ horizontal_halo, vertical_halo, _, site_height = calculate_halo(self.config)
die_width = core_width + horizontal_halo * 2
die_height = core_height + vertical_halo * 2
+ min_height = self.config["MINIMUM_HEIGHT"]
if die_height < min_height:
die_height = min_height
vertical_halo = (die_height - core_height) / 2
diff --git a/models/ram/config.yml b/models/ram/config.yml
index cfe04c0..a1256dd 100644
--- a/models/ram/config.yml
+++ b/models/ram/config.yml
@@ -3,4 +3,4 @@ counts: [8, 32, 128, 256, 512, 1024, 2048]
design_name_template: "RAM{count}{variant}"
variants:
- null
- # - "1RW1R"
+ - "1RW1R"
diff --git a/platforms/gf180mcuD/gf180mcu_fd_sc_mcu7t5v0/tech.yml b/platforms/gf180mcuD/gf180mcu_fd_sc_mcu7t5v0/tech.yml
index 2c3ba5d..75bb290 100644
--- a/platforms/gf180mcuD/gf180mcu_fd_sc_mcu7t5v0/tech.yml
+++ b/platforms/gf180mcuD/gf180mcu_fd_sc_mcu7t5v0/tech.yml
@@ -22,13 +22,13 @@ sta:
fast: gf180mcu_fd_sc_mcu7t5v0__ff_n40C_5v50.lib
clock_periods:
ram:
- "8x*": 5.21
- "32x*": 8
- "128x*": 10.1
- "256x*": 10.49
- "512x*": 11.21
- "1024x*": 12.83
- "2048x*": 14.1
+ "8x*": 16.5
+ "32x*": 16.5
+ "128x*": 16.5
+ "256x*": 16.5
+ "512x*": 16.5
+ "1024x*": 16.5
+ "2048x*": 16.5
rf: {}
fills:
decap: gf180mcu_fd_sc_mcu7t5v0__fillcap_(\d+)
From bf5970d69e382ae551699500568b9a41bb8bcec1 Mon Sep 17 00:00:00 2001
From: Mohamed Gaber
Date: Sat, 4 Oct 2025 08:48:13 +0300
Subject: [PATCH 3/5] bugfix: lix issue
---
flake.lock | 21 ++++++++++-----------
flake.nix | 2 +-
2 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/flake.lock b/flake.lock
index cabadfe..f1a5b4d 100644
--- a/flake.lock
+++ b/flake.lock
@@ -8,11 +8,11 @@
]
},
"locked": {
- "lastModified": 1751196116,
- "narHash": "sha256-y6w1MYMsgfSUPdJoKc+k+4xg0Zi1dUQtv+z71vyCLDU=",
+ "lastModified": 1758194402,
+ "narHash": "sha256-QoaS950TbRvvtndqHf8yz9VrQOZoTJCTPl4wWHgpRDM=",
"owner": "fossi-foundation",
"repo": "ciel",
- "rev": "1260b5f7d752e457d0bef3b1d9ab7fd044ad9c83",
+ "rev": "f4990f916c29f1cb7d890ab5b0716f63ce9de1b4",
"type": "github"
},
"original": {
@@ -65,16 +65,15 @@
"nix-eda": "nix-eda"
},
"locked": {
- "lastModified": 1756988446,
- "narHash": "sha256-3V4+1Pbhd2Q69IiTHqJjtPxh+vp+bNGydKhSj3eKsmE=",
+ "lastModified": 1759170069,
+ "narHash": "sha256-D5Uu1tgSqOEr1WssYAPzQwmgsmp0iTkppETix8RbEu4=",
"owner": "librelane",
"repo": "librelane",
- "rev": "4dc53448d98f3688e0096873a88200b04d268c6c",
+ "rev": "04432e3309e834f68fe5596d0244e31458afe734",
"type": "github"
},
"original": {
"owner": "librelane",
- "ref": "2.4.2",
"repo": "librelane",
"type": "github"
}
@@ -84,16 +83,16 @@
"nixpkgs": "nixpkgs"
},
"locked": {
- "lastModified": 1749403175,
- "narHash": "sha256-+VKZ7ZrVpJxVGA0ULHO4GkDwXNFx2kZvw9TeBTpuqqA=",
+ "lastModified": 1758194255,
+ "narHash": "sha256-IyEhOQOtSoYOO0xdbYeoxOufBUdt7yDrYlJpQgVon8I=",
"owner": "fossi-foundation",
"repo": "nix-eda",
- "rev": "abf388eeae6e55da82adefb9e74e21acea9e5888",
+ "rev": "f8fb90fb348f04d021ca773f268c6e15a24ae11f",
"type": "github"
},
"original": {
"owner": "fossi-foundation",
- "ref": "2.1.3",
+ "ref": "2.1.5",
"repo": "nix-eda",
"type": "github"
}
diff --git a/flake.nix b/flake.nix
index 003531c..9f904ea 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,7 +1,7 @@
# The nix-eda flake template
{
inputs = {
- librelane.url = "github:librelane/librelane/2.4.2";
+ librelane.url = "github:librelane/librelane";
};
outputs = {
From e16f2a73b8a29913e1910e2afeb98aa803264dc5 Mon Sep 17 00:00:00 2001
From: Mohamed Gaber
Date: Sat, 4 Oct 2025 09:01:49 +0300
Subject: [PATCH 4/5] fix ci
---
.github/workflows/main.yml | 2 +-
Readme.md | 4 ----
2 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 751e141..96c474b 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -106,7 +106,7 @@ jobs:
building_blocks=rf
fi
- nix develop --command "\
+ nix develop --command bash -c "\
./dffram.py ${{ matrix.count }}x${{ matrix.width }}\
-p sky130A\
-s sky130_fd_sc_hd\
diff --git a/Readme.md b/Readme.md
index 744a209..c8d8fae 100644
--- a/Readme.md
+++ b/Readme.md
@@ -12,10 +12,6 @@ Standard Cell Library based Memory Compiler using DFF/Latch cells.
See [this document](./docs/Usage.md).
-You can try the
-[Google Colaboratory](https://colab.research.google.com/github/Cloud-V/DFFRAM/blob/main/dffram.ipynb),
-but it is a bit out-of-date at this point.
-
## Platform Support Status
| Configured Platform | Signoff-clean | Silicon-proven\* |
From 92de9d2228d4e6ba823a4df40510fbf197f42034 Mon Sep 17 00:00:00 2001
From: Mohamed Gaber
Date: Sat, 4 Oct 2025 09:24:08 +0300
Subject: [PATCH 5/5] work around 2r1w crash
---
models/rf/model.v | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/models/rf/model.v b/models/rf/model.v
index 34fb9d5..9501ae4 100644
--- a/models/rf/model.v
+++ b/models/rf/model.v
@@ -13,7 +13,9 @@
module DFFRF_2R1W #(parameter WSIZE=32,
RCOUNT=32,
- R0_ZERO=1 )
+ R0_ZERO=1,
+ USE_LATCH=1 // does nothing. just to prevent a flow crash
+)
(
input wire [4:0] RA, RB, RW,
input wire [WSIZE-1:0] DW,