shaiko
Advanced Member level 5
- Joined
- Aug 20, 2011
- Messages
- 2,644
- Helped
- 303
- Reputation
- 608
- Reaction score
- 297
- Trophy points
- 1,363
- Activity points
- 18,302
I'm designing an asynchronous fifo.
My read and write pointers are generated in one clock domain, encoded to gray and transffered to the other clcok domain, decoded and compared.
Now, to generate the control flags (almost_full , full , almost_empty , empty) I use the actual read and write requests double synchronized to the appropriate clock domains (marked in red). I think this is a bad approach because these might not synchronize well and get missed.
Please propose a solution to the problem.
My read and write pointers are generated in one clock domain, encoded to gray and transffered to the other clcok domain, decoded and compared.
Now, to generate the control flags (almost_full , full , almost_empty , empty) I use the actual read and write requests double synchronized to the appropriate clock domains (marked in red). I think this is a bad approach because these might not synchronize well and get missed.
Please propose a solution to the problem.
Code:
--------------------------------------------
-----------WRITE CLOCK DOMAIN---------------
--------------------------------------------
registering_read_request_to_write_clock_domain : process ( write_clock , reset ) is
begin
if reset = '1' then
temp_write_request_synchronized_to_read_domain <= '0' ;
write_request_synchronized_to_read_domain <= '0' ;
elsif rising_edge ( write_clock ) then
temp_write_request_synchronized_to_read_domain <= write_request ;
[COLOR="#FF0000"]write_request_synchronized_to_read_domain[/COLOR] <= temp_write_request_synchronized_to_read_domain ;
end if ;
end process registering_read_request_to_write_clock_domain ;
completely_and_almost_empty_flags : process ( write_clock , reset ) is
begin
if reset = '1' then
completely_empty <= '1' ;
almost_empty <= '0' ;
elsif rising_edge ( write_clock ) then
if read_pointer /= write_pointer_synchronized_to_read_domain then
if write_pointer_synchronized_to_read_domain - read_pointer <= almost_empty_threshold then
almost_empty <= '1' ;
else
almost_empty <= '0' ;
end if ;
end if;
if [COLOR="#FF0000"]write_request_synchronized_to_read_domain[/COLOR] = '1' then -- questinable synchronization success
completely_empty <= '0' ;
end if ;
end if ;
end process completely_and_almost_empty_flags ;
--------------------------------------------
-----------READ CLOCK DOMAIN----------------
--------------------------------------------
registering_write_request_to_read_clock_domain : process ( read_clock , reset ) is
begin
if reset = '1' then
temp_read_request_synchronized_to_write_domain <= '0' ;
read_request_synchronized_to_write_domain <= '0' ;
elsif rising_edge ( write_clock ) then
temp_read_request_synchronized_to_write_domain <= read_request ;
[COLOR="#FF0000"]read_request_synchronized_to_write_domain[/COLOR] <= temp_read_request_synchronized_to_write_domain ;
end if ;
end process registering_write_request_to_read_clock_domain ;
completely_and_almost_full_flags : process ( read_clock , reset ) is
begin
if reset = '1' then
completely_full <= '1' ;
almost_full <= '0' ;
elsif rising_edge ( read_clock ) then
if write_pointer /= read_pointer_synchronized_to_write_domain then
if read_pointer_synchronized_to_write_domain - write_pointer <= almost_full_threshold then
almost_full <= '1' ;
else
almost_full <= '0' ;
end if ;
end if;
if [COLOR="#FF0000"]read_request_synchronized_to_write_domain[/COLOR] = '1' then -- questinable synchronization success
completely_full <= '0' ;
end if ;
end if ;
end process completely_and_almost_full_flags ;