1 ------------------------------------------------------------------------------- 2 -- File : AxiI2cEepromCore.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2016-07-11 5 -- Last update: 2016-09-20 6 ------------------------------------------------------------------------------- 7 -- Description: AXI-Lite Read/ModifyWrite for standard EEPROM Module 10 -- 24AA01F/24LC01F/24FC01F (1kb: ADDR_WIDTH_G = 7) 11 -- 24AA02F/24LC02F/24FC02F (2kb: ADDR_WIDTH_G = 8) 12 -- 24AA04F/24LC04F/24FC04F (4kb: ADDR_WIDTH_G = 9) 13 -- 24AA08F/24LC08F/24FC08F (8kb: ADDR_WIDTH_G = 10) 14 -- 24AA16F/24LC16F/24FC16F (16kb: ADDR_WIDTH_G = 11) 15 -- 24AA32F/24LC32F/24FC32F (32kb: ADDR_WIDTH_G = 12) 16 -- 24AA64F/24LC64F/24FC64F (64kb: ADDR_WIDTH_G = 13) 17 -- 24AA128F/24LC128F/24FC128F (128kb: ADDR_WIDTH_G = 14) 18 -- 24AA256F/24LC256F/24FC256F (256kb: ADDR_WIDTH_G = 15) 19 -- 24AA512F/24LC512F/24FC512F (512kb: ADDR_WIDTH_G = 16) 20 ------------------------------------------------------------------------------- 21 -- This file is part of 'SLAC Firmware Standard Library'. 22 -- It is subject to the license terms in the LICENSE.txt file found in the 23 -- top-level directory of this distribution and at: 24 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 25 -- No part of 'SLAC Firmware Standard Library', including this file, 26 -- may be copied, modified, propagated, or distributed except according to 27 -- the terms contained in the LICENSE.txt file. 28 ------------------------------------------------------------------------------- 31 use ieee.std_logic_1164.
all;
32 use ieee.std_logic_unsigned.
all;
33 use ieee.std_logic_arith.
all;
43 --! @ingroup protocols_i2c 58 -- AXI-Lite Register Interface 70 -- Note: PRESCALE_G = (clk_freq / (5 * i2c_freq)) - 1 71 -- FILTER_G = (min_pulse_time / clk_period) + 1 73 constant PRESCALE_C : := (getTimeRatio(AXI_CLK_FREQ_G, I2C_SCL_5xFREQ_C)) - 1;
76 constant ADDR_SIZE_C : slv(1 downto 0) := toSlv(wordCount(ADDR_WIDTH_G, 8) - 1, 2);
77 constant DATA_SIZE_C : slv(1 downto 0) := toSlv(wordCount(32, 8) - 1, 2);
78 constant I2C_ADDR_C : slv(9 downto 0) := ("000" & I2C_ADDR_G);
79 constant TIMEOUT_C : := (getTimeRatio(AXI_CLK_FREQ_G, 200.
0)) - 1;
-- 5 ms timeout 84 regAddr => (
others => '0'),
85 regWrData => (
others => '0'),
86 regOp => '0', --
1 for write,
0 for read
88 regAddrSize => ADDR_SIZE_C,
89 regDataSize => DATA_SIZE_C,
104 type RegType is record 105 timer : range 0 to TIMEOUT_C;
109 regIn : I2cRegMasterInType;
113 constant REG_INIT_C : RegType := ( 118 regIn => MY_I2C_REG_MASTER_IN_INIT_C,
121 signal r : RegType := REG_INIT_C;
122 signal rin : RegType;
126 -- attribute dont_touch : string; 127 -- attribute dont_touch of r : signal is "TRUE"; 128 -- attribute dont_touch of regOut : signal is "TRUE"; 139 -- I2C Port Interface 142 -- I2C Register Interface 150 variable v : regType;
152 variable axilResp : slv(1 downto 0);
154 -- Latch the current value 157 -- Determine the transaction type 160 -- Update the AXI-Lite response 165 ---------------------------------------------------------------------- 167 if regOut.regAck = '0' then 168 -- Check for a write request 172 -- Send read transaction to I2cRegMaster 174 v.regIn.regOp := '0';
-- Read (then modify write) operation 177 v.state := READ_ACK_S;
178 -- Check for a read request 182 -- Send read transaction to I2cRegMaster 184 v.regIn.regOp := '0';
-- Read operation 187 v.state := READ_ACK_S;
190 ---------------------------------------------------------------------- 192 -- Wait for completion 193 if regOut.regAck = '1' then 196 -- Check for write operation 198 -- Check for I2C failure 200 -- Send AXI-Lite response 204 -- Check if not modification required 206 -- Send AXI-Lite response 212 v.state := READ_DONE_S;
214 -- Else read operation 216 -- Check for I2C failure 220 -- Forward error code on the data bus for debugging 223 -- Forward the readout data 228 -- Send AXI-Lite response 232 ---------------------------------------------------------------------- 234 if regOut.regAck = '0' then 236 v.state := WRITE_REQ_S;
238 ---------------------------------------------------------------------- 240 -- Send write transaction to I2cRegMaster 242 v.regIn.regOp := '1';
-- Write operation 245 v.state := WRITE_ACK_S;
246 ---------------------------------------------------------------------- 248 -- Wait for completion 249 if regOut.regAck = '1' then 252 -- Send AXI-Lite response 254 -- Check for I2C failure 260 v.state := WRITE_DONE_S;
263 ---------------------------------------------------------------------- 265 if regOut.regAck = '0' then 269 ---------------------------------------------------------------------- 271 -- Increment the counter 272 v.timer := r.timer + 1;
274 if (r.timer = TIMEOUT_C) then 280 ---------------------------------------------------------------------- 288 -- Register the variable for next clock cycle 300 r <= rin after TPD_G;
in regInI2cRegMasterInType
in axilWriteMasterAxiLiteWriteMasterType
slv( 31 downto 0) regAddr
AXI_CLK_FREQ_Greal := 156.25E+6
OUTPUT_EN_POLARITY_Ginteger range 0 to 1:= 0
slv( 7 downto 0) regFailCode
I2C_MIN_PULSE_Greal := 100.0E-9
slv( 1 downto 0) := "10" AXI_RESP_SLVERR_C
I2C_SCL_FREQ_Greal := 100.0E+3
AXI_ERROR_RESP_Gslv( 1 downto 0) := AXI_RESP_SLVERR_C
POLL_TIMEOUT_Gpositive := 16
I2C_ADDR_Gslv( 6 downto 0) := "1010000"
AxiLiteReadSlaveType :=(arready => '0',rdata =>( others => '0'),rresp =>( others => '0'),rvalid => '0') AXI_LITE_READ_SLAVE_INIT_C
slv( 31 downto 0) regRdData
in axilReadMasterAxiLiteReadMasterType
slv( 1 downto 0) := "00" AXI_RESP_OK_C
out axilReadSlaveAxiLiteReadSlaveType
ADDR_WIDTH_Gpositive := 16
out axilWriteSlaveAxiLiteWriteSlaveType
FILTER_Ginteger range 2 to 512:= 8
out regOutI2cRegMasterOutType
AxiLiteWriteSlaveType :=(awready => '0',wready => '0',bresp =>( others => '0'),bvalid => '0') AXI_LITE_WRITE_SLAVE_INIT_C
PRESCALE_Ginteger range 0 to 655535:= 62
slv( 31 downto 0) regWrData