This should limit the throughput of the FIFO. The sustained transfer rate will be slower than the slowest clock. I think that transfer and processing of Gray coded pointers is normally a better solution. The sustained transfer rate will be the same as the slowest clock.They would count in the other direction after receiving a synchronized command from the other side.
As I've changed jobs every 3-4 years and am not allowed to "take" the code repositories with me, I've created pretty much every type of FIFO imaginable. I suppose I have an overly antiquated stance on the "work for hire" ethic...I'm paid by an employer to do the work so I don't keep any of it when I leave (since none of it is legally owned by me).Not sure why you would 'occasionally' do either approach, I would think one would do it only once and then simply use it over and over in many different applications.
Done this before too. see above comment.If a reader must know that a complete packet is available before starting to process data from the FIFO, I would hide the real write pointer from the reader until the writer commits a complete packet. One way is to set a "commit" signal when writing the last word. This works for both synchronous and asynchronous FIFOs.
new_write_address <= write_address + 1 ;
new_read_address <= read_address + 1 ;
writing : process ( clock , reset ) is
begin
if reset = '1' then
write_address <= ( others => '0' ) ;
[COLOR="#FF0000"]a_full <= '0' ;[/COLOR]
full <= '0' ;
elsif rising_edge ( clock ) then
if write_request = '1' and full = '0' then
write_address <= new_write_address ;
if new_write_address = read_address then
full <= '1' ;
end if ;
[COLOR="#FF0000"] if read_address - write_address <= a_full_threshold then
a_full <= '1' ;
else
a_full <= '0' ;
end if ;[/COLOR][/COLOR]
end if ;
if read_request = '1' then
full <= '0' ;
[COLOR="#FF0000"] if read_address - write_address <= a_full_threshold then
a_full <= '1' ;
else
a_full <= '0' ;[/COLOR]
end if ;
end if ;
end if ;
end process writing ;
reading : process ( clock , reset ) is
begin
if reset = '1' then
read_address <= ( others => '0' ) ;
[COLOR="#FF0000"]a_empty <= '1' ;[/COLOR]
empty <= '1' ;
elsif rising_edge ( clock ) then
if read_request = '1' and empty = '0' then
read_address <= new_read_address ;
if new_read_address = write_address then
empty <= '1' ;
end if ;
[COLOR="#FF0000"] if write_address - read_address <= a_empty_threshold then
a_empty <= '1' ;
else
a_empty <= '0' ;
end if ;[/COLOR]
end if ;
if write_request = '1' then
empty <= '0' ;
[COLOR="#FF0000"] if write_address - read_address <= a_empty_threshold then
a_full <= '1' ;
else
a_empty <= '0' ;
end if ; [/COLOR]
end if ;
end if ;
end process reading ;
I think it is a bad idea. A synchronous FIFO is simple and an asynchronous FIFO is complicated. The flag generation in my posting #15 will not work for an asynchronous FIFO.My final goal in this subject post is to design a FIFO core that can be either synchronous or asynchronous (configured by generics).
As long as is it doesn't impose a significant performance penalty, I'd both the synchronous & asynchronous versions to be functionally similar - i.e: use the same flag generation method.
If we synchronize everything in the second clock domain and use binary to grey conversion (while still maintaining the same fundamentals for the flag generation) - why shouldn't it work? Please give a specific case when it may fail.The flag generation in my posting #15 will not work for an asynchronous FIFO.
As I mentioned above, I think you should forget about having "read_request" available in the write domain (and vice versa) in an asynchronous FIFO.2. Please comment on the added code (marked in red) on post #65.
As I mentioned above, I think you should forget about having "read_request" available in the write domain (and vice versa) in an asynchronous FIFO.
The code in #65 (and #15) is not OK for an asynchronous FIFO.
The code in #65 will not make "a_full" and "a_empty" work as you want. They will have unwanted "glitches".but is it good for a synchronous fifo?
new_write_address <= write_address + 1 ;
writing : process ( clock , reset ) is
begin
if reset = '1' then
write_address <= ( others => '0' ) ;
almost_full <= '0' ;
full <= '0' ;
elsif rising_edge ( clock ) then
if ( read_address - write_address <= almost_full_threshold ) and empty = '0' then
almost_full <= '1' ;
else
almost_full <= '0' ;
end if ;
if write_request = '1' and full = '0' then
write_address <= new_write_address ;
if new_write_address = read_address then
full <= '1' ;
end if ;
end if ;
if read_request = '1' then
full <= '0' ;
end if ;
end if ;
end process writing ;
new_read_address <= read_address + 1 ;
reading : process ( clock , reset ) is
begin
if reset = '1' then
read_address <= ( others => '0' ) ;
almost_empty <= '1' ;
empty <= '1' ;
elsif rising_edge ( clock ) then
if ( write_address - read_address <= almost_empty_threshold ) and full = '0' then
almost_empty <= '1' ;
else
almost_empty <= '0' ;
end if ;
if read_request = '1' and empty = '0' then
read_address <= new_read_address ;
if new_read_address = write_address then
empty <= '1' ;
end if ;
end if ;
if write_request = '1' then
empty <= '0' ;
end if ;
end if ;
end process reading ;
It seems that you found the bugs in #65 and fixed them.I simulated the design and couldn't find any problems...
Do you see something wrong with it?
*This is for a synchronous FIFO...
The problem will be the clock domain crossing.
Hardware design have little similarity with software design. The concept is already different. when designing hardware you must consider platform's(i.e FPGA) limitation and resources .You can never find a HDL that work same on different platform. Atleast timing is different.so forgot about generic code that work every where. HDL is abbreviation of hardware describing language so using it is natural for describing hardware. if you have doubt just synthesys two or three approach to find out what is differences.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?