Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

BRAM based FIFO buffer for matrix multiplication

Status
Not open for further replies.

maha_66

Newbie level 4
Joined
Jun 30, 2018
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
57
Hello! I am currently working on a matrix multiplication project. After performing the multiplication of the matrices, I am trying to build a module that can write to memory and can be read from by the UART TX module to send to host pc. What I don't understand is how does inferring a BRAM make it function as a FIFO? Do I need a separate module for a fifo buffer unit? The VHDL book I use has a sentence that I am not sure I understand completely: "Infact, the BRAM module of the Artix device can be configured as a FIFO buffer without any extrernal logic."

I have the following code for inferring a Simple(Sync) Dual Port BRAM for the Matrix Result:



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
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity bram_simpledual is
 
generic( ADDR_WIDTH: integer := 4;
         DATA_WIDTH: integer := 16
            );
  Port (    
            clk : in std_logic;
            we : in std_logic ;
            addr_r, addr_w : in std_logic_vector (ADDR_WIDTH - 1 downto 0);
            din_a : in std_logic_vector (DATA_WIDTH - 1 downto 0);
            dout : out std_logic_vector (DATA_WIDTH - 1 downto 0) 
            );
end bram_simpledual;
 
 
architecture beh_arch of bram_simpledual is
    type ram_type is array (0 to 2** ADDR_WIDTH - 1) of std_logic_vector (DATA_WIDTH - 1 downto 0);
    signal ram: ram_type;
begin
    process(clk)
    begin
        if(clk'event and clk = '1')then
            if(we = '1')then
                ram(to_integer(unsigned(addr_w))) <= din_a;
            end if;
            dout <= ram(to_integer(unsigned(addr_r)));
        end if;
     end process;
    
end beh_arch;


 
Last edited by a moderator:

Hi maha_66,
the most simple solution is to use predefined modules/macros: See https://www.xilinx.com/support/docu...linx2018_2/ug953-vivado-7series-libraries.pdf

In your case the XPM_FIFO_SYNC macro would be ideal, or maybe XPM_FIFO_AXIS in case you need some kind of handshaking. Inference of FIFOs is always a pain - better solution is to have some wrapper module, which wraps the macro instantiation, and when moving to other FPGA vendors or families, just replace this implementation.
 

Inferring a BRAM does not make it function as a FIFO, it makes it function as a BRAM. You would have to use Coregen to create a FIFO
 

Inferring a BRAM does not make it function as a FIFO, it makes it function as a BRAM. You would have to use Coregen to create a FIFO

You can make your own FIFO using an infered BRAM. All a FIFO is a ram with control around it to pull the data out in the same order it went it. This requires read and write pointers and control logic to increment the pointers as data is written/read. Plus maybe some logic to ensure the counters cannot be put into an overrun/underrun state (where read/write pointers overtake each other).

While the coregen FIFO (XPM would be better if using Ultrascale devices), or Intel Megawizard/IP Catalog (again, using the SCFIFO yourself gives greater flexability) provide all of this functionality for you, there is not reason you cannot write a FIFO yourself.
 

You can make your own FIFO using an infered BRAM. All a FIFO is a ram with control around it to pull the data out in the same order it went it. This requires read and write pointers and control logic to increment the pointers as data is written/read. Plus maybe some logic to ensure the counters cannot be put into an overrun/underrun state (where read/write pointers overtake each other).

While the coregen FIFO (XPM would be better if using Ultrascale devices), or Intel Megawizard/IP Catalog (again, using the SCFIFO yourself gives greater flexability) provide all of this functionality for you, there is not reason you cannot write a FIFO yourself.
I think there are a lot of reasons not to write a FIFO yourself. Dealing with clock-domain crossing and collision issues is not trivial. Available IP is (presumably) thoroughly tested and validated. Further, IP modules are optimized for the specific architecture where they will be placed.
 

I think there are a lot of reasons not to write a FIFO yourself. Dealing with clock-domain crossing and collision issues is not trivial. Available IP is (presumably) thoroughly tested and validated. Further, IP modules are optimized for the specific architecture where they will be placed.

Yes, but OP has a single clock. So its pretty trivial. If you need cross platform support then making your own infered FIFO is often a plus.

Either way, I would personally usually use Vendor IP when I need a FIFO (Although I detest coregen - as it's not flexible. XPM fifos and Altera's DC/SCFIFO can be parameterised in your HDL)
 

Thank you for the help.
So does this mean every time I infer a BRAM for a project, I need to instantiate a FIFO using the methods suggested? I will be sending data to a UART transmitter to send to a host PC. Can I send data from the bram_fifo module to a UART TX?
 

I think you're getting your brain tied in knots. If you want a BRAM, instsntiate a BRAM. If you want a FIFO, instantiate a FIFO.
 

Thank you for the help.
So does this mean every time I infer a BRAM for a project, I need to instantiate a FIFO using the methods suggested? I will be sending data to a UART transmitter to send to a host PC. Can I send data from the bram_fifo module to a UART TX?

Lets Clarify.
1. A Ram is a design element that can store >1 words where data is written and read via an address interface. A BRAM (Block ram) is the name of a primitive type of ram available on Xilinx devices. RAM can also be created from LUTs (LUTRAM). On Altera Devices you have M9Ks or M20ks. These are all types of ram and function roughly the same.
2. A FIFO (first in first out) is a design concept where words are read from the unit in the same order they were written. They are usually built using a RAM and other control logic. You can either write your own or instantiate a FIFO IP from the vendor (I would recommend the vendor IP)
3. RAM can also be instantiated from Vendor IP. Or it can be inferred from your HDL code. If you want to infer ram then you need to ensure that you code matches the design patterns specified by the vendor to ensure a RAM is inferred.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top