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)

Reply via email to