Electronic – Help with multiple receiver channels and single storage architecture

computer-architecturefpgaserialspartan 6

I want to build a datalogger that has multiple receiver channels that run on serial communication protocol RS232 and then collect the information from the channels in a single storage that would be accessed by another controller whenever it gets full.

I'm using Spartan-6 for the job. I figured I could use Ken Chapman's ultra compact uart to use as receivers and then deploy glue logic to store the data in a FIFO of depth equal to \$noofchannels \cdot (\frac{1}{2}.receiverbufferdepth)+ 4\$
assuming the width to be 8 in all the buffers.
Now I have three fillstate signals available from this UART:

  1. Data Present
  2. Buffer full
  3. Buffer half full

and I have to attach a channel ID every time I read data from the receiver-buffer so that the controller reading my FIFO would know which data was from which channel-this thing introduces overhead. I want my algorithm to have lowest overhead as possible as in I want it to attach an appropriate chunk of data (bytes) with each identifier. My baud rate is 115.200 kBd and my clock is 16 MHz. I'm thinking of having 4 receiver channels.

At first I decided to run an FSM that would start every time a half-full signal goes high and read from that particular buffer till its data-present signal goes zero. Also I calculated that if I keep the buffer depth 4 at each receiver channels and if reading every byte took 2 cycles then I would still have appropriate clock cycles left to read all of the buffers, write it to a single FIFO and ask the controller to read all of it.

Problem with this approach is that I might lose data in case a channel doesn't send more than 7 bytes ( because kcuart6 has a FIFO of depth 16 which I can't change to 4).

Guys I want suggestions for a fool proof architecture that would ensure that no bytes are lost while my glue logic is reading from receiver buffers and also while the controller is accessing my storage memory (because I can't write while the controller is reading my FIFO).

Best Answer

If I understand your design correctly, I think you have a design issue that needs to be addressed first.

You are grabbing data from one of several UART receive buffers and shovelling it directly into a UART transmit buffer.

This will have the impact of mixing up bytes from each of the incoming buffers into the output stream with no apparent way of unmixing them.

Generally when multiplexing streams like this you would receive a delimited packet of some kind, probably terminated with a line feed. You buffer the input until you get the terminator then transmit the buffer, probably with a header marking which stream the line is associated with.

This leads in to answering the problem you are tackling. There are two approaches to this, your current approach is known as hard-realtime. The maximum input rate is X per second, I process them in Y ns, the timing works everything is sweet.

Once you switch to buffers a hard realtime approach gets difficult. A soft realtime approach would use the average rate of incoming data, a buffer (or four in your case) that absorbs some variation in that rate and an average output rate. You design in some margin so the average input is no more than 80% of the output and put in a handler for the very unlikely event that your buffer starts overflowing (dropping packets is normal).

Btw. ring buffers are nice for this kind of constant data in-data out work flow.