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

📄 i2c_master_byte_ctrl.vhd

📁 基于VHDL的I2C程序0003,很不错的论文及程序
💻 VHD
字号:
-------------------------------------------------------------------------                                                             --------  WISHBONE revB2 compl. I2C Master Core; byte-controller     --------                                                             --------                                                             --------  Author: Richard Herveille                                  --------          richard@asics.ws                                   --------          www.asics.ws                                       --------                                                             --------  Downloaded from: http://www.opencores.org/projects/i2c/    --------                                                             -----------------------------------------------------------------------------                                                             -------- Copyright (C) 2000 Richard Herveille                        --------                    richard@asics.ws                         --------                                                             -------- This source file may be used and distributed without        -------- restriction provided that this copyright statement is not   -------- removed from the file and that any derivative work contains -------- the original copyright notice and the associated disclaimer.--------                                                             --------     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     -------- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   -------- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   -------- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      -------- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         -------- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    -------- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   -------- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        -------- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  -------- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  -------- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  -------- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         -------- POSSIBILITY OF SUCH DAMAGE.                                 --------                                                             ---------------------------------------------------------------------------  CVS Log----  $Id: i2c_master_byte_ctrl.vhd,v 1.5 2004/02/18 11:41:48 rherveille Exp $----  $Date: 2004/02/18 11:41:48 $--  $Revision: 1.5 $--  $Author: rherveille $--  $Locker:  $--  $State: Exp $---- Change History:--               $Log: i2c_master_byte_ctrl.vhd,v $--               Revision 1.5  2004/02/18 11:41:48  rherveille--               Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.----               Revision 1.4  2003/08/09 07:01:13  rherveille--               Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.--               Fixed a potential bug in the byte controller's host-acknowledge generation.----               Revision 1.3  2002/12/26 16:05:47  rherveille--               Core is now a Multimaster I2C controller.----               Revision 1.2  2002/11/30 22:24:37  rherveille--               Cleaned up code----               Revision 1.1  2001/11/05 12:02:33  rherveille--               Split i2c_master_core.vhd into separate files for each entity; same layout as verilog version.--               Code updated, is now up-to-date to doc. rev.0.4.--               Added headers.------------------------------------------------ Byte controller section--------------------------------------------library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;entity i2c_master_byte_ctrl is	port (		clk    : in std_logic;		rst    : in std_logic; -- synchronous active high reset (WISHBONE compatible)		nReset : in std_logic;	-- asynchornous active low reset (FPGA compatible)		ena    : in std_logic; -- core enable signal		clk_cnt : in unsigned(15 downto 0);	-- 4x SCL		-- input signals		start,		stop,		read,		write,		ack_in : std_logic;		din    : in std_logic_vector(7 downto 0);		-- output signals		cmd_ack  : out std_logic; -- command done		ack_out  : out std_logic;		i2c_busy : out std_logic; -- arbitration lost		i2c_al   : out std_logic; -- i2c bus busy		dout     : out std_logic_vector(7 downto 0);		-- i2c lines		scl_i   : in std_logic;  -- i2c clock line input		scl_o   : out std_logic; -- i2c clock line output		scl_oen : out std_logic; -- i2c clock line output enable, active low		sda_i   : in std_logic;  -- i2c data line input		sda_o   : out std_logic; -- i2c data line output		sda_oen : out std_logic  -- i2c data line output enable, active low	);end entity i2c_master_byte_ctrl;architecture structural of i2c_master_byte_ctrl is	component i2c_master_bit_ctrl is	port (		clk    : in std_logic;		rst    : in std_logic;		nReset : in std_logic;		ena    : in std_logic;				-- core enable signal		clk_cnt : in unsigned(15 downto 0);		-- clock prescale value		cmd     : in std_logic_vector(3 downto 0);		cmd_ack : out std_logic; -- command done		busy    : out std_logic; -- i2c bus busy		al      : out std_logic; -- arbitration lost		din  : in std_logic;		dout : out std_logic;		-- i2c lines		scl_i   : in std_logic;  -- i2c clock line input		scl_o   : out std_logic; -- i2c clock line output		scl_oen : out std_logic; -- i2c clock line output enable, active low		sda_i   : in std_logic;  -- i2c data line input		sda_o   : out std_logic; -- i2c data line output		sda_oen : out std_logic  -- i2c data line output enable, active low	);	end component i2c_master_bit_ctrl;	-- commands for bit_controller block	constant I2C_CMD_NOP  	: std_logic_vector(3 downto 0) := "0000";	constant I2C_CMD_START	: std_logic_vector(3 downto 0) := "0001";	constant I2C_CMD_STOP	 : std_logic_vector(3 downto 0) := "0010";	constant I2C_CMD_READ	 : std_logic_vector(3 downto 0) := "0100";	constant I2C_CMD_WRITE	: std_logic_vector(3 downto 0) := "1000";	-- signals for bit_controller	signal core_cmd : std_logic_vector(3 downto 0);	signal core_ack, core_txd, core_rxd : std_logic;	signal al : std_logic;	-- signals for shift register	signal sr : std_logic_vector(7 downto 0); -- 8bit shift register	signal shift, ld : std_logic;	-- signals for state machine	signal go, host_ack : std_logic;	signal dcnt : unsigned(2 downto 0); -- data counter	signal cnt_done : std_logic;begin	-- hookup bit_controller	bit_ctrl: i2c_master_bit_ctrl port map(		clk     => clk,		rst     => rst,		nReset  => nReset,		ena     => ena,		clk_cnt => clk_cnt,		cmd     => core_cmd,		cmd_ack => core_ack,		busy    => i2c_busy,		al      => al,		din     => core_txd,		dout    => core_rxd,		scl_i   => scl_i,		scl_o   => scl_o,		scl_oen => scl_oen,		sda_i   => sda_i,		sda_o   => sda_o,		sda_oen => sda_oen	);	i2c_al <= al;	-- generate host-command-acknowledge	cmd_ack <= host_ack;	-- generate go-signal	go <= (read or write or stop) and not host_ack;	-- assign Dout output to shift-register	dout <= sr;	-- generate shift register	shift_register: process(clk, nReset)	begin	    if (nReset = '0') then	      sr <= (others => '0');	    elsif (clk'event and clk = '1') then	      if (rst = '1') then	        sr <= (others => '0');	      elsif (ld = '1') then	        sr <= din;	      elsif (shift = '1') then	        sr <= (sr(6 downto 0) & core_rxd);	      end if;	    end if;	end process shift_register;	-- generate data-counter	data_cnt: process(clk, nReset)	begin	    if (nReset = '0') then	      dcnt <= (others => '0');	    elsif (clk'event and clk = '1') then	      if (rst = '1') then	        dcnt <= (others => '0');	      elsif (ld = '1') then	        dcnt <= (others => '1');  -- load counter with 7	      elsif (shift = '1') then	        dcnt <= dcnt -1;	      end if;	    end if;	end process data_cnt;	cnt_done <= '1' when (dcnt = 0) else '0';	--	-- state machine	--	statemachine : block	    type states is (st_idle, st_start, st_read, st_write, st_ack, st_stop);	    signal c_state : states;	begin	    --	    -- command interpreter, translate complex commands into simpler I2C commands	    --	    nxt_state_decoder: process(clk, nReset)	    begin	        if (nReset = '0') then	          core_cmd <= I2C_CMD_NOP;	          core_txd <= '0';	          shift    <= '0';	          ld       <= '0';	          host_ack <= '0';	          c_state  <= st_idle;	          ack_out  <= '0';	        elsif (clk'event and clk = '1') then	          if (rst = '1' or al = '1') then	            core_cmd <= I2C_CMD_NOP;	            core_txd <= '0';	            shift    <= '0';	            ld       <= '0';	            host_ack <= '0';	            c_state  <= st_idle;	            ack_out  <= '0';	          else	            -- initialy reset all signal	            core_txd <= sr(7);	            shift    <= '0';	            ld       <= '0';	            host_ack <= '0';	            case c_state is	              when st_idle =>	                 if (go = '1') then	                   if (start = '1') then	                     c_state  <= st_start;	                     core_cmd <= I2C_CMD_START;	                   elsif (read = '1') then	                     c_state  <= st_read;	                     core_cmd <= I2C_CMD_READ;	                   elsif (write = '1') then	                     c_state  <= st_write;	                     core_cmd <= I2C_CMD_WRITE;	                   else -- stop	                     c_state  <= st_stop;	                     core_cmd <= I2C_CMD_STOP;	                   end if;	                   ld <= '1';	                 end if;	              when st_start =>	                 if (core_ack = '1') then	                   if (read = '1') then	                     c_state  <= st_read;	                     core_cmd <= I2C_CMD_READ;	                   else	                     c_state  <= st_write;	                     core_cmd <= I2C_CMD_WRITE;	                   end if;	                   ld <= '1';	                 end if;	              when st_write =>	                 if (core_ack = '1') then	                   if (cnt_done = '1') then	                     c_state  <= st_ack;	                     core_cmd <= I2C_CMD_READ;	                   else	                     c_state  <= st_write;       -- stay in same state	                     core_cmd <= I2C_CMD_WRITE;  -- write next bit	                     shift    <= '1';	                   end if;	                 end if;	              when st_read =>	                 if (core_ack = '1') then	                   if (cnt_done = '1') then	                     c_state  <= st_ack;	                     core_cmd <= I2C_CMD_WRITE;	                   else	                     c_state  <= st_read;      -- stay in same state	                     core_cmd <= I2C_CMD_READ; -- read next bit	                   end if;	                   shift    <= '1';	                   core_txd <= ack_in;	                 end if;	              when st_ack =>	                 if (core_ack = '1') then	                   -- check for stop; Should a STOP command be generated ?	                   if (stop = '1') then	                     c_state  <= st_stop;	                     core_cmd <= I2C_CMD_STOP;	                   else	                     c_state  <= st_idle;	                     core_cmd <= I2C_CMD_NOP;	                     -- generate command acknowledge signal	                     host_ack <= '1';	                   end if;	                   -- assign ack_out output to core_rxd (contains last received bit)	                   ack_out  <= core_rxd;	                   core_txd <= '1';	                 else	                   core_txd <= ack_in;	                 end if;	              when st_stop =>	                 if (core_ack = '1') then	                   c_state  <= st_idle;	                   core_cmd <= I2C_CMD_NOP;	                   -- generate command acknowledge signal	                   host_ack <= '1';	                 end if;	              when others => -- illegal states	                 c_state  <= st_idle;	                 core_cmd <= I2C_CMD_NOP;	                 report ("Byte controller entered illegal state.");	            end case;	          end if;	        end if;	    end process nxt_state_decoder;	end block statemachine;end architecture structural;

⌨️ 快捷键说明

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