📄 i2cstdec.vhd
字号:
--------------------------------------------------------------------------------
-- i2cStDec (i2c State Decoder)
-- Takashi Kohno (DigiCat)
-- Rev. 0.5.0c / 20, Jun., 2005
--
----------------------------------------
--
-- Copyright (c) 2005 Takashi Kohno
-- This design is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License
-- as published by the Free Software Foundation; either version 2
-- of the License, or any later version.
--
-- This design is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
--
--------------------------------------------------------------------------------
library IEEE ;
use IEEE.std_logic_1164.all ;
use IEEE.std_logic_arith.all ;
use WORK.i2cBasics.all ;
entity i2cStDec is
port( CLK, nRST, syncRST : in std_logic ;
CKE : in std_logic ; -- CLK enable for sampling clock
-- i2c bus
SCL, SDA : in std_logic ;
-- State Decoder outputs
BSQ : out i2cBusState ; -- i2c Bus state
BoSCH : out std_logic ; -- '1' for 1CLK at rising_edge(SCL)
EoSCH : out std_logic ; -- '1' for 1CLK at falling_edge(SCL)
STAC : out std_logic ; -- '1' for 1CLK at STArt Condition
STPC : out std_logic ; -- '1' for 1CLK at SToP Condition
ReceivedData : out std_logic_vector(7 downto 0) ;
test : out std_logic_vector(7 downto 0) ;
FirstSBit : out std_logic ; -- '1' while processing the first serial bit
-- or nothing
LastSBit : out std_logic ; -- '1' while processing the last serial bit
vSCL, vSDA : out std_logic ; -- current status of SCL / SDA
BFree : out std_logic ; -- '1' while i2c bus is free
BObsc : out std_logic -- '1' while i2c bus status is unknown
) ;
end i2cStDec ;
architecture RTL of i2cStDec is
-- component I/F signals
-- for i2cRcv
signal rcvSCL, rcvSDA : std_logic ;
signal iBoSCH : std_logic ;
signal iEoSCH : std_logic ;
signal iSTAC : std_logic ;
signal iSTPC : std_logic ;
signal ivSDA : std_logic ;
-- Logic signals for Main Seq.
signal iRQ : i2cBusState ;
signal iSBitCntr : std_logic_vector(2 downto 0) ; -- Counts serial data bits
signal sbcEOC : std_logic ; -- '1' when a byte is transferred
signal pcEOC : std_logic ;
-- Data Receiver and Transmitter
signal earlySDA : std_logic ; -- vSDA latched at rising_edge(vSCL)
signal DReceiver : std_logic_vector(7 downto 0) ;
begin
-- Component instantiations: i2cMAU
RcvUnit: i2cRcv
port map( CLK => CLK, nRST => nRST, syncRST => syncRST,
CKE => CKE,
SCL => SCL, SDA => SDA,
BoSCH => iBoSCH,
EoSCH => iEoSCH,
STAC => iSTAC,
STPC => iSTPC,
vSCL => vSCL,
vSDA => ivSDA
) ;
---------------------------------------------------------------------------------------------------
-- Root Sequencer for i2cSeq
---------------------------------------------------------------------------------------------------
-- Sequencer body
i2cSeqRoot: process(CLK, nRST)
begin
if nRST = '0' then
iRQ <= Pend ;
elsif rising_edge(CLK) then
if syncRST = '1' then
iRQ <= Pend ;
elsif iSTAC = '1' then --or STPC = '1' then
iRQ <= STR ;
elsif iSTPC = '1' then
iRQ <= Free ;
else
case iRQ is
when Pend =>
if pcEOC = '1' then
iRQ <= Free ;
end if ;
when Free =>
when STR =>
if iEoSCH = '1' then
iRQ <= ATR ;
end if ;
when ATR | DTR =>
if iEoSCH = '1' and sbcEOC = '1' then
iRQ <= ACK ;
end if ;
when ACK =>
if iEoSCH = '1' then
if earlySDA = '1' then
iRQ <= STP ;
else
iRQ <= DTR ;
end if ;
end if ;
when others =>
end case ;
end if ;
end if ;
end process ;
-- Counts serial data bit location
SerialBitCounter: process(CLK, nRST)
begin
if nRST = '0' then
iSBitCntr <= (others => '0') ;
elsif rising_edge(CLK) then
if syncRST = '1' then
iSBitCntr <= (others => '0') ;
elsif iRQ = ATR or iRQ = DTR then
if iEoSCH = '1' then
iSBitCntr <= unsigned(iSBitCntr) +1 ;
end if ;
else
iSBitCntr <= (others => '0') ;
end if ;
end if ;
end process ;
sbcEOC <= '1' when iSBitCntr = "111" else
'0' ;
pcEOC <= '1' ;
---------------------------------------------------------------------------------------------------
-- Data Receiver
---------------------------------------------------------------------------------------------------
-- SDA -> Parallel
DataReceiver: process(CLK, nRST)
begin
if nRST = '0' then
DReceiver <= (others => '0') ;
elsif rising_edge(CLK) then
if syncRST = '1' then
DReceiver <= (others => '0') ;
elsif iRQ = ATR or iRQ = DTR then
if iBoSCH = '1' then
DReceiver(7 downto 1) <= DReceiver(6 downto 0) ;
DReceiver(0) <= ivSDA ;
end if ;
end if ;
end if ;
end process ;
-- Latch vSDA at rising_edge(vSCL)
SDAatREdgeSCLGen: process(CLK, nRST)
begin
if nRST = '0' then
earlySDA <= '1' ;
elsif rising_edge(CLK) then
if syncRST = '1' then
earlySDA <= '1' ;
elsif iBoSCH = '1' then
earlySDA <= ivSDA ;
end if ;
end if ;
end process ;
---------------------------------------------------------------------------------------------------
-- Output signals
---------------------------------------------------------------------------------------------------
BSQ <= iRQ ;
BoSCH <= iBOSCH ;
EoSCH <= iEOSCH ;
STAC <= iSTAC ;
STPC <= iSTPC ;
ReceivedData <= DReceiver ;
FirstSBit <= '1' when iSBitCntr = "000" else
'0' ;
LastSBit <= sbcEOC ;
vSDA <= ivSDA ;
BFree <= '1' when iRQ = Free else
'0' ;
BObsc <= '1' when iRQ = Pend else
'0' ;
end RTL ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -