In fact, in the first design I tried, the reading was in the process and it didn't infer. When I googled it I found that it has to be outside (http://www.alteraforum.com/forum/showthread.php?t=28242).
But now I found a solution. I first put an inferable ram block (thanks to the previous thread), and then I just rewrite it.
architecture arch of fifo is
signal sRead_ptr : unsigned(unsigned_num_bits(depth-1)-1 downto 0) := (others => '0');
signal sWrite_ptr : unsigned(unsigned_num_bits(depth-1)-1 downto 0) := (others => '0');
type ram_t is array (0 to depth-1) of std_logic_vector(data_in'range);
signal sRam : ram_t;
signal sAddr_read : std_logic_vector(sRead_ptr'range);
begin
pRam : process(clk) is
begin
if rising_edge(clk) then
if W = '1' then
sRam(to_integer(sWrite_ptr)) <= data_in;
end if;
sAddr_read <= std_logic_vector(sRead_ptr);
end if;
end process pRam;
data_out <= sRam(to_integer(unsigned(sAddr_read)));
pRead_ptr : process(clk) is
begin
if rising_edge(clk) and EN = '1'then
if R = '1' then
if sRead_ptr > to_unsigned(depth-2, sRead_ptr'length) then
sRead_ptr <= (others => '0');
else
sRead_ptr <= sRead_ptr + 1;
end if;
end if;
end if;
end process pRead_ptr;
pWrite_ptr : process(clk) is
begin
if rising_edge(clk) and EN = '1'then
if W = '1' then
if sWrite_ptr > to_unsigned(depth-2, sWrite_ptr'length) then
sWrite_ptr <= (others => '0');
else
sWrite_ptr <= sWrite_ptr + 1;
end if;
end if;
end if;
end process pWrite_ptr;
end architecture arch;