gateware: start some design documentation and clarify some design

decisions
This commit is contained in:
David Lenfesty 2023-01-22 20:15:48 -07:00
parent 883b712a53
commit 446db81464
5 changed files with 159 additions and 30 deletions

View File

@ -25,38 +25,10 @@ hardware/ - Directory for any hardware designs
## System Architecture ## System Architecture
<!-- made with asciiflow.com -->
```
┌─────────────┐
│Main Computer│
└─────▲───────┘
┌─────┴──────┐
│Ethernet PHY│
│ ▲ │ Interface Board (x4)
│ │ │ ┌──────────────────────────────┐
│ │ │ │ │ ┌─────────────┐
│ │ │◄──────┤ LVDS Serializer◄─────────ADC │◄───────────┤ Hydrophones │
│ │ │ │ │ └─────────────┘
│ │ │ └──────────────────────────────┘
│ FPGA │
└─────▲──────┘
│ Dev Board
│ or
│ Custom Board
┌──┴───────────────────┐
│ Peak Detector Board │
└──────────────────────┘
(Temporary)
```
## RTL Architecture ## RTL Architecture
General SoC architecture and other similar goodies can be found in `gateware/docs`.
#### Diagram TODO #### Diagram TODO
The plan is to use LiteX and let it do most of the heavy lifting. Components to The plan is to use LiteX and let it do most of the heavy lifting. Components to

View File

@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2023-01-23T01:43:30.735Z" agent="5.0 (X11)" version="20.6.0" etag="-pxXWxeQ9u3il_htgTSB" type="device"><diagram id="VyJ7w-6roeHasMnRayvs" name="Page-1">7VlNc5swEP01nmkPzghhCD7GH2mSSaaZup00p45sZFAHkEcIf+TQ397FCIOMSZ3aLm6nJ6PHaln27ZNWuGX2w+UHQWb+A3dp0MLIXbbMQQtjjCwHflJklSEG6l5miCeYq7ACGLEXmhsqNGEujTVDyXkg2UwHJzyK6ERqGBGCL3SzKQ/0p86IRyvAaEKCKvrEXOlnqGOhAr+hzPPzJxtI3QlJbqyA2CcuX5Qgc9gy+4JzmV2Fyz4N0uzlecnmXdfc3QQmaCT3mfD05fZusBh9/jYeTsfmg3P3cjNud1RscpW/MHXh/dWQC+lzj0ckGBZoT/AkcmnqFcGosLnnfAagAeB3KuVKkUkSyQHyZRiouxCwWH0tD55TZxdWPhwslfNstFKjLNY0wNoUKCjmiZjQV947LyUiPCpfsXM2REGJUx5SiAfmCRoQyeZ6HESVmrex20x95AwixEjpomOqmlCqsDpId5HFpWYVnF4JQVYls1lqEJct4KIUaAGta+ENdWFl8cxJkKiXHBBJAHlkUbyzZu7JGLSv8UwC5kVwPQF6qABgToVkoK0rdSNkrpuVFI3ZCxmv/aVMqxcD51avZQ023KcO6HKX8NXkQm7lqqgv/Sq1ynsbXZiWRlIbZ8MDuW8bulusO+DTaUzlKSg1jAqnI0lkEr/G6v+VYGOHdtfL28qhXsG7q8Xu6CuFidBWbWQej1splUK5GnQxMisVovO/8JmkoxlZp3sB/YDOda2CK6zVitKy9Wx08i5hUWzNRm7jl7ZljFA9MZrQ3pqry0ZlU1LKc/ne6WVj7ikb+0DVHESOWSnkFrYDCLfnsjlceulln4lJEhABhte31x9zC3hgyWjHvHc/cJiunXya5ouEs4DG73O7sdieue2vYSkZeKsF2SUlvENK9qmUZDTSix5REvaekug2KYm8+2hqwWpsn9+XnYP3+YPo2RwW/2oRHP3AtLVYmc5+56VjNUS42hE90JCv36yX/CPnIVxT+KUDkUZC3ib+LrWnP/HYFdaeWOyPeUQBvU05mKY77LltxabV+FbsNLpJNHcYdPbcJMwm9winUtajtPtkkQdon0NueNB4UWPn7PrL6mkAkjVl3jl8/4DVFSFbr3sT/ary16NHKhhkKN1Qji2H7r49U5NyMBo5gjeQ5UO/RR+U5W69eD5Rj8VQf1UF/fFFp3t2OymqLtb5R9fzzRu+PF3eYFj855V1esVfh+bwJw==</diagram></mxfile>

View File

@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2023-01-23T01:37:08.635Z" agent="5.0 (X11)" version="20.6.0" etag="8UEYG30flHjFS4qFvnlN" type="device"><diagram id="V4E715ksNNUp7eaEs-qw" name="Page-1">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</diagram></mxfile>

View File

@ -0,0 +1,29 @@
# Memory Description and Overview
Unfortunately, the ECP5-45k doesn't have a particularly large amount of memory,
so we may need to get fancy if we want decent performance.
We only have 108 19kbit EBRs. In order to sample at full rate, we need enough memory to hold all 2ms
of our sample data. The maximum configuration we can do, while actually having reasoable resources left
over for the rest of the design, is 20MHz @ 9bits/sample, which would take 20EBR blocks per channel.
(40,000 samples, 20 EBRs gives us max 40,960 samples). This would leave us 28 EBR blocks,
or approximately 48KiB of EBR left. Most of this will likely need to be used for cache and other
resources in LiteETH and LiteDRAM.
Generating an example LiteX config with LiteETH and LiteDRAM uses 53 (!!!) EBRs.
LiteETH uses 10
LiteDRAM uses 18
Looks like I'm going to have to back down to 10MHz @ 9bits. Unfortunate, but whatever.
This leaves me with 68 EBRs to play with. I need 10 for LiteETH, so 58 for
system memory and other usages. This may be able to fit the firmware. The
actual amount of business logic I need to fit there is surprisingly small. If it
can't, I may need to add a LiteDRAM instance, add some CPU icache and dcache,
add some DMA and a SPI flash controller to copy the code into DRAM. This will
come at the cost of some performance, and be extra work, but if I have to I have
to.
Everything will just live on a unified memory bus. I'll have one arbiter
handling all initiators and one decoder splitting up the address space.

View File

@ -0,0 +1,126 @@
# Sampling Module Design Datasheet
TODO this should be generated by the gateware build infrastructure
TODO there is also potential to make samples 9 bits, which would take the same
number of EBR resources as 8 bits, it would make the packets larger, but I don't
think that's a major concern. I am thinking we should do 9 bits. It won't slow
down any of our operations, as it goes from byte sized loads to half word loads,
which are all single instructions anyways
## Operation
When the ADCs are enabled (via CCR->ENABLE), then the data FIFOs are
continuously updated with incoming samples. The user can start (CCR->START)
a new capture, which primes the block to save the appropriate samples.
A capture does not happen until it is triggered, which can be done either
automatically (iff CCR->AUTO_TRG_EN is set to 1), or via manual software trigger
(via CCR->TRIGGER). The samples are configured with 2 parameters: CAP_OFFSET, and CAP_LEN.
CAP_OFFSET determines how many samples prior to the trigger will be saved, and CAP_LEN
determines the total number of samples to save.
The sample received on the clock that the trigger will be the (0-indexed) CAP_OFFSET'th sample
in the total capture. (TODO better description for that)
*Note: a capture can not be triggered unless the SR->READY flag is set. The READY
flag is set by the following logic: `CCR->ENABLE && CCR->START && samples_saved >= CACHED_CAP_OFFSET`.*
### Automatic Triggering and Peak Detection
Each acquisition unit has its own peak detector in. This measures the difference
between the maximum and minimum values read within 3/4 of a cycle. The time of a
cycle is determined by the frequency set via CCR->FREQ. This value can be read
via PP_VALUE_X (X being the ADC number).
This value can be manually read by software for each channel to do gain
adjustments or peak detection in software if wanted, however this value can also
be used to trigger automatically. The automatic trigger occurs as soon as this value
is greater than or equal to the value set in CCR->PP_THRESH.
### Interrupts
An external interrupt will be sent to the CPU by this module for both the
trigger event and the acquisition complete event. It will be two different
lines, maskable by the RISCV mie CSR. TBD is how to reset them or if that needs
to happen or whatever.
## Registers
32 bits unless specified otherwise. Fields not specified will always read 0 and writes will do nothing
Shared across all acquisition blocks, except for PP_VALUE_X, and DATA_X which both have one register per ADC.
### CCR (R/W)
Configuration and Control Register
Default value: 0 for all fields
| Field | Bit Width | Description |
|----------------|-----------|-------------|
| ENABLE | 1 | Enables/Disables the ADC itself. Also starts pulling data into FIFO |
| START | 1 | Set this bit to prime a capture. Locks in all offset and frequency settings (sets when not enabled and ready will do nothing, sets with an ongoing trigger re-load new settings, start trigger anew, clear to stop capture), value when read will be if a trigger is active |
| TRIGGER | 1 | Manually trigger a capture. Will always read 0 |
| AUTO_TRG_EN | 1 | Enables
| FREQ | 2 | Sets the frequency the ping detector submodule uses. (See FREQ_ENUM) |
| PP_THRESH | 10 | Full scale peak to peak threshold to auto trigger a capture. |
FREQ_ENUM:
- 0b00: 25kHz
- 0b01: 30kHz
- 0b10: 35kHz
- 0b11: 40kHz
### SR (R/O)
Status Register
This will have 4 sets of fields of status bits, one per ADC
| Field | Bit Width | Description |
|----------------|-----------|-------------|
| READY | 1 | FIFO has acquired enough samples to hold requested history. |
| TRIGGERED | 1 | Capture has been triggered. Cleared on next START |
| COMPLETE | 1 | Capture is finished, cleared on next START |
| TBD status bits| TBD | Any status lines we get from the ADC will be exported here |
### CAP_OFFSET
32-bit field that determines how many samples to acquire from before the trigger. Must be < CAP_LEN - 10
(max value enforced by hardware)
### CAP_LEN
32-bit field that determines how many samples total to acquire for the whole trigger. Must be < size of FIFO
(max size enforced by hardware)
### PP_VALUE_X
One register per acquisition block
10-bit field with the highest measured peak-to-peak values
Write anything to reset to 0
Gets reset to 0 when a new capture is started (note: not when it is triggered)
### DATA_X
8-bit register (otherwise just 0s), returns the top 8 bits of each sample.
(maybe not the top, depending on scale/range, but that can be changed later).
All other bits are 0.
Reading this register before a trigger occurs is invalid.
Reading a byte consumes the byte from the FIFO, user is expected to track the correct
number of bytes to read, reading over the end of the FIFO is invalid.
All invalid reads return 0. (Real data should never be 0, so this is a good indicator.)
## Interrupts
Since all of these should have the same timing offsets, these interrupts are common to all acquisition blocks.
Trigger
Capture complete