Logic Analyzer core: Background
From DP
Background
A little background to help put things in context...
FPGA's
The FPGA (field programmable gate array) is very useful for creating custom hardware. They can implement anything from simple logic up to entire computers. To accomplish this, an fpga contains large numbers of tiny lookup tables and flip-flops as building blocks, plus usually some larger memories (SRAM’s).
Add some I/O pins for talking to the outside world, plus lots of configurable wires to connect everything, and you have an FPGA.
The lookup tables are the interesting piece, and store only 16 bits of data. They have four inputs (the address), an output, and some config pins. Normally they are configured to form logic. Any four-input function can squeeze in there.
For example, a four input AND gate. Load LUT addresses 0 to 14 with all zeros, and set address 15 to one. Now if all inputs are set, you get a one on output -- otherwise zero. Just like an AND gate
In the case of a logic analyzer, even more useful functions are possible. For example, a trigger search on four bits of sampled data. The LUT allows easy matching of any pattern.
LUT's are normally programmed serially when the FPGA powers up. Think shift register. However, they can also be selectively changed during runtime.
The Datapath
The Logic Sniffer is composed of several main blocks. Most are concerned with the data path (see right). In the drawing thin lines are control signals. Thick lines are the data path.
The “sync module” captures input data using the sample clock. The sample clock can either be the internal 100Mhz reference clock, or supplied from an external source.
The “async fifo” transfers the captured input to the rest of the fpga. If the sample clock & internal reference clock are totally unrelated, the fifo avoids timing problems.
The “sampler module” is what implements the “sampling rate”. Assume the sample clock is using the 100Mhz reference. If you want a 10Mhz sample rate, the sampler forwards every tenth valid capture. For 1Mhz, every hundredth valid capture, etc…
The “triggers” look for patterns. They control what ultimately gets stored in SRAM -- with the “capture” signals -- and tell the controller when a trigger hit occurs. The basic trigger captures everything always. The advanced trigger lets you be more selective.
The “delay fifo” aligns its output to the capture/run trigger outputs. The trigger modules take a few clocks to evaluate things. For a trigger “capture” to work, the input to the next state must match.
The “data align” module removes gaps within the input data caused by disabled groups. If you decide to disable groups 0 & 2, the aligner shifts the remaining groups down to fill the gap. This simplifies things later.
The “RLE encoder” looks for repeat captures. If found, counts are stored instead of repeats of unchanging data. This can greatly increase the effective storage capacity.
The “controller” is what decides how much gets captured, and when to send results to the client on your PC.
The “SRAM interface” handles saving & fetching captured data to & from the SRAM memory.
The “SPI interface” uploads the captures serially to the client. Only valid data is sent. Gaps due to disabled groups are filtered out.
A few remaining blocks aren’t shown here. The inbound SPI interface for receiving commands, the command decoder & flags register.
