diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d4852d8..1ee401d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,9 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v1 + - name: Library build + run: | + make library - name: Docker build run: | cd ${{ github.workspace }}/docker diff --git a/.gitignore b/.gitignore index 7a6ad08b..b2ddb51b 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,10 @@ technology/sky130/*_lib technology/sky130/tech/.magicrc .idea compiler/tests/results/ -sky*/ open_pdks/ +dist/ +openram.egg-info/ +sky130A/ +sky130B/ +skywater-pdk/ +sky130_fd_bd_sram/ diff --git a/HINTS.md b/HINTS.md deleted file mode 100644 index 6f29c16b..00000000 --- a/HINTS.md +++ /dev/null @@ -1,117 +0,0 @@ -# Debugging - -When OpenRAM runs, it puts files in a temporary directory that is -shown in the banner at the top. Like: -``` - /tmp/openram_mrg_18128_temp/ -``` -This is where simulations and DRC/LVS get run so there is no network -traffic. The directory name is unique for each person and run of -OpenRAM to not clobber any files and allow simultaneous runs. If it -passes, the files are deleted. If it fails, you will see these files: -+ temp.gds is the layout (.mag files too if using SCMOS) -+ temp.sp is the netlist -+ test1.drc.err is the std err output of the DRC command -+ test1.drc.out is the standard output of the DRC command -+ test1.drc.results is the DRC results file -+ test1.lvs.err is the std err output of the LVS command -+ test1.lvs.out is the standard output of the LVS command -+ test1.lvs.results is the DRC results file - -Depending on your DRC/LVS tools, there will also be: -+ \_calibreDRC.rul\_ is the DRC rule file (Calibre) -+ dc_runset is the command file (Calibre) -+ extracted.sp (Calibre) -+ run_lvs.sh is a Netgen script for LVS (Netgen) -+ run_drc.sh is a Magic script for DRC (Magic) -+ .spice (Magic) - -If DRC/LVS fails, the first thing is to check if it ran in the .out and -.err file. This shows the standard output and error output from -running DRC/LVS. If there is a setup problem it will be shown here. - -If DRC/LVS runs, but doesn't pass, you then should look at the .results -file. If the DRC fails, it will typically show you the command that was used -to run Calibre or Magic+Netgen. - -To debug, you will need a layout viewer. I prefer to use Glade -on my Mac, but you can also use Calibre, Magic, etc. - -1. Klayout - - You can view the designs in [Klayout](https://www.klayout.de/) with the configuration - file provided in the tech directories. For example, -``` - klayout temp.gds -l /home/vagrant/openram/technology/freepdk45/tf/FreePDK45.lyp -``` - -2. Calibre - - Start the Calibre DESIGNrev viewer in the temp directory and load your GDS file: -``` - calibredrv temp.gds -``` - Select Verification->Start RVE and select the results database file in - the new form (e.g., test1.drc.db). This will start the RVE (results - viewer). Scroll through the check pane and find the DRC check with an - error. Select it and it will open some numbers to the right. Double - click on any of the errors in the result browser. These will be - labelled as numbers "1 2 3 4" for example will be 4 DRC errors. - - In the viewer ">" opens the layout down a level. - -3. Glade - - You can view errors in [Glade](http://www.peardrop.co.uk/glade/) as well. - - To remote display over X windows, you need to disable OpenGL acceleration or use vnc - or something. You can disable by adding this to your .bashrc in bash: -``` - export GLADE_USE_OPENGL=no -``` - or in .cshrc/.tcshrc in csh/tcsh: -``` - setenv GLADE_USE_OPENGAL no -``` - To use this with the FreePDK45 or SCMOS layer views you should use the - tech files. Then create a .glade.py file in your user directory with - these commands to load the technology layers: -``` -ui().importCds("default", -"/Users/mrg/techfiles/freepdk45/display.drf", -"/Users/mrg/techfiles/freepdk45/FreePDK45.tf", 1000, 1, -"/Users/mrg/techfiles/freepdk45/layers.map") -``` - Obviously, edit the paths to point to your directory. To switch - between processes, you have to change the importCds command (or you - can manually run the command each time you start glade). - - To load the errors, you simply do Verify->Import Calibre Errors select - the .results file from Calibre. - -4. Magic - - Magic is only supported in SCMOS. You will need to install the MOSIS SCMOS rules - and [Magic](http://opencircuitdesign.com/) - - When running DRC or extraction, OpenRAM will load the GDS file, save - the .ext/.mag files, and export an extracted netlist (.spice). - -5. It is possible to use other viewers as well, such as: - * [LayoutEditor](http://www.layouteditor.net/) - - -# Example to output/input .gds layout files from/to Cadence - -1. To create your component layouts, you should stream them to - individual gds files using our provided layermap and flatten - cells. For example, -``` - strmout -layerMap layers.map -library sram -topCell $i -view layout -flattenVias -flattenPcells -strmFile ../gds_lib/$i.gds -``` -2. To stream a layout back into Cadence, do this: -``` - strmin -layerMap layers.map -attachTechFileOfLib NCSU\_TechLib\_FreePDK45 -library sram_4_32 -strmFile sram_4_32.gds -``` - When you import a gds file, make sure to attach the correct tech lib - or you will get incorrect layers in the resulting library. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 00000000..b2d45363 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,24 @@ +include Makefile +include openram.mk +include setpaths.sh +include requirements.txt +include docker/* +recursive-include compiler * +recursive-include technology * +exclude .DS_Store +exclude .idea +exclude **/model_data +exclude technology/sky130/*_lib +exclude technology/sky130/tech/.magicrc +exclude compiler/gen_stimulus.py +exclude compiler/model_data_util.py +exclude compiler/printGDS.py +exclude compiler/processGDS.py +exclude compiler/uniquifyGDS.py +exclude compiler/view_profile.py +exclude compiler/run_profile.sh +recursive-exclude open_pdks * +recursive-exclude compiler/tests/results * +recursive-exclude technology/freepdk45/ncsu_basekit * +recursive-exclude outputs * +global-exclude *.pyc *~ *.orig *.rej *.aux *.out *.toc *.synctex.gz \ No newline at end of file diff --git a/Makefile b/Makefile index 214b834b..c32f9d3e 100644 --- a/Makefile +++ b/Makefile @@ -84,7 +84,7 @@ $(SRAM_LIB_DIR): check-pdk-root git clone $(SRAM_LIB_GIT_REPO) $(SRAM_LIB_DIR) && \ cd $(SRAM_LIB_DIR) && git pull && git checkout $(SRAM_LIB_GIT_COMMIT)) -install: $(SRAM_LIB_DIR) pdk +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 ] || \ @@ -215,3 +215,16 @@ wipe: uninstall @rm -rf $(OPEN_PDKS_DIR) @rm -rf $(SKY130_PDKS_DIR) .PHONY: wipe + +# Build the openram library +build-library: + @rm -rf dist + @rm -rf openram.egg-info + @python3 -m pip install --upgrade build + @python3 -m build +.PHONY: build-library + +# Build and install the openram library +library: build-library + @python3 -m pip install --find-links=dist openram --force +.PHONY: library \ No newline at end of file diff --git a/README.md b/README.md index e2187f23..895b9f1d 100644 --- a/README.md +++ b/README.md @@ -19,161 +19,8 @@ predictive and fabricable technologies. # Documentation -Please take a look at our presentation We have created a detailed -presentation that serves as our [documentation][documentation]. -This is the most up-to-date information, so please let us know if you see -things that need to be fixed. - -# Basic Setup - -## Dependencies - -Please see the Dockerfile for the required versions of tools. - -In general, the OpenRAM compiler has very few dependencies: -+ Docker -+ Make -+ Python 3.6 or higher -+ Various Python packages (pip install -r requirements.txt) -+ [Git] - -## Docker - -We have a [docker setup](./docker) to run OpenRAM. To use this, you should run: -``` -cd openram/docker -make build -``` -This must be run once and will take a while to build all the tools. - - -## Environment - -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). - -You should also add OPENRAM\_HOME to your PYTHONPATH. - -For example add this to your .bashrc: - -``` - export OPENRAM_HOME="$HOME/openram/compiler" - export OPENRAM_TECH="$HOME/openram/technology" - export PYTHONPATH=$OPENRAM_HOME -``` - -Note that if you want symbols to resolve in your editor, you may also want to add the specific technology -directory that you use and any custom technology modules as well. For example: -``` - export PYTHONPATH="$OPENRAM_HOME:$OPENRAM_TECH/sky130:$OPENRAM_TECH/sky130/custom" -``` - -We include the tech files necessary for [SCMOS] SCN4M_SUBM, -[FreePDK45]. The [SCMOS] spice models, however, are -generic and should be replaced with foundry models. You may get the -entire [FreePDK45 PDK here][FreePDK45]. - - -### Sky130 Setup - -To install [Sky130], you must have the open_pdks files installed in $PDK_ROOT. -To install this automatically, you can run: - - cd $HOME/openram - make pdk - -Then you must also install the [Sky130] SRAM build space and the appropriate cell views -by running: - - cd $HOME/openram - make install - -# Basic Usage - -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: -``` -# Data word size -word_size = 2 -# Number of words in the memory -num_words = 16 - -# Technology to use in $OPENRAM_TECH -tech_name = "scn4m_subm" - -# You can use the technology nominal corner only -nominal_corner_only = True -# Or you can specify particular corners -# Process corners to characterize -# process_corners = ["SS", "TT", "FF"] -# Voltage corners to characterize -# supply_voltages = [ 3.0, 3.3, 3.5 ] -# Temperature corners to characterize -# temperatures = [ 0, 25 100] - -# Output directory for the results -output_path = "temp" -# Output file base name -output_name = "sram_{0}_{1}_{2}".format(word_size,num_words,tech_name) - -# Disable analytical models for full characterization (WARNING: slow!) -# analytical_delay = False - -``` - -You can then run OpenRAM by executing: -``` -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), -use the following command to run all regression tests: - -``` -cd openram/compiler/tests -make -j 3 -``` -The -j can run with 3 threads. By default, this will run in all technologies. - -To run a specific test in all technologies: -``` -cd openram/compiler/tests -make 05_bitcell_array_test -``` -To run a specific technology: -``` -cd openram/compiler/tests -TECHS=scn4m_subm make 05_bitcell_array_test -``` - -To increase the verbosity of the test, add one (or more) -v options and -pass it as an argument to OpenRAM: -``` -ARGS="-v" make 05_bitcell_array_test -``` - -Unit test results are put in a directory: -``` -openram/compiler/tests/results// -``` -If the test fails, there will be a tmp directory with intermediate results. -If the test passes, this directory will be deleted to save space. -You can view the .out file to see what the output of a test is in either case. +Please see our [documentation][documentation] and let us know if anything needs +updating. # Get Involved @@ -186,17 +33,25 @@ You can view the .out file to see what the output of a test is in either case. # Further Help -+ [Additional hints](./HINTS.md) + [Documentation][documentation] + [OpenRAM Slack Workspace][Slack] + [OpenRAM Users Group][user-group] ([subscribe here][user-group-subscribe]) + [OpenRAM Developers Group][dev-group] ([subscribe here][dev-group-subscribe]) -+ @mrg@fostodon.org # License OpenRAM is licensed under the [BSD 3-clause License](./LICENSE). +# Publications + ++ M. R. Guthaus, J. E. Stine, S. Ataei, B. Chen, B. Wu, M. Sarwar, "OpenRAM: An Open-Source Memory Compiler," Proceedings of the 35th International Conference on Computer-Aided Design (ICCAD), 2016 ++ S. Ataei, J. Stine, M. Guthaus, “A 64 kb differential single-port 12T SRAM design with a bit-interleaving scheme for low-voltage operation in 32 nm SOI CMOS,” International Conference on Computer Design (ICCD), 2016, pp. 499-506. ++ E. Ebrahimi, M. Guthaus, J. Renau, “Timing Speculative SRAM”, IEEE In- ternational Symposium on Circuits and Systems (ISCAS), 2017 ++ B. Wu, J.E. Stine, M.R. Guthaus, "Fast and Area-Efficient Word-Line Optimization", IEEE International Symposium on Circuits and Systems (ISCAS), 2019 ++ B. Wu, M. Guthaus, "Bottom Up Approach for High Speed SRAM Word-line Buffer Insertion Optimization", IFIP/IEEE International Conference on Very Large Scale Integration (VLSI-SoC), 2019 ++ H. Nichols, M. Grimes, J. Sowash, J. Cirimelli-Low, M. Guthaus "Automated Synthesis of Multi-Port Memories and Control", IFIP/IEEE International Conference on Very Large Scale Integration (VLSI-SoC), 2019 + + # Contributors & Acknowledgment - [Matthew Guthaus] from [VLSIDA] created the OpenRAM project and is the lead architect. @@ -215,9 +70,9 @@ 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 +[documentation]: docs/source/index.md [dev-group]: mailto:openram-dev-group@ucsc.edu [user-group]: mailto:openram-user-group@ucsc.edu [dev-group-subscribe]: mailto:openram-dev-group+subscribe@ucsc.edu diff --git a/__init__.py b/__init__.py new file mode 100644 index 00000000..5eca3f7e --- /dev/null +++ b/__init__.py @@ -0,0 +1,22 @@ +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 Regents of the University of California and The Board +# of Regents for the Oklahoma Agricultural and Mechanical College +# (acting for and on behalf of Oklahoma State University) +# All rights reserved. +# +import os +import sys + +# Attempt to add the source code to the PYTHONPATH here before running globals.init_openram(). +try: + OPENRAM_HOME = os.path.abspath(os.environ.get("OPENRAM_HOME")) +except: + import openram + OPENRAM_HOME = os.path.dirname(openram.__file__) + "/compiler" + +if not os.path.isdir(OPENRAM_HOME): + assert False + +if OPENRAM_HOME not in sys.path: + sys.path.insert(0, OPENRAM_HOME) \ No newline at end of file diff --git a/compiler/Makefile b/compiler/Makefile index 117e4bd2..d3596421 100644 --- a/compiler/Makefile +++ b/compiler/Makefile @@ -95,7 +95,7 @@ model: $(STAMPS) $(eval bname=$(basename $(notdir $@))) $(eval config_path=$(CONFIG_DIR)/$(addsuffix .py, $(notdir $(basename $@)))) mkdir -p $(SIM_DIR)/$(bname) - -python3 $(OPENRAM_HOME)/openram.py $(OPTS) -p $(SIM_DIR)/$(bname) -o $(bname) -t $(TECH) $(config_path) 2>&1 > /dev/null + -python3 $(OPENRAM_HOME)/../sram_compiler.py $(OPTS) -p $(SIM_DIR)/$(bname) -o $(bname) -t $(TECH) $(config_path) 2>&1 > /dev/null touch $@ clean_model: diff --git a/compiler/debug.py b/compiler/debug.py index 4052e713..8e970cca 100644 --- a/compiler/debug.py +++ b/compiler/debug.py @@ -131,7 +131,7 @@ def bp(): An empty function so you can set soft breakpoints in pdb. Usage: 1) Add a breakpoint anywhere in your code with "import debug; debug.bp()". - 2) Run "python3 -m pdb openram.py config.py" or "python3 -m pdb 05_bitcell_array.test" (for example) + 2) Run "python3 -m pdb sram_compiler.py config.py" or "python3 -m pdb 05_bitcell_array.test" (for example) 3) When pdb starts, run "break debug.bp" to set a SOFT breakpoint. (Or you can add this to your ~/.pdbrc) 4) Then run "cont" to continue. 5) You can now set additional breakpoints or display commands diff --git a/compiler/drc/custom_cell_properties.py b/compiler/drc/custom_cell_properties.py index 4e7e40e7..bbf3829c 100644 --- a/compiler/drc/custom_cell_properties.py +++ b/compiler/drc/custom_cell_properties.py @@ -186,12 +186,15 @@ class cell_properties(): self.names["col_cap_bitcell_2port"] = "col_cap_cell_2rw" self.names["row_cap_bitcell_1port"] = "row_cap_cell_1rw" self.names["row_cap_bitcell_2port"] = "row_cap_cell_2rw" + self.names["internal"] = "internal" + self.use_strap = False self._ptx = _ptx(model_is_subckt=False, bin_spice_models=False) self._pgate = _pgate(add_implants=False) + self._inv_dec = cell(["A", "Z", "vdd", "gnd"], ["INPUT", "OUTPUT", "POWER", "GROUND"]) @@ -231,6 +234,12 @@ class cell_properties(): self._row_cap_2port = bitcell(["wl0", "wl1", "gnd"], ["INPUT", "INPUT", "POWER", "GROUND"]) + self._internal = cell([],[]) + + @property + def internal(self): + return self._internal + @property def ptx(self): return self._ptx diff --git a/compiler/globals.py b/compiler/globals.py index 9a185052..01c52725 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -24,7 +24,7 @@ import subprocess VERSION = "1.2.0" NAME = "OpenRAM v{}".format(VERSION) -USAGE = "openram.py [options] \nUse -h for help.\n" +USAGE = "sram_compiler.py [options] \nUse -h for help.\n" OPTS = options.options() CHECKPOINT_OPTS = None @@ -141,9 +141,6 @@ def print_banner(): debug.print_raw("|=========" + user_info.center(60) + "=========|") dev_info = "Development help: openram-dev-group@ucsc.edu" debug.print_raw("|=========" + dev_info.center(60) + "=========|") - if OPTS.openram_temp: - temp_info = "Temp dir: {}".format(OPTS.openram_temp) - debug.print_raw("|=========" + temp_info.center(60) + "=========|") debug.print_raw("|=========" + "See LICENSE for license info".center(60) + "=========|") debug.print_raw("|==============================================================================|") @@ -432,16 +429,23 @@ def setup_paths(): global OPTS + # If $OPENRAM_HOME is defined, use that path for the source code. + # Otherwise, use the openram package. try: OPENRAM_HOME = os.path.abspath(os.environ.get("OPENRAM_HOME")) except: - debug.error("$OPENRAM_HOME is not properly defined.", 1) + import openram + OPENRAM_HOME = os.path.dirname(openram.__file__) + "/compiler" + # Add this directory to os.environ here + os.environ["OPENRAM_HOME"] = OPENRAM_HOME debug.check(os.path.isdir(OPENRAM_HOME), "$OPENRAM_HOME does not exist: {0}".format(OPENRAM_HOME)) + debug.info(1, "OpenRAM source code found in {}".format(OPENRAM_HOME)) if OPENRAM_HOME not in sys.path: - debug.error("Please add OPENRAM_HOME to the PYTHONPATH.", -1) + sys.path.insert(0, OPENRAM_HOME) + debug.info(2, "Adding source code to PYTHONPATH.") # Use a unique temp subdirectory if multithreaded if OPTS.num_threads > 1 or OPTS.openram_temp == "/tmp": @@ -547,11 +551,30 @@ def import_tech(): debug.info(2, "Importing technology: " + OPTS.tech_name) - # environment variable should point to the technology dir + OPENRAM_TECH = "" + + # Check if $OPENRAM_TECH is defined try: OPENRAM_TECH = os.path.abspath(os.environ.get("OPENRAM_TECH")) except: - debug.error("$OPENRAM_TECH environment variable is not defined.", 1) + debug.info(2, + "$OPENRAM_TECH environment variable is not defined. " + "Only the default technology modules will be considered if installed.") + # Point to the default technology modules that are part of the openram package + try: + import openram + if OPENRAM_TECH != "": + OPENRAM_TECH += ":" + OPENRAM_TECH += os.path.dirname(openram.__file__) + "/technology" + except: + if OPENRAM_TECH == "": + debug.warning("Couldn't find a tech directory. " + "Install openram library or set $OPENRAM_TECH.") + + debug.info(1, "Tech directory found in {}".format(OPENRAM_TECH)) + + # Add this environment variable to os.environ + os.environ["OPENRAM_TECH"] = OPENRAM_TECH # Add all of the paths for tech_path in OPENRAM_TECH.split(":"): diff --git a/compiler/modules/__init__.py b/compiler/modules/__init__.py old mode 100644 new mode 100755 index b2f78ba7..eb0e9da7 --- a/compiler/modules/__init__.py +++ b/compiler/modules/__init__.py @@ -80,3 +80,4 @@ from .write_mask_and_array import * from .sram_1bank import * from .sram_config import * from .sram import * +from .internal_base import * \ No newline at end of file diff --git a/compiler/modules/bitcell_1port.py b/compiler/modules/bitcell_1port.py index 57943697..a0fdf794 100644 --- a/compiler/modules/bitcell_1port.py +++ b/compiler/modules/bitcell_1port.py @@ -29,7 +29,3 @@ class bitcell_1port(bitcell_base): """ self.add_graph_edges(graph, port_nets) - def is_non_inverting(self): - """Return input to output polarity for module""" - - return False diff --git a/compiler/modules/bitcell_2port.py b/compiler/modules/bitcell_2port.py index 716c79b7..c346bad6 100644 --- a/compiler/modules/bitcell_2port.py +++ b/compiler/modules/bitcell_2port.py @@ -99,8 +99,3 @@ class bitcell_2port(bitcell_base): # Port 1 edges graph.add_edge(pin_dict["wl1"], pin_dict["bl1"], self) graph.add_edge(pin_dict["wl1"], pin_dict["br1"], self) - - def is_non_inverting(self): - """Return input to output polarity for module""" - - return False diff --git a/compiler/modules/bitcell_base.py b/compiler/modules/bitcell_base.py index 25d3efe4..ca41725b 100644 --- a/compiler/modules/bitcell_base.py +++ b/compiler/modules/bitcell_base.py @@ -265,3 +265,15 @@ class bitcell_base(design): delay = math.sqrt(2*tstep*(vdd-spice["nom_threshold"])/m) return delay + + def build_graph(self, graph, inst_name, port_nets): + """ + Adds edges based on inputs/outputs. + Overrides base class function. + """ + debug.error("Must override build_graph function in bitcell base class.") + + def is_non_inverting(self): + """Return input to output polarity for module""" + + return False diff --git a/compiler/modules/internal_base.py b/compiler/modules/internal_base.py new file mode 100755 index 00000000..70659f0f --- /dev/null +++ b/compiler/modules/internal_base.py @@ -0,0 +1,14 @@ +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 Regents of the University of California and The Board +# of Regents for the Oklahoma Agricultural and Mechanical College +# (acting for and on behalf of Oklahoma State University) +# All rights reserved. +# + +from base import design + +class internal_base(design): + + def __init__(self, name, cell_name=None, prop=None): + design.__init__(self, name, cell_name, prop) diff --git a/compiler/options.py b/compiler/options.py index 6c518d09..38266b62 100644 --- a/compiler/options.py +++ b/compiler/options.py @@ -13,7 +13,7 @@ class options(optparse.Values): """ Class for holding all of the OpenRAM options. All of these options can be over-riden in a configuration file - that is the sole required command-line positional argument for openram.py. + that is the sole required command-line positional argument for sram_compiler.py. """ ################### diff --git a/compiler/tests/00_code_format_check_test.py b/compiler/tests/00_code_format_check_test.py index cfe72a21..8eff7388 100755 --- a/compiler/tests/00_code_format_check_test.py +++ b/compiler/tests/00_code_format_check_test.py @@ -35,7 +35,7 @@ class code_format_test(openram_test): continue if re.search("debug.py$", code): continue - if re.search("openram.py$", code): + if re.search("sram_compiler.py$", code): continue if re.search("testutils.py$", code): continue diff --git a/compiler/tests/30_openram_back_end_test.py b/compiler/tests/30_openram_back_end_test.py index 9d5b1e42..5519f42e 100755 --- a/compiler/tests/30_openram_back_end_test.py +++ b/compiler/tests/30_openram_back_end_test.py @@ -23,7 +23,7 @@ class openram_back_end_test(openram_test): config_file = "{}/tests/configs/config_back_end".format(os.getenv("OPENRAM_HOME")) globals.init_openram(config_file) - debug.info(1, "Testing top-level back-end openram.py with 2-bit, 16 word SRAM.") + debug.info(1, "Testing top-level back-end sram_compiler.py with 2-bit, 16 word SRAM.") out_file = "testsram" out_path = "/tmp/testsram_{0}_{1}_{2}/".format(OPTS.tech_name, getpass.getuser(), os.getpid()) @@ -54,9 +54,9 @@ class openram_back_end_test(openram_test): # Always perform code coverage if OPTS.coverage == 0: debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage") - exe_name = "{0}/openram.py ".format(OPENRAM_HOME) + exe_name = "{0}/../sram_compiler.py ".format(OPENRAM_HOME) else: - exe_name = "{0}{1}/openram.py ".format(OPTS.coverage_exe, OPENRAM_HOME) + exe_name = "{0}{1}/../sram_compiler.py ".format(OPTS.coverage_exe, OPENRAM_HOME) config_name = "{0}/tests/configs/config_back_end.py".format(OPENRAM_HOME) cmd = "{0} -o {1} -p {2} {3} {4} 2>&1 > {5}/output.log".format(exe_name, out_file, diff --git a/compiler/tests/30_openram_front_end_test.py b/compiler/tests/30_openram_front_end_test.py index 489ea26c..928ac74e 100755 --- a/compiler/tests/30_openram_front_end_test.py +++ b/compiler/tests/30_openram_front_end_test.py @@ -23,7 +23,7 @@ class openram_front_end_test(openram_test): config_file = "{}/tests/configs/config_front_end".format(os.getenv("OPENRAM_HOME")) globals.init_openram(config_file) - debug.info(1, "Testing top-level front-end openram.py with 2-bit, 16 word SRAM.") + debug.info(1, "Testing top-level front-end sram_compiler.py with 2-bit, 16 word SRAM.") out_file = "testsram" out_path = "/tmp/testsram_{0}_{1}_{2}".format(OPTS.tech_name, getpass.getuser(), os.getpid()) @@ -54,9 +54,9 @@ class openram_front_end_test(openram_test): # Always perform code coverage if OPTS.coverage == 0: debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage") - exe_name = "{0}/openram.py ".format(OPENRAM_HOME) + exe_name = "{0}/../sram_compiler.py ".format(OPENRAM_HOME) else: - exe_name = "{0}{1}/openram.py ".format(OPTS.coverage_exe, OPENRAM_HOME) + exe_name = "{0}{1}/../sram_compiler.py ".format(OPTS.coverage_exe, OPENRAM_HOME) config_name = "{0}/tests/configs/config_front_end.py".format(OPENRAM_HOME) cmd = "{0} -n -o {1} -p {2} {3} {4} 2>&1 > {5}/output.log".format(exe_name, out_file, diff --git a/compiler/tests/Makefile b/compiler/tests/Makefile index 24e9a526..f736d222 100644 --- a/compiler/tests/Makefile +++ b/compiler/tests/Makefile @@ -121,8 +121,11 @@ $(TEST_BASES): @mkdir -p results/$*/tmp @$(DOCKER_CMD) sh -c ". /home/cad-user/.bashrc && sleep 1 && python3 -u $(OPENRAM_DIR)/$(getfile).py \ -t $(gettech) -k -v $(ARGS) -p $(OPENRAM_DIR)/results/$* > $(OPENRAM_DIR)/results/$*.out 2>&1 && touch $(OPENRAM_DIR)/results/$*.ok || touch $(OPENRAM_DIR)/results/$*.bad" - @test -f $(TOP_DIR)/compiler/tests/results/$*.ok && echo "$* ... PASS!" && \ - rm -rf $(TOP_DIR)/compiler/tests/results/$* || echo "$* ... FAIL!" +ifdef KEEP + @test -f $(TOP_DIR)/compiler/tests/results/$*.ok && echo "$* ... PASS!" || echo "$* ... FAIL!" +else + @test -f $(TOP_DIR)/compiler/tests/results/$*.ok && echo "$* ... PASS!" && rm -rf $(TOP_DIR)/compiler/tests/results/$* || echo "$* ... FAIL!" +endif .DELETE_ON_ERROR: $(TEST_STAMPS) .PHONY: docker-pull diff --git a/docs/assets/images/architecture/sram_architecture.png b/docs/assets/images/architecture/sram_architecture.png new file mode 100644 index 00000000..4c078042 Binary files /dev/null and b/docs/assets/images/architecture/sram_architecture.png differ diff --git a/docs/assets/images/base_data_structures/layout_1.png b/docs/assets/images/base_data_structures/layout_1.png new file mode 100644 index 00000000..c847602e Binary files /dev/null and b/docs/assets/images/base_data_structures/layout_1.png differ diff --git a/docs/assets/images/base_data_structures/layout_2.png b/docs/assets/images/base_data_structures/layout_2.png new file mode 100644 index 00000000..bb4a406f Binary files /dev/null and b/docs/assets/images/base_data_structures/layout_2.png differ diff --git a/docs/assets/images/base_data_structures/parameterized_cell.png b/docs/assets/images/base_data_structures/parameterized_cell.png new file mode 100644 index 00000000..4961fb46 Binary files /dev/null and b/docs/assets/images/base_data_structures/parameterized_cell.png differ diff --git a/docs/assets/images/base_data_structures/transistor.png b/docs/assets/images/base_data_structures/transistor.png new file mode 100644 index 00000000..74e657cd Binary files /dev/null and b/docs/assets/images/base_data_structures/transistor.png differ diff --git a/docs/assets/images/basic_usage/datasheet_1.png b/docs/assets/images/basic_usage/datasheet_1.png new file mode 100644 index 00000000..ac4c61ca Binary files /dev/null and b/docs/assets/images/basic_usage/datasheet_1.png differ diff --git a/docs/assets/images/basic_usage/datasheet_2.png b/docs/assets/images/basic_usage/datasheet_2.png new file mode 100644 index 00000000..922014eb Binary files /dev/null and b/docs/assets/images/basic_usage/datasheet_2.png differ diff --git a/docs/assets/images/basic_usage/datasheet_3.png b/docs/assets/images/basic_usage/datasheet_3.png new file mode 100644 index 00000000..79d7b21b Binary files /dev/null and b/docs/assets/images/basic_usage/datasheet_3.png differ diff --git a/docs/assets/images/bitcells/10t.png b/docs/assets/images/bitcells/10t.png new file mode 100644 index 00000000..2495eb2b Binary files /dev/null and b/docs/assets/images/bitcells/10t.png differ diff --git a/docs/assets/images/bitcells/6t.png b/docs/assets/images/bitcells/6t.png new file mode 100644 index 00000000..fa125004 Binary files /dev/null and b/docs/assets/images/bitcells/6t.png differ diff --git a/docs/assets/images/bitcells/dff.png b/docs/assets/images/bitcells/dff.png new file mode 100644 index 00000000..cddf485d Binary files /dev/null and b/docs/assets/images/bitcells/dff.png differ diff --git a/docs/assets/images/bitcells/dff_reference.png b/docs/assets/images/bitcells/dff_reference.png new file mode 100644 index 00000000..ff72ad34 Binary files /dev/null and b/docs/assets/images/bitcells/dff_reference.png differ diff --git a/docs/assets/images/bitcells/multiport_bitcells.png b/docs/assets/images/bitcells/multiport_bitcells.png new file mode 100644 index 00000000..9fd05b16 Binary files /dev/null and b/docs/assets/images/bitcells/multiport_bitcells.png differ diff --git a/docs/assets/images/bitcells/parameterized_1.png b/docs/assets/images/bitcells/parameterized_1.png new file mode 100644 index 00000000..0b8e4b11 Binary files /dev/null and b/docs/assets/images/bitcells/parameterized_1.png differ diff --git a/docs/assets/images/bitcells/parameterized_2.png b/docs/assets/images/bitcells/parameterized_2.png new file mode 100644 index 00000000..1d64296f Binary files /dev/null and b/docs/assets/images/bitcells/parameterized_2.png differ diff --git a/docs/assets/images/bitcells/thin_dual.png b/docs/assets/images/bitcells/thin_dual.png new file mode 100644 index 00000000..036c46c5 Binary files /dev/null and b/docs/assets/images/bitcells/thin_dual.png differ diff --git a/docs/assets/images/bitcells/thin_dual_straps.png b/docs/assets/images/bitcells/thin_dual_straps.png new file mode 100644 index 00000000..61d232b0 Binary files /dev/null and b/docs/assets/images/bitcells/thin_dual_straps.png differ diff --git a/docs/assets/images/bitcells/thin_single.png b/docs/assets/images/bitcells/thin_single.png new file mode 100644 index 00000000..46066f84 Binary files /dev/null and b/docs/assets/images/bitcells/thin_single.png differ diff --git a/docs/assets/images/bitcells/thin_single_straps.png b/docs/assets/images/bitcells/thin_single_straps.png new file mode 100644 index 00000000..a6dfc2fa Binary files /dev/null and b/docs/assets/images/bitcells/thin_single_straps.png differ diff --git a/docs/assets/images/characterization/buffer_1.png b/docs/assets/images/characterization/buffer_1.png new file mode 100644 index 00000000..c7771698 Binary files /dev/null and b/docs/assets/images/characterization/buffer_1.png differ diff --git a/docs/assets/images/characterization/buffer_2.png b/docs/assets/images/characterization/buffer_2.png new file mode 100644 index 00000000..15775ee8 Binary files /dev/null and b/docs/assets/images/characterization/buffer_2.png differ diff --git a/docs/assets/images/characterization/buffer_3.png b/docs/assets/images/characterization/buffer_3.png new file mode 100644 index 00000000..d1f573c4 Binary files /dev/null and b/docs/assets/images/characterization/buffer_3.png differ diff --git a/docs/assets/images/characterization/exclusion.png b/docs/assets/images/characterization/exclusion.png new file mode 100644 index 00000000..e39a08d2 Binary files /dev/null and b/docs/assets/images/characterization/exclusion.png differ diff --git a/docs/assets/images/characterization/graph_with_exclusion.png b/docs/assets/images/characterization/graph_with_exclusion.png new file mode 100644 index 00000000..388ab741 Binary files /dev/null and b/docs/assets/images/characterization/graph_with_exclusion.png differ diff --git a/docs/assets/images/characterization/graph_without_exclusion.png b/docs/assets/images/characterization/graph_without_exclusion.png new file mode 100644 index 00000000..0f4d08e1 Binary files /dev/null and b/docs/assets/images/characterization/graph_without_exclusion.png differ diff --git a/docs/assets/images/control_logic/internal_signals_read.png b/docs/assets/images/control_logic/internal_signals_read.png new file mode 100644 index 00000000..5ac7ca1d Binary files /dev/null and b/docs/assets/images/control_logic/internal_signals_read.png differ diff --git a/docs/assets/images/control_logic/internal_signals_write.png b/docs/assets/images/control_logic/internal_signals_write.png new file mode 100644 index 00000000..fc830d11 Binary files /dev/null and b/docs/assets/images/control_logic/internal_signals_write.png differ diff --git a/docs/assets/images/control_logic/read_simulation.png b/docs/assets/images/control_logic/read_simulation.png new file mode 100644 index 00000000..c869d863 Binary files /dev/null and b/docs/assets/images/control_logic/read_simulation.png differ diff --git a/docs/assets/images/control_logic/read_timing.png b/docs/assets/images/control_logic/read_timing.png new file mode 100644 index 00000000..a614e130 Binary files /dev/null and b/docs/assets/images/control_logic/read_timing.png differ diff --git a/docs/assets/images/control_logic/replica_array.png b/docs/assets/images/control_logic/replica_array.png new file mode 100644 index 00000000..0cce70ea Binary files /dev/null and b/docs/assets/images/control_logic/replica_array.png differ diff --git a/docs/assets/images/control_logic/write_simulation.png b/docs/assets/images/control_logic/write_simulation.png new file mode 100644 index 00000000..c361ba4f Binary files /dev/null and b/docs/assets/images/control_logic/write_simulation.png differ diff --git a/docs/assets/images/control_logic/write_timing.png b/docs/assets/images/control_logic/write_timing.png new file mode 100644 index 00000000..7ad61a40 Binary files /dev/null and b/docs/assets/images/control_logic/write_timing.png differ diff --git a/docs/assets/images/design_modules/1d_array.png b/docs/assets/images/design_modules/1d_array.png new file mode 100644 index 00000000..b870318b Binary files /dev/null and b/docs/assets/images/design_modules/1d_array.png differ diff --git a/docs/assets/images/design_modules/2d_array_horizontal.png b/docs/assets/images/design_modules/2d_array_horizontal.png new file mode 100644 index 00000000..a466baf6 Binary files /dev/null and b/docs/assets/images/design_modules/2d_array_horizontal.png differ diff --git a/docs/assets/images/design_modules/2d_array_vertical.png b/docs/assets/images/design_modules/2d_array_vertical.png new file mode 100644 index 00000000..69192cba Binary files /dev/null and b/docs/assets/images/design_modules/2d_array_vertical.png differ diff --git a/docs/assets/images/design_modules/address_decoder.png b/docs/assets/images/design_modules/address_decoder.png new file mode 100644 index 00000000..e0a7baf7 Binary files /dev/null and b/docs/assets/images/design_modules/address_decoder.png differ diff --git a/docs/assets/images/design_modules/bank.png b/docs/assets/images/design_modules/bank.png new file mode 100644 index 00000000..a57ac920 Binary files /dev/null and b/docs/assets/images/design_modules/bank.png differ diff --git a/docs/assets/images/design_modules/bitcell_array.png b/docs/assets/images/design_modules/bitcell_array.png new file mode 100644 index 00000000..ed77fe1e Binary files /dev/null and b/docs/assets/images/design_modules/bitcell_array.png differ diff --git a/docs/assets/images/design_modules/delay_line.png b/docs/assets/images/design_modules/delay_line.png new file mode 100644 index 00000000..2cf87772 Binary files /dev/null and b/docs/assets/images/design_modules/delay_line.png differ diff --git a/docs/assets/images/design_modules/replica_bitcell_array.png b/docs/assets/images/design_modules/replica_bitcell_array.png new file mode 100644 index 00000000..daea61d0 Binary files /dev/null and b/docs/assets/images/design_modules/replica_bitcell_array.png differ diff --git a/docs/assets/images/logos/okstate.png b/docs/assets/images/logos/okstate.png new file mode 100644 index 00000000..f19f5a37 Binary files /dev/null and b/docs/assets/images/logos/okstate.png differ diff --git a/docs/assets/images/logos/vlsida.png b/docs/assets/images/logos/vlsida.png new file mode 100644 index 00000000..784277af Binary files /dev/null and b/docs/assets/images/logos/vlsida.png differ diff --git a/docs/assets/images/results/generated_layout.jpg b/docs/assets/images/results/generated_layout.jpg new file mode 100644 index 00000000..bc6e5b93 Binary files /dev/null and b/docs/assets/images/results/generated_layout.jpg differ diff --git a/docs/assets/images/results/small_layouts_1.png b/docs/assets/images/results/small_layouts_1.png new file mode 100644 index 00000000..bf587882 Binary files /dev/null and b/docs/assets/images/results/small_layouts_1.png differ diff --git a/docs/assets/images/results/small_layouts_2.png b/docs/assets/images/results/small_layouts_2.png new file mode 100644 index 00000000..6dee8f4d Binary files /dev/null and b/docs/assets/images/results/small_layouts_2.png differ diff --git a/docs/assets/images/results/sram_area.png b/docs/assets/images/results/sram_area.png new file mode 100644 index 00000000..cf786905 Binary files /dev/null and b/docs/assets/images/results/sram_area.png differ diff --git a/docs/assets/images/results/timing_and_density_results.png b/docs/assets/images/results/timing_and_density_results.png new file mode 100644 index 00000000..9641621e Binary files /dev/null and b/docs/assets/images/results/timing_and_density_results.png differ diff --git a/docs/assets/images/routing/channel_router_book.png b/docs/assets/images/routing/channel_router_book.png new file mode 100644 index 00000000..7791772e Binary files /dev/null and b/docs/assets/images/routing/channel_router_book.png differ diff --git a/docs/assets/images/routing/channel_router_connection.png b/docs/assets/images/routing/channel_router_connection.png new file mode 100644 index 00000000..087d3527 Binary files /dev/null and b/docs/assets/images/routing/channel_router_connection.png differ diff --git a/docs/assets/images/routing/power_routing.png b/docs/assets/images/routing/power_routing.png new file mode 100644 index 00000000..db320237 Binary files /dev/null and b/docs/assets/images/routing/power_routing.png differ diff --git a/docs/source/FAQ.md b/docs/source/FAQ.md new file mode 100644 index 00000000..a515b17a --- /dev/null +++ b/docs/source/FAQ.md @@ -0,0 +1,38 @@ +### [Go Back](./index.md#table-of-contents) + +# Frequently Asked Questions + +## What to do if OpenRAM encounters an error? + +When OpenRAM runs, it puts files in a temporary directory that is +shown in the banner at the top. Like: +``` + /tmp/openram_mrg_18128_temp/ +``` +This is where simulations and DRC/LVS get run so there is no network +traffic. The directory name is unique for each person and run of +OpenRAM to not clobber any files and allow simultaneous runs. If it +passes, the files are deleted. If it fails, you will see these files: ++ `temp.gds` is the layout (.mag files too if using SCMOS) ++ `temp.sp` is the netlist ++ `test1.drc.err` is the std err output of the DRC command ++ `test1.drc.out` is the standard output of the DRC command ++ `test1.drc.results` is the DRC results file ++ `test1.lvs.err` is the std err output of the LVS command ++ `test1.lvs.out` is the standard output of the LVS command ++ `test1.lvs.results` is the DRC results file + +Depending on your DRC/LVS tools, there will also be: ++ `run\_drc.sh` is a script to run DRC ++ `run\_ext.sh` is a script to run extraction ++ `run\_lvs.sh` is a script to run LVS + +If DRC/LVS fails, the first thing is to check if it ran in the `.out` and +`.err` file. This shows the standard output and error output from +running DRC/LVS. If there is a setup problem it will be shown here. + +If DRC/LVS runs, but doesn't pass, you then should look at the `.results` +file. If the DRC fails, it will typically show you the command that was used +to run Calibre or Magic+Netgen. + + diff --git a/docs/source/architecture.md b/docs/source/architecture.md new file mode 100644 index 00000000..99dea80b --- /dev/null +++ b/docs/source/architecture.md @@ -0,0 +1,25 @@ +### [Go Back](./index.md#table-of-contents) + +# Architecture +This page of the documentation explains the architecture of OpenRAM. + + + +## Table of Contents +1. [SRAM Architecture](#sram-architecture) + + + +## SRAM Architecture +* Bit-cell Array + * Multiport Bitcells +* Each port: + * Address Decoder(s) + * Wordline Driver(s) + * Column Multiplexer(s) + * Bitline Precharge(s) + * Sense Amplifier(s) + * Write Driver(s) + * Control Logic with Replica Bitline + +![OpenRAM SRAM Architecture](../assets/images/architecture/sram_architecture.png) \ No newline at end of file diff --git a/docs/source/base_data_structures.md b/docs/source/base_data_structures.md new file mode 100644 index 00000000..72083e99 --- /dev/null +++ b/docs/source/base_data_structures.md @@ -0,0 +1,72 @@ +### [Go Back](./index.md#table-of-contents) + +# Base Data Structures +This page of the documentation explains the base data structures of OpenRAM. + + + +## Table of Contents +1. [Design Classes](#design-classes) +1. [Base Class Inheritance](#base-class-inheritance) +1. [Parameterized Transistor](#parameterized-transistor-ptx-or-pfinfet) +1. [Parameterized Cells](#parameterized-cells) + + + +## Design Classes + + +* SPICE and GDS2 Interfaces + * Custom cells (read GDS and SPICE) + * Generated cells (creates GDS and SPICE "on the fly") +* Netlist functions + * Add (directional) pins + * Add and connect instances + +* Layout functions + * Place instances + * Add wires, routes, vias + * Channel and Power router +* Verification functions (wrap around DRC and LVS tools) + + + +## Base Class Inheritance +```mermaid +flowchart TD + A[design.py \n\n General design and helper DRC constants] --> B[hierarchy_design.py \n\n DRC/LVS functions] + B --> C["hierarchy_spice.py \n\n Netlist related functionality"] + B --> D["hierarchy_layout.py \n\n Layout related functionality"] + C --> E["Functions: \n add_pins \n add_inst"] + C --> F["sp_read \n sp_write \n Power data \n Delay data"] + D --> G["Functions: \n add_{layout_pin,rect,...} \n place_inst \n create_channel_route \n etc."] + D --> H["gds_read \n gds_write \n get_blockages \n etc."] +``` + + + +## Parameterized Transistor (ptx or pfinfet) + + +* Creates variable size/finger nmos or pmos transistor + * Optional gate and source/drain contacts in naive way + * Not optimal layout, but "good enough" + * Offset (0,0) is lower-left corner of active area +* Size/fingers effect on size must be estimated elsewhere perhaps by trying configurations + + + +## Parameterized Cells + + +Dynamically generated cells (in `$OPENRAM_HOME/pgates`) +* Not the most efficient layouts but "ok" +* Try to use restrictive design rules to keep them portable +* Transistors + * `ptx`, `pfinfet` +* Logic gates + * `pinv`, `pnand2`, `pnand3`, `pnor2` +* Buffer/drivers + * `pbuf`, `pinvbuf`, `pdriver` +* SRAM Logic + * `precharge`, `single_level_column_mux` diff --git a/docs/source/basic_setup.md b/docs/source/basic_setup.md new file mode 100644 index 00000000..2b649d95 --- /dev/null +++ b/docs/source/basic_setup.md @@ -0,0 +1,103 @@ +### [Go Back](./index.md#table-of-contents) + +This page shows the basic setup for using OpenRAM. + +# Basic Setup + +## Dependencies + +Please see the Dockerfile for the required versions of tools. + +In general, the OpenRAM compiler has very few dependencies: ++ Docker ++ Make ++ Python 3.6 or higher ++ Various Python packages (pip install -r requirements.txt) ++ Git + + + +## OpenRAM Library +OpenRAM is available as a Python library. There are a few ways to install it: + ++ Install using Makefile (you need to clone the repo): +``` +git clone git@github.com:VLSIDA/OpenRAM.git +cd OpenRAM +make library +``` ++ Install the latest _dev_ version: +``` +pip3 install git+ssh://git@github.com/VLSIDA/OpenramRAM.git@dev +``` + + +## Docker + +We have a [docker setup](../../docker) to run OpenRAM. To use this, you should run: +``` +cd OpenRAM/docker +make build +``` +This must be run once and will take a while to build all the tools. If you have the +OpenRAM library installed, you can also run the docker setup from the package +installation directory. + + + +## Environment + +If you haven't installed the OpenRAM library or you want to use a different OpenRAM installation, +you can set two environment variables: ++ OPENRAM\_HOME should point to the compiler source directory. ++ OPENRAM\_TECH should point to one or more root technology directories (colon separated). + +If you have the library installed and OPENRAM\_HOME set, the library will use the installation on +the OPENRAM\_HOME path. + +If you don't have the library, you should also add OPENRAM\_HOME to your PYTHONPATH. This is not +needed if you have the library. + +You can add these environment variables to your `.bashrc`: +``` + export OPENRAM_HOME="$HOME/OpenRAM/compiler" + export OPENRAM_TECH="$HOME/OpenRAM/technology" + export PYTHONPATH=$OPENRAM_HOME +``` + +Note that if you want symbols to resolve in your editor, you may also want to add the specific technology +directory that you use and any custom technology modules as well. For example: +``` + export PYTHONPATH="$OPENRAM_HOME:$OPENRAM_TECH/sky130:$OPENRAM_TECH/sky130/custom" +``` + +We include the tech files necessary for [SCMOS] SCN4M\_SUBM, +[FreePDK45]. The [SCMOS] spice models, however, are +generic and should be replaced with foundry models. You may get the +entire [FreePDK45 PDK here][FreePDK45]. + + + +### Sky130 Setup + +To install [Sky130], you must have the open\_pdks files installed in $PDK\_ROOT. +To install this automatically, you can run: +``` +cd $HOME/OpenRAM +make pdk +``` + +Then you must also install the [Sky130] SRAM build space and the appropriate cell views +by running: +``` +cd $HOME/OpenRAM +make install +``` + +You can also run these from the package installation directory if you have the OpenRAM library. + + + +[SCMOS]: https://www.mosis.com/files/scmos/scmos.pdf +[FreePDK45]: https://www.eda.ncsu.edu/wiki/FreePDK45:Contents +[Sky130]: https://github.com/google/skywater-pdk-libs-sky130_fd_bd_sram.git diff --git a/docs/source/basic_usage.md b/docs/source/basic_usage.md new file mode 100644 index 00000000..b64269e4 --- /dev/null +++ b/docs/source/basic_usage.md @@ -0,0 +1,206 @@ +### [Go Back](./index.md#table-of-contents) + +# Basic Usage +This page of the documentation explains the basic usage of OpenRAM. + + + +## Table of Contents +1. [Environment Variable Setup](#environment-variable-setup-assuming-bash) +1. [Script Usage (with library)](#script-usage-with-library) +1. [Command Line Usage (with library)](#command-line-usage-with-library) +1. [Command Line Usage (without library)](#command-line-usage-without-library) +1. [Configuration Files](#configuration-files) +1. [Common Configuration File Options](#common-configuration-file-options) +1. [Output Files](#output-files) +1. [Data Sheets](#data-sheets) + + + +## Environment Variable Setup (assuming bash) +> **Note**: This is optional if you have the OpenRAM library. See [basic setup](./basic_setup.md#go-back) for details. +* OPENRAM\_HOME defines where the compiler directory is + * ```export OPENRAM_HOME="$HOME/openram/compiler"``` +* OPENRAM_TECH defines list of paths where the technologies exist + * `export OPENRAM_TECH="$HOME/openram/technology"` + * Colon separated list so you can have private technology directories +* Must also have any PDK related variables set up +* Add compiler to `PYTHONPATH` + * `export PYTHONPATH="$PYTHONPATH:$OPENRAM_HOME"` + + + +## Script Usage (with library) +If you have the library installed, you can use OpenRAM in any Python script. You can import "openram" as follows: +```python +import openram +import globals +globals.init_openram("myconfig.py") # Config files are explained on this page +``` +Note that you should import "openram" in this order so that the modules are imported properly. You can also look +at `sram_compiler.py` as an example on how to use "openram." + + + +## Command Line Usage (with library) +You can run OpenRAM from the command line using the `sram_compiler.py` script that is included in the +library's installation. You can the package directory on a path like: +``` +/home/mrg/.local/lib/python3.8/site-packages/openram +``` + +Alternatively, you can run the following command to find that path: +``` +echo -e "import os\nimport openram\nprint(os.path.dirname(openram.__file__))" | python3 - +``` + +You can continue with following section for more details. + + +## Command Line Usage (without library) + +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: +```python +# Data word size +word_size = 2 +# Number of words in the memory +num_words = 16 + +# Technology to use in $OPENRAM_TECH +tech_name = "scn4m_subm" + +# You can use the technology nominal corner only +nominal_corner_only = True +# Or you can specify particular corners +# Process corners to characterize +# process_corners = ["SS", "TT", "FF"] +# Voltage corners to characterize +# supply_voltages = [ 3.0, 3.3, 3.5 ] +# Temperature corners to characterize +# temperatures = [ 0, 25 100] + +# Output directory for the results +output_path = "temp" +# Output file base name +output_name = "sram_{0}_{1}_{2}".format(word_size,num_words,tech_name) + +# Disable analytical models for full characterization (WARNING: slow!) +# analytical_delay = False + +``` + +You can then run OpenRAM by executing: +``` +python3 $OPENRAM_HOME/../sram_compiler.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 +``` + +* Common arguments: + * `-t` specify technology (scn4m_subm or scmos or freepdk45) + * `-v` increase verbosity of output + * `-n` don't run DRC/LVS + * `-c` perform simulation-based characterization + * `-d` don't purge /tmp directory contents + + + +## Configuration Files +* Memories are created using a Python configuration file to replicate results + * No YAML, JSON, etc. +* Complete configuration options are in `$OPENRAM_HOME/options.py` +* Some options can be specified on the command line as well + * Not recommended for replicating results +* Example configuration file: + ```python + # Data word size + word_size = 2 + # Number of words in the memory + num_words = 16 + + # Technology to use in $OPENRAM_TECH + tech_name = "scn4m_subm" + # Process corners to characterize + process_corners = [ "TT" ] + # Voltage corners to characterize + supply_voltages = [ 3.3 ] + # Temperature corners to characterize + temperatures = [ 25 ] + + # Output directory for the results + output_path = "temp" + # Output file base name + output_name = "sram_16x2" + + # Disable analytical models for full characterization (WARNING: slow!) + # analytical_delay = False + + # To force this to use magic and netgen for DRC/LVS/PEX + # Could be calibre for FreePDK45 + drc_name = "magic" + lvs_name = "netgen" + pex_name = "magic" + ``` + + + +## Common Configuration File Options +* Characterization corners + * `supply_voltages = [1.7, 1.8, 1.9]` + * `temperatures = [25, 50, 100]` + * `process_corners = ["SS", "TT", "FF"]` +* Do not generate layout + * `netlist_only = True` +* Multi-port options + * `num_rw_ports = 1` + * `num_r_ports = 1` + * `num_w_ports = 0` +* Customized module or bit cell + * `bitcell = "bitcell_1rw_1r"` + * `replica_bitcell = "replica_bitcell_1rw_1r"` +* Enable simulation characterization + > **Warning**: Slow! + * `analytical_delay = False` +* Output name and location + * `output_path = "temp"` + * `output_name = "sram_32x256"` +* Force tool selection (should match the PDK!) + * `drc_name = "magic"` + * `lvs_name = "netgen"` + * `pex_name = "magic"` +* Include shared configuration options using Python imports + * `from corners_freepdk45 import *` + + + +## Output Files +The output files are placed in the `output_dir` defined in the configuration file. + +The base name is specified by `output_name` and suffixes are added. + +The final results files are: +* GDS (.gds) +* SPICE (.sp) +* Verilog (.v) +* P&R Abstract (.lef) +* Liberty (multiple corners .lib) +* Datasheet (.html) +* Log (.log) +* Configuration (.py) for replication of creation + + + +## Data Sheets +![Datasheet 1](../assets/images/basic_usage/datasheet_1.png) +![Datasheet 2](../assets/images/basic_usage/datasheet_2.png) +![Datasheet 3](../assets/images/basic_usage/datasheet_3.png) diff --git a/docs/source/bitcells.md b/docs/source/bitcells.md new file mode 100644 index 00000000..92c5709b --- /dev/null +++ b/docs/source/bitcells.md @@ -0,0 +1,40 @@ +### [Go Back](./index.md#table-of-contents) + +# Bitcells +This page of the documentation explains the bitcells supported by OpenRAM. + + + +## Table of Contents +1. [Multiport Bitcells](#multiport-bitcells) +1. [Relative Bitcell Sizes](#relative-bitcell-sizes-035um-scmos) +1. [Thin SRAM Bitcells](#thin-sram-bitcells-130nm) + + + +## Multiport Bitcells +* Based on 6T SRAM cell + * Standard read-write + * Isolated read-only ports + * Write-only port (not sized for reads) +* Can accommodate foundry bitcells + +![Multiport Bitcells](../assets/images/bitcells/multiport_bitcells.png) + + + +## Relative Bitcell Sizes (0.35um SCMOS) +| | | | +| :-----------------------------------------------: | :------------------------------------------------: | :--------------------------------------------------: | +| Standard 6T (1rw) 6.8um x 9.2um | Isolated Read 10T (1rw, 1r) 10.9um x 13.9um | DFF 21.9um x 21.2um (from OSU standard cell library) | + + + +## Thin SRAM Bitcells (130nm) +| | | | | +| :--------------------------------------------------------: | :------------------------------------------------------: | :-----------------------------------------------------------------: | :-------------------------------------------------------------: | +| Single Port 1.2um x 1.58um | Dual Port 2.40um x 1.58um | Single Port (w/ straps & taps) 2.49um x 1.58um | Dual Port (w/ straps & taps) 3.12um x 1.97um | + +| | +| :----------------------------------------------------------: | +| DFF (for reference) 5.83um x 7.07 um | diff --git a/docs/source/characterization.md b/docs/source/characterization.md new file mode 100644 index 00000000..60adc74a --- /dev/null +++ b/docs/source/characterization.md @@ -0,0 +1,178 @@ +### [Go Back](./index.md#table-of-contents) + +# Characterization +This page of the documentation explains the characterization of OpenRAM. + + + +## Table of Contents +1. [Characterization Overview](#characterization-overview) +1. [Characterizer Organization](#characterizer-organization) +1. [Characterization Options](#characterization-options) +1. [Characterization Measurements](#characterization-measurements) +1. [Analytical Characterization](#analytical-characterization) +1. [Multiport Characterization](#multiport-characterization) +1. [Characterizer Unit Test Use](#characterizer-unit-test-use) +1. [Functional Simulation](#functional-simulation) +1. [Power/Delay Characterization](#powerdelay-characterization) +1. [Timing Graph](#timing-graph) +1. [Graph Creation Example: Buffer](#graph-creation-example-buffer) +1. [Graph Module Exclusion](#graph-module-exclusion) +1. [Timing Measurement Checks](#timing-measurement-checks) + + + +## Characterization Overview +Measures the timing/power through SPICE simulation: +* Generates the SPICE stimulus: The stimulus is written in standard SPICE format and can be used with any simulator that supports this. +* Runs the circuit simulations: To produce the average power, setup/hold times, and timing delay of the memory design. +* Parses the simulator's output: The setup time, hold time, and delay are found using a bidirectional search technique. +* Produces the output in a Liberty (.lib) file. + + + +## Characterizer Organization +* Core Modules + * `delay.py` - Generates the delays and power of input SRAM and corner + * `setup_hold.py` - Generates setup and hold timing of DFFs by corner + * `lib.py` - Characterizes SRAM and builds Liberty file + * `stimuli.py` - Generates SPICE stimulus file for characterization +* Auxiliary Modules + * `simulation.py` - Base class for SRAM characterization modules + * `trim_spice.py` - Removes portions of SRAM SPICE to speedup simulation + * `measurements.py` - Contains classes to aid SPICE measurements + * `char_utils.py` - Contains common functions used during characterization + * `logical_effort.py` - Helper class for analytical delay model +* Testing Support Modules + * Other modules are derivatives of the simulation module used in the unit tests + + + +## Characterization Options +* Characterization by Configuration File + * The process, voltage, and temperature (PVT) for characterization are defined in the config file. + * Running OpenRAM generates a Liberty (.lib) file for every corner characterized. + * Delays, slews, power determined for each input slew and outputs load combination in config file. +* OpenRAM Characterization Mode + * Supports analytical and SPICE based characterization + * Analytical characterization is default + * SPICE characterization enabled with -c flag (requires SPICE simulator) + + + +## Characterization Measurements +* Characterization is performed primarily to generate tables in .lib file + * cell\_rise/cell\_fall - Delay of from negative clock edge to DOUT when reading a 1 or 0 respectively + * rise\_transition/fall\_transition - Slew of DOUT when read 1 or 0 respectively + * Setup and hold time for inputs (setup\_rising, hold\_rising) + * Total power and leakage power + * Delays and slews and intended to be independent of clock period. + * Fall delays are copied to rise delays after characterization* +* Characterizer can help with debugging or optimization + * Delay characterizer also produces Sense Amp Enable Timing to help debug read failures. + * Delay class can edited or can be base class if other measurements are wanted. +> **Note**: Rise delays are dependent on the clock period if measured from negative clock edge due to precharge. + + + +## Analytical Characterization +* Delay + * Assumes a worst case delay through decoder, word line, and bit lines + * Calculates RC delay at each stage using parameters for handmade cells, unit capacitances, and unit resistances which are defined in the technology setup + * Output slews are estimated based on delays + * Wire delays only estimated for bitline delay +* Power + * Dynamic power at each stage calculated using $C * V^2 * frequency$ + * Leakage power estimated with parameters in technology setup +* Corners add linear variations in delay and power + + + +## Multiport Characterization +* Supports any port configuration specified by the configuration file + * Any number of Read, Write, and Read/Write ports + * Any custom bitcells may require modifications for characterization +* Characterization Algorithm + * Feasible period found for each port + * Common minimum period is found for all ports + * Power and delay is characterized on each port +* Characterization Runtime + * Ports are characterized separately for accuracy + * Runtime increases linearly with ports and can be slow. + + + +## Characterizer Unit Test Use +* OpenRAM will use the characterizer to generate data for .lib by default +* Characterizer modules can be instantiated separately from lib.py to generate and test data + * Example: `21_ngspice_delay_test.py` + * Delay module generates data to compare against previously generated data to error check any recent OpenRAM changes having a large effect on the delay +* Delay/Simulation module can be used as base class and altered to include custom measurements + + + +## Functional Simulation +* Assumes uninitialized memory +* Random operations + * Uses multiple ports when available + * Read, write, or noop + * Random address + * Random data +* Memory checks + * Uses standard CMOS noise margins + * Compares read with last write (or feed-through value if being written) + + + +## Power/Delay Characterization +* Prunes unused portions of circuit for run-time +* Setup time, hold time, and delay are found using a bidirectional search. + * Finds a feasible period + * Iterates until convergence +* Dynamic and leakage measured +* Output saved in Liberty (.lib) file. + * Uses NLDM + * Wish list: CCS + + + +## Timing Graph +* OpenRAM has SPICE like modules and instances +* A timing graph is created using the SPICE netlist, names and paths through lower level modules. +* Graph used in characterizer for debugging timing issues associated with the Sense Amp Enable + + + +## Graph Creation Example: Buffer +![Buffer 1](../assets/images/characterization/buffer_1.png) +* SPICE instantiated module (vdd, gnd excluded from graph) +* Xbuf1 A Z vdd gnd Buffer +* Base module has its own naming for ports and internal signals + +![Buffer 2](../assets/images/characterization/buffer_2.png) +* Node names reduced to top-most SPICE level with internal signals maintained. +* Internal modules determine edges between nodes + +![Buffer 3](../assets/images/characterization/buffer_3.png) +* Most lower level modules (gates, PTX, FF, etc) determine edges by connecting every input to every output by default. +* Custom timing paths can be overridden in any module + + + +## Graph Module Exclusion +* Modules can be excluded from the graph before it's built +* This can help trim timing paths that are known to not affect the overall timing +![Graph Module Exclusion](../assets/images/characterization/exclusion.png) + +| | | +| :-------------------------------------------------------------------------: | :----------------------------------------------------------------------------: | +| Graph without exclusion | Graph with exclusion | + + + +## Timing Measurement Checks +In addition to measurements done for characterization. Several measurements are done to help debug memory failures. +* Bitline measurements - Voltage of bitlines measured the checked to have at least a 10% difference +* Bitcell Measurements - Voltage measured on internal storage of cells and check that they match the operation. +* Output voltage measurements - Output voltage (`DOUT`) checked at end of cycle so it matches operation. +* Sense Amp Enable Timing - Delay of `S_EN` should not exceed a half-period diff --git a/docs/source/control_logic.md b/docs/source/control_logic.md new file mode 100644 index 00000000..f760e379 --- /dev/null +++ b/docs/source/control_logic.md @@ -0,0 +1,100 @@ +### [Go Back](./index.md#table-of-contents) + +# Control Logic and Timing +This page of the documentation explains the control logic and timing of OpenRAM. + + + +## Table of Contents +1. [Read Timing](#read-timing) +1. [Write Timing](#write-timing) +1. [External Control Signals](#external-control-signals) +1. [Internal Control Signals](#internal-control-signals) +1. [Replica Bitline (RBL)](#replica-bitline-rbl) +1. [Internal Control Signals Diagram (Read)](#internal-control-signals-diagram-read) +1. [Internal Control Signals Diagram (Write)](#internal-control-signals-diagram-write) +1. [Clock Distribution](#clock-distribution) + + + +## Read Timing +![Read Timing](../assets/images/control_logic/read_timing.png) + + + +### Read Timing Simulation +![Read Timing Simulation](../assets/images/control_logic/read_simulation.png) + + + +## Write Timing +![Write Timing](../assets/images/control_logic/write_timing.png) + + + +### Write Timing Simulation +![Write Timing Simulation](../assets/images/control_logic/write_simulation.png) + + + +## External Control Signals +* Behaves as a synchronous register interface + * Address and data captured on positive edge + * Data is available after the negative edge (before next positive edge) + * Clock is used for internal control generation +* Clock cycle + * Clock high: capture inputs + precharge + decode + * Clock low: read/write +* Reads and writes on multiple ports to the same address in the same cycle "feed through" but the noise margins of the bitcell must be able to handle this + + + +## Internal Control Signals +* Sense Enable (`s_en`) -- Active high sense amp enable from Replica Bit Line (RB) + * RBL input: `rbl_wl = gated_clk_bar & we_bar` + * Delayed RBL output: `pre_s_en = DELAY(rbl_bl)` + * Buffered enable: `s_en = BUF(pre_s_en)` +* Write Driver Enable (`w_en`) -- Active high write driver enable + * `w_en = we` + * `we` is directly from control flops +* Precharge Enable Bar (`p_en_bar`) -- Active low enable of precharge + * `p_en_bar = !(gated_clk_bar)` + * Active for writes as well to prevent half select destruction +* Word line enable (`wl_en`) -- Active high word line enable + * `wl_en = BUF(gated_clk_bar)` + + + +## Replica Bitline (RBL) + + +* Determines when to start sensing by replicating a bitcell array column +* Replica Bitline Column (RBC) matches transition of column + * `rbl_bl = RBC(rbl_wl)` +* Delay Line delays the input signal to match word line driver + * `pre_s_en = DELAY(rbl_bl)` +* Buffer drives `s_en` signal to sense amps + + + +## Internal Control Signals Diagram (Read) +![Internal Control Signals (Read)](../assets/images/control_logic/internal_signals_read.png) + + + +## Internal Control Signals Diagram (Write) +![Internal Control Signals (Write)](../assets/images/control_logic/internal_signals_write.png) + + + +## Clock Distribution +* External clock (`clk`) +* Buffered clock (`clk_buf`) drives all DFFs in the design + * `clk_buf = BUF(clk)` +* Buffered clock bar (`clk_bar`) used in control logic + * `clk_bar = INV(clk_buf)` +* Gated Clocks (`gated_clk` and `gated_clk_bar`) used in control logic + * This is LOW when disabled + * `gated_clk_bar = cs && clk_bar` + * This is LOW when disabled + * `gated_clk = cs && clk_buf` diff --git a/docs/source/debug.md b/docs/source/debug.md new file mode 100644 index 00000000..73cc31db --- /dev/null +++ b/docs/source/debug.md @@ -0,0 +1,179 @@ +### [Go Back](./index.md#table-of-contents) + +# Debugging and Unit Testing +This page of the documentation explains the debugging and unit testing of OpenRAM. + + + +## Table of Contents +1. [Unit Tests](#unit-tests) +1. [Unit Test Organization](#unit-test-organization) +1. [Running Unit Tests](#running-unit-tests) +1. [Successful Unit Tests](#successful-unit-tests) +1. [Debugging Unsuccessful Unit Tests](#debugging-unsuccessful-unit-tests-or-sram_compilerpy) +1. [Temporary Output Files](#temporary-output-files) + + + +## Unit Tests +OpenRAM has the set of thorough regression tests implemented with the Python unit test framework: +* Unit tests allow users to add features without worrying about breaking functionality. +* Unit tests guide users when porting to new technologies. +* Every sub-module has its own regression test. +* There are regression tests for memory functionality, library cell verification, timing verification, and technology verification. + + + +## Unit Test Organization +* `00_code_format_test.py` does basic lint checking. +* `01_library_drc_test.py` checks DRC of all library cells for the technology. +* `02_library_lvs_test.py` checks LVS of all library cells for the technology. +* `03_*_test.py` checks DRC and LVS of wires and transistors classes. +* `04_*_test.py` checks DRC and LVS of parameterized cells. +* `05-19_*_test.py` checks DRC and LVS of module cells (moving upward in hierarchy with numbers) +* `20_*_test.py` check DRC and LVS of full SRAM layouts with various configurations. +* `21_*_test.py` checks timing of full SRAMs and compares (with tolerance) to precomputed result. + > **Note**: These tests may fail using different simulators due to the tolerance level. +* `22_*_test.py` checks functional simulation of full SRAMs with various configurations. +* `23-25_*_test.py` checks lib, lef, and verilog outputs using diff. +* `30_openram_test.py` checks command-line interface and whether output files are created. + + + +## Running Unit Tests + +Regression testing performs a number of tests for all modules in OpenRAM. +From the unit test directory ($OPENRAM\_HOME/tests), +use the following command to run all regression tests: + +``` +cd OpenRAM/compiler/tests +make -j 3 +``` +The -j can run with 3 threads. By default, this will run in all technologies. + +To run a specific test in all technologies: +``` +cd OpenRAM/compiler/tests +make 05_bitcell_array_test +``` +To run a specific technology: +``` +cd OpenRAM/compiler/tests +TECHS=scn4m_subm make 05_bitcell_array_test +``` + +To increase the verbosity of the test, add one (or more) -v options and +pass it as an argument to OpenRAM: +``` +ARGS="-v" make 05_bitcell_array_test +``` + +Unit test results are put in a directory: +``` +OpenRAM/compiler/tests/results// +``` +If the test fails, there will be a tmp directory with intermediate results. +If the test passes, this directory will be deleted to save space. +You can view the .out file to see what the output of a test is in either case. +* Tests can be run in the `$OPENRAM_HOME/tests` directory +* Command line arguments + * `-v` for verbose + * `-t` freepdk45 for tech + * `-d` to preserve /tmp results (done automatically if test fails) +* Individual tests + * `01_library_drc_test.py` +* All tests + * `regress.py` + + +## Successful Unit Tests +```console +user@host:/openram/compiler/tests$ ./regress.py + ______________________________________________________________________________ +|==============================================================================| +|========= Running Test for: =========| +|========= scn4m_subm =========| +|========= ./regress.py =========| +|========= /tmp/openram_mrg_13245_temp/ =========| +|==============================================================================| +runTest (00_code_format_check_test.code_format_test) ... ok +runTest (01_library_drc_test.library_drc_test) ... ok +runTest (02_library_lvs_test.library_lvs_test) ... ok +runTest (03_contact_test.contact_test) ... ok +runTest (03_path_test.path_test) ... ok +. +. +. +``` +```console +user@host:/openram/compiler/tests$ ./03_ptx_1finger_nmos_test.py + ______________________________________________________________________________ +|==============================================================================| +|========= Running Test for: =========| +|========= scn4m_subm =========| +|========= ./03_ptx_1finger_nmos_test.py =========| +|========= /tmp/openram_mrg_13750_temp/ =========| +|==============================================================================| +. +---------------------------------------------------------------------- +Ran 1 test in 0.596s + +OK +``` + + + +## Debugging Unsuccessful Unit Tests (or sram\_compiler.py) +* You will get an ERROR during unit test and see a stack trace +* Examine the temporary output files in the temp directory (/tmp/mydir) +```console + _____________________________________________________________________________ +|==============================================================================| +|========= Running Test for: =========| +|========= scn4m_subm =========| +|========= ./04_pinv_10x_test.py =========| +|========= /tmp/mydir =========| +|==============================================================================| +ERROR: file magic.py: line 174: DRC Errors pinv_0 2 +F +====================================================================== +FAIL: runTest (__main__.pinv_test) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "./04_pinv_10x_test.py", line 22, in runTest + self.local_check(tx) + File "/Users/mrg/openram/compiler/tests/testutils.py", line 45, in local_check + self.fail("DRC failed: {}".format(a.name)) +AssertionError: DRC failed: pinv_0 + +---------------------------------------------------------------------- +Ran 1 test in 0.609s + +FAILED (failures=1) +``` + +### It didn't finish... where are my files? +* OpenRAM puts all temporary files in a temporary directory named: + * `/tmp/openram___temp` + * This allows multiple processes/users to simultaneously run + * This allows /tmp to be mapped to a RAM disk for faster performance + * After a successful run, the directory and contents are deleted + * To preserve the contents, you can run with the `-d` option for debugging +* `OPENRAM_TMP` will override the temporary directory location for debug + * `export OPENRAM_TMP="/home/myname/debugdir"` + + + +## Temporary Output Files +* DRC standard output (`*.drc.out`), errors (`*.drc.err`), and results (`*.drc.results`) +* LVS standard output (`*.lvs.out`), errors (`*.lvs.out`), and results (`*.lvs.results`) +* GDS (and Magic) files for intermediate modules (`temp.gds`, `temp.mag`) +* SPICE netlist for intermediate module results (`temp.sp`) +* Extracted layout netlist for intermediate module results (`extracted.sp`) +* Magic only: Run scripts for DRC (`run_drc.sh`) and LVS (`run_lvs.sh`) +* Calibre only: Runset file for DRC (`drc_runset`) and LVS (`lvs_runset`) + + + + diff --git a/docs/source/design_modules.md b/docs/source/design_modules.md new file mode 100644 index 00000000..f220ef2b --- /dev/null +++ b/docs/source/design_modules.md @@ -0,0 +1,152 @@ +### [Go Back](./index.md#table-of-contents) + +# Hierarchical Design Modules +This page of the documentation explains the hierarchical design modules of OpenRAM. + + + +## Table of Contents +1. [Hierarchical Design Modules](#hierarchical-design-modules-1) +1. [Bank](#bank) +1. [Port Data](#port-data) +1. [Port Address](#port-address) +1. [Plain Bitcell Array](#plain-bitcell-array) +1. [Variations of Bitcells Needed](#variations-of-bitcells-needed) +1. [Replica Bitcell Array](#replica-bitcell-array) +1. [1D Arrays](#1d-arrays) +1. [2D Arrays](#2d-arrays) +1. [Delay Line](#delay-line) +1. [Hierarchical (Address) Decoder](#hierarchical-address-decoder) + + + +## Hierarchical Design Modules +* Memory building blocks + * SRAM, Bank, Control Logic, Decoders, Column Mux, Various arrays (DFF, drivers) + * Can override every module with a custom one in the configuration file +* Each module must: + * Create netlist + * Define inputs/outputs + * Instantiate and connect sub-modules and cells + * Create layout + * Place and route itself + * Route vdd/gnd to M3 + * (Optional) Run DRC/LVS + * Analytically model timing and power + + + +## Bank + + +* Encompasses everything except + * Data and Address Flops + * Control logic + * Multi-bank logic +* Arranges ports + * Port 0 is left/bottom + * Port 1 is right/top + + + +## Port Data +* Encapsulates all of the datapath logic for a rw, w, or r port + * Sense amplifiers (read types) + * Write drivers (write types) + * Column mux (if any) + * Precharge (read or write type) (write to not destroy half selected cells in a row) +* Also includes a precharge for the replica columns + + + +## Port Address +* Encapsulates the row decoder and wordline driver for easier placement next to a bank +* Each port will have its own port\_address module + + + +## Plain Bitcell Array + + +* 2D Array of bit cells + * Each row alternately flips vertically +* Assume bitcells tile + * Boundary is determined by boundary layer in GDS + * Word line must abut + * Bit lines must abut + + + +## Variations of Bitcells Needed +* Normal bitcell for data storage +* Replica bitcell that is fixed to output a 0 value +* Dummy bitcell with bitlines disconnected (purely for wordline load and lithography regularity) + + + + + +## Replica Bitcell Array +* Bitcells: B=regular, D=dummy, R=replica +* Main bitcell array ( $\color{green}{\textrm{green}}$ ) +* Replica cols for each read port ( $\color{skyblue}{\textrm{blue}}$ ) on left or right (any number) +* Dummy bitcells on the top, bottom, left, and right for lithography regularity ( $\color{red}{\textrm{red}}$ ) +* Replica columns activate two replica bitcells + * $\color{blue}{\textrm{One}}$ driven by replica wordline + * $\color{royalblue}{\textrm{Second}}$ driven by one of the normal wordlines (dark blue) +* Second port word and bit lines not shown + * Would be on right and top + + + +## 1D Arrays + + +* Several modules have 1D arrays: + * `sense_amp_array` + * `write_driver_array` + * `precharge_array` + * `single_level_column_mux_array` + * `tri_gate_array` + * `wordline_driver` (*should change name to _array) +* `sense_amp_array`, `write_driver_array`, `tri_gate_array` match column mux stride to space out +* Wish list: Allow wide sense amplifier array to use multiple rows of sense amplifiers. + + + + + +## 2D Arrays +* Regular DFF arrays (`dff_array.py`) +* Buffered DFF arrays (`dff_buf_array.py`) +* Inverted DFF array (`dff_inv_array.py`) +* Can be $1*N$ or $N*1$ or $M*N$ + * Wish list: $M*N$ routes pins to edges + +

+ +

+ + + +## Delay Line + + +* Configurable fanout and stages + * `[4,4,4]` means 3 FO4 stages + * `[1,1,4,4]` means 2 FO1 stages followed by FO4 + + + +## Hierarchical (Address) Decoder + + +* Generic `hierarchical_predecode` class + * Places routing rails and decode inverters +* Derived to implement multiple predecoders + * `hierarchical_predecode_2x4` + * `hierarchical_predecode_3x8` + * `hierarchical_predecode_4x16` +* Hierarchical decoder uses predecoder + another decode stage +* Predecoders are also used for the column mux decode and bank select decode +* Wish list: Handle thin bitcell height diff --git a/docs/source/index.md b/docs/source/index.md new file mode 100644 index 00000000..208bc30d --- /dev/null +++ b/docs/source/index.md @@ -0,0 +1,111 @@ +# OpenRAM Documentation +![OpenRAM Logo](../../images/OpenRAM_logo_yellow_transparent.svg) + +These pages provide the documentation of OpenRAM. You can use the links below to navigate through the documentation. + + + +## Table of Contents +1. [OpenRAM Dependencies](#openram-dependencies) +1. [Supported Technologies](#supported-technologies) +1. [Basic Setup](./basic_setup.md#go-back) +1. [Basic Usage](./basic_usage.md#go-back) +1. [Bitcells](./bitcells.md#go-back) +1. [Architecture](./architecture.md#go-back) +1. [Implementation](#implementation) +1. [Technology and Tool Portability](#technology-and-tool-portability) +1. [Tutorials](./tutorials.md#go-back) +1. [Debugging and Unit Testing](./debug.md#go-back) +1. [Technology Setup](./technology_setup.md#go-back) +1. [Library Cells](./library_cells.md#go-back) +1. [Base Data Structures](./base_data_structures.md#go-back) +1. [Hierarchical Design Modules](./design_modules.md#go-back) +1. [Control Logic and Timing](./control_logic.md#go-back) +1. [Routing](./routing.md#go-back) +1. [Characterization](./characterization.md#go-back) +1. [Results](./results.md#go-back) +1. [FAQ](./FAQ.md#go-back) +1. [Contributors/Collaborators](#contributorscollaborators) + + + + +## OpenRAM Dependencies +Please see the Dockerfile for the required versions of tools. + +In general, the OpenRAM compiler has very few dependencies: ++ Docker ++ Make ++ Python 3.6 or higher ++ Various Python packages (pip install -r requirements.txt) ++ Git + +Commercial tools (optional): +* Spice Simulator + * Hspice I-2013.12-1 (or later) + * CustomSim 2017 (or later) +* DRC + * Calibre 2017.3\_29.23 +* LVS + * Calibre 2017.3\_29.23 + + + +## Supported Technologies +* NCSU FreePDK 45nm + * Non-fabricable but contains DSM rules + * Calibre or klayout for DRC/LVS +* MOSIS 0.35um (SCN4M\_SUBM) + * Fabricable technology + * Magic/Netgen or Calibre for DRC/LVS +* Skywater 130nm (sky130) + * Fabricable technology + * Magic/Netgen or klayout + + + +## Implementation +* Front-end mode + * Generates SPICE, layout views, timing models + * Netlist-only mode can skip the physical design too + * Doesn't perform DRC/LVS + * Estimates power/delay analytically +* Back-end mode + * Generates SPICE, layout views, timing models + * Performs DRC/LVS + * Can perform at each level of hierarchy or at the end + * Simulates power/delay + * Can be back-annotated or not + + + +## Technology and Tool Portability +* OpenRAM is technology independent by using a technology directory that includes: + * Technology's specific information + * Technology's rules such as DRC rules and the GDS layer map + * Custom designed library cells (6T, sense amp, DFF) to improve the SRAM density. +* For technologies that have specific design requirements, such as specialized well contacts, the user can include helper functions in the technology directory. +* Verification wrapper scripts + * Uses a wrapper interface with DRC and LVS tools that allow flexibility + * DRC and LVS can be performed at all levels of the design hierarchy to enhance bug tracking. + * DRC and LVS can be disabled completely for improved run-time or if licenses are not available. + +## Contributors/Collaborators + + +* Prof. Matthew Guthaus (UCSC) +* Prof. James Stine & Dr. Samira Ataei (Oklahoma State University) +* UCSC students: + * Bin Wu + * Hunter Nichols + * Michael Grimes + * Jennifer Sowash + * Jesse Cirimelli-Low + +* Many other past students: + * Jeff Butera + * Tom Golubev + * Marcelo Sero + * Seokjoong Kim + + diff --git a/docs/source/library_cells.md b/docs/source/library_cells.md new file mode 100644 index 00000000..732e9667 --- /dev/null +++ b/docs/source/library_cells.md @@ -0,0 +1,96 @@ +### [Go Back](./index.md#table-of-contents) + +# Library Cells +This page of the documentation explains the library cells of OpenRAM. + + + +## Table of Contents +1. [Required Hard/Custom Cells](#required-hardcustom-cells) +1. [Bitcell(s)](#bitcells) +1. [Multiport Bitcells](#multiport-bitcells) +1. [Parameterized Bitcell](#parameterized-bitcell) +1. [Sense Amplifier](#sense-amplifier) +1. [DFF](#dff) +1. [Tristate/Write Driver](#tristatewrite-driver) + + + +## Required Hard/Custom Cells +* Located in + * `$OPENRAM_TECH//gds_lib` + * `$OPENRAM_TECH//sp_lib` +* A few library cells with layout and SPICE: + * Bitcell (and dummy and replica bitcell) + * Sense amplifier + * DFF (from a standard cell library) + * (Removing soon: write driver, tristate) +* P&R border layer defined for placement +* Sense amplifier pitch matched width to bitcell + + + +## Bitcell(s) +* Python code is in `$OPENRAM_HOME/bitcells` + * Layout in `$OPENRAM_TECH//gds_lib ` + * SPICE in `$OPENRAM_TECH//sp_lib` +* Can be a foundry bitcell if you have the GDS and SPICE. +* May include multiple port configurations: + * `bitcell.py` uses `cell_6t.{gds,sp}` - standard 1rw port + * `bitcell_1w_1r.py` uses `cell_1w_1r.{gds,sp}` for 1w and 1r port + * `bitcell_1rw_1r.py` uses `cell_1rw_1r.{gds,sp}` for 1rw and 1r port +* Wish list: pin names are fixed right now as `bl`, `br`, `wl`, `vdd`, `gnd` + + + +## Multiport Bitcells +* Based on 6T SRAM cell + * Standard read-write + * Isolated read-only ports + * Write-only port (not sized for reads) +* Can accommodate foundry bitcells + +![Multiport Bitcells](../assets/images/bitcells/multiport_bitcells.png) + + + +## Parameterized Bitcell +* If a custom bitcell is not available, we create one with user design rules. + * Not good for area, but may still be better than DFFs. + * Can be useful for simulation/functional work before custom bitcell is available. + * Example 1 RW pbitcell compared to custom 1RW + + + + + + +## Sense Amplifier +* Needs a sense amplifier that is pitch matched to the bitcell. + * `$OPENRAM_TECH/gds_lib/sense_amp.gds` + * `$OPENRAM_TECH/sp_lib/sense_amp.sp` + * `$OPENRAM_HOME/modules/sense_amp.py` +* Wish list: pin names are fixed right now as `bl`, `br`, `dout`, `en`, `vdd`, `gnd` + + + +## DFF +* Needs a standard cell DFF for the address and data registers. + * `$OPENRAM_TECH/gds_lib/dff.gds ` + * `$OPENRAM_TECH/sp_lib/dff.sp` + * `$OPENRAM_HOME/modules/dff.py` +* Have auxiliary code to create: + * Buffered DFFs (`dff_buf.py`) using dynamically generated inverters (pinv) + * Inverted output DFFs (`dff_inv.py`) using a dynamically generated inverters (pinv) + * 2-D DFF arrays + * Regular DFF arrays (`dff_array.py`) + * Buffered DFF arrays (`dff_buf_array.py`) + * Inverted DFF array (`dff_inv_array.py`) +* Wish list: pin names are fixed right now as `D`, `Q`, `Qb`, `clk`, `vdd`, `gnd` + + + +## Tristate/Write Driver +* Tristate is used for multi-bank implementations +* Write driver drives the data onto the bitlines +* Both of these are currently library cells, but plans are to make them dynamically generated (`ptristate.py` and `pwrite_driver.py`) diff --git a/docs/source/results.md b/docs/source/results.md new file mode 100644 index 00000000..8909049c --- /dev/null +++ b/docs/source/results.md @@ -0,0 +1,67 @@ +### [Go Back](./index.md#table-of-contents) + +# Results +This page of the documentation explains the results of OpenRAM. + + + +## Table of Contents +1. [Small Layouts](#small-layouts) +1. [Relative Planar Bitcells](#relative-planar-bitcells-035um-scmos) +1. [SRAM Area](#sram-area) +1. [Generated Layout by OpenRAM](#generated-layout-by-openram-for-a-multiport-6r2w-sram-in-32-nm-soi-cmos-technology) +1. [Timing and Density Results for Generated SRAMs](#timing-and-density-results-for-generated-srams) +1. [Comparison with Fabricated SRAMs](#comparison-with-fabricated-srams) +1. [Conclusions](#conclusions) + + + +## Small Layouts +| | | +| :----------------------------------------------------------: | :----------------------------------------------------------: | +| 512 x 16b x 1rw FreePDK45 | 2048 x 32b x 1rw FreePDK45 | + + + +## Relative Planar Bitcells (0.35um SCMOS) +| | | | +| :-----------------------------------------------: | :------------------------------------------------: | :--------------------------------------------------: | +| Standard 6T (1rw) 6.8um x 9.2um | Isolated Read 10T (1rw, 1r) 10.9um x 13.9um | DFF 21.9um x 21.2um (from OSU standard cell library) | + + + +## SRAM Area +![SRAM Area](../assets/images/results/sram_area.png) + + + +## Generated Layout by OpenRAM for a multiport (6R/2W) SRAM in 32 nm SOI CMOS Technology +![Generated Layout](../assets/images/results/generated_layout.jpg) + + + +## Timing and Density Results for Generated SRAMs +![Timing and Density Results](../assets/images/results/timing_and_density_results.png) + + + +## Comparison with Fabricated SRAMs +| $\textrm{Reference}$ | $\textrm{Feature Size}$ | $\textrm{Technology}$ | $\textrm{Density } (Mb/mm^2)$ | +| :---------------------- | :---------------------: | :-------------------: | :---------------------------: | +| $\textrm{IEEE-VLSI'08}$ | $65 nm$ | $\textrm{CMOS}$ | $0.7700$ | +| $\textrm{JSSC'11}$ | $45 nm$ | $\textrm{CMOS}$ | $0.3300$ | +| $\textrm{JSSC'13}$ | $40 nm$ | $\textrm{CMOS}$ | $0.9400$ | +| $\textrm{OpenRAM}$ | $45 nm$ | $\textrm{FreePDK45}$ | $0.8260$ | +| $\textrm{JSSC'92}$ | $0.5 \mu m$ | $\textrm{CMOS}$ | $0.0036$ | +| $\textrm{JSSC'94}$ | $0.5 \mu m$ | $\textrm{BICMOS}$ | $0.0020$ | +| $\textrm{JSSC'99}$ | $0.5 \mu m$ | $\textrm{CMOS}$ | $0.0050$ | +| $\textrm{OpenRAM}$ | $0.5 \mu m$ | $\textrm{SCMOS}$ | $0.0050$ | + + + +## Conclusions +* The main motivation behind OpenRAM is to promote and simplify memory-related research in academia and provides a platform to implement and test new memory designs. +* OpenRAM is open-sourced, flexible, and portable and can be adapted to various technologies. +* OpenRAM generates the circuit, functional model, and layout of variable-sized SRAMs. +* OpenRAM provides a memory characterizer for synthesis timing/power models. +* We are also actively introducing new features, such as non-6T memories, variability characterization, word-line segmenting, characterization speed-up, etc. diff --git a/docs/source/routing.md b/docs/source/routing.md new file mode 100644 index 00000000..bcaa45fa --- /dev/null +++ b/docs/source/routing.md @@ -0,0 +1,56 @@ +### [Go Back](./index.md#table-of-contents) + +# Routing +This page of the documentation explains the routing of OpenRAM. + + + +## Table of Contents +1. [Power Supply Options](#power-supply-options) +1. [Power Routing](#power-routing) +1. [Power Supply Algorithm](#power-supply-algorithm) +1. [Channel Router](#channel-router) + + + +## Power Supply Options +* Unrouted + * Leave must-connect metal 3 pins for vdd and gnd within the array +* Grid + * Connect in a metal 3 and 4 grid + * Blockage aware + * Can encounter DRC errors with off-grid pins + * Works with commercial tools but not so well with OpenRoad +* Work in Progress: Hanan Grid / Steiner Tree: + * Route tree on Hanan metal 3 and 4 grid instead of full grid + * Blockage aware + + + +## Power Routing + + +* All power pins are brought to M3 and routed as a grid on M3/M4 +* Considers blockages of M3/M4 by control and data signals +* Considers wide/long metal spacing rules + + + +## Power Supply Algorithm +* 1st: Route vertical and horizontal grids (blockage aware, allow connection to correct supply) +* 2nd: Check direct overlaps of power pins +* 3rd: Single direction probes to connect +* 4th: A* maze router + + + +## Channel Router +* SRAMs typically try to use minimal layers of metal + * Primarily used to connect decoders, input/output circuitry, or control logic +* Wish list + * Minimize number of tracks + * Must consider impact on floorplan + +| | | +| :-------------------------------------------------------------------------: | :---------------------------------------------------------------------: | +| Credit: Chen & Chang, EDA Handbook, Chapter 12, Global and detailed routing | Sense amp to data flop connection | diff --git a/docs/source/technology_setup.md b/docs/source/technology_setup.md new file mode 100644 index 00000000..1d0c9d98 --- /dev/null +++ b/docs/source/technology_setup.md @@ -0,0 +1,125 @@ +### [Go Back](./index.md#table-of-contents) + +# Technology Setup +This page of the documentation explains the technology setup of OpenRAM. + + + +## Table of Contents +1. [Technology Directories](#technology-directories) +1. Technology Configuration: + 1. [Layer Map](#technology-configuration-layer-map) + 1. [GDS](#technology-configuration-gds) + 1. [DRC](#technology-configuration-drc) + 1. [SPICE](#technology-configuration-spice) + 1. [Parameters](#technology-configuration-parameters) + + + +## Technology Directories +* Environment variable OPENRAM\_TECH specifies list of technology directories + * Similar to `*nix $PATH` +* Directory structure: + ``` + techname/ + __init__.py -- Sets up PDK environment + tech/ -- Contains technology configuration + __init__.py -- Loads all modules + tech.py -- SPICE, DRC, GDS, and layer config + gds_lib/ -- Contains .gds files for each lib cell + sp_lib/ -- Contains .sp file for each lib cell + models/ -- Contains SPICE device corner models + (tf/) -- May contain some PDK material + (mag_lib/) -- May contain other layout formats + ``` + + + +## Technology Configuration: Layer Map +* Layer map contains mapping of layer names to GDS layers +* Layer names are used in OpenRAM code directly + ```python + layer={} + layer["vtg"] = -1 + layer["vth"] = -1 + layer["contact"] = 47 + layer["pwell"] = 41 + ... + layer["metal4"] = 31 + layer["text"] = 63 + layer["boundary"] = 63 + layer["blockage"] = 83 + ``` + + + +## Technology Configuration: GDS +* OpenRAM uses the gdsMill library (included and heavily modified) +* Units defined for GDS format + * First number is DB units per user units + * Second number is DB unit in meters + ```python + # GDS file info + GDS={} + # gds units + GDS["unit"]=(0.001,1e-6) + # default label zoom + GDS["zoom"] = 0.5 + ``` +* Zoom defines default zoom for labels +* More info on the GDS format at: + * http://boolean.klaasholwerda.nl/interface/bnf/gdsformat.html + + + +## Technology Configuration: DRC +* Creates the design\_rule class with several parts: + * Grid size + * Location of DRC, LVS, PEX rules and layer map + * Subset of design rules for FEOL and BEOL +* Design rules have common naming scheme (names used in OpenRAM) + * `minwidth_` + * `_to_` + * `_extend_` + * `minarea_` + * Allows rule tables for complex rules +```python +# Minimum spacing of metal3 wider than 0.09 & longer than 0.3 = 0.09 +# Minimum spacing of metal3 wider than 0.27 & longer than 0.9 = 0.27 +# Minimum spacing of metal3 wider than 0.5 & longer than 1.8 = 0.5 +# Minimum spacing of metal3 wider than 0.9 & longer than 2.7 = 0.9 +# Minimum spacing of metal3 wider than 1.5 & longer than 4.0 = 1.5 +drc["metal3_to_metal3"] = drc_lut({(0.00, 0.0) : 0.07, + (0.09, 0.3) : 0.09, + (0.27, 0.9) : 0.27, + (0.50, 1.8) : 0.5, + (0.90, 2.7) : 0.9, + (1.50, 4.0) : 1.5}) +``` + + + +## Technology Configuration: SPICE +* Device models (and corners) +* Defaults simulation values + * Voltage + * Temperature + * Feasible period for simulation + * Rise/fall input slews +* Analytical parameters + * For example, device capacitance and "on" resistance + * Used for analytical delay and power estimation + + + +## Technology Configuration: Parameters +* Default design parameters + * Being cleaned up and standardized... +* Defaults simulation values + * Voltage + * Temperature + * Feasible period for simulation + * Rise/fall input slews +* Analytical parameters + * Used for analytical delay and power estimation + * E.g. device capacitance and "on" resistance diff --git a/docs/source/tutorials.md b/docs/source/tutorials.md new file mode 100644 index 00000000..c6f22dd6 --- /dev/null +++ b/docs/source/tutorials.md @@ -0,0 +1,10 @@ +### [Go Back](./index.md#table-of-contents) + +# Tutorials +This page of the documentation includes tutorials for OpenRAM. + + + +## Table of Contents +1. []() + \ No newline at end of file diff --git a/macros/Makefile b/macros/Makefile index 630541c0..a61a180e 100644 --- a/macros/Makefile +++ b/macros/Makefile @@ -65,7 +65,7 @@ OPENRAM_TMP=/openram/macros/$*/tmp %.ok: configs/%.py @echo "Building $*" @mkdir -p $* - @$(DOCKER_CMD) python3 -u /openram/compiler/openram.py $(OPENRAM_OPTS) -o $* -p /openram/macros/$* /openram/macros/$< && touch $@ + @$(DOCKER_CMD) python3 -u /openram/sram_compiler.py $(OPENRAM_OPTS) -o $* -p /openram/macros/$* /openram/macros/$< && touch $@ .DELETE_ON_ERROR: $(STAMPS) diff --git a/openram.mk b/openram.mk index f169fa32..9c131580 100644 --- a/openram.mk +++ b/openram.mk @@ -1,6 +1,6 @@ OPENRAM_HOME := $(abspath $(TOP_DIR)/compiler) OPENRAM_TECH := $(abspath $(TOP_DIR)/technology) -OPENRAM_COMPILER := $(OPENRAM_HOME)/openram.py +OPENRAM_COMPILER := $(abspath $(TOP_DIR)/sram_compiler.py) PDK_ROOT ?= $(TOP_DIR) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..5aebe600 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,15 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "openram" +version = "1.2.0" +description = "An open-source static random access memory (SRAM) compiler" +authors = [ + { name="Matthew Guthaus", email="mrg@ucsc.edu" }, +] +keywords = [ "sram", "magic", "gds", "netgen", "ngspice", "netlist" ] +readme = "README.md" +license = { text = "BSD-3-Clause License" } +requires-python = ">=3.6" \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..6494baeb --- /dev/null +++ b/setup.py @@ -0,0 +1,57 @@ +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2021 Regents of the University of California and The Board +# of Regents for the Oklahoma Agricultural and Mechanical College +# (acting for and on behalf of Oklahoma State University) +# All rights reserved. +# +from setuptools import setup, find_namespace_packages + + +# Include these folder from the root of repo as submodules +include = ["compiler", "docker", "technology", "macros"] +# Exclude files/folders with these words +exclude = ["docs", "images"] + + +# Find all modules inside the 'compiler' folder +dirs = [] +for dir in find_namespace_packages(): + if any(x in dir for x in exclude): + continue + dirs.append(dir) + +# Replace 'compiler' with 'openram' for package names +packages = [] +for dir in dirs: + packages.append(dir) + +# Make the included folders submodules of openram package +for i in range(len(packages)): + if any(x in packages[i] for x in include): + packages[i] = "openram." + packages[i] + +# Fix directory paths +for i in range(len(dirs)): + dirs[i] = dirs[i].replace(".", "/") + +# Insert the root as the openram module +packages.insert(0, "openram") +dirs.insert(0, "") + +# Zip package names and their paths +package_dir = {k: v for k, v in zip(packages, dirs)} + + +# Create a list of required packages +with open("requirements.txt") as f: + reqs = f.read().splitlines() + + +# Call the setup to create the package +setup( + packages=packages, + package_dir=package_dir, + include_package_data=True, + install_requires=reqs, +) \ No newline at end of file diff --git a/compiler/openram.py b/sram_compiler.py similarity index 96% rename from compiler/openram.py rename to sram_compiler.py index a0dcdfba..5fd14e6c 100755 --- a/compiler/openram.py +++ b/sram_compiler.py @@ -16,8 +16,13 @@ a LEF (.lef) file for preliminary P&R (real one should be from layout) a Liberty (.lib) file for timing analysis/optimization """ +import os import sys import datetime +try: + import openram +except: + sys.path.append(os.getenv("OPENRAM_HOME")) import globals as g (OPTS, args) = g.parse_args() diff --git a/technology/scn4m_subm/tech/.magicrc b/technology/scn4m_subm/tech/.magicrc index 8fdad1b7..29c9977f 100644 --- a/technology/scn4m_subm/tech/.magicrc +++ b/technology/scn4m_subm/tech/.magicrc @@ -1,3 +1,12 @@ +# Check if the openram package is installed. If so, append that path to $OPENRAM_TECH. +# If $OPENRAM_TECH isn't defined and the package is installed, use the package directory. +set openramhome [exec echo -e "import os\ntry:\n import openram\n print(os.path.dirname(openram.__file__))\nexcept:\n print(\"notinstalled\")" | python3 -] +set openramtech "${openramhome}/technology/scn4m_subm/tech" +if { [info exists ::env(OPENRAM_TECH)] && ($openramhome != "notinstalled") } { + set ::env(OPENRAM_TECH) $env(OPENRAM_TECH):$openramtech +} elseif { $openramhome != "notinstalled" } { + set ::env(OPENRAM_TECH) $openramtech +} set openram_paths [split $::env(OPENRAM_TECH) ":"] foreach p $openram_paths { path sys +$p/scn4m_subm/tech diff --git a/technology/sky130/custom/sky130_bitcell_array.py b/technology/sky130/custom/sky130_bitcell_array.py index 2c7f5cd5..d6e4066c 100644 --- a/technology/sky130/custom/sky130_bitcell_array.py +++ b/technology/sky130/custom/sky130_bitcell_array.py @@ -29,10 +29,10 @@ class sky130_bitcell_array(bitcell_array, sky130_bitcell_base_array): # This will create a default set of bitline/wordline names self.create_all_bitline_names() self.create_all_wordline_names() - self.create_netlist() if not OPTS.netlist_only: self.create_layout() + self.add_supply_pins() def add_modules(self): """ Add the modules used in this design """ diff --git a/technology/sky130/custom/sky130_bitcell_base_array.py b/technology/sky130/custom/sky130_bitcell_base_array.py index 1604fa02..50199c77 100644 --- a/technology/sky130/custom/sky130_bitcell_base_array.py +++ b/technology/sky130/custom/sky130_bitcell_base_array.py @@ -125,11 +125,23 @@ class sky130_bitcell_base_array(bitcell_base_array): def add_supply_pins(self): """ Add the layout pins """ # Copy a vdd/gnd layout pin from every cell + + for inst in self.insts: + if "wlstrap" in inst.name: + try: + self.copy_layout_pin(inst, "VPWR", "vdd") + except: + pass + try: + self.copy_layout_pin(inst, "VGND", "gnd") + except: + pass for row in range(self.row_size): for col in range(self.column_size): inst = self.cell_inst[row, col] for pin_name in ["vdd", "gnd"]: self.copy_layout_pin(inst, pin_name) + if row == 2: #add only 1 label per col if 'VPB' or 'vpb' in self.cell_inst[row, col].mod.pins: diff --git a/technology/sky130/custom/sky130_internal.py b/technology/sky130/custom/sky130_internal.py index 10637384..83bdd42c 100644 --- a/technology/sky130/custom/sky130_internal.py +++ b/technology/sky130/custom/sky130_internal.py @@ -5,29 +5,36 @@ # All rights reserved. # -import debug -from base import design -from base import get_libcell_size -from tech import layer, GDS +from copy import deepcopy +from modules import internal_base +from tech import cell_properties as props - -class sky130_internal(design): +class sky130_internal(internal_base): def __init__(self, version, name=""): - super().__init__(name) - + prop = deepcopy(props.internal) + prop.boundary_layer = "mem" if version == "wlstrap": self.name = "sky130_fd_bd_sram__sram_sp_wlstrap" + prop.port_order = ["vdd"] + prop.port_types = ["POWER"] + prop.port_map = {'vdd': 'VPWR'} elif version == "wlstrap_p": self.name = "sky130_fd_bd_sram__sram_sp_wlstrap_p" + prop.port_order = ["gnd"] + prop.port_types = ["GROUND"] + prop.port_map = {'gnd': 'VGND'} elif version == "wlstrapa": self.name = "sky130_fd_bd_sram__sram_sp_wlstrapa" + prop.port_order = ["vdd"] + prop.port_types = ["POWER"] + prop.port_map = {'vdd': 'VPWR'} elif version == "wlstrapa_p": self.name = "sky130_fd_bd_sram__sram_sp_wlstrapa_p" + prop.port_order = ["gnd"] + prop.port_types = ["GROUND"] + prop.port_map = {'gnd': 'VGND'} else: debug.error("Invalid version", -1) - design.__init__(self, name=self.name) - (self.width, self.height) = get_libcell_size(self.name, - GDS["unit"], - layer["mem"]) - # pin_map = get_libcell_pins(pin_names, self.name, GDS["unit"]) + + super().__init__(name, cell_name=self.name, prop=prop) diff --git a/technology/sky130/custom/sky130_replica_bitcell_array.py b/technology/sky130/custom/sky130_replica_bitcell_array.py index c7b3c609..93ea3f0b 100644 --- a/technology/sky130/custom/sky130_replica_bitcell_array.py +++ b/technology/sky130/custom/sky130_replica_bitcell_array.py @@ -228,10 +228,6 @@ class sky130_replica_bitcell_array(replica_bitcell_array, sky130_bitcell_base_ar self.add_via_stack_center(from_layer=pin.layer, to_layer='m2', offset=pin_center+supply_inst.ll()+cell_inst.ll() + vector(connection_offset,0)) - #self.add_power_pin(name=pin_name, - # loc=pin_center+supply_inst.ll()+cell_inst.ll() + vector(connection_offset,0), - # start_layer=pin.layer, - # end_layer='m2') # add well contacts to perimeter cells @@ -277,9 +273,6 @@ class sky130_replica_bitcell_array(replica_bitcell_array, sky130_bitcell_base_ar self.add_via_stack_center(from_layer=pin.layer, to_layer='m2', offset=pin_center+supply_inst.ll()+cell_inst.ll() + vector(connection_offset,0)) - #self.add_power_pin(name=pin_name, - # loc=pin_center+supply_inst.ll()+cell_inst.ll() + vector(connection_offset,0), - # start_layer=pin.layer) min_area = drc["minarea_{}".format('m3')] for track,supply, offset in zip(range(1,5),['vdd','vdd','gnd','gnd'],[min_area * 6,min_area * 6, 0, 0]): diff --git a/technology/sky130/custom/sky130_replica_column.py b/technology/sky130/custom/sky130_replica_column.py index 0425160d..66999542 100644 --- a/technology/sky130/custom/sky130_replica_column.py +++ b/technology/sky130/custom/sky130_replica_column.py @@ -90,8 +90,8 @@ class sky130_replica_column(sky130_bitcell_base_array): self.add_pin("vdd", "POWER") self.add_pin("gnd", "GROUND") - #self.add_pin("top_gate", "INPUT") - #self.add_pin("bot_gate", "INPUT") + self.add_pin("top_gate", "INPUT") + self.add_pin("bot_gate", "INPUT") def add_modules(self): self.replica_cell = factory.create(module_type="replica_bitcell_1port", version="opt1") diff --git a/technology/sky130/tech/tech.py b/technology/sky130/tech/tech.py old mode 100644 new mode 100755 index 6957530b..443a61b6 --- a/technology/sky130/tech/tech.py +++ b/technology/sky130/tech/tech.py @@ -782,14 +782,26 @@ library_prefix_name = "sky130_fd_bd_sram__" # This will look for a maglef file and copy it over the mag file # before DRC after extraction +# gds flatglob sky130_fd_bd_sram__openram_sp_cell_opt1a_cell +# gds flatglob sky130_fd_bd_sram__openram_sp_cell_opt1a_replica_ce +# gds flatglob sky130_fd_bd_sram__openram_sp_cell_opt1_replica_cell +# gds flatglob sky130_fd_bd_sram__openram_sp_cell_opt1_replica_ce +# gds flatglob sky130_fd_bd_sram__openram_sp_cell_opt1_replica_cell +# gds flatglob sky130_fd_bd_sram__openram_sp_cell_opt1a_cell +# gds flatglob sky130_fd_bd_sram__sram_sp_cell_fom_serifs + flatglob = ["*_?mos_m*", "sky130_fd_bd_sram__sram_sp_cell_fom_serifs", - "sky130_fd_bd_sram__openram_sp_cell_opt1a_cell", - "sky130_fd_bd_sram__openram_sp_cell_opt1a_replica_ce", + + "sky130_fd_bd_sram__sram_sp_cell", "sky130_fd_bd_sram__openram_sp_cell_opt1_replica_cell", + "sky130_fd_bd_sram__openram_sp_cell_opt1a_replica_cell", + + "sky130_fd_bd_sram__sram_sp_cell_opt1_ce", "sky130_fd_bd_sram__openram_sp_cell_opt1_replica_ce", - "sky130_fd_bd_sram__openram_sp_cell_opt1a_cell", - "sky130_fd_bd_sram__sram_sp_cell_fom_serifs"] + "sky130_fd_bd_sram__openram_sp_cell_opt1a_replica_ce", + "sky130_fd_bd_sram__sram_sp_wlstrap_ce", + "sky130_fd_bd_sram__sram_sp_wlstrap_p_ce"] blackbox_cells = ["sky130_fd_bd_sram__openram_dp_cell", "sky130_fd_bd_sram__openram_dp_cell_dummy",