- Joined
- Sep 10, 2013
- Messages
- 7,944
- Helped
- 1,823
- Reputation
- 3,656
- Reaction score
- 1,808
- Trophy points
- 1,393
- Location
- USA
- Activity points
- 60,209
UNISIM library....Therefore it's on a Xilinx.std_match said:On what device did you develop the shift register FIFO? Which families has the FDCE_1?
"
Behavioral code is good but when you write code in more abstract fashion, you lose something that is vital for high performance hardware(i.e. manual placement).As you can see in good practices most of them write code in RTL rather than behavioral or structural except for TestBench Writing and environment modeling.
Said like a true working engineer, that is told 3 months into the project (after you've already produced the design specification and the majority of the RTL) that the device vendor you chose wasn't cost effect so they want you to use a different vendors parts because they can get them for a huge discount.I'm trying to write generic, reusable IPs whenever possible. While your design example is tailored to a specific device vendor and won't be easily portable to a different one.
The delusion of job security?I don't understand the motivation behind such approach - if your FIFO can't be easily ported, why bother describing it with HDL anyways?
entity fifo_management is
port
(
clock : in std_logic ;
reset : in std_logic ;
write_request : in std_logic ;
read_request : in std_logic ;
full : out std_logic ;
empty : out std_logic ;
data_out : out std_logic_vector ;
read_address : out std_logic_vector ( 2 downto 0 ) ;
write_address : out std_logic_vector ( 2 downto 0 )
) ;
end entity fifo_management ;
architecture rtl_fifo_management of fifo_management is
signal new_write_pointer : unsigned ( 3 downto 0 ) ;
signal new_read_pointer : unsigned ( 3 downto 0 ) ;
begin
write_address <= write_pointer ( write_pointer ' high - 1 downto 0 ) ;
read_address <= read_pointer ( read_pointer ' high - 1 downto 0 ) ;
new_write_pointer <= write_pointer + 1 ;
new_read_pointer <= read_pointer + 1 ;
write_domain : process ( clock , reset ) is
begin
if reset = '1' then
write_pointer <= ( others => '0' ) ;
full <= '0' ;
elsif rising_edge ( clock ) then
if write_request = '1' and full = '0' then
write_pointer <= new_write_pointer ;
if new_write_pointer = read_pointer then
full <= '1' ;
end if ;
end if ;
if read_request = '1' then
full <= '0' ;
end if ;
end if ;
end process write_domain ;
read_domain : process ( clock , reset ) is
begin
if reset = '1' then
read_pointer <= ( others => '0' ) ;
empty <= '0' ;
elsif rising_edge ( clock ) then
if read_request = '1' and empty = '0' then
read_pointer <= new_read_pointer ;
if new_read_pointer = write_pointer then
empty <= '1' ;
end if ;
end if ;
if write_request = '1' then
empty <= '0' ;
end if ;
end if ;
end process read_domain ;
end architecture rtl_fifo_management ;
I don't understand how you can tell how full the FIFO is without doing math on the pointers. Please insert your example into my code.I would write it by having an explicit counter to keep track of how full the fifo is at any time and wouldn't bother with trying to do math on the pointers.
I don't understand how you can tell how full the FIFO is without doing math on the pointers. Please insert your example into my code.
if write = '1' and read = '0' then
if how_full = N-1 then
full <= '1'
end if;
if how_full = 0 then
empty <= '0'
end if;
how_full <= how_full + 1;
elsif write = '0' and read = '1' then
if how_full = 1 then
empty <= '1';
end if;
if how_full = N then
full <= '0';
end if;
how_full <= how_full - 1;
end if;
I can confirm that at least the Altera Quartus FIFO IP is using this method. They have separate counters for read pointer, write pointer and used datawords. Quartus users can review the a_dpfifo.tdf and a_fefifo.tdf AHDL sources. There's also a fast FF based FIFO option, may be similar to the handcoded version by Miralipoor.- I would write it by having an explicit counter to keep track of how full the fifo is at any time and wouldn't bother with trying to do math on the pointers.
Code:if write = '1' and read = '0' then if how_full = N-1 then full <= '1' end if; if how_full = 0 then empty <= '0' end if; how_full <= how_full + 1; elsif write = '0' and read = '1' then if how_full = 1 then empty <= '1'; end if; if how_full = N then full <= '0'; end if; how_full <= how_full - 1; end if;
if write = '1' and read = '0' then
if how_full = N-1 then
full <= '1'
end if;
empty <= '0'
end if;
how_full <= how_full + 1;
elsif write = '0' and read = '1' then
if how_full = 1 then
empty <= '1';
end if;
full <= '0';
how_full <= how_full - 1;
end if;
Please clarify...of course, more logic would be needed to avoid overflows and underflows
Used data words still works with two clock domains, you simply have counters in both domains. From that you can generate all the flags you need in both domains.When read and write are in different clock domains, you can forget the "used datawords" counter. Flags must be generated from the pointers, and it isn't trivial.
Used data words still works with two clock domains, you simply have counters in both domains. From that you can generate all the flags you need in both domains.
What goes away with two clock domains is the whole concept of a single global status (i.e. 'empty', 'full' cannot be reported globally, only within a clock domain which will involve clock domain synchronizer latency).
Both count how much is in the fifo from within their own clock domain.Can you explain what you mean with "counters in both domains"?
What do they count?
What you do is create two sets of flags, each set is synchronized with one of the clock domains. There would be 'rdempty' and 'wrempty', which is the fifo empty status based on the used words counter in the read clock domain (for 'rdempty') and the used words counter in the write clock domain (for 'wrempty'). Do the same for full, and the 'almost' flags.You can not create an "empty" or "almost empty" flag without using signals from both clock domains.
That is not always true. There are applications where the writer needs to know the fifo is empty or almost empty as well as applications where the reader needs to know that the fifo is full or almost full.Also, I don't understand what you mean with a global "empty" signal. Only the read side needs the "empty" flag
That's because there is no single 'full', 'empty', etc. Instead there are flags in both domains that are set based on the used words counter in each clock domain. Signals 'rdempty' and 'wrfull' will have the required behavior to prevent underflow/overflow. Signals 'wrempty' and 'rdfull' are status signals synchronized with the appropriate clock which can be freely used by the reader or writer since they are synchronized. There will be additional latency in generating those signals, but they wouldn't be used for low level control of the fifo anyway so that's OK.I can't see how counters in both domains will help in creating "empty", "full" or the corresponding "almost" flags.
I am missing something here. The counter in the write domain would only increment and the counter in the read domain would only decrement. How can they count in the other direction?Both count how much is in the fifo from within their own clock domain.
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.I typically use the read and write counter approach for single clock domain FIFOs and grey pointer transfers for asynchronous FIFOs. Occasionally I'll implement the more complex read and write counter asynchronous FIFO when I need the count values for other reasons
They would count in the other direction after receiving a synchronized command from the other side.I am missing something here. The counter in the write domain would only increment and the counter in the read domain would only decrement. How can they count in the other direction?
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?