index: first full-ish draft

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
Sean Cross 2020-01-02 14:35:00 +08:00
parent 369bc564a9
commit 6f8dcb1827

View File

@ -109,8 +109,16 @@
projects, but the concepts will carry over into any other Hardware Description
Language you may use.
Common approaches today involve comments in the HDL and/or C header files. This
works, but we can do better. We just need to describe the hardware better.
I'll briefly cover various methods of writing HDL code, then cover the rationale
behind the approach we take with lxsocdoc, then give an example of how to use
lxsocdoc and how you might apply it to your language. Finally, I'll cover the
implications of having documented hardware and how this will help you pay it forward.
Verilog and VHDL are kind of the C or assembly of the FPGA world. They're universal,
but somewhat unwieldy to use. You need to manually set up your address decoders,
and documentation is very free-form. Common approaches today involve comments in
the HDL and/or C header files. This works, but we can do better. We just need to
describe the hardware better.
```//Hardware definitions of the SoC. Also is the main repo of documentation for the
//programmer-centric view of the hardware.```
@ -118,11 +126,13 @@
written in Python. You write Python code and run the program, and it generates
a design file -- either Verilog code, or a Yosys netlist. There are many other
alternatives such as SpinalHDL or Chisel. By writing in Python as opposed to
direct Verilog, we get a lot of nice primitives.
direct Verilog, we get a lot of nice primitives. The examples from this talk
are taken from lxsocdoc and LiteX, but most higher-level hardware description
languages can take similar approaches to documentation.
CSRStorage and CSRStatus are two such primitives. These enable trivial access to
a hardware device from a CPU softcore. Instead of manually wiring up a crossbar
and decoding the addresses ourselves, we just need to write `self.regname = CSRStatus(8)`,
In LiteX, two of the primitives used to expose hardware registers to the CPU softcore
are CSRStorage and CSRStatus. Instead of manually wiring up a crossbar and decoding
the addresses ourselves, we just need to write `self.regname = CSRStatus(8)`,
and the build system will wire up 8 bits of read-only memory to the target CPU.
Similarly, `self.othername = CSRStorage(8)` will give 8-bits of write-only memory.
@ -146,9 +156,16 @@
work through it. I started by creating aliases for the various elements
in the storage array, but then I thought: There has to be a better way!
As an aside, Python has something called Pydoc and Docstrings. These are
comments that go at the top of functions and classes that let you describe
what a Python object is and how to use it. This is almost what we want,
except once the final SoC is generated we don't really care so much about
things like constructor arguments or method properties. Documentation for
the end user is different from documentation for the module developer.
This is when I hit upon the idea of `lxsocdoc`. The basic idea is that
Python is really good at introspecting Python, so let's add a little bit
more information to the CSR objects to make our life easier. So after
more information to the CSR objects to make our life easier. And so, after
working with the LiteX creator Florent, we refactored the bitbang
definition to this:
@ -201,7 +218,25 @@
So now we have register documentation. Can we do better? Of course we can.
SoC reference manuals are more than just register definitions. They also include
background information on protocols, as well as more elaboration on how the block
works.
works. We can take a cue from CSRs themselves, and add module documentation
in a similar fashion.
---ModuleDoc---
Having documentation for humans is great, but we can go one step further and
make documentation for computers. SVD is an XML format defined by ARM that
defines various aspects about a chip, including memory layout, interrupt map,
and register sets. SVD includes information such as default values and field
bits, all information we have thanks to the introspectability of Python.
In addition to generating a reference manual for humans, we can generate an SVD
file that's usable in a wide variety of areas. For example, we can turn an SVD
file into a Rust Peripheral Access Crate (PAC) using `SVD2Rust`, giving us an
easy way to safely access all peripherals on a device.
We can also import this SVD file into an emulator such as Renode, which will
print out fields and flags that get accessed, giving us greater visibility into
what a program is doing.
lxsocdoc
intro to litex/migen