1 ------------------------------------------------------------------------------- 2 -- File : I2cRegMasterAxiBridge.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2013-09-23 5 -- Last update: 2017-05-10 6 ------------------------------------------------------------------------------- 7 -- Description: Maps a number of I2C devices on an I2C bus onto an AXI Bus. 8 ------------------------------------------------------------------------------- 9 -- This file is part of 'SLAC Firmware Standard Library'. 10 -- It is subject to the license terms in the LICENSE.txt file found in the 11 -- top-level directory of this distribution and at: 12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 13 -- No part of 'SLAC Firmware Standard Library', including this file, 14 -- may be copied, modified, propagated, or distributed except according to 15 -- the terms contained in the LICENSE.txt file. 16 ------------------------------------------------------------------------------- 19 use ieee.std_logic_1164.
all;
20 use ieee.std_logic_arith.
all;
21 use ieee.std_logic_unsigned.
all;
28 --! @ingroup protocols_i2c 48 -- Optional User Read/Write Register Interface 56 end entity I2cRegMasterAxiBridge;
60 constant READ_C : := false;
61 constant WRITE_C : := true;
65 -- Number of device register space address bits maped into axi bus is determined by 66 -- the maximum address size of all the devices. 67 constant I2C_REG_ADDR_SIZE_C : := maxAddrSize(DEVICE_MAP_G);
69 constant I2C_REG_AXI_ADDR_LOW_C : := 2;
70 constant I2C_REG_AXI_ADDR_HIGH_C : := 71 ite(I2C_REG_ADDR_SIZE_C = 0, 74 --else (EN_USER_REG_G = true) 75 8), -- Need minimum size of 8 if user regs enabled 76 -- else (I2C_REG_ADDR_SIZE_C > 0) 77 I2C_REG_AXI_ADDR_LOW_C + I2C_REG_ADDR_SIZE_C-1);
79 subtype I2C_REG_AXI_ADDR_RANGE_C is range 80 I2C_REG_AXI_ADDR_HIGH_C downto I2C_REG_AXI_ADDR_LOW_C;
82 -- Number of device address bits mapped into axi bus space is determined by number of devices 83 constant I2C_DEV_AXI_ADDR_LOW_C : := I2C_REG_AXI_ADDR_HIGH_C + 1;
84 constant I2C_DEV_AXI_ADDR_HIGH_C : := ite( 85 (DEVICE_MAP_LENGTH_C = 1), 86 I2C_DEV_AXI_ADDR_LOW_C, 87 (I2C_DEV_AXI_ADDR_LOW_C + log2(DEVICE_MAP_LENGTH_C) - 1));
89 subtype I2C_DEV_AXI_ADDR_RANGE_C is range 90 I2C_DEV_AXI_ADDR_HIGH_C downto I2C_DEV_AXI_ADDR_LOW_C;
92 constant USER_AXI_ADDR_HIGH_C : := I2C_DEV_AXI_ADDR_HIGH_C+1;
93 constant USER_AXI_ADDR_LOW_C : := I2C_DEV_AXI_ADDR_HIGH_C+1;
95 subtype USER_AXI_ADDR_RANGE_C is range 96 USER_AXI_ADDR_HIGH_C downto USER_AXI_ADDR_LOW_C;
98 type RegType is record 105 constant REG_INIT_C : RegType := ( 111 signal r : RegType := REG_INIT_C;
112 signal rin : RegType;
114 -- attribute keep : string; 121 -- i2cRegMasterIn : signal is "TRUE"; 123 -- attribute dont_touch : string; 124 -- attribute dont_touch of 130 -- i2cRegMasterIn : signal is "TRUE"; 135 ------------------------------------------------------------------------------------------------- 137 ------------------------------------------------------------------------------------------------- 140 variable v : RegType;
143 variable axiResp : slv(1 downto 0);
151 if (readN = READ_C) then 175 -- Decode address and perform write 178 -- Decode i2c device address and send command to I2cRegMaster 185 -- User Configuration Address Space 187 -- Check for valid address space range 189 -- Write the the User Register space 194 -- Send AXI Error response 198 -- Send AXI Error response 202 -- Decode address and perform write 205 -- Decode i2c device address and send command to I2cRegMaster 208 -- Send transaction to I2cRegMaster 213 -- User Configuration Address Space 215 -- Check for valid address space range 217 -- Write the the User Register space 221 -- Check for valid address space range 223 -- Write the the User Register space 228 -- Send AXI Error response 232 -- Send AXI Error response 253 ---------------------------------------------------------------------------------------------- 255 ---------------------------------------------------------------------------------------------- 270 ------------------------------------------------------------------------------------------------- 271 -- Sequential Process 272 ------------------------------------------------------------------------------------------------- 275 if (rising_edge(axiClk)) then 276 r <= rin after TPD_G;
280 end architecture rtl;
slv( 1 downto 0) regAddrSize
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_SLVERR_C
array(natural range <> ) of slv( 31 downto 0) Slv32Array
out axiWriteSlaveAxiLiteWriteSlaveType
slv( 31 downto 0) regAddr
array(natural range <> ) of I2cAxiLiteDevType I2cAxiLiteDevArray
DEVICE_MAP_GI2cAxiLiteDevArray := I2C_AXIL_DEV_ARRAY_DEFAULT_C
slv( 7 downto 0) regFailCode
in axiWriteMasterAxiLiteWriteMasterType
slv( 1 downto 0) regDataSize
AxiLiteStatusType axiStatus
out axiReadSlaveAxiLiteReadSlaveType
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
in axiReadMasterAxiLiteReadMasterType
I2cRegMasterInType :=(i2cAddr =>( others => '0'),tenbit => '0',regAddr =>( others => '0'),regWrData =>( others => '0'),regOp => '0',regAddrSkip => '0',regAddrSize =>( others => '0'),regDataSize =>( others => '0'),regReq => '0',busReq => '0',endianness => '0',repeatStart => '0') I2C_REG_MASTER_IN_INIT_C
NUM_WRITE_REG_Ginteger range 1 to 128:= 1
slv( 9 downto 0) i2cAddress
in writeRegisterInitSlv32Array( 0 to NUM_WRITE_REG_G) :=( others => x"00000000")
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
out writeRegisterSlv32Array( 0 to NUM_WRITE_REG_G)
in i2cRegMasterOutI2cRegMasterOutType
NUM_READ_REG_Ginteger range 1 to 128:= 1
slv( 31 downto 0) regRdData
EN_USER_REG_Gboolean := false
I2cAxiLiteDevArray( 0 to 3) :=( 0=>( MakeI2cAxiLiteDevType( "0000000", 8, 8, '0')), 1=>( MakeI2cAxiLiteDevType( "0000010", 16, 16, '0')), 2=>( MakeI2cAxiLiteDevType( "0000100", 32, 8, '0')), 3=>( MakeI2cAxiLiteDevType( "0001000", 32, 32, '0'))) I2C_AXIL_DEV_ARRAY_DEFAULT_C
slv( 1 downto 0) := "00" AXI_RESP_OK_C
out i2cRegMasterInI2cRegMasterInType
in readRegisterSlv32Array( 0 to NUM_READ_REG_G) :=( others => x"00000000")
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
slv( 31 downto 0) regWrData