3.07 KB
Newer Older
Christian Klarhorst's avatar
Christian Klarhorst committed
# Bus Monitor Component for LiteX

The litebusmonitor component enables supervision on a SoCs Bus, for purposes of recoding accesses, detecting anomalies and analyzing a chips behaviour. 
The component is distrbuted into smaller LiteX-Modules:

* _MonitorSender_: Receives the bus(masters) as a parameter. Those are supervised and the output is buffered. The modules source member exposes a litex-stream like interface, with ready, valid and data signals. The data queues data gets concatted into a long string and split into 32-bit words and output to the source member
* _MonitorReceiver_: This modules is connected to the MonitorSender (either directly per SoC defintion, or per external port, etc.). It appends a DMA (direct memory access) and it's master to the SoCs chip / bus and is capable of writing the data. When the data has filled >50% of the DMA allocated space, an interrupt is triggered, and the module stops writing data. It is programmed to stop in the right cycle, in order to preserve entries in memory (since the data is simply one long bit-string, it could potentially be cut in the wrong spot, rendering the decoded data from the resumed next cycle useless). The software (BIOS) now has the responsibility to clear the interrupt and consume the data written (by moving it onto a harddisk, analyzing it, sending it over network, etc.). As soon as the interrupt is cleared, the DMA resets its internal offset and continues data writing.
* _MonitorDetector_

There are two modes of operation for the combination. Either the software (in most cases the BIOS) explicitly allocates a block of memory and sends the starting address pointer to the DMA, allowing it so start writing. The advantage is that at any point the address can be changed and the space be as big as needed.
However this bears the risk of loosing out on data: In case the buffer is filled more quickly than the data can be read (and thus the buffer cleared), bus access entries get discarded because the buffer is full. This happens when the software has to assign the address to write to to the DMA, because at that point the amount of instructions is already far larger than the buffer has space. One possible fix, which works for large chips is to simply increase the buffer size. However in smaller devices this is not possible and thus there is a second solution: When inintializing the MonitorReceiver, you can pass it the address and length to write to, if this is known at build time. As a result, when the SoC gets started, the software does not have to wait and initialize memory itself, but can start writing as soon as the buffer is filled. And because it can be emptied from the first moment and the write-out is fast enough, there are no dropped entries anymore.

## Building
Bjarne Wintermann's avatar
Bjarne Wintermann committed
py basys3 --build --l2-size 0 --integrated-main-ram-size 41384 --integrated-rom-size=64000 --integrated-sram-size=11000 --uart-baudrate 1000000
Bjarne Wintermann's avatar
Bjarne Wintermann committed

## Decoding
py --blocks 20
The decoder waits for the string: SOC_START. This is sent directly after resetting the board.
It writes the output to the terminal and to the build_data directory.