Don't have a Xilinx account yet?

  • Choose to receive important news and product information
  • Gain access to special content
  • Personalize your web experience on Xilinx.com

Create Account

Username

Password

Forgot your password?
XClose Panel
Xilinx Home
Reply
Contributor
zecary
Posts: 25
Registered: ‎03-24-2012
0
Accepted Solution

How to write small FIFO in vhdl in Spartan 6

Hi all,

 

I'm using several "small" FIFOs in my network design as virtual channel buffers. The FIFO width (width of one flit in each packet) is not fixed, maybe 10 bits or 36 bit, but the depth needs to be small. Theoretically, TWO or FOUR flits is enough. By considering the big amount of FIFOs in my design, the depth should be as small as possible.

 

But right now, I could only use CORE generator to build the FIFO which the smallest FIFO is 16  in depth. I tried to write my own fifo in VHDL but then I found the XST used FF to build the memory part for my FIFO but not DRAM(LUT). This really consume a lot of hardware resources.For a single 36bits * 2 ram, I got this from synthesis report:

 

Synthesizing Unit <reg_vhdl_DRAM>.
    Related source file is "c:/cz/fifo_mem_test2/reg_vhdl_dram.vhd".
        DATA_W = 36
        ADDR_W = 1
    Found 36-bit register for signal <reg_c<0>>.
    Found 36-bit register for signal <reg_c<1>>.

 

And I changed the address width from 1 to 4 in order to make a 36bis * 16 ram, I got this

INFO:Xst:3019 - HDL ADVISOR - 576 flip-flops were inferred for signal <reg_c>. You may be trying to describe a RAM in a way that is incompatible with block and distributed RAM resources available on Xilinx devices, or with a specific template that is not supported. Please review the Xilinx resources documentation and the XST user manual for coding guidelines. Taking advantage of RAM resources will lead to improved device usage and reduced synthesis time.

 

Is there a way to write small RAM in VHDL by using the DRAM or LUT instead of FF in spartan6? How to make the depth of RAM be smaller than 16 or be any number I want?

 

Thanks in advance.

 

 

Super Contributor
eschabor
Posts: 110
Registered: ‎08-12-2011
0

Re: How to write small FIFO in vhdl in Spartan 6

There are limitations to how finely the hardware in FPGAs can be configured.  

 

Xilinx FPGAs use 4 input LUTs or 6 input LUTs (it depends on which FPGA family - the newer ones all use 6 input LUTs). When a FIFO is implemented using LUT4s the smallest efficient depth is 16.  For LUT6s the smallest efficient depth is 64.

 

Fortunately the width can be almost any number of bits, with good utilisation efficiency.

 

If you're really squeezed for space you can trade off width against depth.  For example a 3 deep 5 bit wide FIFO can be converted to a 15 deep 1 bit wide FIFO by serialising and deserialising - converting each incoming 5 bit word into 5 single bit writes and on the other side of the FIFO concatenating groups of five single bit reads into 5 bit output words.  

 

There are serious limitations to the approach just outlined:

* the operation frequency increases by the factor of FIFO thinning.  That may or may not be a problem in your application.

* the extra logic to implement serialisation and deserialisation may exceed the logic saved.  In the trivial 3 * 5 example above that would be the case.  If you can fold the serialisation and deserialisation into the source logic and sink logic of the FIFO then you may still end up with a win.

 

Stephen Ecob
Silicon On Inspiration
Sydney Australia
www.sioi.com.au
Spartan 6 LX25 with 2GB DDR3 DIMM for $299:
http://www.sioi.com.au/shop/product_info.php/cPath/24/products_id/55

 

Expert Contributor
eilert
Posts: 2,426
Registered: ‎08-14-2007
0

Re: How to write small FIFO in vhdl in Spartan 6

[ Edited ]

Hi,

the error message is already giving you a hint.

Your description probably contains some statement that are incompatible with Distributed-RAMs.

e.g. such blocks can not have a reset, since a LUT is not resettable.

(You haven't provided your code, so nothing more specific can be said)

 

Please take a look at the coding examples in the ISE Language Templates.

Try to follow these templates as close as possible to acheive the desired synthesis result.

 

Defining the FIFO/RAM size smaller than 16 should not be a problem.

 

You might also take a look at some small FIFO examples  e.g as provided for the UART that comes with the Picoblaze processor. Also gbredthauer has published some FIFO code in the forum or on his own webpage as part of his mcs16 cpu.

 

Have a nice synthesis

  Eilert

Contributor
zecary
Posts: 25
Registered: ‎03-24-2012
0

Re: How to write small FIFO in vhdl in Spartan 6

Thanks, Stephe. I think I get your idea. You mean I can add, for example, mux at the end of fifo output to serialise the wide data further into small piece? 

Contributor
zecary
Posts: 25
Registered: ‎03-24-2012
0

Re: How to write small FIFO in vhdl in Spartan 6

Thanks, Eilert. I've found gbredthauer's website. It's really a good a reference, I will compare my code to his. Just for curiosity, I still want to know how to find the DRAM language template and UART for PicoBlaze in ISE. I'm using 13.4. What I found last night is Device Primitive Instantiation for spartan6. Inside of Distributed RAM, there are three types fixed-size options which are Dual-port, multi-port, and single-port. You mean this one? 

 

And this is my code. It has the reset signal. I will try one without it to see if it helps. More advices are highly welcome. Thanks

 

entity reg_vhdl_DRAM is
    GENERIC( DATA_W : integer := 36;
               ADDR_W : integer := 1);
    PORT( clk : in  STD_LOGIC;
           rst : in  STD_LOGIC;
            w_addr: in STD_LOGIC_VECTOR(ADDR_W-1 downto 0);
            r_addr: in STD_LOGIC_VECTOR(ADDR_W-1 downto 0);
            w_en : in STD_LOGIC;
            din : in STD_LOGIC_VECTOR(DATA_W-1 downto 0);
            dout : out STD_LOGIC_VECTOR(DATA_W-1 downto 0)
            );
end reg_vhdl_DRAM;

architecture Behavioral of reg_vhdl_DRAM is

    type reg_type is array (natural range<>) of STD_LOGIC_VECTOR(DATA_W-1 downto 0);
    signal reg_c : reg_type(2**ADDR_W-1 downto 0) := (others => (others => '0'));
    
begin

    dout <= reg_c(conv_integer(r_addr));
    
    process (clk)
    begin
        if rising_edge(clk) then
            if rst = '1' then
                for i in 0 to (2**ADDR_W)-1 loop
                    reg_c(i) <= (others => '0');
                end loop;
            else
                if w_en = '1' then
                    reg_c(conv_integer(w_addr)) <= din;
                end if;    
            end if;
        end if;        
    end process;

end Behavioral;

 

 

Expert Contributor
gszakacs
Posts: 7,012
Registered: ‎08-14-2007
0

Re: How to write small FIFO in vhdl in Spartan 6

The reason you're getting flip-flops instead of distributed RAM is the reset logic:

 

            if rst = '1' then
                for i in 0 to (2**ADDR_W)-1 loop
                    reg_c(i) <= (others => '0');
                end loop;

 

There's really no reason to reset the memory behind the FIFO.  Just reset the write and

read pointers so the FIFO starts up empty.  Without the reset, you FIFO can use distributed memory.

 

By the way, I've found that the smallest FIFO implementations for a single-clock FIFO use the

"SRL" components.  Check out this thread.

 

-- Gabor

-- Gabor
Super Contributor
eschabor
Posts: 110
Registered: ‎08-12-2011
0

Re: How to write small FIFO in vhdl in Spartan 6

Thanks, Stephe. I think I get your idea. You mean I can add, for example, mux at the end of fifo output to serialise the wide data further into small piece? 


I think you've got the idea.

 

Gabor's advice about SRLs is good, do take a look at the thread he links to.

 

Stephen

 

Contributor
zecary
Posts: 25
Registered: ‎03-24-2012
0

Re: How to write small FIFO in vhdl in Spartan 6

Thanks Gabor, That's really helpful.

Contributor
zecary
Posts: 25
Registered: ‎03-24-2012
0

Re: How to write small FIFO in vhdl in Spartan 6

Gabor,

 

These warnings are what I got when I tried to Map this code. The memory width is 36 bits, and depth is 2.

 

WARNING:Par:288 - The signal Mram_data1_RAMD_D1_O has no load.  PAR will not attempt to route this signal.
WARNING:Par:288 - The signal Mram_data4_RAMD_D1_O has no load.  PAR will not attempt to route this signal.
WARNING:Par:288 - The signal Mram_data3_RAMD_D1_O has no load.  PAR will not attempt to route this signal.
WARNING:Par:288 - The signal Mram_data5_RAMD_D1_O has no load.  PAR will not attempt to route this signal.
WARNING:Par:288 - The signal Mram_data2_RAMD_D1_O has no load.  PAR will not attempt to route this signal.

 

Why? I'm using Spartan6, is it because the fifo's word width do not fit to LUT6? It seems that these warning bring me some serious problems in the later post-map simulation for my design with this type memeory file in FIFO.

 

at 2928423 ps(1), Instance /testbench/I_noc/NoC_gen_nodes_3_AP_CHANNEL_p01_vc_FIFO_Gen_0_FIFO_Gen_True_Inst_vc_wholepackage_wr_ptr_0/ : Warning: /X_SFF HOLD Low VIOLATION ON CE WITH RESPECT TO CLK;

Expected := 0.415 ns; Observed := 0.336 ns; At : 2928.423 ns


This is what I got from ISim, I'm not sure if this is coming from the former warnnings. But those are the only unusual information I get through all steps of synthesis. How could I revise the VHDL code? Thanks you very much.

Expert Contributor
gszakacs
Posts: 7,012
Registered: ‎08-14-2007
0

Re: How to write small FIFO in vhdl in Spartan 6

Without knowing more about how you have hooked up the memories, I can only assume that

some of the output bits of the FIFO are not used in the design, causing the loads of the memory

to get removed.  It's not clear why the associated DRAM is not also removed.  Do you have more

that one instance of the FIFO in youre design?  If so it may be just a single bit from each one

being reported.  You have to try to follow the hierarchy of the path name being reported.  It might

help if you change the setting for hierarchy separator character from "_" to "/" in the synthesis options.

 

The simulation issue seems clear enough - you are not getting enough hold time on the

write enable signal under some circumstances.  Make sure that write enable is synchronous

to the write clock, and if it comes from a test bench make sure it has enough hold time to meet

the requirements at the input pad.  You should be able to get the hold time from the datasheet

section of the post P&R static timing report.

 

-- Gabor

-- Gabor