SURF  1.0
I2cRegMasterAxiBridge.vhd
Go to the documentation of this file.
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 -------------------------------------------------------------------------------
17 
18 library ieee;
19 use ieee.std_logic_1164.all;
20 use ieee.std_logic_arith.all;
21 use ieee.std_logic_unsigned.all;
22 
23 use work.StdRtlPkg.all;
24 use work.AxiLitePkg.all;
25 use work.I2cPkg.all;
26 
27 --! @see entity
28  --! @ingroup protocols_i2c
30 
31  generic (
32  TPD_G : time := 1 ns;
34  EN_USER_REG_G : boolean := false;
35  NUM_WRITE_REG_G : integer range 1 to 128 := 1;
36  NUM_READ_REG_G : integer range 1 to 128 := 1;
38 
39  port (
40  axiClk : in sl;
41  axiRst : in sl;
42 
47 
48  -- Optional User Read/Write Register Interface
49  readRegister : in Slv32Array(0 to NUM_READ_REG_G) := (others => x"00000000");
50  writeRegisterInit : in Slv32Array(0 to NUM_WRITE_REG_G) := (others => x"00000000");
52 
55 
56 end entity I2cRegMasterAxiBridge;
57 
58 architecture rtl of I2cRegMasterAxiBridge is
59 
60  constant READ_C : boolean := false;
61  constant WRITE_C : boolean := true;
62 
63  constant DEVICE_MAP_LENGTH_C : natural := DEVICE_MAP_G'length;
64 
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 : natural := maxAddrSize(DEVICE_MAP_G);
68 
69  constant I2C_REG_AXI_ADDR_LOW_C : natural := 2;
70  constant I2C_REG_AXI_ADDR_HIGH_C : natural :=
71  ite(I2C_REG_ADDR_SIZE_C = 0,
72  ite(EN_USER_REG_G = false,
73  2,
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);
78 
79  subtype I2C_REG_AXI_ADDR_RANGE_C is natural range
80  I2C_REG_AXI_ADDR_HIGH_C downto I2C_REG_AXI_ADDR_LOW_C;
81 
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 : natural := I2C_REG_AXI_ADDR_HIGH_C + 1;
84  constant I2C_DEV_AXI_ADDR_HIGH_C : natural := 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));
88 
89  subtype I2C_DEV_AXI_ADDR_RANGE_C is natural range
90  I2C_DEV_AXI_ADDR_HIGH_C downto I2C_DEV_AXI_ADDR_LOW_C;
91 
92  constant USER_AXI_ADDR_HIGH_C : natural := I2C_DEV_AXI_ADDR_HIGH_C+1;
93  constant USER_AXI_ADDR_LOW_C : natural := I2C_DEV_AXI_ADDR_HIGH_C+1;
94 
95  subtype USER_AXI_ADDR_RANGE_C is natural range
96  USER_AXI_ADDR_HIGH_C downto USER_AXI_ADDR_LOW_C;
97 
98  type RegType is record
103  end record RegType;
104 
105  constant REG_INIT_C : RegType := (
106  writeRegister => (others => x"00000000"),
110 
111  signal r : RegType := REG_INIT_C;
112  signal rin : RegType;
113 
114 -- attribute keep : string;
115 -- attribute keep of
116 -- axiReadMaster,
117 -- axiReadSlave,
118 -- axiWriteMaster,
119 -- axiWriteSlave,
120 -- i2cRegMasterOut,
121 -- i2cRegMasterIn : signal is "TRUE";
122 
123 -- attribute dont_touch : string;
124 -- attribute dont_touch of
125 -- axiReadMaster,
126 -- axiReadSlave,
127 -- axiWriteMaster,
128 -- axiWriteSlave,
129 -- i2cRegMasterOut,
130 -- i2cRegMasterIn : signal is "TRUE";
131 
132 
133 begin
134 
135  -------------------------------------------------------------------------------------------------
136  -- Main Comb Process
137  -------------------------------------------------------------------------------------------------
140  variable v : RegType;
141  variable devInt : integer;
142  variable axiStatus : AxiLiteStatusType;
143  variable axiResp : slv(1 downto 0);
144 
145  impure function setI2cRegMaster (i : integer; readN : boolean) return I2cRegMasterInType is
147  begin
148  ret.i2cAddr := DEVICE_MAP_G(i).i2cAddress;
149  ret.tenbit := DEVICE_MAP_G(i).i2cTenbit;
150 
151  if (readN = READ_C) then
152  ret.regAddr(I2C_REG_ADDR_SIZE_C-1 downto 0) := axiReadMaster.araddr(I2C_REG_AXI_ADDR_RANGE_C);
153  else
154  ret.regAddr(I2C_REG_ADDR_SIZE_C-1 downto 0) := axiWriteMaster.awaddr(I2C_REG_AXI_ADDR_RANGE_C);
155  end if;
156 
157  ret.regWrData(DEVICE_MAP_G(i).dataSize-1 downto 0) := axiWriteMaster.wData(DEVICE_MAP_G(i).dataSize-1 downto 0);
158 
159  ret.regAddrSize := toSlv(wordCount(DEVICE_MAP_G(i).addrSize, 8) - 1, 2);
160  ret.regAddrSkip := toSl(DEVICE_MAP_G(i).addrSize = 0);
161  ret.regDataSize := toSlv(wordCount(DEVICE_MAP_G(i).dataSize, 8) - 1, 2);
164  return ret;
165  end function;
166 
167  begin
168  v := r;
169 
171 
172 
173  if (axiStatus.writeEnable = '1') then
174 
175  -- Decode address and perform write
176  if (axiWriteMaster.awaddr(USER_AXI_ADDR_RANGE_C) = "0" or not EN_USER_REG_G) then
177  -- I2C Address Space
178  -- Decode i2c device address and send command to I2cRegMaster
179  devInt := conv_integer(axiWriteMaster.awaddr(I2C_DEV_AXI_ADDR_RANGE_C));
180 
181  v.i2cRegMasterIn := setI2cRegMaster(devInt, WRITE_C);
182  v.i2cRegMasterIn.regOp := '1'; -- Write
183  v.i2cRegMasterIn.regReq := '1';
184 
185  -- User Configuration Address Space
186  elsif (axiWriteMaster.awaddr(USER_AXI_ADDR_RANGE_C) = "1") and (EN_USER_REG_G = true) then
187  -- Check for valid address space range
188  if (axiWriteMaster.awaddr(8 downto 2) < NUM_WRITE_REG_G) and (axiWriteMaster.awaddr(9) = '1') then
189  -- Write the the User Register space
190  v.writeRegister(conv_integer(axiWriteMaster.awaddr(7 downto 2))) := axiWriteMaster.wdata;
191  -- Send AXI response
192  axiSlaveWriteResponse(v.axiWriteSlave);
193  else
194  -- Send AXI Error response
195  axiSlaveWriteResponse(v.axiWriteSlave, AXI_ERROR_RESP_G);
196  end if;
197  else
198  -- Send AXI Error response
199  axiSlaveWriteResponse(v.axiWriteSlave, AXI_ERROR_RESP_G);
200  end if;
201  elsif (axiStatus.readEnable = '1') then
202  -- Decode address and perform write
203  if (axiReadMaster.araddr(USER_AXI_ADDR_RANGE_C) = "0" or not EN_USER_REG_G) then
204  -- I2C Address Space
205  -- Decode i2c device address and send command to I2cRegMaster
206  devInt := conv_integer(axiReadMaster.araddr(I2C_DEV_AXI_ADDR_RANGE_C));
207 
208  -- Send transaction to I2cRegMaster
209  v.i2cRegMasterIn := setI2cRegMaster(devInt, READ_C);
210  v.i2cRegMasterIn.regOp := '0'; -- Read
211  v.i2cRegMasterIn.regReq := '1';
212 
213  -- User Configuration Address Space
214  elsif (axiReadMaster.araddr(USER_AXI_ADDR_RANGE_C) = "1") and (EN_USER_REG_G = true) then
215  -- Check for valid address space range
216  if (axiReadMaster.araddr(8 downto 2) < NUM_WRITE_REG_G) and (axiReadMaster.araddr(9) = '0') then
217  -- Write the the User Register space
218  v.axiReadSlave.rdata := r.writeRegister(conv_integer(axiReadMaster.araddr(7 downto 2)));
219  -- Send AXI response
220  axiSlaveWriteResponse(v.axiWriteSlave);
221  -- Check for valid address space range
222  elsif (axiReadMaster.araddr(8 downto 2) < NUM_READ_REG_G) and (axiReadMaster.araddr(9) = '1') then
223  -- Write the the User Register space
224  v.axiReadSlave.rdata := readRegister(conv_integer(axiReadMaster.araddr(7 downto 2)));
225  -- Send AXI response
226  axiSlaveWriteResponse(v.axiWriteSlave);
227  else
228  -- Send AXI Error response
229  axiSlaveWriteResponse(v.axiWriteSlave, AXI_ERROR_RESP_G);
230  end if;
231  else
232  -- Send AXI Error response
233  axiSlaveWriteResponse(v.axiWriteSlave, AXI_ERROR_RESP_G);
234  end if;
235 
236  end if;
237 
238  if (i2cRegMasterOut.regAck = '1' and r.i2cRegMasterIn.regReq = '1') then
239  v.i2cRegMasterIn.regReq := '0';
240  axiResp := ite(i2cRegMasterOut.regFail = '1', AXI_ERROR_RESP_G, AXI_RESP_OK_C);
241  if (r.i2cRegMasterIn.regOp = '1') then
242  axiSlaveWriteResponse(v.axiWriteSlave, axiResp);
243  else
245  if (i2cRegMasterOut.regFail = '1') then
247  end if;
248  axiSlaveReadResponse(v.axiReadSlave, axiResp);
249  end if;
250 
251  end if;
252 
253  ----------------------------------------------------------------------------------------------
254  -- Reset
255  ----------------------------------------------------------------------------------------------
256  if (axiRst = '1') then
257  v := REG_INIT_C;
259  end if;
260 
261  rin <= v;
262 
267 
268  end process comb;
269 
270  -------------------------------------------------------------------------------------------------
271  -- Sequential Process
272  -------------------------------------------------------------------------------------------------
273  seq : process (axiClk) is
274  begin
275  if (rising_edge(axiClk)) then
276  r <= rin after TPD_G;
277  end if;
278  end process seq;
279 
280 end architecture rtl;
281 
slv( 1 downto 0) regAddrSize
Definition: I2cPkg.vhd:86
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_SLVERR_C
array(natural range <> ) of slv( 31 downto 0) Slv32Array
Definition: StdRtlPkg.vhd:379
out axiWriteSlaveAxiLiteWriteSlaveType
integer addrSize
Definition: I2cPkg.vhd:163
slv( 31 downto 0) regAddr
Definition: I2cPkg.vhd:82
AxiLiteWriteMasterType
Definition: AxiLitePkg.vhd:111
std_logic sl
Definition: StdRtlPkg.vhd:28
integer dataSize
Definition: I2cPkg.vhd:162
sl endianness
Definition: I2cPkg.vhd:90
slv( 31 downto 0) rdata
Definition: AxiLitePkg.vhd:89
sl regOp
Definition: I2cPkg.vhd:84
array(natural range <> ) of I2cAxiLiteDevType I2cAxiLiteDevArray
Definition: I2cPkg.vhd:176
DEVICE_MAP_GI2cAxiLiteDevArray := I2C_AXIL_DEV_ARRAY_DEFAULT_C
slv( 7 downto 0) regFailCode
Definition: I2cPkg.vhd:113
in axiWriteMasterAxiLiteWriteMasterType
slv( 1 downto 0) regDataSize
Definition: I2cPkg.vhd:87
slv( 31 downto 0) wdata
Definition: AxiLitePkg.vhd:117
sl regAddrSkip
Definition: I2cPkg.vhd:85
AxiLiteStatusType axiStatus
Definition: AxiLitePkg.vhd:183
out axiReadSlaveAxiLiteReadSlaveType
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
Definition: AxiLitePkg.vhd:36
I2cRegMasterOutType
Definition: I2cPkg.vhd:110
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
Definition: I2cPkg.vhd:94
AxiLiteReadMasterType
Definition: AxiLitePkg.vhd:59
sl tenbit
Definition: I2cPkg.vhd:65
sl regReq
Definition: I2cPkg.vhd:88
NUM_WRITE_REG_Ginteger range 1 to 128:= 1
slv( 9 downto 0) i2cAddress
Definition: I2cPkg.vhd:160
_library_ ieeeieee
slv( 31 downto 0) awaddr
Definition: AxiLitePkg.vhd:113
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
Definition: AxiLitePkg.vhd:95
slv( 9 downto 0) i2cAddr
Definition: I2cPkg.vhd:80
I2cRegMasterInType
Definition: I2cPkg.vhd:79
out writeRegisterSlv32Array( 0 to NUM_WRITE_REG_G)
in i2cRegMasterOutI2cRegMasterOutType
NUM_READ_REG_Ginteger range 1 to 128:= 1
AxiLiteReadSlaveType
Definition: AxiLitePkg.vhd:85
slv( 31 downto 0) regRdData
Definition: I2cPkg.vhd:114
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
Definition: I2cPkg.vhd:178
slv( 1 downto 0) := "00" AXI_RESP_OK_C
Definition: AxiLitePkg.vhd:31
out i2cRegMasterInI2cRegMasterInType
slv( 31 downto 0) araddr
Definition: AxiLitePkg.vhd:61
in readRegisterSlv32Array( 0 to NUM_READ_REG_G) :=( others => x"00000000")
sl regAck
Definition: I2cPkg.vhd:111
sl repeatStart
Definition: I2cPkg.vhd:91
sl regFail
Definition: I2cPkg.vhd:112
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
Definition: AxiLitePkg.vhd:156
sl i2cTenbit
Definition: I2cPkg.vhd:161
slv( 31 downto 0) regWrData
Definition: I2cPkg.vhd:83
std_logic_vector slv
Definition: StdRtlPkg.vhd:29