1 -------------------------------------------------------------------------------     2 -- File       : AxiDualPortRam.vhd     3 -- Company    : SLAC National Accelerator Laboratory     4 -- Created    : 2013-12-17     5 -- Last update: 2017-01-11     6 -------------------------------------------------------------------------------     7 -- Description: A wrapper of StdLib DualPortRam that places an AxiLite     8 -- interface on the read/write port.      9 -------------------------------------------------------------------------------    10 -- This file is part of 'SLAC Firmware Standard Library'.    11 -- It is subject to the license terms in the LICENSE.txt file found in the     12 -- top-level directory of this distribution and at:     13 --    https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.     14 -- No part of 'SLAC Firmware Standard Library', including this file,     15 -- may be copied, modified, propagated, or distributed except according to     16 -- the terms contained in the LICENSE.txt file.    17 -------------------------------------------------------------------------------    20 use ieee.std_logic_1164.
all;
    21 use ieee.std_logic_arith.
all;
    22 use ieee.std_logic_unsigned.
all;
    68 end entity AxiDualPortRam;
    72    -- Number of Axi address bits that need to be manually decoded    74    subtype AXI_DEC_ADDR_RANGE_C is  range 1+AXI_DEC_BITS_C downto 2;
    75    subtype AXI_RAM_ADDR_RANGE_C is  range ADDR_WIDTH_G+AXI_DEC_ADDR_RANGE_C'high downto AXI_DEC_ADDR_RANGE_C'high+1;
    78    constant ADDR_AXI_WORDS_C :  := wordCount(DATA_WIDTH_G, 32);
    79    constant ADDR_AXI_BYTES_C :  := wordCount(DATA_WIDTH_G, 8);
    80    constant RAM_WIDTH_C      :  := ADDR_AXI_WORDS_C*32;
    81    constant STRB_WIDTH_C     :  := minimum(4, ADDR_AXI_BYTES_C);
    83    type RegType is record    88       axiRdEn       : slv(2 downto 0);
    91    constant REG_INIT_C : RegType := (    94       axiAddr       => (others => '0'),    96       axiRdEn       => (others => '0'));
    98    signal r   : RegType := REG_INIT_C;
   101    signal axiWrDataFanout : slv(RAM_WIDTH_C-1 downto 0);
   102    signal axiDout         : slv(RAM_WIDTH_C-1 downto 0) := (others => '0');
   104    signal axiSyncWrEn : sl;
   111    -- AXI read only, sys writable or read only (rom)   142    -- System Read only, Axi writable or read only (ROM)   143    -- Logic disables axi writes if AXI_WR_EN_G=false   161             weaByte => r.axiWrStrobe
(ADDR_AXI_BYTES_C-
1 downto 0),
   173 --    -- Both sides writable, true dual port ram   190             weaByte => r.axiWrStrobe
(ADDR_AXI_BYTES_C-
1 downto 0),
   192             addra   => r.axiAddr,
                                 -- [in]   212    axiSyncWrEn <= uOr(r.axiWrStrobe(ADDR_AXI_BYTES_C-1 downto 0));
   218          DATA_WIDTH_G => ADDR_WIDTH_G+DATA_WIDTH_G+ADDR_AXI_BYTES_C
)   222          wr_en  => axiSyncWrEn,
         -- [in]   223          din    => axiSyncIn,
           -- [in]   225          rd_en  => '1',
                 -- [in]   227          dout   => axiSyncOut
);
         -- [out]   234    axiWrMap : for i in 0 to ADDR_AXI_WORDS_C-1 generate   236    end generate axiWrMap;
   239       variable v          : RegType;
   241       variable decAddrInt : ;
   246       -- Reset strobes and shift Register   249       v.axiRdEn(1)  := r.axiRdEn(0);
   250       v.axiRdEn(2)  := r.axiRdEn(1);
   257       -- Multiplex read data onto axi bus   261       -- Set axiAddr to read address by default   264       -- Don't allow a write if a read is active   269             v.axiWrStrobe((decAddrInt+1)*4-1 downto decAddrInt*4) :=   276          -- Set the address bus   278          -- Check for registered BRAM   280             v.axiRdEn := "001";
         -- read in 3 cycles   281          -- Check for non-registered BRAM   283             v.axiRdEn := "010";
         -- read in 2 cycles   284          -- Check for registered LUTRAM   286             v.axiRdEn := "010";
         -- read in 2 cycles   287          -- Else non-registered LUTRAM   289             v.axiRdEn := "100";
         -- read on next cycle   293       if (r.axiRdEn(2) = '1') then   309       if (rising_edge(axiClk)) then   310          r <= rin after TPD_G;
   314 end architecture rtl;
 
out axiWrAddrslv(   ADDR_WIDTH_G- 1 downto  0)  
 
in addrslv(   ADDR_WIDTH_G- 1 downto  0)  :=( others => '0')
 
in rstbsl  :=not (   RST_POLARITY_G)
 
AXI_ERROR_RESP_Gslv( 1 downto  0)  :=   AXI_RESP_DECERR_C
 
ADDR_WIDTH_Ginteger   range  1 to ( 2** 24):= 9
 
SYS_BYTE_WR_EN_Gboolean  :=   false
 
in dinslv(   DATA_WIDTH_G- 1 downto  0)  
 
out doutbslv(   DATA_WIDTH_G- 1 downto  0)  
 
in weaByteslv(   wordCount(   DATA_WIDTH_G,   BYTE_WIDTH_G)- 1 downto  0)  :=( others => '0')
 
DATA_WIDTH_Ginteger   range  1 to ( 2** 24):= 18
 
BYTE_WR_EN_Gboolean  :=   false
 
out doutslv(   DATA_WIDTH_G- 1 downto  0)  
 
DATA_WIDTH_Ginteger  := 32
 
ADDR_WIDTH_Ginteger   range  1 to ( 2** 24):= 4
 
in webByteslv(   wordCount(   DATA_WIDTH_G,   BYTE_WIDTH_G)- 1 downto  0)  :=( others => '0')
 
BRAM_EN_Gboolean  :=   false
 
MODE_Gstring  :=   "read-first"
 
out doutaslv(   DATA_WIDTH_G- 1 downto  0)  
 
BYTE_WR_EN_Gboolean  :=   false
 
out doutslv(   DATA_WIDTH_G- 1 downto  0)  
 
AxiLiteStatusType   axiStatus
 
slv( 1 downto  0)  :=   "10" AXI_RESP_SLVERR_C
 
out axiReadSlaveAxiLiteReadSlaveType  
 
COMMON_CLK_Gboolean  :=   false
 
slv( 1 downto  0)  :=   "11" AXI_RESP_DECERR_C
 
DOB_REG_Gboolean  :=   false
 
in axiWriteMasterAxiLiteWriteMasterType  
 
COMMON_CLK_Gboolean  :=   false
 
out doutaslv(   DATA_WIDTH_G- 1 downto  0)  
 
SYS_WR_EN_Gboolean  :=   false
 
DOB_REG_Gboolean  :=   false
 
in weByteslv(   wordCount(   DATA_WIDTH_G, 8)- 1 downto  0)  :=( others => '0')
 
in addrbslv(   ADDR_WIDTH_G- 1 downto  0)  :=( others => '0')
 
in weaByteslv(   wordCount(   DATA_WIDTH_G,   BYTE_WIDTH_G)- 1 downto  0)  :=( others => '1')
 
out axiWrDataslv(   DATA_WIDTH_G- 1 downto  0)  
 
DATA_WIDTH_Ginteger   range  1 to ( 2** 24):= 16
 
AxiLiteReadSlaveType  :=(arready  => '0',rdata  =>( others => '0'),rresp  =>( others => '0'),rvalid  => '0') AXI_LITE_READ_SLAVE_INIT_C
 
in rstasl  :=not (   RST_POLARITY_G)
 
in addraslv(   ADDR_WIDTH_G- 1 downto  0)  :=( others => '0')
 
in dinaslv(   DATA_WIDTH_G- 1 downto  0)  :=( others => '0')
 
DOA_REG_Gboolean  :=   false
 
in axiReadMasterAxiLiteReadMasterType  
 
out axiWriteSlaveAxiLiteWriteSlaveType  
 
in dinslv(   DATA_WIDTH_G- 1 downto  0)  :=( others => '0')
 
slv( 1 downto  0)  :=   "00" AXI_RESP_OK_C
 
BRAM_EN_Gboolean  :=   false
 
DOA_REG_Gboolean  :=   false
 
in rstasl  :=not (   RST_POLARITY_G)
 
out doutbslv(   DATA_WIDTH_G- 1 downto  0)  
 
in addraslv(   ADDR_WIDTH_G- 1 downto  0)  :=( others => '0')
 
MODE_Gstring  :=   "read-first"
 
ADDR_WIDTH_Ginteger   range  1 to ( 2** 24):= 5
 
MODE_Gstring  :=   "read-first"
 
out axiWrStrobeslv(   wordCount(   DATA_WIDTH_G, 8)- 1 downto  0)  
 
in rstbsl  :=not (   RST_POLARITY_G)
 
AxiLiteWriteSlaveType  :=(awready  => '0',wready  => '0',bresp  =>( others => '0'),bvalid  => '0') AXI_LITE_WRITE_SLAVE_INIT_C
 
in dinaslv(   DATA_WIDTH_G- 1 downto  0)  :=( others => '0')
 
AXI_WR_EN_Gboolean  :=   true
 
in dinbslv(   DATA_WIDTH_G- 1 downto  0)  :=( others => '0')
 
DATA_WIDTH_Ginteger   range  1 to ( 2** 24):= 16
 
in addrbslv(   ADDR_WIDTH_G- 1 downto  0)  :=( others => '0')