Search code examples
vhdlxilinxvivado

combine ports to bram interface


I want to write an IP to store/read data using BRAM.

What I have so far is using the (C)DMA to read memory mapped data out of the RAM and get an AXIS.

Then I created a new source file in VHDL to accept the AXIS on one side which worked like a charm. On the other side I want to create a BRAM interface but vivado does not combine ports for the BRAM interface.

Located in the "vivado/data/ip/interfaces/bram_v1_0" folder a file "bram_rtl.xml" is present. I tried to use the ports used in the xml file. Especially the ports with the "required" tag.

The AXI BRAM Controller is combining them right so I am pretty sure I made a mistake. Using the same naming like the AXI BRAM Controller didn't work either.

My VHDL looks like this:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity AXIS_TO_BRAM is
    generic (
        addr_size : integer range 1 to 12 := 10
    );
    Port (
        --axistream
        tdata : in std_logic_vector(31 downto 0);
        tkeep : in std_logic_vector(3 downto 0);
        tlast : in std_logic;
        tready : out std_logic;
        tvalid : in std_logic;
        aclk : in std_logic;    

        --BRAM
        en : out std_logic;
        dout : in std_logic_vector(31 downto 0);
        din : out std_logic_vector(31 downto 0);
        we : out std_logic;
        addr : out std_logic_vector(addr_size-1 downto 0);
        clk : out std_logic;
        rst : out std_logic);
end AXIS_TO_BRAM;

architecture Behavioral of AXIS_TO_BRAM is

begin    
end Behavioral;

I am using vivado 2016.4 for Zynq 7020 on Linux.

Is there something missing in the VHDL code to get vivado recognize my ports as BRAM interface or is this a bug in this version?

Thank your for any ideas


Solution

  • Here is the complete working and synthesizable VHDL code.

    The correct solution (or at least the important part) is given in the comments by Vinay Madapura.

    The predefined interfaces can be found in the folder $vivado/$version/data/ip/interfaces.

    I hope this code will help other people struggling with similar problems.

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    
    entity AXIS_TO_BRAM is
    generic(
        addr_size : integer range 1 to 12 := 10
    );
    Port(
        tdata : in std_logic_vector(31 downto 0);
        tkeep : in std_logic_vector(3 downto 0);
        tlast : in std_logic;
        tready : out std_logic;
        tvalid : in std_logic;
        aclk : in std_logic;
    
        addra : out std_logic_vector(addr_size-1 downto 0);
        clka : out std_logic;
        dina : out std_logic_vector(31 downto 0);
        douta : in std_logic_vector(31 downto 0);
        ena : out std_logic;
        rsta : out std_logic;
        wea : out std_logic_vector(0 downto 0)
    );
    end AXIS_TO_BRAM;
    
    architecture Behavioral of AXIS_TO_BRAM is
    
        ATTRIBUTE X_INTERFACE_INFO : string;
        ATTRIBUTE X_INTERFACE_INFO OF addra: SIGNAL IS "xilinx.com:interface:bram:1.0 BRAM_PORTA ADDR";
        ATTRIBUTE X_INTERFACE_INFO OF clka: SIGNAL IS "xilinx.com:interface:bram:1.0 BRAM_PORTA CLK";
        ATTRIBUTE X_INTERFACE_INFO OF dina: SIGNAL IS "xilinx.com:interface:bram:1.0 BRAM_PORTA DIN";
        ATTRIBUTE X_INTERFACE_INFO OF douta: SIGNAL IS "xilinx.com:interface:bram:1.0 BRAM_PORTA DOUT";
        ATTRIBUTE X_INTERFACE_INFO OF ena: SIGNAL IS "xilinx.com:interface:bram:1.0 BRAM_PORTA EN";
        ATTRIBUTE X_INTERFACE_INFO OF rsta: SIGNAL IS "xilinx.com:interface:bram:1.0 BRAM_PORTA RST";
        ATTRIBUTE X_INTERFACE_INFO OF wea: SIGNAL IS "xilinx.com:interface:bram:1.0 BRAM_PORTA WE";
    
    begin
    end Behavioral;