diff --git a/doc/.gitignore b/doc/.gitignore
new file mode 100644
index 00000000..b77ad873
--- /dev/null
+++ b/doc/.gitignore
@@ -0,0 +1,3 @@
+*~
+/venv
+/_build
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 00000000..a1008113
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+SPHINXPROJ = zero-riscy
+SOURCEDIR = .
+BUILDDIR = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644
index 00000000..53be1aba
--- /dev/null
+++ b/doc/conf.py
@@ -0,0 +1,162 @@
+# -*- coding: utf-8 -*-
+#
+# zero-riscy documentation build configuration file, created by
+# sphinx-quickstart on Thu Nov 8 15:42:18 2018.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+# 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 os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+numfig=True
+numfig_format = {'figure': 'Figure %s', 'table': 'Table %s', 'code-block': 'Listing %s'}
+
+# -- 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 = []
+
+# 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'
+
+# General information about the project.
+project = u'ZERO-RISCY'
+copyright = u'2017-2018, ETH Zurich and University of Bologna'
+author = u'Pasquale Davide Schiavone'
+
+from setuptools_scm import get_version
+release = get_version(root='..', relative_to=__file__)
+
+# 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 short X.Y version.
+version = u''
+# The full version, including alpha/beta/rc tags.
+#release = u''
+
+# 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 patterns also effect to html_static_path and html_extra_path
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'venv']
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = False
+
+
+# -- 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_rtd_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 = {
+}
+
+html_logo = 'images/pulp.png'
+
+# 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']
+
+# -- Options for HTMLHelp output ------------------------------------------
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'zero-riscydoc'
+
+
+
+# -- 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, 'zero-riscy.tex', u'ZERO-RISCY Documentation',
+ u'ETH Zurich and University of Bologna', 'manual'),
+]
+
+latex_logo = 'images/pulp_title.png'
+
+# -- 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, 'zero-riscy', u'zero-riscy 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, 'zero-riscy', u'zero-riscy Documentation',
+ author, 'zero-riscy', 'One line description of project.',
+ 'Miscellaneous'),
+]
diff --git a/doc/copyright.rst b/doc/copyright.rst
new file mode 100644
index 00000000..d4684b51
--- /dev/null
+++ b/doc/copyright.rst
@@ -0,0 +1,4 @@
+Copyright
+=========
+
+Copyright and related rights are licensed under the Solderpad Hardware License, Version 0.51 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law or agreed to in writing, software, hardware and materials distributed under this 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.
diff --git a/doc/cs_registers.rst b/doc/cs_registers.rst
new file mode 100644
index 00000000..56177a3a
--- /dev/null
+++ b/doc/cs_registers.rst
@@ -0,0 +1,104 @@
+.. _cs-registers:
+
+Control and Status Registers
+============================
+
+ZERO-RISCY does not implement all control and status registers specified in the RISC-V privileged specifications, but is limited to the registers that were needed for the PULP system. The reason for this is that we wanted to keep the footprint of the core as low as possible and avoid any overhead that we do not explicitly need.
+
+.. tabularcolumns:: |p{1cm}|p{.6cm}|p{.6cm}|p{1cm}|p{1cm}|p{1.5cm}|p{1.2cm}|p{6cm}|
+
++----------------------------+--------+---------+--------+-----------------------------------+
+| CSR Address | Hex | Name | Access | Description |
++-------+-----+-----+--------+--------+---------+--------+-----------------------------------+
+| 11:10 | 9:8 | 7:6 | 5:0 | | | | |
++=======+=====+=====+========+========+=========+========+===================================+
+| 00 | 11 | 00 | 000000 | 0x300 | MSTATUS | R/W | Machine Status |
++-------+-----+-----+--------+--------+---------+--------+-----------------------------------+
+| 00 | 11 | 00 | 000101 | 0x305 | MTVEC | R | Machine Trap-Vector Base Address |
++-------+-----+-----+--------+--------+---------+--------+-----------------------------------+
+| 00 | 11 | 01 | 000001 | 0x341 | MEPC | R/W | Machine Exception Program Counter |
++-------+-----+-----+--------+--------+---------+--------+-----------------------------------+
+| 00 | 11 | 01 | 000010 | 0x342 | MCAUSE | R/W | Machine Trap Cause |
++-------+-----+-----+--------+--------+---------+--------+-----------------------------------+
+| 01 | 11 | 00 | 0xxxxx | 0x780- | PCCRs | R/W | Performance Counter Counter |
+| | | | | 0x79F | | | Registers |
++-------+-----+-----+--------+--------+---------+--------+-----------------------------------+
+| 01 | 11 | 10 | 100000 | 0x7A0 | PCER | R/W | Performance Counter Enable |
++-------+-----+-----+--------+--------+---------+--------+-----------------------------------+
+| 01 | 11 | 10 | 100001 | 0x7A1 | PCMR | R/W | Performance Counter Mode |
++-------+-----+-----+--------+--------+---------+--------+-----------------------------------+
+| 11 | 11 | 00 | 010100 | 0xF14 | MHARTID | R | Hardware Thread ID |
++-------+-----+-----+--------+--------+---------+--------+-----------------------------------+
+
+
+Machine Status (MSTATUS)
+------------------------
+
+CSR Address: ``0x300``
+
+Reset Value: ``0x0000_1800``
+
++-------+-----+------------------------------------------------------------------+
+| Bit# | R/W | Description |
++-------+-----+------------------------------------------------------------------+
+| 12:11 | R | **MPP:** Statically 2’b11 and cannot be altered (read-only). |
++-------+-----+------------------------------------------------------------------+
+| 7 | R/W | **Previous Interrupt Enable:** When an exception is encountered, |
+| | | MPIE will be set to IE. When the mret instruction is executed, |
+| | | the value of MPIE will be stored to IE. |
++-------+-----+------------------------------------------------------------------+
+| 3 | R/W | **Interrupt Enable:** If you want to enable interrupt handling |
+| | | in your exception handler, set the Interrupt Enable to 1’b1 |
+| | | inside your handler code. |
++-------+-----+------------------------------------------------------------------+
+
+
+Machine Trap-Vector Base Address (MTVEC)
+----------------------------------------
+
+CSR Address: ``0x305``
+
+When an exception is encountered, the core jumps to the corresponding handler using the content of the MTVEC as base address. It is a read-only register which contains the boot address.
+
+
+Machine Exception PC (MEPC)
+---------------------------
+
+CSR Address: ``0x341``
+
+Reset Value: ``0x0000_0000``
+
+When an exception is encountered, the current program counter is saved in MEPC, and the core jumps to the exception address. When an mret instruction is executed, the value from MEPC replaces the current program counter.
+
+
+Machine Cause (MCAUSE)
+----------------------
+
+CSR Address: ``0x342``
+
+Reset Value: ``0x0000_0000``
+
++-------+-----+------------------------------------------------------------------+
+| Bit# | R/W | Description |
++-------+-----+------------------------------------------------------------------+
+| 31 | R | **Interrupt:** This bit is set when the exception was triggered |
+| | | by an interrupt. |
++-------+-----+------------------------------------------------------------------+
+| 4:0 | R | **Exception Code** |
++-------+-----+------------------------------------------------------------------+
+
+
+MHARTID
+-------
+
+CSR Address: ``0xF14``
+
+Reset Value: Defined
+
++-------+-----+------------------------------------------------------------------+
+| Bit# | R/W | Description |
++-------+-----+------------------------------------------------------------------+
+| 10:5 | R | **Cluster ID:** ID of the cluster |
++-------+-----+------------------------------------------------------------------+
+| 3:0 | R | **Core ID:** ID of the core within the cluster |
++-------+-----+------------------------------------------------------------------+
diff --git a/doc/debug.rst b/doc/debug.rst
new file mode 100644
index 00000000..83710029
--- /dev/null
+++ b/doc/debug.rst
@@ -0,0 +1,251 @@
+.. _debug-unit:
+
+Debug Unit
+==========
+
+
+Address Map
+-----------
+
++--------------+-----------------+--------------------------------------------------+
+| Address | Name | Description |
++==============+=================+==================================================+
+| **0x0000** - | Debug Registers | Always accessible, even when the core is running |
+| **0x007F** | | |
++--------------+-----------------+--------------------------------------------------+
+| **0x400** - | GPR (x0-x31) | General Purpose Registers. Only accessible if |
+| **0x47F** | | the core is halted |
++--------------+-----------------+--------------------------------------------------+
+| **0x500** - | FPR (f0-f31) | Reserved. Not used in the ZERO-RISCY core. |
+| **0x5FF** | | |
++--------------+-----------------+--------------------------------------------------+
+| **0x2000** - | Debug Registers | Only accessible if the core is halted |
+| **0x20FF** | | |
++--------------+-----------------+--------------------------------------------------+
+| **0x4000** - | CSR | Control and Status Registers |
+| **0x7FFF** | | Only accessible if the core is halted |
++--------------+-----------------+--------------------------------------------------+
+
+Addresses are intended for a bus system with 32-bit wide words.
+FPR get more address space than GPR because they can be 64-bit wide even in a 32-bit system.
+Addresses have to be aligned to word-boundaries.
+
+
+Debug Registers
+---------------
+
++--------------+-----------------+--------------------------------------------------+
+| Address | Name | Description |
++==============+=================+==================================================+
+| **0x00** | DBG_CTRL | Debug Control |
++--------------+-----------------+--------------------------------------------------+
+| **0x04** | DBG_HIT | Debug Hit |
++--------------+-----------------+--------------------------------------------------+
+| **0x08** | DBG_IE | Debug Interrupt Enable |
++--------------+-----------------+--------------------------------------------------+
+| **0x0C** | DBG_CAUSE | Debug Cause (Why we entered debug state) |
++--------------+-----------------+--------------------------------------------------+
+| **0x40** | DBG_BPCTRL0 | HW BP0 Control |
++--------------+-----------------+--------------------------------------------------+
+| **0x44** | DBG_BPDATA0 | HW BP0 Data |
++--------------+-----------------+--------------------------------------------------+
+| **0x48** | DBG_BPCTRL1 | HW BP1 Control |
++--------------+-----------------+--------------------------------------------------+
+| **0x4C** | DBG_BPDATA1 | HW BP1 Data |
++--------------+-----------------+--------------------------------------------------+
+| **0x50** | DBG_BPCTRL2 | HW BP2 Control |
++--------------+-----------------+--------------------------------------------------+
+| **0x54** | DBG_BPDATA2 | HW BP2 Data |
++--------------+-----------------+--------------------------------------------------+
+| **0x58** | DBG_BPCTRL3 | HW BP3 Control |
++--------------+-----------------+--------------------------------------------------+
+| **0x5C** | DBG_BPDATA3 | HW BP3 Data |
++--------------+-----------------+--------------------------------------------------+
+| **0x60** | DBG_BPCTRL4 | HW BP4 Control |
++--------------+-----------------+--------------------------------------------------+
+| **0x64** | DBG_BPDATA4 | HW BP4 Data |
++--------------+-----------------+--------------------------------------------------+
+| **0x68** | DBG_BPCTRL5 | HW BP5 Control |
++--------------+-----------------+--------------------------------------------------+
+| **0x6C** | DBG_BPDATA5 | HW BP5 Data |
++--------------+-----------------+--------------------------------------------------+
+| **0x70** | DBG_BPCTRL6 | HW BP6 Control |
++--------------+-----------------+--------------------------------------------------+
+| **0x74** | DBG_BPDATA6 | HW BP6 Data |
++--------------+-----------------+--------------------------------------------------+
+| **0x78** | DBG_BPCTRL7 | HW BP7 Control |
++--------------+-----------------+--------------------------------------------------+
+| **0x7C** | DBG_BPDATA7 | HW BP7 Data |
++--------------+-----------------+--------------------------------------------------+
+| **0x2000** | DBG_NPC | Next PC |
++--------------+-----------------+--------------------------------------------------+
+| **0x2004** | DBG_PPC | Previous PC |
++--------------+-----------------+--------------------------------------------------+
+
+
+Debug Control (DBG_CTRL)
+------------------------
+
++-------+-----+------------------------------------------------------------------+
+| Bit# | R/W | Description |
++=======+=====+==================================================================+
+| 16 | W1 | **HALT:** When 1 written, core enters debug mode, when 0 |
+| | | written, core exits debug mode. |
+| | | When read, 1 means core is in debug mode |
++-------+-----+------------------------------------------------------------------+
+| 0 | R/W | **SSTE:** Single-step enable |
++-------+-----+------------------------------------------------------------------+
+
+
+Debug Hit (DBG_HIT)
+-------------------
+
++-------+-----+------------------------------------------------------------------+
+| Bit# | R/W | Description |
++=======+=====+==================================================================+
+| 16 | R | **SLEEP:** Set when the core is in a sleeping state and waits |
+| | | for an event |
++-------+-----+------------------------------------------------------------------+
+| 0 | R/W | **SSTH:** Single-step hit, sticky bit that must be cleared by |
+| | | external debugger |
++-------+-----+------------------------------------------------------------------+
+
+
+Debug Interrupt Enable (DBG_IE)
+-------------------------------
+
++-------+-----+------------------------------------------------------------------+
+| Bit# | R/W | Description |
++=======+=====+==================================================================+
+| 11 | R/W | **ECALL:** Environment call from M-Mode |
++-------+-----+------------------------------------------------------------------+
+| 7 | R/W | **SAF:** Store Access Fault (together with **LAF**) |
++-------+-----+------------------------------------------------------------------+
+| 6 | R/W | **SAM:** Store Address Misaligned (never traps) |
++-------+-----+------------------------------------------------------------------+
+| 5 | R/W | **LAF:** Load Access Fault (together with **SAF**) |
++-------+-----+------------------------------------------------------------------+
+| 4 | R/W | **LAM:** Load Address Misaligned (never traps) |
++-------+-----+------------------------------------------------------------------+
+| 3 | R/W | **BP:** EBREAK instruction causes trap |
++-------+-----+------------------------------------------------------------------+
+| 2 | R/W | **ILL:** Illegal Instruction |
++-------+-----+------------------------------------------------------------------+
+| 1 | R/W | **IAF:** Instruction Access Fault (not implemented) |
++-------+-----+------------------------------------------------------------------+
+| 0 | R/W | **IAM:** Instruction Address Misaligned (never traps) |
++-------+-----+------------------------------------------------------------------+
+
+When ‘1’ exceptions cause traps, otherwise normal exceptions.
+
+
+Debug Cause (DBG_CAUSE)
+-----------------------
+
++-------+-----+------------------------------------------------------------------+
+| Bit# | R/W | Description |
++=======+=====+==================================================================+
+| 31 | R | **IRQ:** Interrupt caused us to enter debug mode |
++-------+-----+------------------------------------------------------------------+
+| 4:0 | R | **CAUSE:** Exception/interrupt number |
++-------+-----+------------------------------------------------------------------+
+
+
+Debug Hardware Breakpoint x Control (DBG_BPCTRLx)
+-------------------------------------------------
+
++-------+-----+------------------------------------------------------------------+
+| Bit# | R/W | Description |
++=======+=====+==================================================================+
+| 0 | R | **IMPL:** ZERO-RISCY does not implement hardware breakpoints. |
+| | | Always read as 0. |
++-------+-----+------------------------------------------------------------------+
+
+
+Debug Next Program Counter (DBG_NPC)
+------------------------------------
+
++-------+-----+------------------------------------------------------------------+
+| Bit# | R/W | Description |
++=======+=====+==================================================================+
+| 31:0 | R/W | **NPC:** Next PC to be executed |
++-------+-----+------------------------------------------------------------------+
+
+When written core jumps to PC.
+
+
+Debug Previous Program Counter (DBG_PPC)
+----------------------------------------
+
++-------+-----+------------------------------------------------------------------+
+| Bit# | R/W | Description |
++=======+=====+==================================================================+
+| 31:0 | W | **PPC:** Previous PC, already executed |
++-------+-----+------------------------------------------------------------------+
+
+Values of PPC and NPC when entering debug mode:
+
++---------------------+------------------------+------------------+---------+------------+
+| Reason | PPC | NPC | Cause | GDB Sigval |
++=====================+========================+==================+=========+============+
+| ebreak | ebreak instruction | next instruction | BP | TRAP |
++---------------------+------------------------+------------------+---------+------------+
+| ecall | ecall instruction | IVT entry | ECALL | TRAP |
++---------------------+------------------------+------------------+---------+------------+
+| illegal instruction | illegal instruction | IVT entry | ILL | ILL |
++---------------------+------------------------+------------------+---------+------------+
+| invalid mem access | load/store instruction | IVT entry | LAF/SAF | SEGV |
++---------------------+------------------------+------------------+---------+------------+
+| interrupt | last instruction | IVT entry | ? | INT |
++---------------------+------------------------+------------------+---------+------------+
+| halt | last instruction | next instruction | ? | TRAP |
++---------------------+------------------------+------------------+---------+------------+
+| single-step | last instruction | next instruction | ? | TRAP |
++---------------------+------------------------+------------------+---------+------------+
+
+
+Control and Status Registers
+----------------------------
+
++--------------+------------------+--------------------------------------------------+
+| Address | Name | Description |
++==============+==================+==================================================+
+| 0x4000 | CSR 0 = 0x000 | CSR |
++--------------+------------------+--------------------------------------------------+
+| ... | ... | ... |
++--------------+------------------+--------------------------------------------------+
+| 0x7FFC | CSR 4095 = 0xFFF | CSR |
++--------------+------------------+--------------------------------------------------+
+
+Can only be accessed when core is in debug mode.
+
+Interface
+---------
+
++-------------------------+-----------+----------------------------------------------+
+| Signal | Direction | Description |
++=========================+===========+==============================================+
+| ``debug_req_i`` | input | Request |
++-------------------------+-----------+----------------------------------------------+
+| ``debug_gnt_o`` | output | Grant |
++-------------------------+-----------+----------------------------------------------+
+| ``debug_rvalid_o`` | output | Read data valid |
++-------------------------+-----------+----------------------------------------------+
+| ``debug_addr_i[14:0]`` | input | Address for write/read |
++-------------------------+-----------+----------------------------------------------+
+| ``debug_we_i`` | input | Write Enable |
++-------------------------+-----------+----------------------------------------------+
+| ``debug_wdata_i[31:0]`` | input | Write data |
++-------------------------+-----------+----------------------------------------------+
+| ``debug_rdata_o[31:0]`` | output | Read data |
++-------------------------+-----------+----------------------------------------------+
+| ``debug_halted_o`` | output | Is high when core is in debug mode |
++-------------------------+-----------+----------------------------------------------+
+| ``debug_halt_i`` | input | Set high when core should enter debug mode |
++-------------------------+-----------+----------------------------------------------+
+| ``debug_resume_i`` | input | Set high when core should exit debug mode |
++-------------------------+-----------+----------------------------------------------+
+
+``debug_halted_o``, ``debug_halt_i`` and ``debug_resume_i`` are intended for cross-triggering between multiple cores. They are not required for single-core debug, thus ``debug_halt_i`` and ``debug-resume_i`` can be tied to 0.
+
+``debug_halt_i`` and ``debug_resume_i`` should be high for only one single cycle to avoid deadlock issues.
diff --git a/doc/exception_interrupts.rst b/doc/exception_interrupts.rst
new file mode 100644
index 00000000..62d3a7f9
--- /dev/null
+++ b/doc/exception_interrupts.rst
@@ -0,0 +1,43 @@
+.. _exceptions-interrupts:
+
+Exceptions and Interrupts
+=========================
+
+ZERO-RISCY supports interrupts, exceptions on illegal instructions.
+
++------------+-----------------------------+
+| Address | Description |
++============+=============================+
+| **0x00** - | Interrupts 0 – 31 |
+| **0x7C** | |
++------------+-----------------------------+
+| **0x80** | Reset |
++------------+-----------------------------+
+| **0x84** | Illegal Instruction |
++------------+-----------------------------+
+| **0x88** | ECALL Instruction Executed |
++------------+-----------------------------+
+
+The base address of the interrupt vector table is given by the boot address. The most significant 3 bytes of the boot address given to the core are used for the first instruction fetch of the core and as the basis of the interrupt vector table. The core starts fetching at the address made by concatenating the most significant 3 bytes of the boot address and the reset value (0x80) as the least significant byte. The boot address can be changed after the first instruction was fetched to change the interrupt vector table address. It is assumed that the boot address is supplied via a register to avoid long paths to the instruction fetch unit.
+
+
+Interrupts
+----------
+
+Interrupts can only be enabled/disabled on a global basis and not individually. It is assumed that there is an event/interrupt controller outside of the core that performs masking and buffering of the interrupt lines. The global interrupt enable is done via the CSR register MSTATUS.
+
+Multiple interrupts requests are assumed to be handled by event/interrupt controller. When an interrupt is taken, the core gives an acknowledge signal to the event/interrupt controller as well as the interrupt id taken.
+
+
+Exceptions
+----------
+
+The illegal instruction exception and ecall instruction exceptions cannot be disabled and are always active.
+
+
+Handling
+--------
+
+ZERO-RISCY does support nested interrupt/exception handling. Exceptions inside interrupt/exception handlers cause another exception, thus exceptions during the critical part of your exception handlers, i.e. before having saved the MEPC and MESTATUS registers, will cause those register to be overwritten. Interrupts during interrupt/exception handlers are disabled by default, but can be explicitly enabled if desired.
+
+Upon executing an mret instruction, the core jumps to the program counter saved in the CSR register MEPC and restores the MPIE value of the register MSTATUS to IE. When entering an interrupt/exception handler, the core sets MEPC to the current program counter and saves the current value of MIE in MPIE of the MSTATUS register.
diff --git a/doc/images/blockdiagram.png b/doc/images/blockdiagram.png
new file mode 100644
index 00000000..830db3fe
Binary files /dev/null and b/doc/images/blockdiagram.png differ
diff --git a/doc/images/blockdiagram.svg b/doc/images/blockdiagram.svg
new file mode 100644
index 00000000..830db3fe
Binary files /dev/null and b/doc/images/blockdiagram.svg differ
diff --git a/doc/images/pcer.png b/doc/images/pcer.png
new file mode 100644
index 00000000..b646b064
Binary files /dev/null and b/doc/images/pcer.png differ
diff --git a/doc/images/pcer.svg b/doc/images/pcer.svg
new file mode 100644
index 00000000..014623ef
--- /dev/null
+++ b/doc/images/pcer.svg
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/doc/images/pulp.png b/doc/images/pulp.png
new file mode 100644
index 00000000..99b9a657
Binary files /dev/null and b/doc/images/pulp.png differ
diff --git a/doc/images/pulp_title.png b/doc/images/pulp_title.png
new file mode 100644
index 00000000..46bc5429
Binary files /dev/null and b/doc/images/pulp_title.png differ
diff --git a/doc/images/timing1.png b/doc/images/timing1.png
new file mode 100644
index 00000000..c9fe562e
Binary files /dev/null and b/doc/images/timing1.png differ
diff --git a/doc/images/timing1.svg b/doc/images/timing1.svg
new file mode 100644
index 00000000..c9fe562e
Binary files /dev/null and b/doc/images/timing1.svg differ
diff --git a/doc/images/timing2.png b/doc/images/timing2.png
new file mode 100644
index 00000000..92e96822
Binary files /dev/null and b/doc/images/timing2.png differ
diff --git a/doc/images/timing2.svg b/doc/images/timing2.svg
new file mode 100644
index 00000000..92e96822
Binary files /dev/null and b/doc/images/timing2.svg differ
diff --git a/doc/images/timing3.png b/doc/images/timing3.png
new file mode 100644
index 00000000..aeb10172
Binary files /dev/null and b/doc/images/timing3.png differ
diff --git a/doc/images/timing3.svg b/doc/images/timing3.svg
new file mode 100644
index 00000000..aeb10172
Binary files /dev/null and b/doc/images/timing3.svg differ
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644
index 00000000..10662a23
--- /dev/null
+++ b/doc/index.rst
@@ -0,0 +1,27 @@
+.. zero-riscy documentation master file, created by
+ sphinx-quickstart on Thu Nov 8 15:42:18 2018.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+ZERO-RISCY: User Manual
+=======================
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Contents:
+
+ introduction
+ instruction_fetch
+ load_store_unit
+ register_file
+ cs_registers
+ performance_counters
+ exception_interrupts
+ debug
+
+
+.. toctree::
+ :hidden:
+
+ copyright
+
diff --git a/doc/instruction_fetch.rst b/doc/instruction_fetch.rst
new file mode 100644
index 00000000..e6b1e5ed
--- /dev/null
+++ b/doc/instruction_fetch.rst
@@ -0,0 +1,37 @@
+.. _instruction-fetch:
+
+Instruction Fetch
+=================
+
+The instruction fetcher of the core is able to supply one instruction to the ID stage per cycle if the instruction cache or the instruction memory is able to serve one instruction per cycle. The instruction address must be half-word-aligned due to the support of compressed instructions. It is not possible to jump to instruction addresses that have the LSB bit set.
+
+For optimal performance and timing closure reasons, a prefetcher is used which fetches instruction from the instruction memory, or instruction cache.
+
+The following table describes the signals that are used to fetch instructions. This interface is a simplified version that is used by the LSU that is described in :ref:`load-store-unit`. The difference is that no writes are possible and thus it needs less signals.
+
+
+.. tabularcolumns:: |p{4cm}|l|p{9cm}|
+
++-------------------------+-----------+-----------------------------------------------+
+| Signal | Direction | Description |
++=========================+===========+===============================================+
+| ``instr_req_o`` | output | Request ready, must stay high until |
+| | | ``instr_gnt_i`` is high for one cycle |
++-------------------------+-----------+-----------------------------------------------+
+| ``instr_addr_o[31:0]`` | output | Address |
++-------------------------+-----------+-----------------------------------------------+
+| ``instr_rdata_i[31:0]`` | input | Data read from memory |
++-------------------------+-----------+-----------------------------------------------+
+| ``instr_rvalid_i`` | input | ``instr_rdata_is`` holds valid data when |
+| | | ``instr_rvalid_i`` is high. This signal will |
+| | | be high for exactly one cycle per request. |
++-------------------------+-----------+-----------------------------------------------+
+| ``instr_gnt_i`` | input | The other side accepted the request. |
+| | | ``instr_addr_o`` may change in the next cycle |
++-------------------------+-----------+-----------------------------------------------+
+
+
+Protocol
+--------
+
+The protocol used to communicate with the instruction cache or the instruction memory is the same as the protocol used by the LSU. See the description of the LSU in :ref:`LSU Protocol` for details about the protocol.
diff --git a/doc/introduction.rst b/doc/introduction.rst
new file mode 100644
index 00000000..c50097c5
--- /dev/null
+++ b/doc/introduction.rst
@@ -0,0 +1,36 @@
+Introduction
+============
+
+.. figure:: images/blockdiagram.png
+ :name: blockdiagram
+
+ Block Diagram
+
+ZERO-RISCY is a 2-stage in-order 32b RISC-V processor core. ZERO-RISCY has been designed to be small and efficient. Via two parameters, the core is configurable to support four ISA configurations. :numref:`blockdiagram` shows a block diagram of the core.
+
+Supported Instruction Set
+-------------------------
+
+ZERO-RISCY supports the following instructions:
+
+* Full support for RV32I Base Integer Instruction Set
+* Full support for RV32E Base Integer Instruction Set
+* Full support for RV32C Standard Extension for Compressed Instructions
+* Full support for RV32M Integer Multiplication and Division Instruction Set Extension
+
+The RV32M and RV32E can be enable and disable using two parameters.
+
+ASIC Synthesis
+--------------
+
+ASIC synthesis is supported for ZERO-RISCY. The whole design is completely synchronous and uses positive-edge triggered flip-flops, except for the register file, which can be implemented either with latches or with flip-flops. See Chapter 4 for more details about the register file. The core occupies an area of about 18.9 kGE when the latch based register file and the RV32IMC ISA is used or 11.6 kGE when the RV32EC is used .
+
+FPGA Synthesis
+--------------
+
+FPGA synthesis is supported for ZERO-RISCY when the flip-flop based register file is used. Since latches are not well supported on FPGAs, it is crucial to select the flip-flop based register file.
+
+Outline
+-------
+
+This document summarizes all the functionality of the ZERO-RISCY core in more detail. First, the instruction and data interfaces are explained in :ref:`instruction-fetch` and :ref:`load-store-unit`. :ref:`register-file` explains the register file. Control and status registers are explained in :ref:`cs-registers` and Chapter :ref:`performance-counters` gives an overview of all performance counters. Chapter :ref:`exceptions-interrupts` deals with exceptions and interrupts, and finally Chapter :ref:`debug-unit` summarizes the accessible debug registers.
diff --git a/doc/load_store_unit.rst b/doc/load_store_unit.rst
new file mode 100644
index 00000000..8a2664f0
--- /dev/null
+++ b/doc/load_store_unit.rst
@@ -0,0 +1,67 @@
+.. _load-store-unit:
+
+Load-Store-Unit (LSU)
+=====================
+
+The LSU of the core takes care of accessing the data memory. Load and stores on words (32 bit), half words (16 bit) and bytes (8 bit) are supported.
+
+Signals that are used by the LSU:
+
++-------------------------+-----------+-----------------------------------------------+
+| Signal | Direction | Description |
++=========================+===========+===============================================+
+| ``data_req_o`` | output | Request ready, must stay high until |
+| | | ``data_gnt_i`` is high for one cycle |
++-------------------------+-----------+-----------------------------------------------+
+| ``data_addr_o[31:0]`` | output | Address |
++-------------------------+-----------+-----------------------------------------------+
+| ``data_we_o`` | output | Write Enable, high for writes, low for |
+| | | reads. Sent together with ``data_req_o`` |
++-------------------------+-----------+-----------------------------------------------+
+| ``data_be_o[3:0]`` | output | Byte Enable. Is set for the bytes to |
+| | | write/read, sent together with ``data_req_o`` |
++-------------------------+-----------+-----------------------------------------------+
+| ``data_wdata_o[31:0]`` | output | Data to be written to memory, sent together |
+| | | with ``data_req_o`` |
++-------------------------+-----------+-----------------------------------------------+
+| ``data_rdata_i[31:0]`` | input | Data read from memory |
++-------------------------+-----------+-----------------------------------------------+
+| ``data_rvalid_i`` | input | ``data_rdata_is`` holds valid data when |
+| | | ``data_rvalid_i`` is high. This signal will |
+| | | be high for exactly one cycle per request. |
++-------------------------+-----------+-----------------------------------------------+
+| ``data_gnt_i`` | input | The other side accepted the request. |
+| | | ``data_addr_o`` may change in the next cycle |
++-------------------------+-----------+-----------------------------------------------+
+
+
+Misaligned Accesses
+-------------------
+
+The LSU is able to perform misaligned accesses, meaning accesses that are not aligned on natural word boundaries. However, it needs to perform two separate word-aligned accesses internally. This means that at least two cycles are needed for misaligned loads and stores.
+
+.. _lsu-protocol:
+
+Protocol
+--------
+
+The protocol that is used by the LSU to communicate with a memory works as follows:
+
+The LSU provides a valid address in ``data_addr_o`` and sets ``data_req_o`` high. The memory then answers with a ``data_gnt_i`` set high as soon as it is ready to serve the request. This may happen in the same cycle as the request was sent or any number of cycles later. After a grant was received, the address may be changed in the next cycle by the LSU. In addition, the ``data_wdata_o``, ``data_we_o`` and ``data_be_o`` signals may be changed as it is assumed that the memory has already processed and stored that information. After receiving a grant, the memory answers with a ``data_rvalid_i`` set high if ``data_rdata_i`` is valid. This may happen one or more cycles after the grant has been received. Note that ``data_rvalid_i`` must also be set when a write was performed, although the ``data_rdata_i`` has no meaning in this case.
+
+:numref:`timing1`, :numref:`timing2` and :numref:`timing3` show example-timing diagrams of the protocol.
+
+.. figure:: images/timing1.png
+ :name: timing1
+
+ Basic Memory Transaction
+
+.. figure:: images/timing2.png
+ :name: timing2
+
+ Back-to-back Memory Transaction
+
+.. figure:: images/timing3.png
+ :name: timing3
+
+ Slow Response Memory Transaction
diff --git a/doc/make.bat b/doc/make.bat
new file mode 100644
index 00000000..efdcb3d8
--- /dev/null
+++ b/doc/make.bat
@@ -0,0 +1,36 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+set SPHINXPROJ=zero-riscy
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+
+:end
+popd
diff --git a/doc/performance_counters.rst b/doc/performance_counters.rst
new file mode 100644
index 00000000..347b438f
--- /dev/null
+++ b/doc/performance_counters.rst
@@ -0,0 +1,146 @@
+.. _performance-counters:
+
+Performance Counters
+====================
+
+Performance Counters in ZERO-RISCY are placed inside the Control and Status Registers and can be accessed with csrr and csrw instructions.
+
+
+Performance Counter Mode Register (PCMR)
+----------------------------------------
+
+CSR Address: ``0x7A1``
+
+Reset Value: ``0x0000_0003``
+
++-------+-----+------------------------------------------------------------------+
+| Bit# | R/W | Description |
++=======+=====+==================================================================+
+| 1 | R/W | **Global Enable:** Activate/deactivate all performance counters. |
+| | | If this bit is 0, all performance counters are disabled. After |
+| | | reset, this bit is set. |
++-------+-----+------------------------------------------------------------------+
+| 0 | R/W | **Saturation:** If this bit is set, saturating arithmetic is |
+| | | used in the performance counter counters. After reset, this bit |
+| | | is set. |
++-------+-----+------------------------------------------------------------------+
+
+
+Performance Counter Event Register (PCER)
+-----------------------------------------
+
+CSR Address: ``0x7A0``
+
+Reset Value: ``0x0000_0000``
+
++-------+-----+------------------------------------------------------------------+
+| Bit# | R/W | Description |
++=======+=====+==================================================================+
+| 16 | R/W | **TCDM_CONT** |
++-------+-----+------------------------------------------------------------------+
+| 15 | R/W | **ST_EXT_CYC** |
++-------+-----+------------------------------------------------------------------+
+| 14 | R/W | **LD_EXT_CYC** |
++-------+-----+------------------------------------------------------------------+
+| 13 | R/W | **ST_EXT** |
++-------+-----+------------------------------------------------------------------+
+| 12 | R/W | **LD_EXT** |
++-------+-----+------------------------------------------------------------------+
+| 11 | R/W | **DELAY_SLOT** |
++-------+-----+------------------------------------------------------------------+
+| 10 | R/W | **BRANCH** |
++-------+-----+------------------------------------------------------------------+
+| 9 | R/W | **JUMP** |
++-------+-----+------------------------------------------------------------------+
+| 8 | R/W | **ST** |
++-------+-----+------------------------------------------------------------------+
+| 7 | R/W | **LD** |
++-------+-----+------------------------------------------------------------------+
+| 6 | R/W | **WBRANCH_CYC** |
++-------+-----+------------------------------------------------------------------+
+| 5 | R/W | **WBRANCH** |
++-------+-----+------------------------------------------------------------------+
+| 4 | R/W | **IMISS** |
++-------+-----+------------------------------------------------------------------+
+| 3 | R/W | **RESERVED** |
++-------+-----+------------------------------------------------------------------+
+| 2 | R/W | **RESERVED** |
++-------+-----+------------------------------------------------------------------+
+| 1 | R/W | **INSTR** |
++-------+-----+------------------------------------------------------------------+
+| 0 | R/W | **CYCLES** |
++-------+-----+------------------------------------------------------------------+
+
+Each bit in the PCER register controls one performance counter. If the bit is 1, the counter is enabled and starts counting events. If it is 0, the counter is disabled and its value won’t change.
+
+In the ASIC there is only one counter register, thus all counter events are masked by PCER and ORed together, i.e. if one of the enabled event happens, the counter will be increased. If multiple non-masked events happen at the same time, the counter will only be increased by one.
+In order to be able to count separate events on the ASIC, the program can be executed in a loop with different events configured.
+
+In the FPGA or RTL simulation version, each event has its own counter and can be accessed separately.
+
+Performance Counter Counter Register (PCCR0-31)
+-----------------------------------------------
+
+CSR Address: ``0x780`` - ``0x79F``
+
+Reset Value: ``0x0000_0000``
+
+PCCR registers support both saturating and wrap-around arithmetic. This is controlled by the saturation bit in PCMR.
+
++----------+----------------+----------------------------------------------------------------+
+| Register | Name | Description |
++==========+================+================================================================+
+| PCCR0 | **CYCLES** | Counts the number of cycles the core was active (not sleeping) |
++----------+----------------+----------------------------------------------------------------+
+| PCCR1 | **INSTR** | Counts the number of instructions executed |
++----------+----------------+----------------------------------------------------------------+
+| PCCR2 | **-** | Reserved |
++----------+----------------+----------------------------------------------------------------+
+| PCCR3 | **-** | Reserved |
++----------+----------------+----------------------------------------------------------------+
+| PCCR4 | **IMISS** | Cycles waiting for instruction fetches, i.e. number of |
+| | | instructions wasted due to non-ideal caching |
++----------+----------------+----------------------------------------------------------------+
+| PCCR5 | **LD** | Number of data memory loads executed. Misaligned accesses are |
+| | | counted twice |
++----------+----------------+----------------------------------------------------------------+
+| PCCR6 | **ST** | Number of data memory stores executed. Misaligned accesses are |
+| | | counted twice |
++----------+----------------+----------------------------------------------------------------+
+| PCCR7 | **JUMP** | Number of unconditional jumps (j, jal, jr, jalr) |
++----------+----------------+----------------------------------------------------------------+
+| PCCR8 | **BRANCH** | Number of branches. Counts taken and not taken branches |
++----------+----------------+----------------------------------------------------------------+
+| PCCR9 | **BTAKEN** | Number of taken branches. |
++----------+----------------+----------------------------------------------------------------+
+| PCCR10 | **RVC** | Number of compressed instructions executed |
++----------+----------------+----------------------------------------------------------------+
+| PCCR11 | **LD_EXT** | Number of memory loads to EXT executed. Misaligned accesses |
+| | | are counted twice. Every non-TCDM access is considered |
+| | | external (PULP only) |
++----------+----------------+----------------------------------------------------------------+
+| PCCR12 | **ST_EXT** | Number of memory stores to EXT executed. Misaligned accesses |
+| | | are counted twice. Every non-TCDM access is considered |
+| | | external (PULP only) |
++----------+----------------+----------------------------------------------------------------+
+| PCCR13 | **LD_EXT_CYC** | Cycles used for memory loads to EXT. Every non-TCDM access is |
+| | | considered external (PULP only) |
++----------+----------------+----------------------------------------------------------------+
+| PCCR14 | **ST_EXT_CYC** | Cycles used for memory stores to EXT. Every non-TCDM access is |
+| | | considered external (PULP only) |
++----------+----------------+----------------------------------------------------------------+
+| PCCR15 | **TCDM_CONT** | Cycles wasted due to TCDM/log-interconnect contention |
+| | | (PULP only) |
++----------+----------------+----------------------------------------------------------------+
+| PCCR31 | **ALL** | Special Register, a write to this register will set all |
+| | | counters to the supplied value |
++----------+----------------+----------------------------------------------------------------+
+
+In the FPGA, RTL simulation and Virtual-Platform there are individual counters for each event type, i.e. PCCR0-30 each represent a separate register. To save area in the ASIC, there is only one counter and one counter register. Accessing PCCR0-30 will access the same counter register in the ASIC. Reading/writing from/to PCCR31 in the ASIC will access the same register as PCCR0-30.
+
+:numref:`pcer` shows how events are first masked with the PCER register and then ORed together to increase the one performance counter PCCR.
+
+.. figure:: images/pcer.png
+ :name: pcer
+
+ Events and PCCR, PCMR and PCER on the ASIC.
diff --git a/doc/register_file.rst b/doc/register_file.rst
new file mode 100644
index 00000000..98466257
--- /dev/null
+++ b/doc/register_file.rst
@@ -0,0 +1,25 @@
+.. _register-file:
+
+Register File
+=============
+
+ZERO-RISCY has 31 or 15 32-bit wide registers depending if the RV32E extension is enabled. Register x0 is statically bound to 0 and can only be read, it does not contain any sequential logic.
+
+There are two flavors of register file available:
+
+1. Latch-based
+2. Flip-flop based
+
+While the latch-based register file is recommended for ASICs, the flip-flop based register file is recommended for FPGA synthesis, although both are compatible with either synthesis target. Note the flip-flop based register file is significantly larger than the latch-based register-file for an ASIC implementation.
+
+Latch-based Register File
+-------------------------
+
+The latch based register file contains manually instantiated clock gating cells to keep the clock inactive when the latches are not written.
+
+It is assumed that there is a clock gating cell for the target technology that is wrapped in a module called ``cluster_clock_gating`` and has the following ports:
+
+* ``clk_i``: Clock Input
+* ``en_i``: Clock Enable Input
+* ``test_en_i``: Test Enable Input (activates the clock even though en_i is not set)
+* ``clk_o``: Gated Clock Output
diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 00000000..a0700776
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1,3 @@
+setuptools_scm
+sphinx
+sphinx_rtd_theme
diff --git a/doc/user_manual.doc b/doc/user_manual.doc
deleted file mode 100755
index 3e588173..00000000
Binary files a/doc/user_manual.doc and /dev/null differ