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

📄 i2c_core.vhd

📁 这是我做的I2C的vhdl程序和仿真和下载文件
💻 VHD
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity i2c_core is
port(
     clk,
     nreset: in std_logic;

     din:in std_logic;

     start,
     stop,
     read,
     write: in std_logic;

     SCL,
     SDA: inout std_logic
);
end i2c_core;

architecture arc_i2c_core of i2c_core is

signal sclo,sdao:std_logic;
signal  dcnt:unsigned(3 downto 0);
signal iload,ishift:std_logic;
type cmds is (idle, start_a, start_b, start_c, start_d, stop_a, stop_b, stop_c, rd_a, rd_b, rd_c, rd_d, wr_a, wr_b, wr_c,wr_d, ack_a,ack_b,ack_c,ack_d,nack_a,nack_b,nack_c,nack_d);
--state:     00000  00001    00010    00011    00100   00101    00110  00111  01000  01001 01010  01011 01100 01101 01110 01111 10000 10001 10010 10011 10100 10101  10110   10111
signal state,nxt_state:cmds;

signal iflag: std_logic;


begin
-- generate statemachine
--generate i2c_core data transfer 
p1 : process (nreset,clk,state,start,read,write,din)

        variable iscl,isda:std_logic;
        variable idcnt:unsigned(3 downto 0);
     
      
	begin

	-- generate regs
		if (nReset = '0' )  then
			state <= idle;
       
            scl<='0';
            sda<='1';
            dcnt<="1000";
          
        elsif (clk'event and clk = '1') then
			
               SCL<=sclo;
               SDA<=sdao;
               
              dcnt<=idcnt;
                
        case state is    
            when idle=>
                iscl:='0';    
			    isda:='0';
                if(start='1')  then
                              state<=start_a;
                elsif stop='1' then
                               state<=stop_a;
                elsif read='1'    then
                              idcnt:="1000";
                              ishift<='1';
                              state<=rd_a;

                else
                              idcnt:="1000";
                              iload<='1';
                              state<=wr_a;

               end if;
         
                            	
            -- start
			when start_a =>
				iscl := '0'; -- keep SCL in same state (for repeated start)
				isda := '1'; -- set SDA high
           		state <= start_b;
              

			when start_b =>
                iscl:='1';
                isda:='1';
                
               	state <= start_c;
                
		
			when start_c =>
				iscl:='1';
                isda:='0';
                
                state <= start_d;
                            

			when start_d =>
                iscl:='0';
                isda:='0';
               -- icmd_ack := '1';
			   --if core_ack='1' then
                
                                
                  if read='1' then
                               idcnt:="1000";
                               ishift<='1';
                               state<=rd_a;	
                  else
                               idcnt:="1000";
                               iload<='1';
                               state<=wr_a;

                 end if;
            
			-- stop
			when stop_a =>
                iscl:='0';
                isda:='0';
				state <= stop_b;

			when stop_b =>
                iscl:='1';
                isda:='0';
				state <= stop_c;

			when stop_c =>
                iscl:='1';
                isda:='1';

--			when stop_d =>
				state <= idle;

			-- read
			when rd_a =>
                iscl:='0';
                isda:=sda;
                state <= rd_b;
              
			when rd_b =>
                iscl:='1';
                isda:=sda;
                state <= rd_c;
               
			when rd_c =>
                iscl:='1';
                isda:=sda;
                
                state <=rd_d;
              
			when rd_d =>
                iscl:='0';
                isda:=sda;
                idcnt:=idcnt-1;
                
                if stop='1' then
                             state<=nack_a;
                 elsif idcnt=0  then
            				state <= ack_a;
				 else   
                            state<=rd_a;
			    end if;

        

           -- write
			when wr_a =>
                iscl:='0';
                isda:=din;
                iflag<='0';
                state <= wr_b;
               
			when wr_b =>
                iscl:='1';
                isda:=din;
                iflag<='0';
                state <= wr_c;
  
			when wr_c =>
                iscl:='1';
                isda:=din;
                iflag<='0';
                state <= wr_d;

			when wr_d =>
                iscl:='0';
                isda:=din;
                iflag<='1';
               idcnt:=idcnt-1;
               
                if(idcnt=0)  then 
                    			state <= ack_a;
                                iflag<='0';
                else  
                                state<=wr_a;
                end if;
                

            when ack_a=> 
                iscl:='0';
                isda:='0';
                state <= ack_b;
 
           
            when ack_b=>
                 isda:='0';
                 iscl:='1';
                 state <= ack_c;
     
           when ack_c=>
                 iscl:='1';
                 state <= ack_d;
           
           when ack_d=>
                 isda:='0';
                 iscl:='0';
                 if  stop='1' then
                                state<=stop_a;
                 elsif(write='1') then
                               state<=wr_a;
                               idcnt:="1000";
                               iload<='1';
                 elsif(read='1') then
                               state<=rd_a;
                               idcnt:="1000";
                               ishift<='1';
                              
                else
                               state<=idle;
                end if;
        
           when nack_a=>
                iscl:='0';
                isda:='1';
                state <= nack_b;
               
            when nack_b=>
                isda:='1';
                iscl:='1';
                state <= nack_c;

           when nack_c=>
                 isda:='1';
                 iscl:='0';
                 state <= nack_d;
           
           when nack_d=>
                 isda:='1';
                 state<=stop_a;
                         
		end case;
        sclo<=iscl;
        sdao<=isda;
  end if;
          
  end process p1;

     
end architecture arc_i2c_core;



⌨️ 快捷键说明

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