diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..6fd5945 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,62 @@ +# Minimal makefile for Sphinx documentation + +DOCSDIR := $(dir $(lastword $(MAKEFILE_LIST))) +TOPDIR := $(realpath $(DOCSDIR)/..) + +include $(TOPDIR)/scripts/make/conda.mk + +SHELL = /bin/bash + +EXP_OPEN := $$(( +EXP_CLOSE := )) +CPU_CORES := $(shell nproc) +CPU_CORES_2 := $(shell echo $(EXP_OPEN) $(CPU_CORES) * 2 $(EXP_CLOSE)) + +SPHINXOPTS = -j $(CPU_CORES_2) +SPHINXBUILD = $(IN_CONDA_ENV) sphinx-build +SPHINXAUTOBUILD = $(IN_CONDA_ENV) sphinx-autobuild +SPHINXPROJ = SkyWaterPDK +SOURCEDIR = $(DOCSDIR) +BUILDDIR = $(DOCSDIR)/_build + +# Put it first so that "make" without argument is like "make help". +help: | $(CONDA_ENV_PYTHON) + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +# Vim makes a '4913' file for file system checking. Seriously. +livehtml: | $(CONDA_ENV_PYTHON) + @$(SPHINXAUTOBUILD) \ + -b html \ + --delay 5 \ + \ + --ignore \*.swp \ + --ignore \*~ \ + --ignore env \ + --ignore _build \ + --ignore .git \ + --ignore */4913 \ + \ + $(SPHINXOPTS) \ + "$(SOURCEDIR)" \ + "$(BUILDDIR)/html" + +.PHONY: help livehtml Makefile + +# Various automated fixups that can be run +fixup: + # Make sure it is SkyWater + find ../ -type f -name \*.rst -exec sed -i 's/Skywater/SkyWater/gi' \{\} \+ + # Strip trailing space + find ../ -type f -name \*.rst -exec sed -i 's/ \+$$//' \{\} \+ + # Make sure all library names have the :lib: role. + find ../ -type f -name \*.rst -exec sed -i -e'/:name:.*/!s/\(:lib:\)\?`\?\(sky130_[a-z0-9]\+_[a-z0-9]\+\(_[a-z0-9]\+\)\?\)`\?\(\s\|$$\)/:lib:`\2`\4/g' \{\} \+ + +.PHONY: fixup + +echo: | $(CONDA_ENV_PYTHON) + @echo '$(SPHINXBUILD) -M XXXX "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)' + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +.DEFAULT: | $(CONDA_ENV_PYTHON) + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..455b579 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,326 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import docutils +import os +import re +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'Skywater SKY130 PDK' +copyright = '2020, Skywater PDK Authors' +author = 'Skywater PDK Authors' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.todo', + 'sphinx.ext.mathjax', + 'sphinx.ext.ifconfig', + 'sphinx.ext.githubpages', + 'sphinxcontrib_verilog_diagrams', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# Enable github links when not on readthedocs +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' +if not on_rtd: + html_context = { + "display_github": True, # Integrate GitHub + "github_user": "mithro", # Username + "github_repo": "python-sphinx-verilog", # Repo name + "github_version": "master", # Version + "conf_py_path": "/doc/", + } +else: + docs_dir = os.path.abspath(os.path.dirname(__file__)) + print("Docs dir is:", docs_dir) + import subprocess + subprocess.call('git fetch origin --unshallow', cwd=docs_dir, shell=True) + subprocess.check_call('git fetch origin --tags', cwd=docs_dir, shell=True) + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = re.sub('^v', '', os.popen('git describe ').read().strip()) +# The short X.Y version. +version = release + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'env', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = None + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_symbiflow_theme" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +html_theme_options = { + # Specify a list of menu in Header. + # Tuples forms: + # ('Name', 'external url or path of pages in the document', boolean, 'icon name') + # + # Third argument: + # True indicates an external link. + # False indicates path of pages in the document. + # + # Fourth argument: + # Specify the icon name. + # For details see link. + # https://material.io/icons/ + 'header_links': [ + ('Home', 'index', False, 'home'), + ("GitHub", "https://github.com/google/skywater-pdk", True, 'link'), + ("SkyWater", "https://www.skywatertechnology.com/", True, 'link'), + ], + + # Customize css colors. + # For details see link. + # https://getmdl.io/customize/index.html + # + # Values: amber, blue, brown, cyan deep_orange, deep_purple, green, grey, indigo, light_blue, + # light_green, lime, orange, pink, purple, red, teal, yellow(Default: indigo) + 'primary_color': + 'light_green', + # Values: Same as primary_color. (Default: pink) + 'accent_color': + 'teal', + + # Customize layout. + # For details see link. + # https://getmdl.io/components/index.html#layout-section + 'fixed_drawer': + True, + 'fixed_header': + True, + 'header_waterfall': + True, + 'header_scroll': + False, + + # Render title in header. + # Values: True, False (Default: False) + 'show_header_title': + False, + # Render title in drawer. + # Values: True, False (Default: True) + 'show_drawer_title': + True, + # Render footer. + # Values: True, False (Default: True) + 'show_footer': + True +} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'SkywaterSKY130PDKdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'SkywaterSKY130PDK.tex', 'Skywater SKY130 PDK Documentation', + 'Skywater PDK Authors', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'skywaters8pdk', 'Skywater SKY130 PDK Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'SkywaterSKY130PDK', 'Skywater SKY130 PDK Documentation', + author, 'SkywaterSKY130PDK', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for todo extension ---------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +import re +from docutils.parsers.rst import directives, roles, nodes + + +LIB_REGEX = re.compile('sky130_(?P[^_\s]*)_(?P[^_\s]*)(_(?P[^_\s]*))?') + +def lib_role(name, rawtext, text, lineno, inliner, options={}, content=[]): + """Library name which gets colorized.""" + m = LIB_REGEX.match(text) + if not m: + msg = inliner.reporter.error("Malformed library name of "+repr(text), line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] + app = inliner.document.settings.env.app + + #lib_process_role = roles.role('lib_src', inliner.language, lineno, inliner.reporter) + #lib_src_role = roles.role('lib_src', inliner.language, lineno, inliner.reporter) + #lib_type_role = roles.role('lib_src', inliner.language, lineno, inliner.reporter) + #lib_name_role = roles.role('lib_src', inliner.language, lineno, inliner.reporter) + lib_process = 'sky130' + lib_src = m.group('lib_src') + lib_type = m.group('lib_type') + lib_name = m.group('lib_name') + + r = [ + nodes.inline(lib_process, lib_process, classes=['lib-process']), + nodes.inline('_', '_', options=options), + nodes.inline(lib_src, lib_src, classes=['lib-src']), + nodes.inline('_', '_', options=options), + nodes.inline(lib_type, lib_type, classes=['lib-type']), + ] + if lib_name: + r.append(nodes.inline('_', '_', options=options)) + r.append(nodes.inline(lib_name, lib_name, classes=['lib-name'])) + + return r, [] + + +def add_role(app, new_role_name): + options = { + 'class': directives.class_option(new_role_name), + } + role = roles.CustomRole(new_role_name, roles.generic_custom_role, options, "") + app.add_role(new_role_name, role) + + +def setup(app): + app.add_css_file('extra.css') + add_role(app, 'lib_process') + add_role(app, 'lib_src') + add_role(app, 'lib_type') + add_role(app, 'lib_name') + add_role(app, 'drc_rule') + add_role(app, 'drc_tag') + add_role(app, 'drc_flag') + add_role(app, 'layer') + app.add_role('lib', lib_role) diff --git a/docs/fixup-headers.py b/docs/fixup-headers.py new file mode 100755 index 0000000..b140ddf --- /dev/null +++ b/docs/fixup-headers.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +# Copyright 2020 SkyWater PDK Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + + +import os.path +import sys +import tempfile +from collections import defaultdict + + +def count_chars(l): + o = defaultdict(lambda: 0) + for i in l: + o[i] += 1 + if '\n' in o: + del o['\n'] + return dict(o) + + +def main(argv): + assert len(argv) == 1, argv + + fname = argv[0] + assert fname.endswith('.rst'), fname + assert os.path.exists(fname), fname + + output = ['',] + with open(fname) as f: + for l in f: + output.append(l) + c = count_chars(l) + if len(c) != 1: + continue + + header = list(c.keys())[0] + if header not in ['-', '=', '+', '~']: + print("Possible header?", repr(l)) + continue + + lastline = output[-2] + + if len(lastline) <= 4: + continue + + oheader = (header * (len(lastline)-1))+'\n' + output[-1] = oheader + + with open(fname, 'w') as f: + f.write("".join(output[1:])) + + return 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..1be3b4f --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,22 @@ +Welcome to SkyWater SKY130 PDK's documentation! +=============================================== + +TODO: Put documentation here. + +.. toctree:: + :hidden: + + contributing + code-of-conduct + + known_issues + versioning + status + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..d63f78d --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,18 @@ +git+https://github.com/SymbiFlow/sphinx_materialdesign_theme.git#egg=sphinx-symbiflow-theme + +docutils +sphinx +sphinx-autobuild + +# Verilog diagrams using Yosys + netlistsvg +git+https://github.com/SymbiFlow/sphinxcontrib-verilog-diagrams.git#egg=sphinxcontrib-verilog-diagrams + +# Module diagrams +symbolator + +# pycairo +# vext.gi + +restructuredtext-lint + +tabulate diff --git a/environment.yml b/environment.yml index 69f2ca1..18e9369 100644 --- a/environment.yml +++ b/environment.yml @@ -14,9 +14,16 @@ # # SPDX-License-Identifier: Apache-2.0 name: skywater-pdk-scripts +channels: +- symbiflow +- conda-forge +- defaults dependencies: - python - pip +- yosys +- netlistsvg # Packages installed from PyPI - pip: - -r file:requirements.txt + - -r file:docs/requirements.txt diff --git a/scripts/make/conda.mk b/scripts/make/conda.mk index 68b52a0..0370295 100644 --- a/scripts/make/conda.mk +++ b/scripts/make/conda.mk @@ -14,6 +14,7 @@ # # SPDX-License-Identifier: Apache-2.0 + SHELL := /bin/bash UNAME_S := $(shell uname -s) @@ -30,7 +31,8 @@ ifneq (, $(findstring MINGW, $(UNAME_S))) OSFLAG := Linux endif -TOP_DIR := $(shell git rev-parse --show-toplevel) +MAKE_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +TOP_DIR := $(realpath $(MAKE_DIR)/../..) ENV_DIR := $(TOP_DIR)/env REQUIREMENTS_FILE := $(TOP_DIR)/requirements.txt ENVIRONMENT_FILE := $(TOP_DIR)/environment.yml @@ -60,12 +62,14 @@ $(CONDA_PKGS_DEP): $(CONDA_PYTHON) $(CONDA_PYTHON): $(DOWNLOADS_DIR)/Miniconda3-latest-$(OSFLAG)-x86_64.sh $(DOWNLOADS_DIR)/Miniconda3-latest-$(OSFLAG)-x86_64.sh -p $(CONDA_DIR) -b -f + touch $(CONDA_PYTHON) $(CONDA_DIR)/envs: $(CONDA_PYTHON) $(IN_CONDA_ENV_BASE) conda config --system --add envs_dirs $(CONDA_DIR)/envs $(CONDA_ENV_PYTHON): $(ENVIRONMENT_FILE) $(REQUIREMENTS_FILE) | $(CONDA_PYTHON) $(CONDA_DIR)/envs $(CONDA_PKGS_DEP) $(IN_CONDA_ENV_BASE) conda env update --name $(CONDA_ENV_NAME) --file $(ENVIRONMENT_FILE) + touch $(CONDA_ENV_PYTHON) env: $(CONDA_ENV_PYTHON) $(IN_CONDA_ENV) conda info @@ -86,3 +90,25 @@ dist-clean: rm -rf conda .PHONY: dist-clean + + +FILTER_TOP = sed -e's@$(TOP_DIR)/@$$TOP_DIR/@' +env-info: + @echo " Top level directory is: '$(TOP_DIR)'" + @echo " The version number is: '$$(git describe)'" + @echo " Git repository is using: $$(du -h -s $(TOP_DIR)/.git | sed -e's/\s.*//')" \ + | $(FILTER_TOP) + @echo + @echo " Environment setup directory is: '$(ENV_DIR)'" \ + | $(FILTER_TOP) + @echo " Download and cache directory is: '$(DOWNLOADS_DIR)' (using $$(du -h -s $(DOWNLOADS_DIR) | sed -e's/\s.*//'))" \ + | $(FILTER_TOP) + @echo " Conda's directory is: '$(CONDA_DIR)' (using $$(du -h -s $(CONDA_DIR) | sed -e's/\s.*//'))" \ + | $(FILTER_TOP) + @echo " Conda's packages download cache is: '$(CONDA_PKGS_DIR)' (using $$(du -h -s $(CONDA_PKGS_DIR) | sed -e's/\s.*//'))" \ + | $(FILTER_TOP) + @echo " Conda's Python binary is: '$(CONDA_ENV_PYTHON)'"\ + | $(FILTER_TOP) + + +.PHONY: info