Xilinx UART Macro ERROR???

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.

Reply to
john orlando
Loading thread data ...

Reply to
Peter Alfke

Peter Alfke wrote:

Yes. Synchronize the slow data to 90 MHz and use a synchronous fifo.

For synth fifo code examples see

formatting link

-- Mike Treseler

Reply to
Mike Treseler

John wrote regarding XAPP223:

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

Reply to
Brian Davis

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

formatting link
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

Reply to
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

Reply to
john orlando

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.