Logic Analyzer core: Background
A little background to help put things in context...
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).
Figure 2 - Logic Block
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.
Figure 3 - FPGA Layout
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
Figure 4 - AND gate equivalent
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.
2.2 The Datapath
Figure 5 - Datapath Diagram
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 clockThe 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.
2.3 The SUMP Protocol
The SUMP communication protocol assumes a standard RS232 port connection. Although the Logic Sniffer is USB based it emulates a very fast serial port from the perspective of the PC.
When sending captured data the analyzer sends back a contiguous block of data. Disabled channels are not sent however. First byte sent corresponds to sampled bits 7:0 (assuming channel 0 isn't disabled).
The following list documents the commands understood by the Logic Sniffer FPGA.
Short Commands (one byte commands)
0x00 - Reset
Reset the analyzer. Send at least five times to ensure FPGA in a known state. Clears any previous long commands that might have gotten stuck.
0x01 - Arm Basic/Legacy Trigger
Arm the basic trigger. Sampling begins immediately. Once the trigger fires, the controller waits for "delay count" additional samples before returning captured data to client.
0x02 - Query ID
The device responds with four bytes. Currently "SLA1" to maintain backwards compatible SUMP protocol, output LSB first. ie: "1", "A", "L", "S"
0x04 - Query Meta Data
The device responds with a variable length block of data composed of one or more tokens + associated data.
• Token 0 denotes end of meta data • Tokens 0x01 to 0x1F are followed by a null terminated string (UTF-8 encoded). • Tokens 0x20 to 0x3F are followed by a 32-bit unsigned integer (MSB first). • Tokens 0x40 to 0x5F are followed by a 8-bit unsigned integer. • All other token ranges are reserved.
The following fields are currently defined:
Token Description FPGA Currently Returns 0x00 End of Meta Data 0 0x01 Device Name "Open Logic Sniffer v1.01" 0x02 Version of FPGA firmware "3.0" 0x03 Ancillary Version (PIC firmware) - 0x20 Number of Probes - 0x21 Sample memory available (bytes) 24576 0x22 Dynamic memory available (bytes) - 0x23 Maximum sample rate (Hz) 200000000 0x24 Protocol version - 0x40 Number of Probes (short version) 32 0x41 Protocol version (short version) 2
Clients should accept data from either long or short versions of a meta field, if both are possible.
0x05 - Finish Now (disable RLE mode)
Turns off RLE mode specified in the flags register (see 0x82 command below). In RLE mode, the analyzer can sit forever if inputs aren't changing. This gives the PC client application an opportunity to finish a capture on demand.
Finish now also aborts the advanced trigger, & forces data capture to quickly fill the buffer & end capture.
0x06 - Query Input Data
The device responds with four bytes. Gives a snapshot of the current logic analyzer input bits.
0x0F - Arm Advanced Trigger
Arm the advanced trigger. Conditional capturing (under control of trigger sequencer) begins immediately. Once trigger fires, the controller waits for "delay count" additional samples before returning captured data to client.
0x11 - XON Depreciated. On a serial port, this would pause output when FPGA was returning captured data. Currently ignored by the FPGA.
0x13 - XOFF Depreciated. On a serial port, this would resume output when FPGA was returning captured data. Currently ignored by the FPGA.
2.3.2 Long Commands (five byte commands)
0x80 - Set Sample Rate
The Logic Sniffer samples at rates lower than the reference clock by using a divisor-count. Every given number of clocks, a sample is accepted. To set the sample rate, the divisor count is computed as follows:
divider = (clock / sample-rate) - 1
0x81 - Set Read Count & Delay Count
The read-count specifies the number of samples (divided by four) to be returned to the client on your PC. The delay-count is the number of samples (divided by four) to capture -after- the basic or advanced trigger fires.
A read-count larger than the delay-count returns captures from before the trigger. Such pre-trigger captures are only valid if the device was running long enough before the trigger fired. ie: a trigger that fires immediately could return garbage.
0x82 - Set Flags
The flags register configures a whole range of miscellaneous Logic Sniffer features including:
- Demux Mode. Double-Data-Rate Capturing. Not compatible with filter mode. Should be used with max sample-rate (ie: set divisor to zero -- see 0x80 above). 1= Enabled.
- Noise Filter Mode. Reduces occurrence of glitches on inputs. 1 = Enabled.
- Disabled Channel Groups. Don't capture specified groups of input data. 1 = Disable group.
- External Clock Source. Use external clock for sampling. If disabled, use internal 100Mhz reference clock instead. When enabled the Logic Sniffer is basically in "state mode" (sample synchronous with input) verses "timing mode" (asynchronous internal reference clock). 1 = Enabled.
- Inverted External Capture Clock. Capture data on falling edge of sample clock when using external clock.
- Enable RLE compression mode. Duplicate samples are compressed into counts. Most significant bit of sample replaced with "rle-flag", and is thus no longer available. Requires client support to decode. A value is stored, followed by a count of repeats. Count's are exclusive of value, so <value><count=7> means there are 8 samples.
- Swap Number Scheme. Swap upper 16 bits & lower 16 bits of input in capture buffer. 1 = Enabled.
- External test mode. Output 16-bit test pattern on capture pins 31:16. 1 = Enabled.
- Internal test mode. Supply internally generated 32-bit test pattern to capture buffer. Input data is ignored.
- Extra RLE compression modes. For input samples which change infrequently, rle-count's can fill to maximum. The Logic Sniffer then stores that count & starts counting again. The extra modes control how often another <value> is stored (even if it hasn't changed):
Mode Description 0&1 Issue <value> & <rle-count> as pairs. Backwards compatible. 2 Periodic. <values> reissued approximately every 256 <rle-count> fields. 3 Unlimited. <values> can be followed by unlimited numbers of <rle-counts>.
0x9E - Advanced Trigger Configuration Select The advanced trigger needs a lot of configuring (84 different selectors), so it seems prudent to provide a separate address space to cover programming the 11000+ config bits. This register selects what to configure in the advanced trigger. Please see Appendix A for the list of advanced trigger registers.
0x9F - Advanced Trigger Write Data Register The trigger-data register loads the LUT chains of trigger terms, range checks, edge detects & summing terms. It is also used to write the sequence states & timer limit registers.
0xC0/C4/C8/CC - Set Basic Trigger Mask The trigger-mask controls which basic trigger-value bits participate in a compare. A mask bit set to zero causes the corresponding trigger-value bit to be ignored.
0xC1/C5/C9/CD - Set Basic Trigger Value The target-value is what the fpga looks for in the sampled input data. Each bit corresponds directly 1:1 with the captured input data. Note: Disabled groups still participate in a trigger. If you want to exclude a disabled group, then be sure to set the trigger mask accordingly.
NOTE: The FPGA requires trigger masks & values be written back-to-back. ie: Write the mask, then the value, for trigger 0. Then the mask/value for trigger 1, etc... The basic triggers use the same LUT based compare mechanism as the advanced triggers. For backwards compatibility, a widget converts the mask/value pairs into serial LUT chains automatically for the basic trigger.
0xC2/C6/CA/CE - Set Basic Trigger Configuration Writing this register configures the selected basic trigger stage. There are various fields available for customizing the operation of the trigger:
• Stage Delay. If a trigger match occurs, the action of the stage is delayed by number of samples. • Serial Mode. If enabled, trigger operates as a serial trigger. 1 = Serial Mode. • Serial Channel. In serial mode, select which input pin to treat as serial channel (0 to 31). • Level. Trigger level at which current stage will become active. Level 0 means activate immediately. • Start. Tell controller the basic trigger has fired.
Serial Mode: In serial mode, a trigger stage monitors only a single sampled input bit, selected with the "serial-channel". The selected bit is fed into a serial-to-parallel shift register. Thus the last 32 samples of a single bit can be evaluated using the normal masked compare logic.
To be effective, you should use an external clock in serial mode. Otherwise it's very difficult to predict exactly when samples are taken & added to the shift register. So for example, when monitoring a SPI bus use the SPI clock for capturing.
Figure 6 - Basic Trigger Serial Mode
Trigger Levels: The basic trigger has a simple level counter. When any trigger stage matches something, the level count is incremented. When the level count matches a given stages "trigger-level", the stage becomes active. Thus you can search for a simple sequence of events.
ie: Setup trigger 0 to start immediately, triggers 1 & 2 to start on level 1, and trigger 3 to start on level 2. When trigger 0 matches, both triggers 1 & 2 activate. When either of them matches, trigger 3 activates.
This document is Copyright © 2011 Ian Davis Released under the GNU General Public License