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')