It not "unsafe" in the meaning "may not work". I mean that you don't know what the synthesis tool will do. Do you want to write code that can generate 1 or 2 adders, when it is enough with 1 adder?I don't see how it can be "unsafe"...
Clear.It not "unsafe" in the meaning "may not work". I mean that you don't know what the synthesis tool will do.
write_flags_and_queue : process ( clock , reset ) is
begin
if reset = '1' then
full <= '0' ;
write_pointer <= ( others => '0' ) ;
elsif rising_edge ( clock ) then
if write_request = '1' and full = '0' then
write_pointer <= write_pointer + 1 ;
end if ;
if
( write_pointer_next ( write_pointer_next ' high - 1 downto 0 ) =
read_pointer ( read_pointer ' high - 1 downto 0 ) ) and
( write_pointer_next ' high /= read_pointer ' high ) then
full < = '1' ;
else
full < = '0' ;
end if ;
end process write_flags_and_queue ;
The "full" flag can be set even if there is a read request in the same clock cycle.Please point out why it won't work with a combined read/write operation...
shaiko is now comparing with "write_pointer_next" which is assigned "write_pointer + 1" outside of a clocked process, so it is correct (except for simultaneous read and write).The problem, as has already been pointed out, is that the full and empty flags are delayed by 1 clock compared to the read and write pointers.
It is exactly the cases you mention. The "empty" and "full" flags will be set for one clock cycle in those situations. Maybe "fail" is a strong word for this, but it is not optimal.I'm simulating the design with simultaneous read/write and can't make it fail.
Please point out the conditions in which you think it will fail.
For example, when the fifo is one address from being full and a simultaneous write/read request occurs, when the fifo is one address from being empty and a simultaneous read/write occurs, etc...
signal write_pointer, read_pointer, write_request, read_request;
variable new_write_pointer;
-- write process
if reset = '1' then
full <= '0' ;
write_pointer <= ( others => '0' ) ;
elsif rising_edge(clock) then
new_write_pointer := write_pointer + 1;
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;
write_queue : process ( clock , reset ) is
begin
if reset = '1' then
write_pointer <= ( others => '0' ) ;
elsif rising_edge ( clock ) then
if write_request = '1' and full = '0' then
write_pointer <= write_pointer + 1 ;
end if ;
end if ;
end process write_queue ;
full <= '1' when
( write_pointer_next ( write_pointer_next ' high - 1 downto 0 ) =
read_pointer ( read_pointer ' high - 1 downto 0 ) ) and
( write_pointer_next ' high /= read_pointer ' high )
else '0' ;
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_write_pointer = read_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 ;
No, you have 2 typos in the read process in the following lineIs this fail proof ?
if new_write_pointer = read_pointer then
No, you have 2 typos in the read process in the following line
Code:if new_write_pointer = read_pointer then
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 --In the name Of ***** --Author Mehdi Miralipoor --Description : High performance Fifo Module --Date: --Revision: Library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; Library UNISIM; use UNISIM.vcomponents.all; Entity HFifo is Generic (DataWidth:natural:=8;Depth:natural:=10); port ( clk,rst:std_logic; DataOut:out std_logic_vector(DataWidth-1 downto 0); DataIn:in std_logic_vector(DataWidth-1 downto 0); pop:in std_logic; push:in std_logic; isFull:out std_logic; isnEmpty:out std_logic ); end HFifo; Architecture RTL of HFifo is signal beans:std_logic_vector(Depth-1 downto 0); type fifoArrayT is Array(Depth-1 downto 0) of std_logic_vector(DataWidth-1 downto 0); signal fifoArray:fifoArrayT; signal en:std_logic_vector(Depth-1 downto 0); begin isnEmpty<=beans(0) ; isFull<= beans(Depth-1) and beans(Depth-2); en(0)<=pop or not(beans(0)); ens_ins:for i in Depth -2 downto 1 generate en(i)<=(not (beans(i-1)) )or (not (beans(i))) or pop ; end generate; en(Depth-1)<=(not beans(Depth-2)) or (push and (not beans(Depth-1))) or pop ; beanDepthMDepth_1 : FDCE_1 port map ( Q => beans(Depth-1), C => clk, CE => en(Depth-1), CLR => rst, D => push ); beans_ins:for i in Depth -2 downto 0 generate BeansFDCE : FDCE_1 port map ( Q => beans(i), C => clk, CE => en(i), CLR => rst, D => beans(i+1) ); end generate; WordGenerate0:for j in DataWidth-1 downto 0 generate Word0FDCE : FDCE_1 port map ( Q => fifoArray(Depth-1)(j), C => clk, CE => en(Depth-1), CLR => rst, D => DataIn(j) ); end generate; FifoArray_ins:for i in Depth -2 downto 0 generate WordGenerate:for j in DataWidth-1 downto 0 generate WordsFDCE : FDCE_1 port map ( Q => fifoArray(i)(j), C => clk, CE => en(i), CLR => rst, D => fifoArray(i+1)(j) ); end generate; end generate; DataOut<=fifoArray(0); end RTL;
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?