doc: add lxsocdoc.md (README from lxsocdoc repository)
authorSean Cross <sean@xobs.io>
Wed, 5 Feb 2020 10:05:04 +0000 (11:05 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 5 Feb 2020 10:06:57 +0000 (11:06 +0100)
doc/lxsocdoc.md [new file with mode: 0644]

diff --git a/doc/lxsocdoc.md b/doc/lxsocdoc.md
new file mode 100644 (file)
index 0000000..b61e5b8
--- /dev/null
@@ -0,0 +1,147 @@
+# lxsocdoc: Document your LiteX SoC Automatically
+
+`lxsocdoc` lets you take a synthesized LiteX SoC and generate full
+register-level documentation.  Additionally, it will generate `.svd` files,
+suitable for use with various header generation programs.
+
+## Required Software
+
+You must have `sphinx` and `sphinx.wavedrom` installed in order to build
+the documentation.  These can be installed with pip:
+
+```
+$ pip3 install sphinxcontrib-wavedrom sphinx
+```
+
+## Usage
+
+To use `lxsocdoc`, import the module and call `lxsocdoc.generate_docs(soc, path)`.
+You can also generate an SVD file.  For example:
+
+```python
+import lxsocdoc
+
+...
+    soc = BaseSoC(platform)
+    builder = Builder(soc)
+    vns = builder.build()
+    soc.do_exit(vns)
+    lxsocdoc.generate_docs(soc, "build/documentation")
+    lxsocdoc.generate_svd(soc, "build/software")
+```
+
+After you build your design, you will have a Sphinx documentation source available
+in the above directory.  To build this into a target document, use `sphinx-build`.
+
+For example, if `sphinx-build` is in your path, you can run:
+
+`sphinx-build -M html build/documentation/ build/documentation/_build`
+
+`sphinx-build` may be located in `~/.local/bin/` depending on your installation environment.
+
+You can then verify the contents by starting a local webserver and opening a web
+browser to [localhost:8000](http://localhost:8000):
+
+`python3 -m http.server --directory build/documentation/_build/html`
+
+## Documenting your Registers
+
+You can add documentation to your registers by defining your `CSRStorage` and `CSRStatus` registers with an additional `field` list.  For example:
+
+```python
+self.bitbang = CSRStorage(4, fields=[
+    CSRField("mosi", description="Output value for MOSI..."
+    CSRField("clk", description="Output value for SPI CLK..."
+    CSRField("cs_n", description="Output value for SPI C..."
+    CSRField("dir", description="Sets the dir...", values=[
+        ("0", "OUT", "SPI pins are all output"),
+        ("1", "IN", "SPI pins are all input"),
+    ])
+], description="""Bitbang controls for SPI output.  Only
+    standard 1x SPI is supported, and as a result all
+    four wires are ganged together.  This means that it
+    is only possible to perform half-duplex operations,
+    using this SPI core.""")
+```
+
+There are several interesting properties here:
+
+* The first argument to a `CSRStorage` or `CSRStatus` is the bit width.
+* You can pass a list of `CSRField` objects, which will get turned into bit fields
+* Both `CSRStorage` and `CSRStatus` support a freeform `description` property that will be used to describe the overall register.
+
+A `CSRField` object has the following properties:
+
+* `name`: The short name of the register.  This should be just a few characters long, as it will be used in the register diagram as well as accessor objects.  **Required**
+* `size`: The size of this field.  This is optional, and defaults to `1`
+* `offset`: The offset of this particular field.  If unspecified, defaults to following the previous field.  Use this to add gaps to your register definitions, for example to have reserved fields.
+* `reset`: If specified, the value of this field at reset.  Defaults to `0`.
+* `description`: A textual description of this register.  This is optional, but should be specified because it provides critical information to the user about what this field does.
+* `pulse`: If `True`, then this value is `1` only for one clock cycle after the user writes a `1` to this field.  This is especially useful for `START` bits used to initiate operations, or `RESET` bits used to clear an operation.
+* `access`: The accessibility of this field.  One of `CSRAccess.ReadWrite`, `CSRAccess.WriteOnly`, or `CSRAccess.ReadOnly`
+* `values`: If present, a list of tuples of values.  The first field is the numeric value, with `x` for `don't care`.  The second field, if present, is the short name of the value.  The final field is a textual description of the value.  For example:
+
+```python
+    [
+        ("0b0000", "disable the timer"),
+        ("0b0001", "slow", "slow timer"),
+        ("0b1xxx", "fast timer"),
+    ]
+```
+
+## Further Module Documentation
+
+You can add additional documentation to your module with the `ModuleDoc` class.  Add it to your base object.
+
+**To use further Module Documentation, your Module must inherit from `AutoDoc`**.  For example:
+
+```python
+from litex.soc.integration.doc import AutoDoc, ModuleDoc
+class DocExample(Module, AutoCSR, AutoDoc):
+    def __init__(self):
+        self.mydoc = ModuleDoc("Some documentation")
+```
+
+You may pass a single string to the constructor, in which case the first line becomes the title, or you may pass a separate `title` and `body` parameters to the constructor.  For example:
+
+```python
+    self.intro = ModuleDoc("""Introduce ModuleDoc
+
+    This is an example of how to document using ModuleDoc.  An additional
+    section will get added to the output documentation for this module,
+    with the title ``Introduce ModuleDoc`` and with this paragraph
+    as a body""")
+```
+
+Note that the default documentatino format is `rst`. You can switch to markdown by passing `format="markdown"` to the constructor, however support is not very good.
+
+### External Documentation
+
+You can have external documentation by passing `file` to the constructor.
+For example:
+
+```python
+    self.extra_doc = ModuleDoc(file="extra_doc.rst")
+```
+
+This will be included at build-time.
+
+### Using Python Docstrings
+
+You can also simply have your module inherit from `ModuleDoc`, in which case
+the documentation will be taken from the docstring.  For example:
+
+```python
+from litex.soc.integration.doc import AutoDoc, ModuleDoc
+class DocExample(Module, AutoCSR, AutoDoc, ModuleDoc):
+    """
+    Automatically Documented Module
+
+    This module will be automatically documented, and included in the
+    generated module documentation output.  You can add additional
+    ModuleDoc objects to this module, in order to add further subsections
+    to the output docs.
+    """
+    def __init__(self):
+        pass
+```