Merge branch 'dev' into klayout

This commit is contained in:
mrg 2022-02-01 11:57:56 -08:00
commit 63a6168b35
49 changed files with 596 additions and 152 deletions

152
Makefile
View File

@ -1,53 +1,42 @@
# -*- coding: utf-8 -*-
#
# Copyright 2020 Regents of the University of California
#
# 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
# The top directory where environment will be created.
TOP_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
include $(TOP_DIR)/openram.mk
.DEFAULT_GOAL := all
.DEFAULT_GOAL := install
# Keep it locally if they didn't specify
PDK_ROOT ?= $(TOP_DIR)
# Skywater PDK SRAM library
#SRAM_LIBRARY ?= $(PDK_ROOT)/skywater-pdk/libraries/sky130_fd_bd_sram
#SRAM_GIT_REPO ?= https://github.com/google/skywater-pdk-libs-sky130_fd_bd_sram.git
SRAM_GIT_REPO ?= git@github.com:VLSIDA/sky130_fd_bd_sram.git
SRAM_LIBRARY ?= $(TOP_DIR)/sky130_fd_bd_sram
SRAM_LIB_DIR ?= $(PDK_ROOT)/sky130_fd_bd_sram
SRAM_LIB_GIT_REPO ?= https://github.com/google/skywater-pdk-libs-sky130_fd_bd_sram.git
SRAM_LIB_GIT_COMMIT ?= main
# Open PDKs
PDK_ROOT ?= $(TOP_DIR)/open_pdks
OPEN_PDKS_REPO ?= https://github.com/RTimothyEdwards/open_pdks.git
OPEN_PDKS ?= $(PDK_ROOT)/sky130/sky130A
OPEN_PDKS_DIR ?= $(PDK_ROOT)/open_pdks
OPEN_PDKS_GIT_REPO ?= https://github.com/RTimothyEdwards/open_pdks.git
OPEN_PDKS_GIT_COMMIT ?= 1.0.156
SKY130_PDK ?= $(PDK_ROOT)/sky130A
# Skywater PDK
SKY130_PDKS_DIR ?= $(PDK_ROOT)/skywater-pdk
SKY130_PDKS_GIT_REPO ?= https://github.com/google/skywater-pdk.git
SKY130_PDKS_GIT_COMMIT ?= main
# Create lists of all the files to copy/link
GDS_FILES := $(sort $(wildcard $(SRAM_LIBRARY)/cells/*/*.gds))
MAG_FILES := $(sort $(wildcard $(SRAM_LIBRARY)/cells/*/*.mag))
GDS_FILES := $(sort $(wildcard $(SRAM_LIB_DIR)/cells/*/*.gds))
MAG_FILES := $(sort $(wildcard $(SRAM_LIB_DIR)/cells/*/*.mag))
SPICE_SUFFIX := spice
SPICE_LVS_SUFFIX := lvs.$(SPICE_SUFFIX)
SPICE_CALIBRE_SUFFIX := lvs.calibre.$(SPICE_SUFFIX)
SPICE_KLAYOUT_SUFFIX := lvs.klayout.$(SPICE_SUFFIX)
SPICE_BASE_SUFFIX := base.$(SPICE_SUFFIX)
ALL_SPICE_FILES := $(sort $(wildcard $(SRAM_LIBRARY)/cells/*/*.$(SPICE_SUFFIX)))
ALL_SPICE_FILES := $(sort $(wildcard $(SRAM_LIB_DIR)/cells/*/*.$(SPICE_SUFFIX)))
MAGLEF_SUFFIX := maglef
MAGLEF_FILES := $(sort $(wildcard $(SRAM_LIBRARY)/cells/*/*.$(MAGLEF_SUFFIX)))
MAGLEF_FILES := $(sort $(wildcard $(SRAM_LIB_DIR)/cells/*/*.$(MAGLEF_SUFFIX)))
MAGICRC_FILE := $(OPEN_PDKS)/libs.tech/magic/sky130A.magicrc
MAGICRC_FILE := $(SKY130_PDK)/libs.tech/magic/sky130A.magicrc
ALL_FILES := $(ALL_SPICE_FILES) $(GDS_FILES) $(MAG_FILES) $(MAGLEF_FILES)
@ -56,34 +45,59 @@ INSTALL_BASE_DIRS := gds_lib mag_lib sp_lib lvs_lib calibre_lvs_lib klayout_lvs_
INSTALL_BASE := $(OPENRAM_HOME)/../technology/sky130
INSTALL_DIRS := $(addprefix $(INSTALL_BASE)/,$(INSTALL_BASE_DIRS))
check-pdk-root:
ifndef PDK_ROOT
$(error PDK_ROOT is undefined, please export it before running make)
endif
install: $(INSTALL_DIRS)
$(SKY130_PDKS_DIR): check-pdk-root
git clone https://github.com/google/skywater-pdk.git $(PDK_ROOT)/skywater-pdk
cd $(SKY130_PDKS_DIR) && \
git checkout main && git pull && \
git checkout -qf $(SKY130_PDKS_GIT_COMMIT) && \
git submodule update --init libraries/sky130_fd_pr/latest
$(SRAM_LIBRARY):
git clone $(SRAM_GIT_REPO) $(SRAM_LIBRARY)
$(OPEN_PDKS_DIR): $(SKY130_PDKS_DIR)
@echo "Cloning open_pdks..."
git clone $(OPEN_PDKS_GIT_REPO) $(OPEN_PDKS_DIR)
cd $(OPEN_PDKS_DIR) && git checkout $(OPEN_PDKS_GIT_COMMIT)
$(OPEN_PDKS):
git clone $(OPEN_PDKS_REPO) $(PDK_ROOT)
cd $(PDK_ROOT) &&\
$(PDK_ROOT)/configure --enable-sky130-pdk
make -C $(PDK_ROOT)
$(SKY130_PDK): $(OPEN_PDKS_DIR)
@echo "Installing open_pdks..."
cd $(OPEN_PDKS_DIR) && \
./configure --enable-sky130-pdk=$(PDK_ROOT)/skywater-pdk/libraries --with-sky130-local-path=$(PDK_ROOT) --enable-sram-sky130=$(INSTALL_SRAM) && \
cd sky130 && \
make veryclean && \
make && \
make SHARED_PDKS_PATH=$(PDK_ROOT) install
.PHONY: $(SRAM_LIBRARY) $(OPEN_PDKS) $(INSTALL_DIRS) install
$(SRAM_LIB_DIR): check-pdk-root
@[ -d $(SRAM_LIB_DIR) ] || (\
echo "Cloning SRAM library..." && git clone $(SRAM_LIB_GIT_REPO) $(SRAM_LIB_DIR) && \
cd $(SRAM_LIB_DIR) && git checkout $(SRAM_LIB_GIT_COMMIT))
all: $(SRAM_LIBRARY) $(OPEN_PDKS)
install: $(SRAM_LIB_DIR)
@[ -d $(PDK_ROOT)/sky130A ] || \
(echo "Warning: $(PDK_ROOT)/sky130A not found!! Run make pdk first." && false)
@[ -d $(PDK_ROOT)/skywater-pdk ] || \
(echo "Warning: $(PDK_ROOT)/skywater-pdk not found!! Run make pdk first." && false)
@echo "Installing sky130 SRAM PDK..."
@echo "PDK_ROOT='$(PDK_ROOT)'"
@echo "SRAM_LIBRARY='$(SRAM_LIBRARY)'"
@echo "OPEN_PDKS='$(OPEN_PDKS)'"
make install
@echo "SRAM_LIB_DIR='$(SRAM_LIB_DIR)'"
@echo "SKY130_PDK='$(SKY130_PDK)'"
@make $(INSTALL_DIRS)
.PHONY: install
pdk: $(SKY130_PDK)
@true
.PHONY: pdk
$(INSTALL_BASE)/gds_lib: $(GDS_FILES)
@echo
@echo "Setting up GDS cell library for OpenRAM."
@echo "=================================================================="
mkdir -p $@
@cp -va $? $@
cp -va $? $@
@echo "=================================================================="
@echo
@ -163,11 +177,43 @@ $(INSTALL_BASE)/sp_lib: $(filter-out %.$(SPICE_LVS_SUFFIX) %.$(SPICE_CALIBRE_SUF
@echo "=================================================================="
@echo
macros:
cd macros && make
.PHONY: macros
mount:
@docker run -it -v $(TOP_DIR):/openram \
-v $(SKY130_PDK):$(SKY130_PDK) \
-e PDK_ROOT=$(PDK_ROOT) \
-e OPENRAM_HOME=/openram/compiler \
-e OPENRAM_TECH=/openram/technology \
--user $(UID):$(GID) \
vlsida/openram-ubuntu:latest
.PHONY: mount
clean:
rm -rf $(SRAM_LIBRARY)
rm -rf $(PDK_ROOT)
rm -f $(INSTALL_BASE)/tech/.magicrc
rm -f $(INSTALL_BASE)/mag_lib/.magicrc
rm -f $(INSTALL_BASE)/lef_lib/.magicrc
rm -f $(INSTALL_BASE)/maglef_lib/.magicrc
rm -rf $(INSTALL_DIRS)
@rm -f *.zip
.PHONE: clean
uninstall: clean
@rm -f $(INSTALL_BASE)/tech/.magicrc
@rm -f $(INSTALL_BASE)/mag_lib/.magicrc
@rm -f $(INSTALL_BASE)/lef_lib/.magicrc
@rm -f $(INSTALL_BASE)/maglef_lib/.magicrc
@rm -rf $(INSTALL_DIRS)
.PHONY: uninstall
# wipe the entire repos
wipe: uninstall
@echo $(SKY130_PDK)
@echo $(SRAM_LIB_DIR)
@echo $(OPEN_PDKS_DIR)
@echo $(SKY130_PDKS_DIR)
@echo "Wiping above PDK repos in 5 sec... (ctrl-c to quit)"
@sleep 5
@rm -rf $(SKY130_PDK)
@rm -rf $(SRAM_LIB_DIR)
@rm -rf $(OPEN_PDKS_DIR)
@rm -rf $(SKY130_PDKS_DIR)
.PHONY: wipe

24
PORTING.md Normal file
View File

@ -0,0 +1,24 @@
# Porting to a New Technology
If you want to support a new technology, you will need to create:
+ a setup script for each technology you want to use
+ a technology directory for each technology with the base cells
We provide two technology examples for [SCMOS] and [FreePDK45]. Each
specific technology (e.g., [FreePDK45]) should be a subdirectory
(e.g., $OPENRAM_TECH/freepdk45) and include certain folders and files:
* gds_lib folder with all the .gds (premade) library cells:
* dff.gds
* sense_amp.gds
* write_driver.gds
* cell_1rw.gds
* replica\_cell\_1rw.gds
* dummy\_cell\_1rw.gds
* sp_lib folder with all the .sp (premade) library netlists for the above cells.
* layers.map
* A valid tech Python module (tech directory with \_\_init\_\_.py and tech.py) with:
* References in tech.py to spice models
* DRC/LVS rules needed for dynamic cells and routing
* Layer information
* Spice and supply information
* etc.

View File

@ -26,21 +26,25 @@ things that need to be fixed.
# Basic Setup
## Docker
We have a [docker setup](./docker) to run OpenRAM.
## Dependencies
The OpenRAM compiler has very few dependencies:
+ [Ngspice] 26 (or later) or HSpice I-2013.12-1 (or later) or CustomSim 2017 (or later) or [Xyce] 7.2 (or later)
+ Python 3.5 or higher
+ [Ngspice] 34 (or later) or HSpice I-2013.12-1 (or later) or CustomSim 2017 (or later) or [Xyce] 7.4 (or later)
+ Python 3.6 or higher
+ Various Python packages (pip install -r requirements.txt)
+ [Git]
If you want to perform DRC and LVS, you will need either:
+ Calibre (for [FreePDK45])
+ [Magic] 8.3.130 or newer
+ [Netgen] 1.5.164 or newer
+ [Magic] 8.3.197 or newer
+ [Netgen] 1.5.195 or newer
You must set two environment variables:
+ OPENRAM\_HOME should point to the compiler source directory.
You must set two environment variables:
+ OPENRAM\_HOME should point to the compiler source directory.
+ OPENERAM\_TECH should point to one or more root technology directories (colon separated).
## Environment
@ -58,24 +62,20 @@ You may also wish to add OPENRAM\_HOME to your PYTHONPATH:
export PYTHONPATH="$PYTHONPATH:$OPENRAM_HOME"
```
We include the tech files necessary for [SCMOS] SCN4M_SUBM. The
[SCMOS] spice models, however, are generic and should be replaced with
foundry models. If you are using [FreePDK45], you should also have
that set up and have the environment variable point to the PDK. For
example add this to your .bashrc:
We include the tech files necessary for [SCMOS] SCN4M_SUBM,
[FreePDK45], and [Sky130]. The [SCMOS] spice models, however, are
generic and should be replaced with foundry models. You may get the
entire [FreePDK45 PDK here][FreePDK45].
To install [Sky130], simply run:
```
export FREEPDK45="/bsoe/software/design-kits/FreePDK45"
make install
```
You may get the entire [FreePDK45 PDK here][FreePDK45].
If you are using [SCMOS], you should install [Magic] and [Netgen].
We have included the most recent SCN4M_SUBM design rules from [Qflow].
# Basic Usage
Once you have defined the environment, you can run OpenRAM from the command line
using a single configuration file written in Python.
Once you have defined the environment, you can run OpenRAM from the command line
using a single configuration file written in Python.
For example, create a file called *myconfig.py* specifying the following
parameters for your memory:
@ -116,60 +116,44 @@ python3 $OPENRAM_HOME/openram.py myconfig
You can see all of the options for the configuration file in
$OPENRAM\_HOME/options.py
To run designs in Docker, it is suggested to use, for example:
```
cd openram/macros
make example_config_scn4m_subm
```
# Unit Tests
Regression testing performs a number of tests for all modules in OpenRAM.
From the unit test directory ($OPENRAM\_HOME/tests),
From the unit test directory ($OPENRAM\_HOME/tests),
use the following command to run all regression tests:
```
python3 regress.py
cd openram/compiler/tests
make regress
```
To run a specific test:
```
python3 {unit test}.py
ce openram/compiler/tests
make 05_bitcell_array_test
```
The unit tests take the same arguments as openram.py itself.
To increase the verbosity of the test, add one (or more) -v options:
To increase the verbosity of the test, add one (or more) -v options and
pass it as an argument to OpenRAM:
```
python3 tests/00_code_format_check_test.py -v -t freepdk45
make 05_bitcell_array_test ARGS="-v -t scn4m_subm"
```
To specify a particular technology use "-t <techname>" such as
"-t freepdk45". The default for a unit test is scn4m_subm.
"-t freepdk45". The default for a unit test is scn4m_subm.
The default for openram.py is specified in the configuration file.
# Porting to a New Technology
If you want to support a new technology, you will need to create:
+ a setup script for each technology you want to use
+ a technology directory for each technology with the base cells
We provide two technology examples for [SCMOS] and [FreePDK45]. Each
specific technology (e.g., [FreePDK45]) should be a subdirectory
(e.g., $OPENRAM_TECH/freepdk45) and include certain folders and files:
* gds_lib folder with all the .gds (premade) library cells:
* dff.gds
* sense_amp.gds
* write_driver.gds
* cell_1rw.gds
* replica\_cell\_1rw.gds
* dummy\_cell\_1rw.gds
* sp_lib folder with all the .sp (premade) library netlists for the above cells.
* layers.map
* A valid tech Python module (tech directory with \_\_init\_\_.py and tech.py) with:
* References in tech.py to spice models
* DRC/LVS rules needed for dynamic cells and routing
* Layer information
* Spice and supply information
* etc.
# Get Involved
+ [Port it](./PORTING.md) to a new technology.
+ Report bugs by submitting [Github issues].
+ Develop new features (see [how to contribute](./CONTRIBUTING.md))
+ Submit code/fixes using a [Github pull request]
+ Submit code/fixes using a [Github pull request]
+ Follow our [project][Github project].
+ Read and cite our [ICCAD paper][OpenRAMpaper]
@ -181,7 +165,7 @@ specific technology (e.g., [FreePDK45]) should be a subdirectory
+ [OpenRAM Users Group][user-group] ([subscribe here][user-group-subscribe])
+ [OpenRAM Developers Group][dev-group] ([subscribe here][dev-group-subscribe])
# License
# License
OpenRAM is licensed under the [BSD 3-clause License](./LICENSE).
@ -203,7 +187,7 @@ If I forgot to add you, please let me know!
[Github issues]: https://github.com/VLSIDA/OpenRAM/issues
[Github pull request]: https://github.com/VLSIDA/OpenRAM/pulls
[Github project]: https://github.com/VLSIDA/OpenRAM
[Github project]: https://github.com/VLSIDA/OpenRAM
[documentation]: https://docs.google.com/presentation/d/10InGB33N51I6oBHnqpU7_w9DXlx-qe9zdrlco2Yc5co/edit?usp=sharing
[dev-group]: mailto:openram-dev-group@ucsc.edu
@ -218,8 +202,8 @@ If I forgot to add you, please let me know!
[Xyce]: http://xyce.sandia.gov/
[Git]: https://git-scm.com/
[OSUPDK]: https://vlsiarch.ecen.okstate.edu/flow/
[FreePDK45]: https://www.eda.ncsu.edu/wiki/FreePDK45:Contents
[SCMOS]: https://www.mosis.com/files/scmos/scmos.pdf
[Sky130]: https://github.com/google/skywater-pdk-libs-sky130_fd_bd_sram.git
[Slack]: https://join.slack.com/t/openram/shared_invite/enQtNDgxMjc3NzU5NTI1LWZiYWMwNjNkZThmYTdkODc3NDE1NDhjNzUxNDhmMDQ4ZTM3NDgwNWFlNjM5NWFiZDkyMzBlNzc1NTg3ZjllNTY

View File

@ -35,7 +35,7 @@ ${CELL_TESTS} \
${MODULE_TESTS} \
${TOP_TESTS} \
${CHAR_TESTS} \
${USAGE_TESTS}
${USAGE_TESTS}
.PHONY: ${ALL_TESTS}
@ -64,8 +64,8 @@ usage: ${USAGE_TESTS}
$(ALL_TESTS):
python3 $@ -t ${TECH}
OPENRAM_TECHS = $(subst :, ,$(OPENRAM_TECH))
TECH_DIR := $(word 1, $(foreach dir,$(OPENRAM_TECHS),$(wildcard $(dir)/$(TECH))))
CONFIG_DIR = $(OPENRAM_HOME)/model_configs
@ -75,9 +75,9 @@ CSV_DIR = $(TECH_DIR)/sim_data
# Creates names of technology specific okay files for the configs
STAMPS=$(addprefix $(SIM_DIR)/, $(addsuffix .ok, $(notdir $(basename $(MODEL_CONFIGS)))))
OPTS =
OPTS =
# Characterize and perform DRC/LVS
OPTS += -c
OPTS += -c
# Do not characterize or perform DRC/LVS
OPTS += -n
# Verbosity
@ -100,8 +100,7 @@ model: $(STAMPS)
clean_model:
rm -f -r $(SIM_DIR)/*.ok
clean:
find . -name \*.pyc -exec rm {} \;
find . -name \*~ -exec rm {} \;

76
compiler/tests/Makefile Normal file
View File

@ -0,0 +1,76 @@
TOP_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))../..)
include $(TOP_DIR)/openram.mk
.DEFAULT_GOAL := regress
ARGS ?= "-k"
TEST_DIR = $(TOP_DIR)/compiler/tests
TEST_SRCS=$(sort $(notdir $(wildcard $(TEST_DIR)/*_test.py)))
TEST_DIRS=$(basename $(TEST_SRCS))
TEST_STAMPS=$(addsuffix .ok,$(TEST_DIRS))
TEST_BROKEN := \
50_riscv_1k_1rw1r_func_test.py \
50_riscv_1k_1rw_func_test.py \
50_riscv_1rw1r_func_test.py \
50_riscv_1rw1r_phys_test.py \
50_riscv_1rw_func_test.py \
50_riscv_1rw_phys_test.py \
50_riscv_2k_1rw1r_func_test.py \
50_riscv_2k_1rw_func_test.py \
50_riscv_4k_1rw1r_func_test.py \
50_riscv_4k_1rw_func_test.py \
50_riscv_512b_1rw1r_func_test.py \
50_riscv_512b_1rw_func_test.py \
50_riscv_8k_1rw1r_func_test.py \
50_riscv_8k_1rw_func_test.py
WORKING_TEST_STAMPS=$(filter-out $(addsuffix .ok, (TEST_BROKEN)), $(TEST_STAMPS))
$(TEST_DIRS):
@$(MAKE) --no-print-directory $@.ok
tests:
@echo "Running the following tests"
@for S in $(WORKING_TEST_STAMPS); do echo " - $$S"; done
@sleep 5
@$(MAKE) $(WORKING_TEST_STAMPS)
.PHONY:
%.ok: %.py
@echo "Running $*"
@mkdir -p $(TOP_DIR)/compiler/tests/results/$*
@docker run -v $(TOP_DIR):/openram \
-v $(SKY130_PDK):$(SKY130_PDK) \
-e PDK_ROOT=$(PDK_ROOT) \
-e OPENRAM_HOME=/openram/compiler \
-e OPENRAM_TECH=/openram/technology \
-e OPENRAM_TMP=/openram/compiler/tests/results/$* \
--user $(UID):$(GID) \
vlsida/openram-ubuntu:latest \
python3 -u /openram/compiler/tests/$*.py $(ARGS) && touch $@
.DELETE_ON_ERROR: $(TEST_STAMPS)
TECHS := scn4m_subm freepdk45
#sky130
$(TECHS):
@docker run -v $(TOP_DIR):/openram \
-e OPENRAM_HOME=/openram/compiler \
-e OPENRAM_TECH=/openram/technology \
--user $(UID):$(GID) \
-e OPENRAM_TMP=/openram/compiler/tests/tmp_$@/$* \
vlsida/openram-ubuntu:latest \
sh -c "python3 -u /openram/compiler/tests/regress.py $(ARGS) -t $@"
.PHONY: $(TECHS)
regress: $(TECHS)
.PHONY: regress
clean:
@rm -rf $(TEST_STAMPS)
@rm -rf $(TEST_DIRS)
.PHONE: clean

View File

@ -24,24 +24,24 @@ class openram_test(unittest.TestCase):
def tearDown(self):
duration = time.time() - self.start_time
print('%s: %.3fs' % (self.id(), duration))
def fail(self, msg):
import inspect
s = inspect.stack()
base_filename = os.path.splitext(os.path.basename(s[2].filename))[0]
try:
OPENRAM_HOME = os.path.abspath(os.environ.get("OPENRAM_HOME"))
except:
debug.error("$OPENRAM_HOME is not properly defined.", 1)
import shutil
zip_file = "{0}/../{1}_{2}".format(OPENRAM_HOME, base_filename, os.getpid())
debug.info(0, "Archiving failed temp files {0} to {1}".format(OPTS.openram_temp, zip_file))
shutil.make_archive(zip_file, 'zip', OPTS.openram_temp)
# import shutil
# zip_file = "{0}/../{1}_{2}".format(OPENRAM_HOME, base_filename, os.getpid())
# debug.info(0, "Archiving failed temp files {0} to {1}".format(OPTS.openram_temp, zip_file))
# shutil.make_archive(zip_file, 'zip', OPTS.openram_temp)
super().fail(msg)
def local_drc_check(self, w):
self.reset()
@ -55,7 +55,7 @@ class openram_test(unittest.TestCase):
self.fail("DRC failed: {}".format(w.name))
elif not OPTS.keep_temp:
self.cleanup()
def local_check(self, a, final_verification=False):
self.reset()
@ -128,7 +128,7 @@ class openram_test(unittest.TestCase):
def cleanup(self):
""" Reset the duplicate checker and cleanup files. """
files = glob.glob(OPTS.openram_temp + '*')
for f in files:
# Only remove the files

99
docker/Dockerfile Normal file
View File

@ -0,0 +1,99 @@
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND noninteractive
RUN ln -s /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
RUN echo "America/Los_Angeles" > /etc/timezone
RUN apt-get update
RUN apt-get --no-install-recommends -y upgrade
### Dependencies ###
# General tools for building etc.
RUN apt-get install --no-install-recommends -y build-essential git ssh vim gosu autoconf automake libtool bison flex
# Use bash instead of dash
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# Needed by OpenRAM
RUN apt-get install --no-install-recommends -y python3 python3-numpy python3-scipy python3-pip python3-matplotlib python3-venv python3-sklearn python3-subunit python3-coverage
# Needed by Netgen
RUN apt-get install --no-install-recommends -y m4 csh tk tk-dev tcl-dev
# Needed by ngspice
RUN apt-get install --no-install-recommends -y libxaw7-dev libreadline8 libreadline-dev
# X11
RUN apt-get install --no-install-recommends -y libx11-dev libcairo2-dev
# Klayout
RUN apt-get install --no-install-recommends -y qt5-default qtcreator ruby-full ruby-dev python3-dev qtmultimedia5-dev libqt5multimediawidgets5 libqt5multimedia5-plugins libqt5multimedia5 libqt5svg5-dev libqt5designer5 libqt5designercomponents5 libqt5xmlpatterns5-dev qttools5-dev
### Klayout ###
ARG KLAYOUT_COMMIT=ea1bf40a1ee1c1c934e47a0020417503ab3d7e7e
WORKDIR /root
RUN git clone https://github.com/KLayout/klayout
WORKDIR /root/klayout
RUN git checkout ${KLAYOUT_COMMIT}
RUN ./build.sh -qt5 \
&& cp -r bin-release /usr/local/klayout
RUN rm -rf /root/klayout
### Magic ###
ARG MAGIC_COMMIT=8.3.254
WORKDIR /root
RUN git clone git://opencircuitdesign.com/magic-8.3 magic
WORKDIR /root/magic
RUN git checkout ${MAGIC_COMMIT}
RUN ./configure \
&& make \
&& make install
RUN rm -rf /root/magic
### Ngspice ###
ARG NGSPICE_COMIT=032b1c32c4dbad45ff132bcfac1dbecadbd8abb0
WORKDIR /root
RUN git clone git://git.code.sf.net/p/ngspice/ngspice
WORKDIR /root/ngspice
RUN git checkout ${NGSPICE_COMMIT}
RUN ./autogen.sh \
&& ./configure --enable-openmp --with-readline \
&& make \
&& make install
RUN rm -rf /root/ngspice
### Netgen ###
ARG NETGEN_COMMIT=88d53fab15eb611cffc024eebf8743fae5cf8cb7
WORKDIR /root
RUN git clone git://opencircuitdesign.com/netgen-1.5 netgen
WORKDIR /root/netgen
RUN git checkout ${NETGEN_COMMIT}
RUN ./configure \
&& make -j$(nproc) \
&& make install
RUN rm -rf /root/netgen
#ARG XYCE_COMMIT=b7bb12d81f11d8b50141262537299b09d64b5565
#ARG TRILINOS_COMIT=
### CLEAN UP ###
# Remove development tools to save space
RUN apt-get remove -y build-essential autoconf automake libtool bison flex tcl-dev tk-dev
# Cleanup to save some space
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*
# ### SET UP A GENERIC USER ###
# WORKDIR /p
# RUN echo "cd ~" >> /etc/skel/.bashrc
# RUN echo "source /set-paths.sh" >> /etc/skel/.bashrc
# ADD set-paths.sh /set-paths.sh
# RUN chmod 755 /set-paths.sh
### ADD ENTRY POINT ###
# COPY entrypoint.sh /usr/local/bin/entrypoint.sh
# RUN chmod 755 /usr/local/bin/entrypoint.sh
# ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# CMD ["/bin/bash"]
RUN mkdir /home/cad-user
RUN useradd cad-user
RUN chown -R cad-user /home/cad-user
RUN chgrp -R cad-user /home/cad-user
USER cad-user
WORKDIR /home/cad-user

30
docker/Makefile Normal file
View File

@ -0,0 +1,30 @@
DOCKER_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
TOP_DIR := $(realpath $(DOCKER_DIR)/..)
include $(TOP_DIR)/openram.mk
TAG_DATE := $(shell date +%F)
all: build push
.PHONY: build
build:
docker build -t vlsida/openram-ubuntu:${TAG_DATE} -f Dockerfile . | tee -i openram-ubuntu.log
docker tag vlsida/openram-ubuntu:${TAG_DATE} vlsida/openram-ubuntu:latest
.PHONY: push
push:
docker login
docker push vlsida/openram-ubuntu:latest
.PHONY: pull
pull:
docker pull vlsida/openram-ubuntu:latest
mount:
docker run -it -v $(TOP_DIR):/openram \
-v $(SKY130_PDK):$(SKY130_PDK) \
-e PDK_ROOT=$(PDK_ROOT) \
-e OPENRAM_HOME=/openram/compiler \
-e OPENRAM_TECH=/openram/technology \
--user $(UID):$(GID) \
vlsida/openram-ubuntu:latest
.PHONY: mount

47
docker/README.md Normal file
View File

@ -0,0 +1,47 @@
# Docker images for OpenRAM #
## Installing Docker ##
There are a number of ways to install Docker. Pick your favorite.
* On Mac from docker.com with .app:
https://docs.docker.com/docker-for-mac/install/
* On Windows from docker.com:
https://docs.docker.com/docker-for-windows/install/
* On Ubuntu:
https://docs.docker.com/install/linux/docker-ce/ubuntu/
NOTE: If you plan to use a VPN, do *NOT* use the Docker Toolbox for
Mac or the docker from [Macports](https://www.macports.org/
"Macports") as these require a network socket that breaks when you
install some VPN software. To understand the difference, check out [this
page](https://docs.docker.com/docker-for-mac/docker-toolbox/).
## Running Docker ##
### Terminal only ###
* To run as a generic user:
```
make mount
```
## Updating the image ##
If there are updates to the image, you can pull a new one from the hub with:
```
make pull
```
This is not automatically done, so if you have a problem, make sure you are up-to-date.
## Building your own image ##
You can run the build script to build a local image:
```
make build
```
If you want to change things, modify the openram-ubuntu/Dockerfile and let me know what should be fixed.

20
docker/set-paths.sh Normal file
View File

@ -0,0 +1,20 @@
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
export SWROOT=/software
# Klayout
export PATH=$PATH:/usr/local/klayout/bin
# Xyce
export XYCE_HOME=$SWROOT/Xyce/Parallel
export XYCE_PATH=$XYCE_HOME/bin
export PATH=$PATH:$XYCE_PATH
export XYCE_LIB=$XYCE_HOME/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$XYCE_LIB
export XYCE_NO_TRACKING="anything at all"
# PDKs
export FREEPDK45=/home/PDKs/FreePDK45
# Set to the PDK you want to use
export PDK_DIR=$FREEPDK45

86
macros/Makefile Normal file
View File

@ -0,0 +1,86 @@
MACRO_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
TOP_DIR := $(realpath $(MACRO_DIR)/..)
include $(TOP_DIR)/openram.mk
.DEFAULT_GOAL := all
SKY130_PDK ?= $(PDK_ROOT)/sky130A
OPENRAM_OPTS := $(OPENRAM_OPTS)
# Define `OPENRAM_FULL` in your environment to run a full characterize
ifeq ($(OPENRAM_FULL),)
# Do not characterize (default)
else
# Characterize
OPTS += -c
endif
# Verbosity
OPENRAM_OPTS += -v --keeptemp
CONFIG_DIR = configs
SRCS=$(filter-out disabled-% %_common.py,$(sort $(notdir $(wildcard $(CONFIG_DIR)/*.py))))
DIRS=$(basename $(SRCS))
STAMPS=$(addsuffix .ok,$(DIRS))
configs:
@echo
@echo "Using OpenRAM at $(OPENRAM_HOME)"
@echo " (which is version $$(cd $(OPENRAM_HOME); git describe --tags))"
@echo
@echo "Configurations:"
@for D in $(DIRS); do echo " - $$D"; done
@echo
.PHONY: configs
BROKEN := \
sky130_sram_1kbyte_1r1w_8x1024_8 \
sky130_sram_1kbyte_1rw_32x256_8 \
sky130_sram_2kbyte_1rw_32x512_8 \
sky130_sram_4kbyte_1rw_32x1024_8 \
WORKING_STAMPS=$(filter-out $(addsuffix .ok, $(BROKEN)), $(STAMPS))
all: | configs
@echo
@echo "Building following working configs"
@for S in $(WORKING_STAMPS); do echo " - $$S"; done
@sleep 5
$(MAKE) $(WORKING_STAMPS)
@echo "Built all macros."
%.ok: configs/%.py
@echo "Building $*"
@mkdir -p $*
docker run -v $(TOP_DIR):/openram \
-v $(SKY130_PDK):$(SKY130_PDK) \
-e PDK_ROOT=$(PDK_ROOT) \
-e OPENRAM_HOME=/openram/compiler \
-e OPENRAM_TECH=/openram/technology \
-e OPENRAM_TMP=/openram/macros/$*/tmp \
--user $(UID):$(GID) \
vlsida/openram-ubuntu:latest \
python3 -u /openram/compiler/openram.py $(OPENRAM_OPTS) -o $* -p /openram/macros/$* /openram/macros/$< && touch $@
mount:
docker run -it -v $(TOP_DIR):/openram \
-v $(SKY130_PDK):$(SKY130_PDK) \
-e PDK_ROOT=$(PDK_ROOT) \
-e OPENRAM_HOME=/openram/compiler \
-e OPENRAM_TECH=/openram/technology \
--user $(UID):$(GID) \
vlsida/openram-ubuntu:latest
.PHONY: mount
.DELETE_ON_ERROR: $(STAMPS)
$(DIRS):
@$(MAKE) --no-print-directory $@.ok
.PHONY: $(DIRS)
clean:
rm -rf $(STAMPS)
rm -rf $(DIRS)
.PHONY: clean

View File

@ -0,0 +1,21 @@
"""
Dual port (1 read/write + 1 read only) 1 kbytes SRAM with byte write.
FIXME: What is this useful for?
FIXME: Why would you want byte write on this?
"""
word_size = 8 # Bits
num_words = 16
human_byte_size = "{:.0f}kbytes".format((word_size * num_words)/1024/8)
# Allow byte writes
write_size = 2 # Bits
# Dual port
num_rw_ports = 1
num_r_ports = 1
num_w_ports = 0
ports_human = '1rw1r'
import os
exec(open(os.path.join(os.path.dirname(__file__), 'sky130_sram_common.py')).read())

11
openram.mk Normal file
View File

@ -0,0 +1,11 @@
OPENRAM_HOME := $(abspath $(TOP_DIR)/compiler)
OPENRAM_TECH := $(abspath $(TOP_DIR)/technology)
OPENRAM_COMPILER := $(OPENRAM_HOME)/openram.py
ifeq (,$(wildcard $(OPENRAM_COMPILER)))
$(error Did not find '$(OPENRAM_COMPILER)' in '$(OPENRAM_HOME)' (from $$OPENRAM_HOME))
endif
export OPENRAM_HOME
export OPENRAM_TECH
UID = $(shell id -u)
GID = $(shell id -g)

View File

@ -6,3 +6,4 @@ tech load SCN4M_SUBM.20 -noprompt
scalegrid 1 4
set GND gnd
set VDD vdd
set SUB gnd

View File

@ -333,7 +333,7 @@ style lambda=0.20(p)
templayer TCSB nwsd,nwsc
grow 40
and-not TNWR
layer CSB nwsd,nwsc,nwr
grow 140
and-not TCSB
@ -375,7 +375,7 @@ style lambda=0.20(p)
bloat-or pdiff,apres,rpd,pdc/a * 40 nsd,nsc/a 0
or TPS
#final pselect
#final pselect
templayer FSP
bloat-or pdiff,apres,rpd,pfet,psd,pdc/a,psc/a,pfet * 40 ndiff,anres,rnd,ndc/a,nsd,nsc/a,nfet 0
or XDP
@ -772,7 +772,7 @@ style lambda=0.20(cp)
templayer TCSB nwsd,nwsc
grow 40
and-not TNWR
layer CSB nwsd,nwsc,nwr
grow 140
and-not TCSB
@ -814,7 +814,7 @@ style lambda=0.20(cp)
bloat-or pdiff,apres,rpd,pdc/a * 40 nsd,nsc/a 0
or TPS
#final pselect
#final pselect
templayer FSP
bloat-or pdiff,apres,rpd,pfet,psd,pdc/a,psc/a,pfet * 40 ndiff,anres,rnd,ndc/a,nsd,nsc/a,nfet 0
or XDP
@ -1119,7 +1119,7 @@ style lambda=0.20(c)
templayer TCSB nwsd,nwsc
grow 40
and-not TNWR
layer CSB nwsd,nwsc,nwr
grow 140
and-not TCSB
@ -1151,7 +1151,7 @@ style lambda=0.20(c)
bloat-or pdiff,apres,rpd,pdc/a * 40 nsd,nsc/a 0
or TPS
#final pselect
#final pselect
templayer FSP
bloat-or pdiff,apres,rpd,pfet,psd,pdc/a,psc/a,pfet * 40 ndiff,anres,rnd,ndc/a,nsd,nsc/a,nfet 0
or XDP
@ -1456,7 +1456,7 @@ style lambda=0.20()
templayer TCSB nwsd,nwsc
grow 40
and-not TNWR
layer CSB nwsd,nwsc,nwr
grow 140
and-not TCSB
@ -1488,7 +1488,7 @@ style lambda=0.20()
bloat-or pdiff,apres,rpd,pdc/a * 40 nsd,nsc/a 0
or TPS
#final pselect
#final pselect
templayer FSP
bloat-or pdiff,apres,rpd,pfet,psd,pdc/a,psc/a,pfet * 40 ndiff,anres,rnd,ndc/a,nsd,nsc/a,nfet 0
or XDP
@ -6471,7 +6471,7 @@ end
mzrouter
style irouter
# layer hCost vCost jogCost hintCost
# layer hCost vCost jogCost hintCost
layer metal4 2 1 2 1
layer metal3 1 2 2 1
layer metal2 2 1 2 1
@ -6944,7 +6944,7 @@ drc
"Silicide-Block overlap of Silicide-Block polyR/activeR < 2 (Mosis #20.15)"
edge4way sb,pres,anres,apres diff,ndiff,rnd,nfet,nsd,nwsd,pdiff,rpd,pfet,psd,ndc/a,nsc/a,nwsc/a,pdc/a,psc/a 3 diff,ndiff,rnd,nfet,nsd,nwsd,pdiff,rpd,pfet,psd,ndc/a,nsc/a,nwsc/a,pdc/a,psc/a 0 0 \
"Diffusion overhang of Silicide-Block < 3 (Mosis #20.17)
"Diffusion overhang of Silicide-Block < 3 (Mosis #20.17)
spacing gv3 gv3 3 touching_ok \
"GV3 via spacing < 3 (Mosis #21.2)"
@ -7145,7 +7145,7 @@ drc
spacing m4p m4p 4 touching_ok \
"Metal4 PIN spacing < 4 (do_pins)"
#CC cifstyle lambda=0.20(p)
#CC cifstyle lambda=0.20(p)
#CC cifwidth CWN 240 \
#CC "generated CIF layer CWN width will be < 12 (';cif see CWN')"
#CC cifspacing CWN CWN 120 touching_ok \
@ -7223,6 +7223,7 @@ extract
resist (m2,fm2,rm2,m2c,m3c,m3c)/metal2 70
resist (m3,fm3,rm3,m3c,m4c,m4c)/metal3 80
resist (m4,fm4,rm4,m4c,pad)/metal4 40
resist bb None
contact ndc 4 4100
contact pdc 4 3400
@ -7288,25 +7289,25 @@ extract
sideoverlap (m1,fm1,rm1,ndc,pdc,pc,m2c)/metal1 ~(m1,fm1,rm1,ndc,pdc,pc,m2c)/metal1 ~space/w 2.226 ~space/a
#rnw
overlap (m1,fm1,rm1,ndc,pdc,pc,m2c)/metal1 rnw,nwr/active 1.666
sideoverlap (m1,fm1,rm1,ndc,pdc,pc,m2c)/metal1 ~(m1,fm1,rm1,ndc,pdc,pc,m2c)/metal1 rnw,nwr/active 2.226
overlap (m1,fm1,rm1,ndc,pdc,pc,m2c)/metal1 rnw,nwr/active 1.666
sideoverlap (m1,fm1,rm1,ndc,pdc,pc,m2c)/metal1 ~(m1,fm1,rm1,ndc,pdc,pc,m2c)/metal1 rnw,nwr/active 2.226
#metal1-diff blocked by
overlap (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 (ndiff,anres,rnd,ndc)/active 1.640
sideoverlap (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 ~(m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 (ndiff,anres,rnd,ndc)/active 2.226
overlap (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 (pdiff,apres,rpd,pdc)/active 1.640
sideoverlap (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 ~(m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 (pdiff,apres,rpd,pdc)/active 2.226
#metal1-diff blocked by
overlap (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 (ndiff,anres,rnd,ndc)/active 1.640
sideoverlap (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 ~(m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 (ndiff,anres,rnd,ndc)/active 2.226
overlap (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 (pdiff,apres,rpd,pdc)/active 1.640
sideoverlap (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 ~(m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 (pdiff,apres,rpd,pdc)/active 2.226
#metal1-poly blocked by
overlap (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 (poly,fp,pres,rp,pc,nfet,pfet,fet)/active 1.687
sideoverlap (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 ~(m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 (poly,fp,pres,rp,pc,nfet,pfet,fet)/active 2.250
sideoverlap (poly,fp,pres,rp,pc,nfet,pfet,fet)/active ~(poly,fp,pres,rp,pc,nfet,pfet,fet)/active (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 2.250
#metal1-poly blocked by
overlap (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 (poly,fp,pres,rp,pc,nfet,pfet,fet)/active 1.687
sideoverlap (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 ~(m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 (poly,fp,pres,rp,pc,nfet,pfet,fet)/active 2.250
sideoverlap (poly,fp,pres,rp,pc,nfet,pfet,fet)/active ~(poly,fp,pres,rp,pc,nfet,pfet,fet)/active (m1,fm1,rm1,ndc,nsc,nwsc,pdc,psc,pc,m2c)/metal1 2.250
#metal2
sidewall (m2,fm2,rm2,m2c,m3c)/metal2 ~(m2,fm2,rm2,m2c,m3c)/metal2 ~(m2,fm2,rm2,m2c,m3c)/metal2 (m2,fm2,rm2,m2c,m3c)/metal2 23.532
areacap (m2,fm2,rm2,m3c)/metal2 0.581
#metal2-sub blocked by
#metal2-sub blocked by
overlap (m2,fm2,rm2,m3c)/metal2 ~space/w 0.581 ~space/a,~space/m1
perimc (m2,fm2,rm2,m2c,m3c)/metal2 ~(m2,fm2,rm2,m2c,m3c)/metal2 0.836
sideoverlap (m2,fm2,rm2,m2c,m3c)/metal2 ~(m2,fm2,rm2,m2c,m3c)/metal2 ~space/w 0.836 ~space/a,~space/m1
@ -7732,4 +7733,3 @@ style gremlin
pc/a,ndc/a,pdc/a,psc/a,nsc/a,nwsc/a,gc,gc,gc,gv1 X
end

View File

@ -25,9 +25,9 @@ if 'PDK_ROOT' in os.environ:
else:
raise SystemError("Unable to find open_pdks tech file. Set PDK_ROOT.")
spice_model_dir = os.path.join(open_pdks, "SIMULATOR",)
# The ngspice models work with Xyce too now
spice_model_dir = os.path.join(open_pdks, "ngspice")
sky130_lib_ngspice = os.path.join(open_pdks, "ngspice", "sky130.lib.spice")
# We may end up using Xyce but check if at least ngspice exists
if not os.path.exists(sky130_lib_ngspice):
raise SystemError("Did not find {} under {}".format(sky130_lib_ngspice, open_pdks))
os.environ["SPICE_MODEL_DIR"] = spice_model_dir