?? i2c_main_blk.vhd
字號:
------------------------------------------------------------------------------
--
-- Name: I2C_Main_Blk.vhd
--
-- Description: Main state machine block controls the transaction on the
-- I2C bus. It acts as an interface between the I2C controller
-- and the I2C bus.
--
-- $Revision: 1.0 $
--
-- Copyright 2004 Lattice Semiconductor Corporation. All rights reserved.
--
------------------------------------------------------------------------------
-- Permission:
--
-- Lattice Semiconductor grants permission to use this code for use
-- in synthesis for any Lattice programmable logic product. Other
-- use of this code, including the selling or duplication of any
-- portion is strictly prohibited.
--
-- Disclaimer:
--
-- This VHDL or Verilog source code is intended as a design reference
-- which illustrates how these types of functions can be implemented.
-- It is the user's responsibility to verify their design for
-- consistency and functionality through the use of formal
-- verification methods. Lattice Semiconductor provides no warranty
-- regarding the use or functionality of this code.
------------------------------------------------------------------------------
--
-- Lattice Semiconductor Corporation
-- 5555 NE Moore Court
-- Hillsboro, OR 97124
-- U.S.A
--
-- TEL: 1-800-Lattice (USA and Canada)
-- 408-826-6000 (other locations)
--
-- web: http://www.latticesemi.com/
-- email: techsupport@latticesemi.com
--
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity I2C_Main is
port(MPU_CLK : in std_logic; -- MP Clock
Rst_L : in std_logic; -- Main Reset, active low
SCL : in bit;--7/14std_logic; -- I2C F/S mode Clock
SDA : in bit;--7/14std_logic; -- SDA
Bit_Count : in std_logic_vector(2 downto 0); -- Bit count for I2C packets
Bit_Cnt_Flag : in std_logic; -- Bit Count overflow flag
Byte_Cnt_Flag : in std_logic; -- Byte Count overflow flag
Trans_Buffer : in std_logic_vector(7 downto 0); -- Data from MPU for I2C Write
Low_Address_Reg : in std_logic_vector(7 downto 0); -- Low order Address bits for I2C Slave
Lost_Arb : in std_logic; -- Lost Arbitration Bit
Start_Det : in std_logic; -- I2C Start Detect
Stop_Det : in std_logic; -- I2C Stop Detect
Command_Reg : in std_logic_vector(1 downto 0); -- CMD part of Command_Status Reg Contains:
-- Go, Abort. Does not include: I2C_Mode,
-- I2C_address Size,Iack,Trans_IE and Recieve_IE.
Status_Reg : out std_logic_vector(3 downto 0); -- Status part of Command_Status Reg Contains:
-- I2C_Bus_Busy, Abort_Ack, Error,Done
-- Does not include:Trans_Buf_Empty, Recieve_Buf_Full,
-- Lost_Arb. Lost Arb comes from arbiter
Read_Buffer : out std_logic_vector(7 downto 0); -- I2C read data byte
Bit_Cnt_EN : out std_logic; -- Bit count enable
Byte_Cnt_EN : out std_logic; -- Byte count enable
Start_EN : out std_logic; -- Start enable
Stop_EN : out std_logic; -- Stop enable
SDA_EN1 : out std_logic; -- SDA enable
TBE_Set : out std_logic; -- set Transmit_Buffer_Empty flag for MPU block
RBF_Set : out std_logic; -- set Recieve_Buffer_Full flag for MPU block
Go_Clear : out std_logic; -- Request to clear go bit
WCS_Ack : out std_logic;
RCS_Ack : out std_logic);
end I2C_Main;
architecture I2C_Main_Behave of I2C_Main is
--Command_Reg bits (used by I2C Main Blk)
signal go : std_logic;
signal abort : std_logic;
-- signal I2C_Add_Size : std_logic; -- not implemented yet
--Status_Reg bits (set by I2C Main Blk)
signal I2C_Bus_Busy : std_logic;
signal Error : std_logic;
signal Abort_Ack : std_logic;
signal Done : std_logic;
signal Reset : std_logic;
--signal Retry_Cnt : std_logic_vector(1 downto 0);
--Low_Address_Reg bits
signal I2C_RW_Bit : std_logic;
--
signal Read_SR : std_logic_vector(7 downto 0);
signal Trans_Buffer_SR : std_logic_vector(7 downto 0);
signal Value : std_logic;
signal det_low : std_logic;
signal det_high : std_logic;
signal MCS_Write_Flag : std_logic;
signal MCS_Read_Flag : std_logic;
signal load : std_logic_vector(1 downto 0);
signal shift : std_logic;
signal bit_cnt2 : std_logic;
--testing 7/26
signal b0 :std_logic;
signal b1 :std_logic;
signal s :std_logic;
--7/20 signal condition : std_logic_vector(2 downto 0);
-- State Bits for the Main State Machine
-- ONLY 3 state bits
signal MCS : std_logic_vector(4 downto 0);
constant Idle_State : std_logic_vector(4 downto 0) := "00001";
constant Delay_Start_EN_State : std_logic_vector(4 downto 0) := "00010";
constant Write_Slv_Addr_State : std_logic_vector(4 downto 0) := "00100";
constant Main_Write_State : std_logic_vector(4 downto 0) := "01000";
constant Main_Read_State : std_logic_vector(4 downto 0) := "10000";
-- State Bits for the Write State Machine
-- ONLY 2 state bits
signal WCS : std_logic_vector(4 downto 0);
signal Next_WCS : std_logic_vector(4 downto 0);
constant Write_State : std_logic_vector(4 downto 0) := "00001";
constant Delay_Write_State : std_logic_vector(4 downto 0) := "00010";
constant Delay_Ack_Write_State : std_logic_vector(4 downto 0) := "00100";
constant Ack_Write_State : std_logic_vector(4 downto 0) := "01000";
constant Error_Write_State : std_logic_vector(4 downto 0) := "10000";
-- State Bits for the Read State Machine
-- ONLY 2 state bits
signal RCS : std_logic_vector(5 downto 0);
signal Next_RCS : std_logic_vector(5 downto 0);
constant Read_State : std_logic_vector(5 downto 0) := "000001";
constant Delay_Read_State : std_logic_vector(5 downto 0) := "000010";
constant Delay_Ack_Read_State : std_logic_vector(5 downto 0) := "000100";
constant Delay_Ack_Read_State2 : std_logic_vector(5 downto 0) := "001000";
constant Ack_Read_State : std_logic_vector(5 downto 0) := "010000";
constant Error_Read_State : std_logic_vector(5 downto 0) := "100000";
begin
go <= Command_Reg(1);
abort <= Command_Reg(0);
I2C_RW_Bit <= Low_Address_Reg(0);
WCS_Ack <= WCS(3);
RCS_Ack <= RCS(4);
Status_Reg <= I2C_Bus_Busy & Error & Abort_Ack & Done;
Reset <= '0' when RST_L = '0' or abort = '1' else '1';-- or WCS(4) = '1' or RCS(3) = '1' else '1';
MCS_Read_Flag <= '1' when MCS(4) = '1' and I2C_RW_Bit = '1' else '0';
MCS_Write_Flag <= '1' when MCS(2) = '1' or ((MCS(3) = '1') and I2C_RW_Bit = '0') else '0';
output_proc: process(MPU_CLK,Reset,WCS,MCS,Start_Det,Stop_Det,I2C_RW_Bit,det_low,bit_cnt2)
begin
if(Reset = '0') then
Abort_Ack <= '0';
Error <= '0';
I2C_Bus_Busy <= '0';
Done <= '0';
TBE_Set <= '0';
RBF_Set <= '0';
Bit_Cnt_En <= '0';
bit_cnt2 <= '0';
Byte_Cnt_En <= '0';
Start_En <= '0';
Stop_En <= '0';
Go_Clear <= '0';
Read_Buffer <= "00000000";
b0 <= '0';
b1 <= '0';
s <= '0';
elsif(rising_edge(MPU_CLK)) then
if(abort = '1') then
Abort_Ack <= '1';
else
Abort_Ack <= '0';
end if;
if((WCS(4) = '1')or(RCS(5) = '1')) then
Error <= '1';
else
Error <= '0';
end if;
if(start_det = '1') then
I2C_Bus_Busy <= '1';
end if;
if(stop_det = '1' and I2C_Bus_Busy = '1') then
I2C_Bus_Busy <= '0';
end if;
if((s = '0' and b0 = '0' and b1 = '1') or ( s = '1' and ( b0 = '1' or b1 = '1'))) then
b0 <= '1';
else
b0 <= '0';
end if;
if( s = '1' and b0 = '0' and b1 = '0') then
b1 <= '1';
else
b1 <= '0';
end if;
if(WCS(1) = '1' and I2C_RW_Bit = '0' and Bit_Count = "001" and Byte_Cnt_Flag = '0' and MCS(3) = '1') then
s <= '1';
else
s <= '0';
end if;
if(b0 = '0' and b1 = '1') then
TBE_Set <= '1';
else
TBE_Set <= '0';
end if;
if(RCS(4) = '1' and I2C_RW_Bit = '1' and MCS(4) = '1') then
RBF_Set <= '1';
else
RBF_Set <= '0';
end if;
if(((WCS(0) = '1' and MCS_Write_Flag = '1') or (RCS(0) = '1' and MCS_Read_Flag = '1' )) and bit_cnt2 = '1') then
Bit_Cnt_En <= '1';
else
Bit_Cnt_En <= '0';
end if;
if((MCS(2) = '1' or MCS(3) = '1' ) and det_low = '1') then
bit_cnt2 <= '1';
elsif(MCS(0) = '1') then
bit_cnt2 <= '0';
end if;
if((WCS(3) = '1' and MCS_Write_Flag = '1') or (RCS(2) = '1' and MCS_Read_Flag = '1')) then
Byte_Cnt_En <= '1';
else
Byte_Cnt_En <= '0';
end if;
if(MCS(1) = '1' and det_low = '1' and I2C_Bus_Busy = '0') then
Start_En <= '1';
else
Start_En <= '0';
end if;
if(MCS(1) = '1') then
Go_Clear <= '1';
Done <= '0';
Stop_En <= '0';
elsif((MCS(0) = '1' and (WCS(0) = '1' or RCS(2) = '1'))and
Bit_Cnt_Flag = '1' and Byte_Cnt_Flag = '1' and det_low = '1' and I2C_Bus_Busy = '1') then
Done <= '1';
Go_Clear <= '0';
Stop_En <= '1';
else
Go_Clear <= '0';
Stop_En <= '0';
end if;
if(RCS(4) = '1') then
Read_Buffer <= Read_SR;
end if;
end if;
end process;
I2C_Det : process(MPU_CLK, Reset, SCL)
begin
if(Reset = '0') then
det_low <= '0';
det_high <= '0';
elsif(rising_edge(MPU_CLK)) then
if(SCL = '0') then -- data can only change during scl low
det_low <= '1';
else
det_low <= '0';
end if;
if(SCL = '1') then -- data can only change during scl low
det_high <= '1';
else
det_high <= '0';
end if;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -