I'm trying to infer the usage of a RAM block of my FPGA, but I fail to understand what are the hints needed. I use Synplify Pro as my synthesis tool. If I'm not mistaken, this is a dual port synchronous RAM that I need to infer.

library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

entity fifo is
    constant DATA_WIDTH : integer;
    constant FIFO_DEPTH : integer
    clk       : in std_logic;
    mmc_clk   : in std_logic; 
    reset     : in std_logic;
    spi_done  : in std_logic;
    rx_data   : in std_logic_vector(7 downto 0);

    write_en  : in std_logic;
    read_en   : in std_logic;

    data_out  : out std_logic_vector(7 downto 0);
    data_in   : in std_logic_vector(7 downto 0);
    empty_o   : out std_logic;
    full_o    : out std_logic;

    level_o   : out std_logic_vector(7 downto 0)
end fifo;

architecture arch of fifo is

signal mmc_clk_prev, mmc_clk_i : std_logic;


-- Memory Pointer Process
fifo_proc : process (CLK)
    type FIFO_memory is array (0 to FIFO_DEPTH-1) of std_logic_vector(DATA_WIDTH - 1 downto 0);
    variable memory : FIFO_memory;

    variable head : integer range 0 to FIFO_DEPTH - 1;
    variable tail : integer range 0 to FIFO_DEPTH - 1;

    variable looped : boolean;
    if reset = '1' then
        head := 0;
        tail := 0;
        looped := false;
        full_o  <= '0';
        empty_o <= '1';
    elsif rising_edge(CLK) then
        if (read_en = '1') then
            if ((looped = true) or (head /= tail)) then
                -- Update data output
                data_out <= memory(tail);
                -- Update tail pointer as needed
                if (tail = FIFO_DEPTH - 1) then
                    tail := 0;
                    looped := false;
                    tail := tail + 1;
                end if;
            end if;
        end if;

        if (write_en = '1') then
            if ((looped = false) or (head /= tail)) then
                -- Write Data to memory
                memory(head) := data_in;
                -- Increment head pointer as needed
                if (head = FIFO_DEPTH - 1) then
                    head := 0;
                    looped := true;
                    head := head + 1;
                end if;
            end if;
        end if;

        -- Update empty_o and full_o flags
        if (head = tail) then
            if looped then
                full_o <= '1';
                empty_o <= '1';
            end if;
            empty_o   <= '0';
            full_o    <= '0';
        end if;
    end if;

    if head-tail >= 0 then
        level_o <= std_logic_vector(to_unsigned(head-tail,level_o'length));
    end if;
end process;

end arch;

What am I missing?

  • \$\begingroup\$ Is this more of a software issue or a hardware issue? \$\endgroup\$
    – user105652
    Commented Jul 26, 2016 at 17:47
  • \$\begingroup\$ What do you mean? My FIFO can store up to 128 bytes, I want to be able to store them into one of the RAM block of my FPGA to reduce LUTs usage \$\endgroup\$
    – Fluffy
    Commented Jul 26, 2016 at 17:49
  • \$\begingroup\$ Try using signals instead of variables and try to simplify the process a bit (e.g. all the tail/head stuff can go to a separate process). Software is always a bit picky to recognize such constructs in complicated processes. \$\endgroup\$
    – asdfex
    Commented Jul 26, 2016 at 18:10
  • \$\begingroup\$ As @asdfex wrote : Try putting the RAM in a separate, simple process. There may be also some synthesis options, 128 bytes may be considered too small as default for a block RAM, check the synthesis report. \$\endgroup\$
    – Grabul
    Commented Jul 26, 2016 at 18:31
  • \$\begingroup\$ What is the target architecture? Altera, Lattice, Xilinx, ...? I suspect your target BlockRAM has no read enable (you described one), which is not needed for a FIFO memory. \$\endgroup\$
    – Paebbels
    Commented Jul 27, 2016 at 7:05

2 Answers 2


I would recommend making a separate dual port ram similar to the one here and using it as a building block for your FIFO. I understand that will make your design a little more cumbersome, however the synthesis tool will actually be able to infer a dual port ram.

  • \$\begingroup\$ Yes. Separating the pointer logic and the dual-port RAM logic will greatly improve the ability for the synthesizer to infer hardware blocks. A vendor may even (often does) provide IP that generates the assuredly-correct mapping onto memory blocks. \$\endgroup\$ Commented Oct 25, 2016 at 3:17

Have you tried the syn_ramstyle attribute.

Refer to http://www.ece.ucdavis.edu/~soheil/teaching/EEC180B-S06/inferring_blockRAMs.pdf

So, in your case, the code would look something like this:

attribute syn_ramstyle : string;
attribute syn_ramstyle of memory : signal is "block_ram";



Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.