I was able to spend some more time on the FPGA code, but not as much as I hoped for. This time my focus was on the host interface (SPI, UART) and the related protocol.
The current protocol is based on the SUMP project and was extended for the LogicSniffer project (most additions were probably for triggers, there is also a verbose response regarding the version of the hardware). I found issues in the protocol, which affect generalization and portability. The three major issues are:
1. protocol commands (codes) are not organized hierarchically
2. sample data is read from the memory in reverse order
3. the RTL implementation is not separated into layers
The issues are described in details below.
I will still try to implement the UART host interface with the current protocol, some discussion is needed before any protocol changes could be made.
1. command hierarchy
By far the most common way to configure a block of hardware (as part of a larger system), is to connect it to a CPU accessible system bus (Wishbone, AMBA APB, Avalon MM, ...). This way, hardware components are organized into a memory mapped address space, composed of registers and fields inside registers. The CPU can configure a component by writing to registers, usually some data can also be read from this registers. So a system bus usually has a read/write signal, an address, and read/write data. This is how an SoC is made.
If there is the need to configure the same hardware not using the CPU, but over an external bus (I2C, SPI, JTAG, ..., rarely UART), an interface adapter is usually used connecting the external bus as a master on the system bus. Some level of transparency can be achieved, so the HOST CPU will see the hardware as memory mapped although there is a serial protocol in between.
Memory mapped peripherals are extensible, as long as the address space is large enough to allow adding new registers or entire peripherals (new or multiple existing). The address space is usually hierarchical, using the same hierarchy as is visible in the block diagram for a hardware component. This hierarchy is important to reduce the number of address bits to be decoded at each level.
The SUMP protocol is lacking a hierarchy of commands. This means, it is difficult to add hardware (new trigger modes, hardware protocol decoders, FFT for analog signals, ...) without changes to the protocol.
It would make sense to have a protocol with a few basic commands (software reset, ...), streaming commands (sequential access without repeated address) and everything else would be a command providing a read/write bit and an address (for SPI the serial Flash protocol might be used as an example).
By organizing configuration registers into a memory map, it would also be possible to directly connect the logic analyzer directly to the CPU as a SoC inside the FPGA.
2. data read order
As mentioned before the data written into the RAM is read out in the reversed order, from the last to the first sample. It is not totally clear to me if this is really necessary, but it seems the original author thought it would be easier to read the data from the last written address compared to calculating the start address. This is an issue for hardware with SDRAM or DDR buffers, since burst access to SDRAM requires increasing addresses. Not really a big issue, since most serial host interfaces are slow compared even to random access to SDRAM.
Reading data in reverse order is probably also causing problems with the driver which must reorder the data. So I think it would make sense to change this.
3. protocol layers
The current RTL implementation does not offer separation between protocol layers. The physical and data link layer (SPI, UART, JTAG, I2C, USB, FX2 FIFO) should be separated from higher network and transport layers (protocol commands). The main issue here is, it is difficult to change the physical layer without rewriting the code handling higher layers.
I already started writing (not finished yet) this separation for the UART protocol:
- rtl/uart.v rtl/uart_tx.v rtl/uart_rx.v implement the physical layer, there is no data link layer for UART (this is a point to point protocol)
- rtl/ctrl.v implements the higher layers by decoding the command structure and sending commands (configuration writes) to deeper modules