On Thu, 2005-11-10 at 17:20 -0500, Timothy Miller wrote: > 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.
Disclaimer: I haven't tried this, but I think it should work. Keep two counters running in parallel; one is a "normal" 5-bit counter, and the other is a gray-encoded version of the same thing. Rather than actually try to count in gray codes, it's probably easier to just gray-encode the original counter on each clock. I don't remember Verilog or VHDL syntax, but something like this, where ":=" is a registered assignment: counter := prev_counter+1 gray_counter := gray(prev_counter+1) (Don't do "gray_counter = gray(counter)" (unregistered), because that might glitch as counter changes.) Use bits [3:0] of counter (not gray_counter) as your address bits, and use gray_counter to compare with the other clock domain. When gray_counter is equal to other_gray_counter, the FIFO is empty; when xor(gray_counter, other_gray_counter) is equal to 24 (yes, 24, not 16), the FIFO is full. Be sure to register the outputs of your "FIFO is empty" and "FIFO is full" computations (and make sure your synthesis tool does not replicate these registers); otherwise, you may run into issues where part of the circuit acts as if the FIFO is empty and part of it does not. Carl Witty _______________________________________________ Open-graphics mailing list [email protected] http://lists.duskglow.com/mailman/listinfo/open-graphics List service provided by Duskglow Consulting, LLC (www.duskglow.com)
