moving repo from git to local repo
This commit is contained in:
@@ -0,0 +1,305 @@
|
||||
--345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
-- 1 2 3 4 5 6 7
|
||||
-- Title: I2C Master Controller
|
||||
-- Engineer: Evgeny Shumilov <eugene.shumilov@gmail.com>
|
||||
-- Company: For HiTechGlobal
|
||||
-- Project:
|
||||
-- File name: i2c.vhd
|
||||
--------------------------------------------------------------------------------
|
||||
-- Purpose:
|
||||
--------------------------------------------------------------------------------
|
||||
-- Simulator: Modelsim
|
||||
-- Synthesis: Xilinx ISE
|
||||
--------------------------------------------------------------------------------
|
||||
-- Revision: 0.65
|
||||
-- Modification date: 03/05/2003
|
||||
-- Limitation:
|
||||
-- Notes:
|
||||
--------------------------------------------------------------------------------
|
||||
-- Modifications List:
|
||||
--
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
USE ieee.std_logic_arith.all;
|
||||
use IEEE.std_logic_unsigned.all;
|
||||
--use IEEE.std_logic_signed.all;
|
||||
USE ieee.numeric_std.all;
|
||||
use IEEE.std_logic_misc.all;
|
||||
|
||||
library unisim;
|
||||
use unisim.vcomponents.all;
|
||||
|
||||
|
||||
entity i2c is
|
||||
generic (
|
||||
count_div : integer range 0 to 1023:= 512 -- sysclk divide coafficien (2 to 1023 max)
|
||||
);
|
||||
port (
|
||||
ADDR_IN : in std_logic_vector (7 downto 0); -- word address
|
||||
DAT_IN : in std_logic_vector(7 downto 0); -- write data
|
||||
DEV_ADDR : in std_logic_vector (6 downto 0); -- device address
|
||||
CONTINUE : in std_logic; -- continue read operation from ADDR_IN
|
||||
AP_EN : in std_logic; -- Enable Address Phase During Write
|
||||
WR_OP : in std_logic; -- write operation WRITE ONE WORD <= '0', RD <= '1'
|
||||
WR_EN : in std_logic; -- enable write ADDR_IN, DAT_IN, ID_ADDR, WR_OP
|
||||
CLK : in std_logic; -- main clock
|
||||
RST : in std_logic; -- system reset
|
||||
|
||||
I2C_RDATA : out std_logic_vector(7 downto 0); -- i2c read data
|
||||
ACK_L : out std_logic; -- acknowledge WR_EN (active '0')
|
||||
-- SDA : inout std_logic; -- i2c data
|
||||
-- SCL : out std_logic; -- i2c CLK
|
||||
|
||||
I_SDA_I : in std_logic;
|
||||
O_SDA_O : out std_logic;
|
||||
O_SDA_T : out std_logic;
|
||||
|
||||
I_SCL_I : in std_logic;
|
||||
O_SCL_O : out std_logic;
|
||||
O_SCL_T : out std_logic;
|
||||
|
||||
|
||||
|
||||
I2C_RDY : out std_logic; -- i2c ready
|
||||
I2C_ACT : out std_logic; -- i2c cycle active
|
||||
ACK_ERR : out std_logic -- i2c(ack) error
|
||||
);
|
||||
end entity i2c;
|
||||
|
||||
architecture translated of i2c is
|
||||
|
||||
component IOBUF
|
||||
port
|
||||
(
|
||||
O : out std_ulogic;
|
||||
IO : inout std_ulogic;
|
||||
I : in std_ulogic;
|
||||
T : in std_ulogic
|
||||
);
|
||||
end component;
|
||||
|
||||
component OBUFT
|
||||
port
|
||||
(
|
||||
O : out std_ulogic;
|
||||
I : in std_ulogic;
|
||||
T : in std_ulogic
|
||||
);
|
||||
end component;
|
||||
|
||||
component i2c_st
|
||||
port (
|
||||
WRD_ADD : in std_logic_vector(7 downto 0); -- i2c address
|
||||
WRD_DAT : in std_logic_vector(7 downto 0);
|
||||
DEV_ADDR : in std_logic_vector (6 downto 0);
|
||||
CONTINUE : in std_logic;
|
||||
ENAPH : in std_logic; -- Enable Address Phase During Write
|
||||
WR_L : in std_logic;
|
||||
RST : in std_logic; -- reset
|
||||
CLK : in std_logic; -- mpu CLK
|
||||
SCL_TICK : in std_logic; -- 5 usec CLK tick
|
||||
I2C_GO : in std_logic; -- start i2c cycle
|
||||
SDA_PIN : in std_logic; -- i2c data muxed input
|
||||
|
||||
I2C_RDATA : out std_logic_vector(7 downto 0); -- i2c read data
|
||||
SDA : out std_logic; -- i2c data
|
||||
SCL : out std_logic; -- i2c CLK
|
||||
SCL_CNT_EN : out std_logic; -- SCL cntr enable
|
||||
I2C_RDY : out std_logic; -- i2c ready
|
||||
I2C_ACT : out std_logic; -- i2c cycle active
|
||||
ACK_ERR : out std_logic -- ack error
|
||||
);
|
||||
end component;
|
||||
|
||||
---------------------------------------------------------------------------------------------------
|
||||
constant sim_timescale : time := 1 ns;
|
||||
|
||||
function length_ct (int_length : integer) return positive is
|
||||
variable conv_length : std_logic_vector(9 downto 0);
|
||||
variable index : positive:= 1;
|
||||
begin
|
||||
conv_length := CONV_STD_LOGIC_VECTOR(int_length, 10);
|
||||
for i in 9 downto 1 loop
|
||||
index:= i;
|
||||
exit when conv_length(i) = '1';
|
||||
end loop;
|
||||
return index;
|
||||
end length_ct;
|
||||
|
||||
|
||||
|
||||
|
||||
signal cntr : std_logic_vector(length_ct(count_div) downto 0);
|
||||
signal cntr_length : std_logic_vector(length_ct(count_div) downto 0);
|
||||
signal scl_tick : std_logic;
|
||||
signal wrd_addr : std_logic_vector(7 downto 0);
|
||||
signal wrd_dat : std_logic_vector(7 downto 0);
|
||||
signal dev_addr_int : std_logic_vector(6 downto 0);
|
||||
signal ENAPH : std_logic;
|
||||
signal scl_cnt_en : std_logic;
|
||||
signal i2c_go : std_logic;
|
||||
signal sda_in : std_logic;
|
||||
signal sda_o : std_logic;
|
||||
signal scl_o : std_logic;
|
||||
signal wr_l_int : std_logic;
|
||||
signal port_switch : std_logic:= '0';
|
||||
signal sda_o_spd : std_logic;
|
||||
signal scl_o_spd : std_logic;
|
||||
signal GND : std_logic;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
GND <= '0';
|
||||
|
||||
---------------------------------------------------------------------------------------------------
|
||||
-- CLOCK DIVIDER SECTION:
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
cntr_length <= CONV_STD_LOGIC_VECTOR(count_div, (length_ct(count_div)+1));
|
||||
|
||||
process (CLK,RST)
|
||||
begin
|
||||
if (RST = '1') then
|
||||
cntr <= (others => '0') after 1 * sim_timescale;
|
||||
elsif (CLK'event and CLK = '1') then
|
||||
if (scl_cnt_en = '1') then
|
||||
cntr <= cntr + 1 after 1 * sim_timescale;
|
||||
else
|
||||
cntr <= (others => '0');
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (CLK,RST)
|
||||
begin
|
||||
if (RST = '1') then
|
||||
scl_tick <= '0' after 1 * sim_timescale;
|
||||
elsif (CLK'event and CLK = '1') then
|
||||
if (cntr = cntr_length) then
|
||||
scl_tick <= '1' after 1 * sim_timescale;
|
||||
else
|
||||
scl_tick <= '0' after 1 * sim_timescale;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
---------------------------------------------------------------------------------------------------
|
||||
-- ADDRESS REGISTERS SECTION:
|
||||
---------------------------------------------------------------------------------------------------
|
||||
process (CLK)
|
||||
begin
|
||||
if (CLK'event and CLK = '1') then
|
||||
if WR_EN = '1'
|
||||
then wrd_addr <= ADDR_IN after 1 * sim_timescale;
|
||||
dev_addr_int <= DEV_ADDR after 1 * sim_timescale;
|
||||
wr_l_int <= WR_OP after 1 * sim_timescale;
|
||||
wrd_dat <= DAT_IN after 1 * sim_timescale;
|
||||
ENAPH <= AP_EN after 1 * sim_timescale;
|
||||
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (CLK)
|
||||
begin
|
||||
if (CLK'event and CLK = '1') then
|
||||
if WR_EN = '1'
|
||||
then port_switch <= (DEV_ADDR(3) and not DEV_ADDR(2) and DEV_ADDR(1) and not DEV_ADDR(0)) after 1 * sim_timescale; -- "1010" (SPD)
|
||||
else null;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
|
||||
process (CLK, RST)
|
||||
begin
|
||||
-- send ack right back
|
||||
|
||||
if (RST = '1') then
|
||||
i2c_go <= '0' after 1 * sim_timescale;
|
||||
elsif (CLK'event and CLK = '1') then
|
||||
if WR_EN = '1'
|
||||
then
|
||||
i2c_go <= '1' after 1 * sim_timescale;
|
||||
else
|
||||
if (scl_cnt_en = '1') then
|
||||
i2c_go <= '0' after 1 * sim_timescale;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (CLK, RST)
|
||||
begin
|
||||
if (RST = '1') then
|
||||
ACK_L <= '1' after 1 * sim_timescale;
|
||||
elsif (CLK'event and CLK = '1') then
|
||||
if WR_EN = '1'
|
||||
then ACK_L <= '0' after 1 * sim_timescale;
|
||||
else
|
||||
ACK_L <= '1' after 1 * sim_timescale;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
---------------------------------------------------------------------------------------------------
|
||||
-- I2C STATE MACHINE SECTION:
|
||||
---------------------------------------------------------------------------------------------------
|
||||
MAIN_FSM : i2c_st
|
||||
port map(
|
||||
WRD_ADD => wrd_addr,
|
||||
WRD_DAT => wrd_dat,
|
||||
DEV_ADDR => dev_addr_int,
|
||||
CONTINUE => CONTINUE,
|
||||
ENAPH => ENAPH,
|
||||
WR_L => wr_l_int,
|
||||
RST => RST,
|
||||
CLK => CLK,
|
||||
SCL_TICK => scl_tick,
|
||||
I2C_GO => i2c_go,
|
||||
SDA_PIN => sda_in,
|
||||
|
||||
I2C_RDATA => I2C_RDATA,
|
||||
SDA => sda_o,
|
||||
SCL => scl_o,
|
||||
SCL_CNT_EN => scl_cnt_en,
|
||||
I2C_RDY => I2C_RDY,
|
||||
I2C_ACT => I2C_ACT,
|
||||
ACK_ERR => ACK_ERR
|
||||
);
|
||||
|
||||
|
||||
sda_o_spd <= sda_o;
|
||||
scl_o_spd <= scl_o;
|
||||
|
||||
--SDA_BUF: IOBUF
|
||||
-- port map
|
||||
-- (
|
||||
-- O => sda_in,
|
||||
-- IO => SDA,
|
||||
-- I => GND,
|
||||
-- T => sda_o_spd
|
||||
-- );
|
||||
|
||||
|
||||
sda_in <= I_SDA_I;
|
||||
O_SDA_O <= GND;
|
||||
O_SDA_T <= sda_o_spd;
|
||||
|
||||
--SCL_BUF: OBUFT
|
||||
-- port map
|
||||
-- (
|
||||
-- O => SCL,
|
||||
-- I => GND,
|
||||
-- T => scl_o_spd
|
||||
-- );
|
||||
|
||||
-- scl_in <= I_SCL_I
|
||||
O_SCL_O <= GND;
|
||||
O_SCL_T <= scl_o_spd;
|
||||
|
||||
|
||||
end architecture translated;
|
||||
Reference in New Issue
Block a user