OpenRAM: a compiler that turns an SRAM spec into layout, netlists and timing models
An open-source static random access memory (SRAM) compiler.
At a glance
- What is it?
- OpenRAM is a Python framework that generates the layout, netlists, timing and power models, placement and routing views needed to use SRAMs in an ASIC design, with both predictive and fabricable technologies. Its real dependency is not Python but the open EDA toolchain around it, Klayout, Magic, Netgen and ngspice, plus a process design kit and a bitcell library.
- Who is it for?
- OpenRAM is worth adopting for a university course, a research group or a small team that needs a real SRAM macro in a real open PDK and cannot afford the commercial memory compilers, because the whole path from bitcell to GDS is scripted rather than hand drawn.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A memory compiler rather than a memory editor
OpenRAM is described as an open-source static random access memory compiler, and the word compiler is doing real work in that sentence.
The README puts it this way: OpenRAM is an award winning open-source Python framework to create the layout, netlists, timing and power models, placement and routing models, and other views necessary to use SRAMs in ASIC design. It supports integration in both commercial and open-source flows with both predictive and fabricable technologies.
That list of outputs is the whole point. A memory compiler is not a schematic capture tool. It takes a specification, such as a word count, a bitcell and a port configuration, and it emits a set of views that the rest of the design flow can consume, the same way a logic synthesis tool emits a netlist and a place and route tool emits a layout. The list of views is broad because a hard memory macro is consumed in several ways at once, and a macro that only has a GDS file is not usable in a flow that wants to simulate it, check it against a schematic or extract its parasitics.
The claim of being award winning refers to the ICCAD 2016 paper, which is listed among the publications along with the DOI link, and that paper is where the design rationale lives for anyone who wants more than the README.
The project is BSD-3-Clause licensed, the homepage is openram.org, the default branch is stable, and the last push was on 2026-10-15. The recent releases are v1.2.48 from 2024-01-21, v1.2.47 from 2024-01-19 and v1.2.46 from 2024-01-04, so the tagged line stopped in early 2024 while the repository itself kept moving.
The README also lists a set of external tools and technologies that OpenRAM drives or depends on, which is the single most useful thing on the page for a newcomer: Klayout, Magic, Netgen, Qflow, Ngspice, Xyce and Git, plus FreePDK45, SCMOS and the Sky130 SRAM library.
The compiler is the small part, the EDA environment is the large part
The repository layout shows a tool that is mostly glue, and understanding the glue is most of understanding OpenRAM.
At the root there are the entry points, sram_compiler.py, sram_char.py for the characterisation flow, rom_compiler.py for read-only memory, sram_func.py and common.py. Then there are the four directories that carry the real weight, compiler/ for the compiler itself, technology/ for the process-specific parts, macros/ for the macro generators, and docker/ for the container setup.
The technology/ directory is the reason a user has to be careful. SRAM generation is inseparable from the process, because the bitcell geometry, the design rules and the timing models all come from the PDK. A technology port is not a configuration file, it is a new implementation of a set of assumptions that the compiler was not written to guess. The README lists porting to a new technology as a contribution opportunity and points to PORTING.md, and the project is explicit that this is work rather than a setting.
The tool list in the README tells you what the generated artefacts are checked against. Klayout handles the GDS layout, Magic is the layout editor and the source of the .mag files that the Makefile collects, Netgen is the LVS netlist comparison tool, and ngspice and Xyce are the simulators used for the characterisation step. Qflow is the open synthesis flow.
The Python dependencies are modest by comparison:
scikit-learn>=0.22.2
coverage>=4.5.2
scipy>=1.3.3
numpy>=1.17.4
python-subunit>=1.4.0
unittest2>=1.1.0
ciel>=2.0.0There is no netlist library and no layout library in that list, because OpenRAM does not parse or write GDS itself, it drives the tools that do. The two names that stand out are ciel, which is the chip infrastructure for execution, a container based environment for running the tool flows, and scikit-learn, which is there for the statistical models used in characterisation.
So the practical reading of the dependency list is that OpenRAM is a Python program that shells out to a serious open source EDA stack, and the effort of adoption is in getting that stack right.
The Makefile pins the PDKs, the SRAM library and the Ciel images by commit
The Makefile in the repository root is where the reproducibility story lives, and it is unusually explicit about versions.
SRAM_LIB_DIR ?= $(PDK_ROOT)/sky130_fd_bd_sram
SRAM_LIB_GIT_REPO ?= https://github.com/vlsida/sky130_fd_bd_sram.git
SRAM_LIB_GIT_COMMIT ?= dd64256961317205343a3fd446908b42bafba388
SKY130_PDK ?= $(PDK_ROOT)/sky130A
GF180_PDK ?= $(PDK_ROOT)/gf180mcuDEvery one of those is pinned. The SRAM library is fetched from a specific repository at a specific commit hash, and the file carries both the release repository and two commented-out development alternatives, one over SSH and one pointing at the Google upstream of the Sky130 SRAM library. The PDK paths are Sky130 and GF180, which is the GlobalFoundries 180 nm MCU open PDK, and both are expressed relative to a PDK_ROOT variable that the user supplies.
The Ciel images are pinned by commit as well, and the comments carry the dates:
# Ciel SKY130 PDK
SKY130_CIEL = e8294524e5f67c533c5d0c3afa0bcc5b2a5fa066 # 2022.07.29
# Ciel GF180 PDK
GF180_CIEL = cd1748bb197f9b7af62a54507de6624e30363943 # 2023.12.04That is a Ciel container image per PDK, pinned to a commit with the build date in a comment, so the environment is fixed rather than tracking a moving tag. The Skywater PDK and the GF180 PDK are also pinned, with a commit for the Skywater one and a branch name for the GF180 one.
Then the file enumerates the artefacts it gathers, which is a description of what the flow produces. GDS files are collected from the SRAM library cells with a wildcard, and .mag files the same way, and there is a set of SPICE suffix variables covering the plain spice output, the LVS variants for both Calibre and Klayout, and the base spice file. The Makefile also includes openram.mk, which is where the actual targets live, and the default goal is install.
The takeaway is that OpenRAM is built for reproducibility. If you are evaluating it, the Makefile is where you find out what has to be present before anything runs, and the answer is a specific set of repositories at specific commits.
setup.py is doing unusual work to turn a repository into a package
The packaging story in this repository is worth a paragraph, because it explains why the top-level layout looks the way it does.
The build system is plain setuptools, with pyproject.toml declaring setuptools as the build requirement and setup_meta as the backend, and nothing else. The version is not in the metadata at all, it is read from a file:
# Read version from file
version = open("VERSION", "r").read().rstrip()So there is a VERSION file at the repository root, and the package version is whatever it says. That is a common pattern for projects that tag releases by hand.
The unusual part is the package discovery. The setup script finds all namespace packages, excludes anything under docs and images, and then rewrites the package names so that the top-level folders become subpackages of a package called openram:
# Include these folder from the root of repo as submodules
include = ["compiler", "docker", "technology", "macros"]
# Exclude files/folders with these words
exclude = ["docs", "images"]The comment in the script says it makes the included folders submodules of the openram package, and the loop that does it prefixes the four included directories with openram., inserting the root itself as the openram package at the front.
The result is that a user who runs pip install openram gets a single importable package with compiler, technology, macros and docker inside it, and the directories at the root of the git repository are the same directories inside the wheel. That is not how most Python projects are laid out, and it is the reason the repository root looks flat.
One detail worth noticing is that docker/ is packaged as a module. The container setup is part of the installable package, which fits with the Ciel based workflow and means the environment can be reproduced from an installed package rather than only from a clone.
The long description is the README itself, read from disk, and the URL is https://openram.org/.
Characterisation and ROM are separate entry points, not options on one switch
Two of the root files tell you that the repository holds more than one compiler.
sram_char.py is the characterisation flow, and sram_func.py sits next to it. In an SRAM design flow, characterisation is the step where the bitcell is measured and modelled, and it produces the timing and power models that the rest of the flow consumes. The README lists timing and power models among the views OpenRAM creates, and characterisation is where they come from.
The root listing shows macros/ holding the macro generators, and a separate rom_compiler.py for read-only memory. A ROM is a different circuit from an SRAM, with a different bitcell and different views, and giving it its own entry point rather than a mode flag keeps the SRAM path from carrying conditions that only make sense for ROM.
The characterisation step is where the open source simulators matter. Ngspice and Xyce both appear in the tool list, and Xyce is the Sandia simulator, which matters because the SPICE suffix variables in the Makefile distinguish a plain spice output from the LVS flavours, and a characterisation run has to be reproducible against a specific simulator version.
The scikit-learn dependency fits here as well. A statistical model of an SRAM cell across process corners is a regression problem, and the publications list includes a thesis on statistical modeling of SRAMs, which is the academic version of the same idea.
For a reader trying to work out what the tool actually does at runtime, the honest answer is that the README does not spell out the flow step by step, and the documentation, whose index is at docs/source/index.md, and the ICCAD paper are where the sequence lives.
Where OpenRAM is the wrong tool
The limits are severe but they are all consequences of the same thing, which is that this is a research tool that expects a complete open source IC design environment.
The first limit is the environment. To run OpenRAM you need Klayout, Magic, Netgen, a SPICE simulator, a Ciel container setup, a process design kit, and an SRAM bitcell library for that process. None of that is optional and none of it is trivial to set up. A team that has a commercial memory compiler already has a better path, and a team that has neither will spend more time on the environment than on the compiler.
The second limit is the technology coverage. The Makefile covers Sky130 and GF180, and porting to another technology is a documented piece of work rather than a parameter. The README lists it as a contribution opportunity, which is the correct way to describe something that takes weeks. An ASIC team on a node that is not in the list is looking at a porting project before they are looking at a compiler.
The third limit is the release rhythm. The newest tag is v1.2.48 from January 2024, and the repository has been pushed to as recently as 2026-10-15. The last push being more than two and a half years after the last release means the code on the default branch and the code in the last published package are not the same thing, and the version in the wheel comes from the VERSION file in whatever tree you installed. For a research group that tracks the repository, that is fine. For a team that needs a versioned, supportable dependency, it is a problem to raise before adopting.
The fourth is what the output is good enough for. The README says the framework supports both predictive and fabricable technologies, which is an ambitious claim, and it does not state a signoff status, a foundry qualification, or a yield result for any generated macro. A macro generated by a self-compiled tool at an open node is a research artefact, and treating it as a drop-in replacement for a qualified memory in a tapeout is a decision that needs a foundry's involvement rather than a repository's.
The fifth is the scope of the community. The project was created by Matthew Guthaus from VLSIDA, co-founded by James Stine from VLSIARCH, and the README credits many students as contributors, with the ICCAD 2016 paper as the origin. That is a healthy academic project with a real body of work behind it, and it is also a project maintained by people whose primary commitment is research and teaching. A team that needs a commercial memory compiler with a support contract will not find one here.
Editorial conclusion
OpenRAM is worth adopting for a university course, a research group or a small team that needs a real SRAM macro in a real open PDK and cannot afford the commercial memory compilers, because the whole path from bitcell to GDS is scripted rather than hand drawn. It is the wrong tool for a tapeout that cannot accept a self-compiled macro, and it is the wrong tool if you do not already have the surrounding EDA environment, since the compiler is the small part and Klayout, Magic, Netgen, ngspice, the PDK and the SRAM library are the large part. Before starting, read PORTING.md for the technology bring-up, check the pinned commits in the Makefile against the versions your environment has, and set the PDK_ROOT variable to the place your process kit is actually installed.
Frequently asked questions
What does OpenRAM do?
OpenRAM is a Python framework that creates the layout, netlists, timing and power models, placement and routing models, and other views needed to use SRAMs in ASIC design, and it supports both commercial and open-source flows with predictive and fabricable technologies.
Which tools does OpenRAM need to run?
The README lists Klayout for GDS layout, Magic as the layout editor, Netgen for netlist comparison, Ngspice and Xyce as simulators, Qflow for synthesis and Git for the repositories. It also needs a process design kit, with the Makefile pointing at Sky130 and GF180, and an SRAM bitcell library.
How do I port OpenRAM to a new technology?
The README lists porting to a new technology as a contribution opportunity and points at PORTING.md for the details. The technology/ directory holds the process specific parts of the compiler, and the Makefile sets the PDK paths through the PDK_ROOT variable.
What is OpenRAM written in and what does it depend on in Python?
It is written in Python and uses setuptools, with the version read from the VERSION file rather than declared in the metadata. The Python requirements are scikit-learn, coverage, scipy, numpy, python-subunit, unittest2 and ciel, the last of which is the container based environment for running the tool flows.
What is the most recent OpenRAM release?
The recent releases are v1.2.48 from 2024-01-21, v1.2.47 from 2024-01-19 and v1.2.46 from 2024-01-04, and the default branch is stable. The repository itself was pushed to on 2026-10-15, so the branch carries work that is not in the last published release.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vlsida-openram)Was this useful?