11-05-2020 08:31 AM
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).
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.
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.
11-14-2020 08:08 AM
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.
11-05-2020 09:35 AM
11-05-2020 09:50 AM
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).
11-06-2020 04:39 AM
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.
11-06-2020 04:41 AM
11-06-2020 05:32 AM
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?
11-06-2020 06:04 AM
11-06-2020 06:31 AM
11-06-2020 07:33 AM
11-06-2020 11:15 AM
11-06-2020 12:01 PM
11-07-2020 05:20 AM
11-07-2020 09:21 AM
11-07-2020 10:51 AM
11-14-2020 08:08 AM
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.