⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rif_i2cslave.vhd

📁 DesignWave 2005 8 Verilog Example
💻 VHD
字号:
--------------------------------------------------------------------------------
-- rif_i2cSlave (Register I/F for i2cSlave)
-- Takashi Kohno (DigiCat)
-- Rev. 0.5.0c  / 27, May., 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 ;


entity rif_i2cSlave is
	port(	CLK, nRST			: in std_logic ;
			CKE					: in std_logic ;  -- CLK enable for sampling clock
			
			-- Register I/F
			WrEn, RdEn			: in std_logic ;
			Usel				: in std_logic ;  -- Unit select
			Uadrs				: in std_logic_vector(2 downto 0) ;
			Din					: in std_logic_vector(7 downto 0) ;
			Dout				: out std_logic_vector(7 downto 0) ;
			Int					: out std_logic ;

			-- Local bus for slave functions
			syncRST				: out std_logic ;
			-- Transaction query
			SReq				: in std_logic ;
			Si2cAdrs			: in std_logic_vector(6 downto 0) ;
			SRnW				: in std_logic ;
			SAck				: out std_logic ;

			-- Slave write stream
			SwrDReq				: in std_logic ;
			SwrData				: in std_logic_vector(7 downto 0) ;
			SwrTerm				: out std_logic ;
			SwrDRdy				: out std_logic ;
			
			-- Slave read stream
			SrdDReq				: in std_logic ;
			SrdData				: out std_logic_vector(7 downto 0) ;
			SrdDRdy				: out std_logic ;

			-- Status Reports
			srpTerm				: in std_logic ;
			srpAbort			: in std_logic ;
			srpBFree			: in std_logic ;
			srpBObsc			: in std_logic ;

			-- Timing Parameters
			Dsup				: out std_logic_vector(1 downto 0)
			) ;
end rif_i2cSlave ;



architecture RTL of rif_i2cSlave is

-- Register addresses
constant ADRS_CMDSTS	: std_logic_vector(2 downto 0) := "000" ;
constant ADRS_I2CADRS	: std_logic_vector(2 downto 0) := "001" ;
constant ADRS_SWDATA	: std_logic_vector(2 downto 0) := "010" ;
constant ADRS_SRDATA	: std_logic_vector(2 downto 0) := "011" ;
constant ADRS_SCFG		: std_logic_vector(2 downto 0) := "100" ;
constant ADRS_STRNS		: std_logic_vector(2 downto 0) := "111" ;

-- Register select signals
signal rselCmdSts		: std_logic ;
signal rseli2cAdrs		: std_logic ;
signal rselSwrData		: std_logic ;
signal rselSrdData		: std_logic ;
signal rselSCfg			: std_logic ;
signal rselSTrns		: std_logic ;

-- Registers
signal regGCAEn			: std_logic ;
signal regSRdEn			: std_logic ;
signal regSWrEn			: std_logic ;
signal regSts			: std_logic_vector(7 downto 0) ;
signal regi2cAdrs		: std_logic_vector(7 downto 0) ;
signal regSrdData		: std_logic_vector(7 downto 0) ;
signal regSCfg			: std_logic_vector(7 downto 0) ;
signal regSTrns			: std_logic_vector(7 downto 0) ;
signal regINTen			: std_logic ;

alias regDsup			: std_logic_vector(1 downto 0) is regSCfg(1 downto 0) ;

-- Status
signal stsRdTrans		: std_logic ;
signal stsWrTrans		: std_logic ;
signal stsGCA			: std_logic ;

-- Internal signals
signal sel_i2cAdrs, sel_GCA		: std_logic ;
signal dsrpTerm, redgsrpTerm	: std_logic ;
signal dsrpAbort, redgsrpAbort	: std_logic ;

signal SrdDFull			: std_logic ;

signal btSAck			: std_logic ;

signal msgs				: std_logic ;
signal IntMsg			: std_logic ;
signal IntSrd			: std_logic ;
signal IntSwr			: std_logic ;
signal dmsgs			: std_logic ;  	-- msgs delayed for 1 clock
signal dSrdDReq			: std_logic ;  	-- SrdDReq delayed for 1 clock
signal dSwrDReq			: std_logic ;  	-- SwrDReq delayed for 1 clock


begin

-- Register select signals
	rselCmdSts <= Usel when Uadrs = ADRS_CMDSTS else
				  '0' ;
	rseli2cAdrs <= Usel when Uadrs = ADRS_I2CADRS else
				   '0' ;
	rselSwrData <= Usel when Uadrs = ADRS_SWDATA else
				   '0' ;
	rselSrdData <= Usel when Uadrs = ADRS_SRDATA else
				   '0' ;
	rselSCfg <= Usel when Uadrs = ADRS_SCFG else
				'0' ;
	rselSTrns <= Usel when Uadrs = ADRS_STRNS else
				 '0' ;

-- Register I/F output
	with Uadrs select
		Dout <= regSts when ADRS_CMDSTS,
				regi2cAdrs when ADRS_I2CADRS,
				SwrData when ADRS_SWDATA,
				regSrdData when ADRS_SRDATA,
				regSCfg when ADRS_SCFG,
				regSTrns when ADRS_STRNS,
				(others => '0') when others ;

	Int <= regINTen when (IntMsg or IntSwr or IntSrd) = '1' else
		   '0' ;



---------------------------------------------------------------------------------------------------
-- Command I/F
---------------------------------------------------------------------------------------------------
	-- Registers
	QueryBusRegs: process(CLK, nRST)
	begin
		if nRST = '0' then
			regGCAEn <= '0' ;
			regSRdEn <= '0' ;
			regSWrEn <= '0' ;
			regi2cAdrs <= (others => '0') ;
		elsif rising_edge(CLK) then
			if WrEn = '1' then
				if rselCmdSts = '1' then
					regGCAEn <= Din(2) ;
					regSRdEn <= Din(1) ;
					regSWrEn <= Din(0) ;
				end if ;
				if rseli2cAdrs = '1' then
					regi2cAdrs <= Din ;
				end if ;
			end if ;
		end if ;
	end process ;

	-- WrTrans Bit in Status Reg.
	AddressDecoder0: process(CLK, nRST)
	begin
		if nRST = '0' then
			stsWrTrans <= '0' ;
		elsif rising_edge(CLK) then
			if SReq = '1' then
				if sel_i2cAdrs = '1' and SRnW = '0' and regSWrEn = '1' then
					stsWrTrans <= '1' ;
				else
					stsWrTrans <= '0' ;
				end if ;
			elsif redgsrpTerm = '1' or redgsrpAbort = '1' then
				stsWrTrans <= '0' ;
			end if ;
		end if ;
	end process ;

	-- RdTrans Bit in Status Reg.
	AddressDecoder1: process(CLK, nRST)
	begin
		if nRST = '0' then
			stsRdTrans <= '0' ;
		elsif rising_edge(CLK) then
			if SReq = '1' then
				if sel_i2cAdrs = '1' and SRnW = '1' and regSRdEn = '1' then
					stsRdTrans <= '1' ;
				else
					stsRdTrans <= '0' ;
				end if ;
			elsif redgsrpTerm = '1' or redgsrpAbort = '1' then
				stsRdTrans <= '0' ;
			end if ;
		end if ;
	end process ;

	-- GCA Bit in Status Reg.
	AddressDecoder2: process(CLK, nRST)
	begin
		if nRST = '0' then
			stsGCA <= '0' ;
		elsif rising_edge(CLK) then
			if SReq = '1' then
				if sel_GCA = '1' and SRnW = '0' and regGCAEn = '1' then
					stsGCA <= '1' ;
				else
					stsGCA <= '0' ;
				end if ;
			elsif redgsrpTerm = '1' or redgsrpAbort = '1' then
				stsGCA <= '0' ;
			end if ;
		end if ;
	end process ;

	DetectTermAbort: process(CLK, nRST)
	begin
		if nRST = '0' then
			dsrpTerm <= '1' ;
			dsrpAbort <= '1' ;
		elsif rising_edge(CLK) then
			dsrpTerm <= srpTerm ;
			dsrpAbort <= srpAbort ;
		end if ;
	end process ;

	redgsrpTerm <= '1' when dsrpTerm = '0' and srpTerm = '1' else
				   '0' ;
	redgsrpAbort <= '1' when dsrpAbort = '0' and srpAbort = '1' else
					'0' ;

	sel_i2cAdrs <= '1' when Si2cAdrs = regi2cAdrs(6 downto 0) else
				   '0' ;
	sel_GCA <= '1' when Si2cAdrs = "0000000" else
			   '0' ;

	-- Query bus signals
	SAck <= btSAck when stsRdTrans = '1' or stsWrTrans = '1' or stsGCA = '1' else
			'0' ;

	SAckGen: process(CLK, nRST)
	begin
		if nRST = '0' then
			btSAck <= '0' ;
		elsif rising_edge(CLK) then
			btSAck <= SReq ;
		end if ;
	end process ;
				
	-- Status register output
	regSts <= (stsRdTrans, stsWrTrans, srpBFree, srpBObsc, stsGCA, '0', srpTerm, srpAbort) ;



---------------------------------------------------------------------------------------------------
-- Slave-Write Data I/F
---------------------------------------------------------------------------------------------------
	-- Slwave-Write bus signals
	SwrDataBus: process(CLK, nRST)
	begin
		if nRST = '0' then
			SwrTerm <= '0' ;
		elsif rising_edge(CLK) then
			if (WrEn and rselSwrData) = '1' then
				SwrTerm <= '1' ;
			elsif SwrDReq = '1' then
				SwrTerm <= '0' ;
			end if ;
		end if ;
	end process ;

	SwrDRdy <= '1' when (RdEn and rselSwrData) = '1' else
			   '0' ;



---------------------------------------------------------------------------------------------------
-- Slave-Read Data I/F
---------------------------------------------------------------------------------------------------
	SrdDataBusSeq: process(CLK, nRST)
	begin
		if nRST = '0' then
			regSrdData <= (others => '0') ;
			SrdDFull <= '0' ;
		elsif rising_edge(CLK) then
			if SrdDFull = '0' then
				if SrdDReq = '0' and (WrEn and rselSrdData) = '1' then
					SrdDFull <= '1' ;
					regSrdData <= Din ;
				end if ;
			else
				if SrdDReq = '1' then
					SrdDFull <= '0' ;
				end if ;
			end if ;
		end if ;
	end process ;

	SrdDRdy <= '0' when SrdDFull = '0' and (WrEn and rselSrdData) = '0' else
			   '1' ;
	SrdData <= Din when SrdDFull = '0' else
			   regSrdData ;



---------------------------------------------------------------------------------------------------
-- Interruption generator
---------------------------------------------------------------------------------------------------
	-- Transaction register
	TrReg: process(CLK, nRST)
	begin
		if nRST = '0' then
			regINTen <= '0' ;
		elsif rising_edge(CLK) then
			if WrEn = '1' and rselSTrns = '1' then
				regINTen <= Din(0) ;
			end if ;
		end if ;
	end process ;

	syncRST <= Din(7) when WrEn = '1' and rselSTrns = '1' else
			   '0' ;

	-- Transaction register output
	regSTrns <= (IntMsg, '0', IntSrd, IntSwr, SrdDFull, SrdDReq, SwrDReq, regINTen) ;

	-- Interruption generator
	StsDelayers: process(CLK, nRST)
	begin
		if nRST = '0' then
			dmsgs <= '0' ;
			dSrdDReq <= '0' ;
			dSwrDReq <= '0' ;
		elsif rising_edge(CLK) then
			dmsgs <= msgs ;
			dSrdDReq <= SrdDReq ;
			dSwrDReq <= SwrDReq ;
		end if ;
	end process ;

	IntMsgGen: process(CLK, nRST)
	begin
		if nRST = '0' then
			IntMsg <= '0' ;
		elsif rising_edge(CLK) then
			if dmsgs = '0' and msgs = '1' then
				IntMsg <= '1' ;
			elsif RdEn = '1' and rselSTrns = '1' then
				IntMsg <= '0' ;
			end if ;
		end if ;
	end process ;

	IntSrdGen: process(CLK, nRST)
	begin
		if nRST = '0' then
			IntSrd <= '0' ;
		elsif rising_edge(CLK) then
			if dSrdDReq = '0' and SrdDReq = '1' then
				IntSrd <= '1' ;
			elsif RdEn = '1' and rselSTrns = '1' then
				IntSrd <= '0' ;
			end if ;
		end if ;
	end process ;

	IntMrdGen: process(CLK, nRST)
	begin
		if nRST = '0' then
			IntSwr <= '0' ;
		elsif rising_edge(CLK) then
			if dSwrDReq = '0' and SwrDReq = '1' then
				IntSwr <= '1' ;
			elsif RdEn = '1' and rselSTrns = '1' then
				IntSwr <= '0' ;
			end if ;
		end if ;
	end process ;

	msgs <= srpTerm or srpAbort ;


---------------------------------------------------------------------------------------------------
-- Configuration Registers
---------------------------------------------------------------------------------------------------
	CRegs: process(CLK, nRST)
	begin
		if nRST = '0' then
			regSCfg <= (others => '0') ;
		elsif rising_edge(CLK) then
			if WrEn = '1' then
				if rselSCfg = '1' then
					regSCfg <= Din ;
				end if ;
			end if ;
		end if ;
	end process ;

	-- for i2cMaster
	DSup <= regDsup ;



end RTL ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -