📄 i2c.vhd
字号:
---------------------------------------------------------------------------------------------------
--*************************************************************************************************
-- CreateDate : 2007-08-21
-- ModifData : 2007-08-21
-- Description : I2C ( 24LC16B )
-- Author : Explorer01
-- Version : V1.0
--*************************************************************************************************
---------------------------------------------------------------------------------------------------
-- VHDL library Declarations
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.std_logic_unsigned.ALL;
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- The Entity Declarations
ENTITY I2C IS
PORT
(
RESET : IN STD_LOGIC;
GCLK : IN STD_LOGIC;
CLK : IN STD_LOGIC;
SCL : OUT STD_LOGIC;
SDA : INOUT STD_LOGIC;
I2C_CS : IN STD_LOGIC;
I2C_RW : IN STD_LOGIC;
I2C_STRB: IN STD_LOGIC;
I2C_Address : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
I2C_Data : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END I2C;
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- The Architecture of Entity Declarations
ARCHITECTURE Behavioral OF I2C IS
--
CONSTANT CON_IDLE : STD_LOGIC_VECTOR(2 DOWNTO 0) := "000";
CONSTANT CON_START : STD_LOGIC_VECTOR(2 DOWNTO 0) := "001";
CONSTANT CON_CONTROL : STD_LOGIC_VECTOR(2 DOWNTO 0) := "010";
CONSTANT CON_ADDRESS : STD_LOGIC_VECTOR(2 DOWNTO 0) := "011";
CONSTANT CON_DATA : STD_LOGIC_VECTOR(2 DOWNTO 0) := "100";
CONSTANT CON_STOP : STD_LOGIC_VECTOR(2 DOWNTO 0) := "101";
CONSTANT CON_ACK : STD_LOGIC_VECTOR(2 DOWNTO 0) := "110";
SIGNAL STEP : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL CountSTEP1, CountSTEP2 : INTEGER RANGE 0 TO 31; -- 32
SIGNAL Start, Enable : STD_LOGIC;
SIGNAL DataOUT : STD_LOGIC_VECTOR(7 DOWNTO 0);
-- Clock:
SIGNAL CLK200KHz, CLK100KHz, CLKSCL : STD_LOGIC;
--
SIGNAL Value : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL COMMAND, ADDRESS, DATA : STD_LOGIC_VECTOR(7 DOWNTO 0);
--
SIGNAL FLAG, READ : STD_LOGIC;
SIGNAL SDAIN, SDAOUT : STD_LOGIC;
BEGIN
--==============================================
-------------------------------------------------
-- The Flag of Enable
PROCESS( RESET, GCLK, I2C_STRB, I2C_RW )
VARIABLE Count : STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
IF ( RESET='0' ) THEN Count := "11";
ELSIF( I2C_RW='0' ) THEN Count := "00";
ELSIF( GCLK'EVENT AND GCLK='1' ) THEN
IF( Count<"11" ) THEN Count := Count + 1;
END IF;
END IF;
IF( Count="10" ) THEN Enable <= '1';
ELSE Enable <= '0';
END IF;
END PROCESS;
-------------------------------------------------
-- The main interface
PROCESS( RESET, GCLK, I2C_CS, I2C_STRB, I2C_RW, I2C_Address, I2C_Data, DataOUT, Value, COMMAND, CountSTEP1, FLAG, READ )
VARIABLE Count : STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
-------------------------------------
-- Bidirectional I/O Port
IF( RESET='0' OR I2C_CS='1' ) THEN
I2C_Data <= (OTHERS=>'Z');
ELSE
IF( I2C_RW='0' ) THEN Value <= I2C_Data; -- Receive Command
ELSE I2C_Data <= DataOUT; -- Send the data readed from 24LC16B
END IF;
END IF;
-------------------------------------
IF( I2C_RW='0' AND I2C_STRB='1' ) THEN
IF ( I2C_Address="00" ) THEN COMMAND <= Value;
ELSIF( I2C_Address="01" ) THEN ADDRESS <= Value;
ELSIF( I2C_Address="10" ) THEN DATA <= Value;
END IF;
END IF;
-------------------------------------
--
IF( RESET='0' OR (FLAG='1' AND CountSTEP1=11) ) THEN FLAG <= '0';
ELSIF( I2C_RW'EVENT AND I2C_RW='1' ) THEN
IF( COMMAND(0)='1' ) THEN FLAG <= '1';
END IF;
END IF;
-------------------------------------
IF( RESET='0' OR READ='0' ) THEN Count := (OTHERS=>'0');
ELSIF( GCLK'EVENT AND GCLK='1' ) THEN
IF( Count<"11" ) THEN Count := Count + 1;
END IF;
END IF;
IF ( RESET='0' OR Count="01" ) THEN READ <= '0';
ELSIF( FLAG'EVENT AND FLAG='0' ) THEN READ <= '1';
END IF;
END PROCESS;
--==============================================
------------------------------------------------
-- GCLK: 100K Hz For Clock Frequency
PROCESS( RESET, GCLK, Start )
VARIABLE Count : STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
IF( RESET='0' OR Start='0' ) THEN
Count := (OTHERS=>'0');
ELSIF( GCLK'EVENT AND GCLK='1' ) THEN
-- 100K
IF( Count>"011" ) THEN Count := (OTHERS=>'0');
ELSE Count := Count + 1;
END IF;
END IF;
IF( Count<"011" ) THEN CLK200KHz <= '0';
ELSE CLK200KHz <= '1';
END IF;
END PROCESS;
-------------------------------------------------
-- GCLK: 100K Hz For Data Change
PROCESS( RESET, CLK200KHz )
BEGIN
IF ( RESET='0' ) THEN CLK100KHz <= '1';
ELSIF( CLK200KHz'EVENT AND CLK200KHz='0' ) THEN CLK100KHz <= NOT CLK100KHz;
END IF;
END PROCESS;
-------------------------------------------------
-- GCLK: 100K Hz For Clock Frequency
PROCESS( RESET, CLK200KHz )
BEGIN
IF ( RESET='0' ) THEN CLKSCL <= '1';
ELSIF( CLK200KHz'EVENT AND CLK200KHz='1' ) THEN CLKSCL <= NOT CLKSCL;
END IF;
END PROCESS;
--==============================================
------------------------------------------------
-- The Flag of start
PROCESS( RESET, Enable, CountSTEP2 )
BEGIN
IF ( RESET='0' OR CountSTEP2=1 ) THEN Start <= '0';
ELSIF( Enable='1' ) THEN Start <= '1';
END IF;
END PROCESS;
------------------------------------------------
-- CountSTEP1 For Step Change
PROCESS( RESET, Start, CLK100KHz, CountSTEP1, COMMAND, READ )
BEGIN
IF( RESET='0' OR Start='0' OR READ='1' ) THEN CountSTEP1 <= 31;
ELSE
IF( CLK100KHz'EVENT AND CLK100KHz='0' ) THEN
IF( COMMAND(0)='1' AND FLAG='0' AND CountSTEP1=22 ) THEN CountSTEP1 <= 12; -- Read
ELSE CountSTEP1 <= CountSTEP1 - 1;
END IF;
END IF;
END IF;
END PROCESS;
------------------------------------------------
-- CountSTEP2 For Stop
PROCESS( RESET, Start, CLK100KHz, CountSTEP2, COMMAND, READ )
BEGIN
IF( RESET='0' OR Start='0' OR READ='1' ) THEN CountSTEP2 <= 31;
ELSE
IF( CLK100KHz'EVENT AND CLK100KHz='1' ) THEN
IF( COMMAND(0)='1' AND FLAG='0' AND CountSTEP2=22 ) THEN CountSTEP2 <= 13; -- Read
ELSE CountSTEP2 <= CountSTEP2 - 1;
END IF;
END IF;
END IF;
END PROCESS;
------------------------------------------------
-- STEP
PROCESS( RESET, CountSTEP1 )
BEGIN
IF ( RESET='0' ) THEN STEP <= CON_IDLE;
ELSIF( CountSTEP1=30 ) THEN STEP <= CON_START;
ELSIF( CountSTEP1>21 AND CountSTEP1<30 ) THEN STEP <= CON_CONTROL;
ELSIF( CountSTEP1>12 AND CountSTEP1<21 ) THEN STEP <= CON_ADDRESS;
ELSIF( CountSTEP1>3 AND CountSTEP1<12 ) THEN STEP <= CON_DATA;
ELSIF( CountSTEP1=2 ) THEN STEP <= CON_STOP;
ELSIF( CountSTEP1=21 OR CountSTEP1=12 OR CountSTEP1=3 ) THEN STEP <= CON_ACK;
ELSE STEP <= CON_IDLE;
END IF;
END PROCESS;
--==============================================
------------------------------------------------
--
PROCESS( RESET, SDA, SDAIN, SDAOUT, Start, STEP, CountSTEP1, CountSTEP2, CLK100KHz, CLKSCL, COMMAND, ADDRESS, DATA, FLAG )
BEGIN
-------------------------------------
-- SCL
IF( RESET='0' OR Start='0' ) THEN SCL <= 'Z';
ELSIF( CountSTEP1=31 ) THEN SCL <= 'Z';
ELSIF( CountSTEP1=30 ) THEN SCL <= NOT CLK100KHz;
ELSIF( CountSTEP1=2 ) THEN
IF( CountSTEP2=3 ) THEN SCL <= '0';
ELSE SCL <= '1';
END IF;
ELSIF( CountSTEP1>2 ) THEN SCL <= CLKSCL;
ELSE SCL <= 'Z';
END IF;
-------------------------------------
-- SDA
CASE STEP IS
WHEN CON_IDLE => SDA <= '1';
WHEN CON_START => SDA <= '0';
WHEN CON_CONTROL=>
IF( FLAG='1' AND CountSTEP1=22 ) THEN SDA <= '0';
ELSE SDA <= COMMAND( CountSTEP1-22 );
END IF;
WHEN CON_ADDRESS=>
SDA <= ADDRESS( CountSTEP1-13 );
WHEN CON_DATA =>
IF( COMMAND(0)='1' ) THEN -- Read From 24LC16B
IF( CLKSCL='1' ) THEN DataOUT( CountSTEP1-4 ) <= SDA;
ELSE SDA <= 'Z';
END IF;
ELSE -- Write To 24LC16B
SDA <= DATA( CountSTEP1-4 );
END IF;
WHEN CON_STOP => SDA <= '0';
------------------------------------
WHEN CON_ACK => SDA <= 'Z';
WHEN OTHERS => SDA <= '1';
END CASE;
END PROCESS;
END Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -