Forums

Xilinx UART Macro ERROR???

Started by john orlando November 13, 2003
Hello,
We have recently been using the free Xilinx UART macro with the
16-byte FIFO (from app note XAPP223) in a design, instantiated in a
Virtex XC2V1000.  We are using both the Rx and Tx macros (actually, 32
of each for a total of 32 UARTs in the device).  Our actual setup
looks like this:

StrongArm SA-1100  <--> Virtex XC2V1000 <--> 32 serial devices

where the UART FIFOs in the XC2V1000 are essentially memory-mapped
into the StrongArm's memory space to read and write to the serial
devices.

Occassionally, we are seeing a MISSED byte being sent from a random
serial device.  We have scoped the serial lines between the serial
devices and the XC2V1000 and know the serial data is showing up there.
 We put a high-speed logic analyzer on the interface between the
SA-1100 and the XC2V1000, and know that the byte does not appear
there.

After three weeks of investigating this issue, we are starting to
wonder if the lost byte may be due to the macro.  Is there any
condition with the macro where performing a read from the UARTs Rx
FIFO to pull a byte out on the same clock edge where a stop-bit has
been received and recognized, and the received byte added to the Rx
FIFO, would cause the received byte to be lost?  Specifically, it
seems as though we see N bytes in the UART's Rx FIFO to be read, we
perform N reads (actually, N+1 reads, because the N+1 read is what
indicates to us that DATA_PRESENT is not asserted, and that byte
should be thrown away...we do 16-bit reads: 8 bits data, and 8-bits of
status, with the DATA_PRESENT part of the status).  We only see the
missing bytes when we eventually see DATA_PRESENT again, which
interrupts us (the interrupt is actually delayed 4-byte times in our
system), and we perform a read of the data in the Rx FIFO again.  We
should be able to read 4 valid data bytes.  However, the first byte we
read from the FIFO is actually the SECOND byte that should have been
in the FIFO, and the first byte is gone forever (the remaining third
and fourth byte are read just fine).

Anyone out there ever seen this type of behavior with the macro
before?  Our baud rates are running at 38.4 KBps, and our FPGA is
being clocked by the StrongArm at ~90 MHz, in case you're curious. 
Any help would be appreciated....thanks in advance!

Regards,
John O.
General warning: FIFOs with two independent clocks are tricky when it
comes to detecting the Empty condition. That's why Gray-coded addresses
are a must to avoid comparator glitches.
In your case, the Baud rate is so extremely slow that you might convert
the whole FIFO into a trivial synchronous 90 MHz design, by
double-synchronizing (anti-metastable) the slow clock to the 90 MHz. 
Crossing clock boundaries can be dangerous to your mental health. I know!
Peter Alfke
=================================
john orlando wrote:
> > Hello, > We have recently been using the free Xilinx UART macro with the > 16-byte FIFO (from app note XAPP223) in a design, instantiated in a > Virtex XC2V1000. We are using both the Rx and Tx macros (actually, 32 > of each for a total of 32 UARTs in the device). Our actual setup > looks like this: > > StrongArm SA-1100 <--> Virtex XC2V1000 <--> 32 serial devices > > where the UART FIFOs in the XC2V1000 are essentially memory-mapped > into the StrongArm's memory space to read and write to the serial > devices. > > Occassionally, we are seeing a MISSED byte being sent from a random > serial device. We have scoped the serial lines between the serial > devices and the XC2V1000 and know the serial data is showing up there. > We put a high-speed logic analyzer on the interface between the > SA-1100 and the XC2V1000, and know that the byte does not appear > there. > > After three weeks of investigating this issue, we are starting to > wonder if the lost byte may be due to the macro. Is there any > condition with the macro where performing a read from the UARTs Rx > FIFO to pull a byte out on the same clock edge where a stop-bit has > been received and recognized, and the received byte added to the Rx > FIFO, would cause the received byte to be lost? Specifically, it > seems as though we see N bytes in the UART's Rx FIFO to be read, we > perform N reads (actually, N+1 reads, because the N+1 read is what > indicates to us that DATA_PRESENT is not asserted, and that byte > should be thrown away...we do 16-bit reads: 8 bits data, and 8-bits of > status, with the DATA_PRESENT part of the status). We only see the > missing bytes when we eventually see DATA_PRESENT again, which > interrupts us (the interrupt is actually delayed 4-byte times in our > system), and we perform a read of the data in the Rx FIFO again. We > should be able to read 4 valid data bytes. However, the first byte we > read from the FIFO is actually the SECOND byte that should have been > in the FIFO, and the first byte is gone forever (the remaining third > and fourth byte are read just fine). > > Anyone out there ever seen this type of behavior with the macro > before? Our baud rates are running at 38.4 KBps, and our FPGA is > being clocked by the StrongArm at ~90 MHz, in case you're curious. > Any help would be appreciated....thanks in advance! > > Regards, > John O.
> ================================= > john orlando wrote:
>>Anyone out there ever seen this type of behavior with the macro >>before? Our baud rates are running at 38.4 KBps, and our FPGA is >>being clocked by the StrongArm at ~90 MHz, in case you're curious. >>Any help would be appreciated....thanks in advance! >> >>Regards, >>John O.
Peter Alfke wrote: > In your case, the Baud rate is so extremely slow that you might convert > the whole FIFO into a trivial synchronous 90 MHz design, by > double-synchronizing (anti-metastable) the slow clock to the 90 MHz. Yes. Synchronize the slow data to 90 MHz and use a synchronous fifo. For synth fifo code examples see http://www.edif.org/lpmweb/more/vhdl.htm -- Mike Treseler
John wrote regarding XAPP223:
> > Occassionally, we are seeing a MISSED byte being sent from > a random serial device. >
The XAPP223 UART has a flaw in the receive section that causes that problem- just re-clock the incoming data through a couple of registers, using the UART clock, before driving the UART data input. ( Internally to the macro, the UART input data is registered and used in more than one place without a synchronizer stage... ) Brian john@jrobot.net (john orlando) wrote in message news:<cc4b5d44.0311131330.77f8afc5@posting.google.com>...
> Hello, > We have recently been using the free Xilinx UART macro with the > 16-byte FIFO (from app note XAPP223) in a design, instantiated in a > Virtex XC2V1000. We are using both the Rx and Tx macros (actually, 32 > of each for a total of 32 UARTs in the device). Our actual setup > looks like this: > > StrongArm SA-1100 <--> Virtex XC2V1000 <--> 32 serial devices > > where the UART FIFOs in the XC2V1000 are essentially memory-mapped > into the StrongArm's memory space to read and write to the serial > devices. > > Occassionally, we are seeing a MISSED byte being sent from a random > serial device. We have scoped the serial lines between the serial > devices and the XC2V1000 and know the serial data is showing up there. > We put a high-speed logic analyzer on the interface between the > SA-1100 and the XC2V1000, and know that the byte does not appear > there. > > After three weeks of investigating this issue, we are starting to > wonder if the lost byte may be due to the macro. Is there any > condition with the macro where performing a read from the UARTs Rx > FIFO to pull a byte out on the same clock edge where a stop-bit has > been received and recognized, and the received byte added to the Rx > FIFO, would cause the received byte to be lost? Specifically, it > seems as though we see N bytes in the UART's Rx FIFO to be read, we > perform N reads (actually, N+1 reads, because the N+1 read is what > indicates to us that DATA_PRESENT is not asserted, and that byte > should be thrown away...we do 16-bit reads: 8 bits data, and 8-bits of > status, with the DATA_PRESENT part of the status). We only see the > missing bytes when we eventually see DATA_PRESENT again, which > interrupts us (the interrupt is actually delayed 4-byte times in our > system), and we perform a read of the data in the Rx FIFO again. We > should be able to read 4 valid data bytes. However, the first byte we > read from the FIFO is actually the SECOND byte that should have been > in the FIFO, and the first byte is gone forever (the remaining third > and fourth byte are read just fine). > > Anyone out there ever seen this type of behavior with the macro > before? Our baud rates are running at 38.4 KBps, and our FPGA is > being clocked by the StrongArm at ~90 MHz, in case you're curious. > Any help would be appreciated....thanks in advance! > > Regards, > John O.
So I confess it was me that made the macros in XAPP223 and I made a
mistake or at least an assumption.

The serial input to the Rx is of course asynchronous to the clock and
therefore should be synchronised to the internal clock domain before it is
distributed. My macro did not do this. Unfortunately, I always use the
input flip-flops in the I/O blocks whenever possible in all designs and as
such all my testing never showed up an error. Occasional reports of errors
have always been cleared up by using a flip-flop in the serial line and of
course putting it in the IOB makes it free. Other than this issue, I have
had only happy reports by the thousand (plus requests for parity support
of course!).

I have learnt from my mistake and have now re-implemented the UART macros
which are currently bundled with PicoBlaze (www.xilinx.com/picoblaze)
since this is where they get the most use and where the micro controller
is an ideal partner. These macros have included input synchronising
flip-flops so that they don't rely on I/O flip-flops. I guess I had to
give up an additional slice of logic to make things easier to use :-)

Ken Chapman


Thank you for your response Ken.

We have used the macro before with little difficulty.

We were aware of the metastability problem with the serial input. 
We have the synchronization flip-flops in our design.

We found the problem. It was not with the UART macro. It was with our
use of the macro.

We were using the rising edge of OE- to generate our read pulse. By
the time OE- was synchronized and the edge detected we were 1 to 2
cycles past the rising edge of OE-. We were assured that the data
would not be changing when the processor read the data. This also
allowed us to read the data with zero wait states.

The problem we ran into was when the buffer was empty. If the received
byte was completed between when the processor read the data and the
read pulse then the macro would clear Data_Present and the byte would
be over written on the next received byte.

This was exaggerated by the fact that we were using bit 8 (we have a
32 bit bus) of a data read to provide the Data_Present status. With
one read we can get a received byte and status at the same time
instead of one read for data and another read for status. This caused
us to always do one more read than the data we had. If the input
buffer was truly empty this did not cause a problem.

The way we are fixing it is to latch the Data_Present status with our
Register_Enable signal and then use this latch version to gate the
read pulse. So if we read the buffer and Data_Present is not asserted
on the rising edge of Register_Enable the read pulse will not be
generated.

The problem with this is to detect the rising edge of Register_Enable
and latch Data_Present causes us to have to add 2 additional wait
states for our FPGA accesses.

Thanks to everyone who took the time to respond.

John

Ken Chapman <chapman@xilinx.com> wrote in message news:<3FB8A405.57F8D5BB@xilinx.com>...
> So I confess it was me that made the macros in XAPP223 and I made a > mistake or at least an assumption. > > The serial input to the Rx is of course asynchronous to the clock and > therefore should be synchronised to the internal clock domain before it is > distributed. My macro did not do this. Unfortunately, I always use the > input flip-flops in the I/O blocks whenever possible in all designs and as > such all my testing never showed up an error. Occasional reports of errors > have always been cleared up by using a flip-flop in the serial line and of > course putting it in the IOB makes it free. Other than this issue, I have > had only happy reports by the thousand (plus requests for parity support > of course!). > > I have learnt from my mistake and have now re-implemented the UART macros > which are currently bundled with PicoBlaze (www.xilinx.com/picoblaze) > since this is where they get the most use and where the micro controller > is an ideal partner. These macros have included input synchronising > flip-flops so that they don't rely on I/O flip-flops. I guess I had to > give up an additional slice of logic to make things easier to use :-) > > Ken Chapman