Ok, I suppose I should know this stuff, but I've never done it before this way (the way I did it before was inferior).
Anyhow, so I'm redesigning the fifo I posted quite a long time ago so that it could handle different clock rates for input and output. In the past, I used special hand-shake logic to make the head and tail pointers safely cross clock domains. As suggested by others here, I'm converting it to use graycodes so that the pointers are glitch-free without any special logic. The basic idea is to use 4-bit graycode counters. As long as the memory cells are written and read in the same order, it doesn't matter that they're not in normal memory sequence. But there's another problem. In order for the fifo to hold 16 entries (using 16-entry memory blocks), I needed to use a 5-bit counter. The upper bit serves as a "wrap" flag. If both the head and tail are the same value, is the fifo empty or full? Having the high bits of head and tail differ serves to indicate that the tail pointer (where stuff goes in) has "lapped" the head pointer (where stuff comes out). Unfortunately, this poses a problem for graycodes. Looking at a 5-bit graycode sequence, bits [3:0] do not count in the same order for the first half of the sequence as for the second half. In fact, the order is completely reversed. While this might make a good stack, it makes a lousy queue, because there would be collisions between new writes and things not read yet. Another option is to make the high bit count differently. That is, the high bit is just a binary flag that is concatenated with a 4-bit graycode counter. Since we have 16 cells, that 4-bit counter works perfectly. The problem is that when we transition from 8 (the 'highest' graycode value) to 0, we also need to flip the wrap flag. But this is two simultaneous transitions, which we all know is not really simultaneous, and this race condition could cause the fifo to misbehave. So, what's the solution? One idea I had was to insert a dead cycle for the extra transition. It's like enqueueing into a full queue or dequeueing from an empty one. There's a protocol for that that everyone conforms to. I'm not sure that would work, though. Another solution is to only hold 15 entries. You don't have the 'wrap flag' problem since the fifo is full at 15 entries, and the tail pointer can never lap the head pointer. _______________________________________________ Open-graphics mailing list [email protected] http://lists.duskglow.com/mailman/listinfo/open-graphics List service provided by Duskglow Consulting, LLC (www.duskglow.com)
