In Spartan-3 Generation designs, the read data is captured into FIFOs using DQS.
Each FIFO has a read pointer and a write pointer.
The write pointer is incremented using DQS and the read pointer is incremented with clk90.
To generate the FIFO empty status, the read and write pointers are compared.
When the FIFO is not empty, the "Data Valid" signal is generated and you can start reading the data.
An issue occurs with this algorithm because it compares two pointers that are in two different asynchronous domains.
The comparison is done in the clk90 domain.
The write pointers are registered three times using clk90, and the third register is compared with the read pointer.
Consequently, if the first register goes to a metastable state, there is a possibility of latching the wrong value.
The write pointers would receive incorrect values and as a result, the FIFO data would be lost.
To work around this issue, the write and read pointer compare logic needs to be replaced with a new algorithm.
After the read command is issued, the new algorithm waits a fixed delay of time before reading the FIFOs (this is to prevent incorrect data being latched).
This issue is resolved in the MIG v2.3 release.
In the meantime, you must make changes to the following four RTL files to incorporate the resolution manually:
Logical modifications are made only to the controller and data_read_controller files.
Only the top and data_path files are modified to include the appropriate port connectivity.
Summary of Changes
New flag "read_fifo_rden" is generated and brought to the output port.
This flag is generated with clk180 in the last "always block" and has the same timing as rst_dqs_div.
See the comment in the attached RTL controller files.
Signal read_fifo_rden is input from Controller.v/.vhd.
The signal is then pipelined three times in the clk90 domain using the signals read_fifo_rden_90r1, read_fifo_rden_90r2, and read_fifo_rden_90r3.
The read_fifo_rden_90r3 signal is then assigned to the read_valid_data_0_1 signal.
No logic changes are made within these files; only port mappings of the read_fifo_rden are added in the instantiations.
The ZIP file below contains an example RTL with the fix.
These files should be used as reference when manually modifying a user MIG output, rather than copying and replacing: