Skip to content

Commit e553723

Browse files
committed
doc: document design.
1 parent e892e54 commit e553723

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

documentation/design.md

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# μHAL Design
2+
3+
A [primer on the hardware](hardware.md) with which this project interfaces
4+
should be useful in understanding the design choices made.
5+
6+
## Low level interface
7+
8+
The low level interface consists simply of a `struct pcie_bars` object, which
9+
allows its user to read and write from BARs 2 and 4 (`BAR0` is considered an
10+
implementation detail) using the functions defined in `util/pcie.h`.
11+
12+
`BAR4` can also be accessed when `struct pcie_bars` points to a serial port,
13+
which is used when debugging boards outside of a μTCA crate. The serial port
14+
doesn't allow access to `BAR2`, though.
15+
16+
All other functionality of this project depends on this low level interface.
17+
18+
## Basic abstractions
19+
20+
### SDB access
21+
22+
SDB access is provided by the functions in `util/util_sdb.h`. These functions
23+
are higher level abstractions on top of the `libsdbfs` project.
24+
25+
Unlike HALCS, which iterated through the SBD and launched a handler for each
26+
core it found, the only function in this library which iterates over the SDB is
27+
the one which prints its contents. For any other use, users of the library will
28+
search for specific cores (with their index in depth-first traversal) with
29+
`read_sdb()`. In order to know which cores should be available in a given
30+
board, users should consult the build information provided by
31+
`get_synthesis_info()`.
32+
33+
While this implementation might seem less flexible at first, it's impossible to
34+
escape from the need to know what cores are available when using this library
35+
on an IOC: records for them must be instantiated and have the proper names.
36+
Therefore, this isn't adding any new limitations to an IOC.
37+
38+
### FPGA core access
39+
40+
For the most part, acess to each FPGA core is split into two classes under the
41+
core's namespace (e.g. `afc_timing`): one is the "decoder", `afc_timing::Core`,
42+
the other is the "controller", `afc_timing::Controller`. Usually, the decoder
43+
implements read-only access, while the controller has to be read-write.
44+
45+
The base classes involved in this are `class RegisterDecoderBase`, `class
46+
RegisterDecoder`, `class RegisterController` and `class
47+
RegisterDecoderController`. The implementation for each core is under the
48+
`modules/` directory.
49+
50+
#### Register maps
51+
52+
The register map for each module is encoded as a C struct, which is provided by
53+
the header generated by `cheby`. Headers generated by `wbgen2` don't include a
54+
C struct, so it is necessary to define this struct ourselves.
55+
56+
These register fields are decoded using bitmasks — and only bitmasks, we don't
57+
use shift macros and instead obtain the shift directly from the mask, in order
58+
to simplify boilerplate code and avoid mismatches — provided by the generated
59+
headers, using the functions from `util/util-bits.h`.
60+
61+
#### RegisterController and RegisterDecoderController
62+
63+
Before `class RegisterDecoderController` was created, controllers were mostly
64+
developed manually, duplicating the correspondence between the register fields
65+
we are interested in and their location in the register map, the mask used to
66+
obtain them, and how to interpret their data. This also made it necessary for
67+
library users to address fields differently when reading or writing them.
68+
69+
`class RegisterDecoderController` removes this need, requiring only a small
70+
amount of boilerplate to expose writing into register fields under a common
71+
interface.
72+
73+
#### Unconventional controllers
74+
75+
Some FPGA cores couldn't be implemented simply by decoding and encoding
76+
register fields. Some of them are listed here:
77+
78+
- `acq::Controller`
79+
- `ad9510::Controller`
80+
- `si57x_ctrl::Controller`

0 commit comments

Comments
 (0)