Open AdDraw opened 1 year ago
Currently fullness of the FIFO is based on the a_wr_ptr - a_rd_ptr_bin
, where a_rd_ptr_bin
is the read pointer from the B clock domain which has been synchronized to A clock domain using a dual flip-flop synchronizer, which means that it lags 2 A clock cycles behind B clock domain's read pointer(the one that represents the actual state)
Possible fix in 16fd40d59df208e56e0f0073b3e8cd39731b44a4
Main thing was that buffer size equation sometimes underestimated the minimum fifo size required. This was due to 3 things for async buffers:
wr_ptr
from wr clock domain(A) crosses over to rd clock domain(B) in 2 rd clocksrd_ptr
is the same but it takes it to cross from domain B to A in 2 wr clocksempty
deassertedto
read` asserted and sampled
Above points cut into the time frame reader can read from the FIFO before next burst of data comes(or continuous data stream still writes to the fifo) meaning that to better estimate the minimum fifo size should be bigger and delays between clock domains etc have to be accounted for.
Overall the time fifo can read should be equal to:
time_to_read = time_to_write - time_for_rd_ptr_sync - time_for_wr_ptr_sync - time_to_assert&sample_read_after_empty_deasserts
where:
time_to_write = (write_burst_size + write_burst_idle_cycles)*write_burst_n*write_period
time_for_rd_ptr_sync = 2 * wr_period
time_for_wr_ptr_sync = 2 * rd_period
time_to_assert&sample_read_after_empty_deasserts = rd_period
2
for sync was chosen as deafult, but should be changed toSYNCHRONIZER_STAGES
More problems:
For async clocks that have aligned rising edges above equations work, but they do not work for cases where risign edges are misaligned.
Ex. rd_freq: 4Hz, wr_freq: 6Hz does not work
TODO: fix this
To properly estimate the buffer size, I think it comes down to stuff like clock phases etc between each other.
Because of this, we sometimes need more buffer space/words than estimations show. Additionally, Asynchronous FIFO has a 2cycle(due to 2ff synchronizers) synchronisation delay for pointers, thus read that happens will update the counters on the write side in 2 cycles, even though in a synchronous fifo, read would happen almost instantaneously and overall making it all work.
TODO:
CustomClk
python classs from thecdc
repo