cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
mrmiziev7
Contributor
Contributor
1,019 Views
Registered: ‎05-16-2019

FIFO generator 9.3: Stuck data and duplication issues

Jump to solution

Dear Mr/Mrs,

I am currently working with Spartan 6 via ISE 14.7. I am using the Spartan as a master to 32-bit ADC. Every 6 ms Spartan recieves 512 measurements from ADC, stores it inside FIFO (16 width, 1024 depth block RAM independent clocks) , and then transmits the stored data via UART when reading operation is requested. 

Since Data Ready arrival from ADC is not stable, to avoid trash data and missampling I check DRDY state every 5 ns (200 MHz) clock. After 40 ns since  DRDY is 0 (active low), register sample outputs a pulse (15 ns duration). The sample is used as writing clock, so on every positive edge of sample the data is shifted into FIFO.  The sample  frequency is approximately  5 MHz. After I shift 512 measurements (1024 of 16 bit words) into FIFO, writing stopps and 2 reading clock cycles later the reading starts. 

As for my reading clock I used clocking wizard to generate 5 MHz clock. Reading starts 2 clock cycles after the writing is finished and it goes on until FIFO is empty (no data counting)

 

Spartan successfully recives data, stores it and transmits it to the host computer. See the Correct data png below as the demonstration. Blue brackets show an individual measurment from ADC, which consists of 4 bytes including 1 status register byte A4 (marked red). 

Correct data.PNG

The problem:  after some time (which can be 30 seconds or 10 minutes) Spartan transmits the duplicate of MSB word and then shuts down. See the wrong data png below as the demonstration. It can be seen that 2A4E MSB word got duplicated. 

Wrong data.PNG

Immediately after such a situation happens, FIFO crashes while showing that it's NOT empty. I created such a condition that nothing will be written into FIFO unless it's empty.  So there is a data stuck in it and it does not react on reading requests at all. In the beggining I thought that this situation might be the case of underflow or overflow, but I checked the prodcut guide and found out that both underflow and overflow don't damage the data stored in FIFO. 

 

Please, can someone help me to solve this problem out? I can't solve this problem for long... I attached zip of the project below, if needed bo better understanding. 

0 Kudos
Reply
1 Solution

Accepted Solutions
mrmiziev7
Contributor
Contributor
562 Views
Registered: ‎05-16-2019

Hi,

 

I followed the advice and checked the ILA, it didn't give me anything I didn't know with using simle flags, however it somehow pushed me to the thought of where the error could be. And in the end it was right. I will write it down just in case if any other developer one day will face the sampe problem one day.

For my project it is important to observe seperate packets of data, so instead of streaming the data non-stop I had to create a store-and-give FIFO for bulk transmission. I needed to write 512 measurements from ADC in the specific moment of time (urrelevant here why it is specifc), and then wait until all the data is read and FIFO is empty to start new writing. This is a strict condition that I forced upon my logic because this is rellevant for my project. In order to do that, I constructed my own word counter... The  counter was used to count measurements, and when the counter value reached 512, FIFO writing was disabled and reading was enabled. 

The thing is that the logic I constructed for a mechanism, that "looks" on the counter value and  controls wr_en and rd_en respectively was fragile and way too complicated. So I had to face situations, when at some random point of time I was writing 513 measurements, while counter was showing 512 data packets. This happened because sometimes wr_en was disabled just a little later compared to the clocking used for counter. And after 512 measurements were read, there was still 1 measurement in FIFO. Hence, I had a data stuck situation, since my condition states: "No new writing unless the FIFO is empty".

So I erased completely the logic of my data counter and instead used simple Programmable Full flag". Sometimes, simplicity is the best friend of a developer. Thank you guys for trying to help me out here. 

View solution in original post

14 Replies
drjohnsmith
Teacher
Teacher
998 Views
Registered: ‎07-09-2009
remember, the fifos need constant clocks into the read / write port, and the reading g / writing must be done by toggling the enables.

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Reply
olupj
Explorer
Explorer
988 Views
Registered: ‎01-27-2008

@mrmiziev7 

Have you simulated this?

Is the system synchronous?  If not you can get interesting issues.

Since your data is 32b oriented can you switch to a 32b fifo?  Not that it will help (you'll probably get the 32b repetition instead of 16b).

Is there some pipeline after the fifo read that might store this repetition?

I don't see shutdown from your posted example - it looks like 32b words start again (misaligned due to the 16b fifo).

0 Kudos
Reply
mrmiziev7
Contributor
Contributor
917 Views
Registered: ‎05-16-2019

Hi olupj,

-The FIFO is asynchrnous in order to cross clock domains (data is stored and then read at different frequency). The UART transmission is sycnrhonous though. 

-About switching from 16 bits FIFO to 32 bits. The thing is that I transmist the data to a host computer via Cypress EZ-USB board, which has 16 bit parallel input. So for this occasion it's really more comfortable to just store 16 bits instead of 32. 

- No, there is not. After the READ module I have USB interface module that has no way of storing extra word as long as extra word was not provided. 

- Ops, sorry for not being clear. I will explain a little bit better: Spartan stores a packet consisting of 512 measurements (2048 bytes) and then transmits to it host computer. The second example I provided you with shows that the LAST succesfully transmitted packet always has a duplicate of MSB word. In the end of this packet there is nothing, since transmission silinces.  From what I understand these 2 bytes trash duplicates take place of useful 2 bytes, that were not transmitted. And somehow the data stored in FIFO does not react on reading request.  My condition says that if FIFO is not empty, writing new 512 measurements is forbidden. So to conclude: succesfull operation --> correct data packets --> wrong data packet with FIRST word's MSB duplicated --> FIFO is not empty --> FIFO does not react on reading requests ---> Writing is forbidden until FIFO is empty ---> Reading and Writing are impossible --> Operation is stuck forever.

0 Kudos
Reply
mrmiziev7
Contributor
Contributor
916 Views
Registered: ‎05-16-2019
Dear John,

Thank you. I do remember that and in fact my design is taking this concept as basis. I use DataReady from ADC to generate internal clocks that are permanent. And I do writing and reading only by toggling enables.
0 Kudos
Reply
olupj
Explorer
Explorer
880 Views
Registered: ‎01-27-2008

@mrmiziev7 

I see you attached your design. I'll take a look, but am tied up for the day - so, later tonight. Have you simulated (sorry might not have tracked that response)? Is there a testbench?

0 Kudos
Reply
mrmiziev7
Contributor
Contributor
868 Views
Registered: ‎05-16-2019
Thank you. Sorry, forgot to reply on that point. Yes, the simulation was done and testbench is provided in the project.
0 Kudos
Reply
drjohnsmith
Teacher
Teacher
861 Views
Registered: ‎07-09-2009
one other question,
the flags , full , empty etc, are with reference to their clock domain,
Its always best to use the data available flag to enable a read , to the read clock, and not full flag to enable the write to the write clock.
If you have logic that uses both flags , then you need to provide the clock crossing of the flags.

My guess if your getting repeated data , is you are not using the empty flag on a read, and possibly to the wrong clock.



<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Reply
mrmiziev7
Contributor
Contributor
850 Views
Registered: ‎05-16-2019
Yes, full and empty flags are with reference to their clock domain. There are individual modules for both reading and writing operations to ensure that the clock crossing is not corrupted.

My writing starts when FIFO is empty and full flag is constantly monitored to enable/disable writing to FIFO.

My reading starts only when 512 measurements are written + little delay. Dyring reading the empty flag is constantly monitored to switch from reading state to waiting state and vice versa.
0 Kudos
Reply
drjohnsmith
Teacher
Teacher
800 Views
Registered: ‎07-09-2009
how big is the fifo ?
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Reply
mrmiziev7
Contributor
Contributor
788 Views
Registered: ‎05-16-2019
16 width, 1024 depth block RAM independent clocks.
0 Kudos
Reply
drjohnsmith
Teacher
Teacher
718 Views
Registered: ‎07-09-2009
from what yo have said,
you have covered all the obvious,
a) constant clocks into the fifo
b) fifo bigger than needed
c) using the empty / full flags
d) using the flags on the correct clocks
e) simulated design,
f) your design is constrained correct and passes timing.

At this point,
its time to insert two ILA's , one on the read side, one on the write side,
to see whats really happening.

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Reply
mrmiziev7
Contributor
Contributor
704 Views
Registered: ‎05-16-2019
ILA Chipscope shows the exact thing I have been talking about: after some amount of succesful transactions, the last transaction has a duplicate word and FIFO is not empty.
My writing and reading processes don't interact with each other. They are 2 seperate processes. I write equally 512 measurements, and only after that I start reading until the point when FIFO is empty. When FIFO is empty coupled with the delay, I start writing again. And so it goes in the loop.

So when the last transaction with error duplicates is read, somehow FIFO is not empty. Hence, new writing is impossible.

so if I write 512 measurements to FIFO and read everything until FIFO is empty, then I should never have a condition where FIFO is not empty after reading.
0 Kudos
Reply
drjohnsmith
Teacher
Teacher
691 Views
Registered: ‎07-09-2009
yes your right, but remember it takes a few clocks for the flags to propagate from one side of the fifi to the other,

show us the data and the flags from the two ILAs
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
Reply
mrmiziev7
Contributor
Contributor
563 Views
Registered: ‎05-16-2019

Hi,

 

I followed the advice and checked the ILA, it didn't give me anything I didn't know with using simle flags, however it somehow pushed me to the thought of where the error could be. And in the end it was right. I will write it down just in case if any other developer one day will face the sampe problem one day.

For my project it is important to observe seperate packets of data, so instead of streaming the data non-stop I had to create a store-and-give FIFO for bulk transmission. I needed to write 512 measurements from ADC in the specific moment of time (urrelevant here why it is specifc), and then wait until all the data is read and FIFO is empty to start new writing. This is a strict condition that I forced upon my logic because this is rellevant for my project. In order to do that, I constructed my own word counter... The  counter was used to count measurements, and when the counter value reached 512, FIFO writing was disabled and reading was enabled. 

The thing is that the logic I constructed for a mechanism, that "looks" on the counter value and  controls wr_en and rd_en respectively was fragile and way too complicated. So I had to face situations, when at some random point of time I was writing 513 measurements, while counter was showing 512 data packets. This happened because sometimes wr_en was disabled just a little later compared to the clocking used for counter. And after 512 measurements were read, there was still 1 measurement in FIFO. Hence, I had a data stuck situation, since my condition states: "No new writing unless the FIFO is empty".

So I erased completely the logic of my data counter and instead used simple Programmable Full flag". Sometimes, simplicity is the best friend of a developer. Thank you guys for trying to help me out here. 

View solution in original post