1
\$\begingroup\$

Hardware:

I have an asic-"sensor" which sends me 32-bit packages (serial). I need to detect this packages with an FPGA.

When I start the readout, the sensor is sending me data-packages until I stop the readout. There can be idle-times (no specific length) between the data-packages. If the asic is sending no package (idle-time), I receive 0xA3 as idle-data.

The sensor is sending LSB first (of one package). That means that I get the data first. I receive the header at the end of a packet transfer. In my FPGA I want to detect these packages. Is there a general way to do this?

I already managed to format the serial bit stream in 8 bit parallel data.

Demonstration of the problem that I have:

The general problem is that there can be data that looks like idle or data that looks like a header. Which is not bad when it is not the last data byte of the packet, like in the 2. Example:

I -> 0xA3 (idle-data)

H -> 0x6 (header of the package)

D -> 0x00 - 0xFF (data in package)

ID -> 0xA3 (data that looks like idle)

HD -> 0x6 (data that looks like a header)

1. Example (Sensor is sending LSB first):

 MSB
| packet 2  | packet 1  |
 H  D  D  D  H  D  D  D  I  I

these 2 packages are easy to detect because there is no "ID" or "HD".

2. Example (Sensor is sending LSB first):

 MSB
| packet 3  | packet 2  | packet 1  |
 H  D  D  D  H  D  D  HD H  D  D  ID I

Hard to detect. The first package starts with an idle sequence and the second package has data that looks like a header.

Is there a general way to detect this? I thought about convolution, but I am not sure how to implement it here. I am using VHDL.

\$\endgroup\$
3
\$\begingroup\$

There are no guarantees with an unfortunate protocol design like this. But you can do at least as well as a UART does on asynchronous serial data. Let me explain.

Since you have already found the byte boundaries in the data stream, you can think of the header (H) byte as being similar to a UART start bit, and the idle (I) byte as being similar to an (optional) UART stop bit.

Set up a state machine that starts in an "idle" state, and searches for the next header byte, ignoring anything that isn't an H (including actual I bytes). Once you find an H, you then capture the next 3 data bytes regardless of their value. Then, depending on whether the next byte after that is H or not, you advance to the "header" or "idle" state.

enter image description here

Yes, just like a UART, this can get locked into a misalignment if the data packages (I prefer the term "packets") contain H bytes repeatedly, but unless the data is particularly pathological, the state machine should quickly align itself on the "real" headers — all it takes is one packet that does not contain a fake H byte.

If you can make sure that the ASIC doesn't send its first packet until the state machine is initialized, then there should be no problem. Otherwise, if the state machine is started at an arbitrary point in an already-running data stream, it can get into trouble. You can check for non-I bytes when you're in the "idle" state — this is an indication that you're out of alignment.


EDIT: The answer above was based on the mistaken assumption that the "H" byte comes before the data in any given packet; it turns out that I was wrong about that. However, I'm going to leave that part as-is, because that is by far the more common case. Below, I'll address the problem that the OP faces, which has the "H" byte following the data bytes.

In a situation like this, it is necessary to set up a pipeline (shift register) that can contain the complete 4-byte packet.

block diagram

The bytes shift through the four registers across the top in sequence. The oldest byte (the LSB, which arrived first) ends up in the rightmost register at the same time that the "H" byte for that packet arrives in the leftmost register.

The state machine monitors the contents of the "H" register, and if it is in fact the "H" value when it is in the "header" state, its output is asserted, which enables the capture register in the second row, and also asserts the "valid out" signal.

The state diagram looks like this:

state diagram

We start on the left, and sequence through the three data states before looking for the first H byte. If we're in the "header" state when we find an H byte, the previous three bytes MUST have been data bytes, so they get captured. We then cycle back through the three data states again to capture at least three more bytes before we start looking for the H again.

Unfortunately, this protocol can easily get out of sync if any packet that contains an "HD" (fake header) byte is also preceded by I (idle) bytes. In order for this implementation to stay in sync, at least one of the two conditions must be met:

  • There are no HD bytes in the packets.
  • There are no I bytes between packets.

Otherwise, there is simply no robust way to maintain packet alignment. As I said, this is an "unfortunate" choice of protocol on the part of the ASIC designer. If the H byte came first in the packet rather than last, these constraints would go away.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the answer! I think I explained it wrong: There is LSB first. So I get first data and at the end the header. So problem can be that the LSB of the packets looks like IDLE. I will add a few more words in the main post to make my problem more understandable. \$\endgroup\$ – puzzled Oct 26 '18 at 5:28
  • \$\begingroup\$ Ah. I didn't realize that you have time flowing right-to-left in your byte sequences. Normally, we would assume that time flows left-to-right, just like it does on an oscilloscope or logic analyzer. In other words, the byte you're calling a "header" is really a "trailer". That does complicate matters slightly, and I will update my answer accordingly later today. \$\endgroup\$ – Dave Tweed Oct 26 '18 at 11:46
  • \$\begingroup\$ You're quite welcome! It gave me an opportunity to learn more about using Graphviz to easily produce high-quality diagrams. \$\endgroup\$ – Dave Tweed Oct 27 '18 at 11:49
  • \$\begingroup\$ Is it freeware? Looks great. \$\endgroup\$ – puzzled Oct 27 '18 at 12:33
0
\$\begingroup\$

I assume you have no control of the design of the ASIC and therefore can't solve it there (eg by out of band signalling of packet start, or using a data encoding that allows an illegal value to specify idle or packet start markers). If you can get the asic changed, it would be better to do so.

Otherwise, I'd start by writing a regular expression that describes the possible packet formats. Once you have that, it can be converted to a state machine that recognizes an entire packet. You cab then implement that state machine and use it to generate a sync pulse.

You'll lose the first whole packet you receive after reset. It is also possible that you may recognize an entire valid packet inside the data of another packet, but that is unlikely - to be sure you'd want to detect repeated invalid data and reset if that happens. This may cause a nontrivial number of packets to be lost on rare occasions. This may or may not be appropriate for your application, but is far easier than the alternative (which involves buffering a significant amount of data so you can be sure when you're synchronized and then process it retrospectively).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.