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

📄 i2c.vhd

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

entity i2c is
port(
     clk: in std_logic;
     nreset: in std_logic;

     d:inout std_logic_vector(7 downto 0);

     start,
     stop,
     read,
     write: in std_logic;

    -- load,
   --  shift: out std_logic;
 
      -- sdai:in std_logic;
     SCL,
     SDA: inout std_logic
);
end i2c;

architecture arc_i2c_core of i2c is

--signal for i2c_core
signal sclo,sdao:std_logic;
signal din:std_logic;
--signal  dcnt:unsigned(2 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:cmds;

--signal for p2s
signal shifter: std_logic_vector(7 downto 0);
signal sr: std_logic;
type state_type is( s0,s1,s2,s3,s4,s5,s6,s7,s8,s9);
signal state_p2s:state_type;

-- signal for s2p
signal shift:std_logic_vector(7 downto 0);
type state_type1 is(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9);
signal state_s2p:state_type1;

--signal for lacth_input data
signal sh: std_logic_vector(7 downto 0);
signal flag: std_logic;


begin
-- generate statemachine

--u1: p2s1 port map(clk=>clk,nreset=>nreset,data=>data_in,sr=>din);
--u2: latch1 port map(clk=>clk,nreset=>nreset,flag=>iflag,d=>din_in,q=>din);

-- generate statemachine
p1 : process (nreset,clk,state,start,read,write)
		--variable nxt_state : cmds;
		--variable icmd_ack, ibusy, store_sda : std_logic;
		--variable itxd : std_logic;
        --variable iload,ishift:std_logic;
        variable iscl,isda:std_logic;
        variable idcnt:unsigned(2 downto 0);
     
      
	begin

	-- generate regs
		if (nReset = '0' )  then
			state <= idle;
       
			--cmd_ack <= '0';
			--busy <= '0';
			--txd <= '0';
			--Dout <= '0';
            scl<='1';
            sda<='1';
            --dcnt<="111";
            --shift<='0';
           --load<='0';
        elsif (clk'event and clk = '1') then
			--if (clk_en = '1') then
				--state <= idle;
				--busy <= ibusy;

				--txd <= itxd;
				--if (store_sda = '1') then
				--	Dout <= SDA;--SDA;
				--end if;
              
               SCL<=sclo;
               SDA<=sdao;
               
              --load<=iload;
              -- shift<=ishift;
               --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:="111";
                              ishift<='1';
                              state<=rd_a;

                else
                              idcnt:="111";
                              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:="111";
                               ishift<='1';
                               state<=rd_a;	
                  else
                               idcnt:="111";
                               iload<='1';
                               state<=wr_a;

                 end if;
               -- elsif core_ack='0' then
                --               nxt_state:=start_
				--ibusy := '0'; -- not busy when idle


			-- 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';
--				nxt_state := stop_d;

--			when stop_d =>
				state <= idle;
				--ibusy := '0'; -- not busy when idle

			-- read
			when rd_a =>
                iscl:='0';
                isda:='1';--sda;
             --   icmd_ack := '1';
                state <= rd_b;
              
			when rd_b =>
                iscl:='1';
                isda:='0';--sda;
                state <= rd_c;
               
			when rd_c =>
                iscl:='1';
                isda:='1';--sda;
                
                state <=rd_d;
              
			when rd_d =>
                iscl:='0';
                isda:='0';--sda;
           --     icmd_ack := '1';
                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;
                state <= wr_c;
  
			when wr_c =>
                iscl:='1';
               -- isda:=din;
                state <= wr_d;

			when wr_d =>
                iscl:='0';
               -- isda:=din;
               -- iflag<='1';
           --     icmd_ack := '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:='0';
                 state <= ack_d;
           
           when ack_d=>
                 isda:='0';
                 if  stop='1' then
                                state<=stop_a;
                 elsif(write='1') then
                               state<=wr_a;
                               idcnt:="111";
                               iload<='1';
                 elsif(read='1') then
                               state<=rd_a;
                               idcnt:="111";
                               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;

p2:process( nreset,en,d)  --latch for input data
begin

  if(nreset='0')  then
                    sh<="00000000";
  elsif en='1'  then
      --if flag='1' then
                   sh<=d;
    --  end if;
  end if;
end process p2;


p2s:  process(clk)
   begin
        if(clk'event and clk='1') then
        if(iload='1') then
            shifter<=d;
            --state_p2s<=s0;
            case state_p2s is
              when s0=>
                     sr<='0';
                     if(nreset='0') then
                                    state_p2s<=s0;
                     else      
                                    state_p2s<=s1;
                     end if;

              when s1=>
                     sr<=shifter(7);
                     if(nreset='0') then
                                    state_p2s<=s0;
                     else      
                                    state_p2s<=s2;
                     end if;

              when s2=>
                     sr<=shifter(6);
                     if(nreset='0') then
                                    state_p2s<=s0;
                     else      
                                    state_p2s<=s3;
                     end if;

              when s3=>
                     sr<=shifter(5);
                     if(nreset='0') then
                                    state_p2s<=s0;
                     else      
                                    state_p2s<=s4;
                     end if;

              when s4=>
                     sr<=shifter(4);
                     if(nreset='0') then
                                    state_p2s<=s0;
                     else      
                                    state_p2s<=s5;
                     end if;

              when s5=>
                     sr<=shifter(3);
                     if(nreset='0') then
                                    state_p2s<=s0;
                     else      
                                    state_p2s<=s6;
                     end if;

              when s6=>
                     sr<=shifter(2);
                     if(nreset='0') then
                                    state_p2s<=s0;
                     else      
                                    state_p2s<=s7;
                     end if;

              when s7=>
                     sr<=shifter(1);
                     if(nreset='0') then
                                    state_p2s<=s0;
                     else      
                                    state_p2s<=s8;
                     end if;

              when s8=>
                     sr<=shifter(0);
                     if(nreset='0') then
                                    state_p2s<=s0;
                     else      
                                    state_p2s<=s1;
                     end if;

              when s9=>
                     if(nreset='0') then
                                    state_p2s<=s0;
                     else      
                                    state_p2s<=s1;
                     end if;
             end case;
       end if;

      end if;
     
      din<=sr;

      end process p2s;

   s2p:process(clk)
    begin
      if(clk'event and clk='1') then
       if(ishift='1') then
          case state_s2p is
           when t0=>
                 if(nreset='0') then
                                state_s2p<=t0;
                 elsif nreset='1' then
                                state_s2p<=t1;
                 end if;
   
           when t1=>
                 shift<=sda&shift(7 downto 1);
                 
                 if(nreset='0') then
                                state_s2p<=t0;
                 elsif nreset='1' then
                                state_s2p<=t2;
                 end if;  

           when t2=>
                 shift<=sda&shift(7 downto 1);

                 if(nreset='0') then
                                state_s2p<=t0;
                 elsif nreset='1' then
                                state_s2p<=t3;
                 end if;     


           when t3=>
                 shift<=sda&shift(7 downto 1);

                 if(nreset='0') then
                                state_s2p<=t0;
                 elsif nreset='1' then
                                state_s2p<=t4;
                 end if;    


           when t4=>
                 shift<=sda&shift(7 downto 1);

                 if(nreset='0') then
                                state_s2p<=t0;
                 elsif nreset='1' then
                                state_s2p<=t5;
                 end if; 


           when t5=>
                 shift<=sda&shift(7 downto 1);

                 if(nreset='0') then
                                state_s2p<=t0;
                 elsif nreset='1' then
                                state_s2p<=t6;
                 end if;     
   

           when t6=>
                 shift<=sda&shift(7 downto 1);

                 if(nreset='0') then
                                state_s2p<=t0;
                 elsif nreset='1' then
                                state_s2p<=t7;
                 end if;     
   

           when t7=>
                 shift<=sda&shift(7 downto 1);

                 if(nreset='0') then
                                state_s2p<=t0;
                 elsif nreset='1' then
                                state_s2p<=t8;
                 end if;  


           when t8=>
                 shift<=sda&shift(7 downto 1);

                 if(nreset='0') then
                                state_s2p<=t0;
                 elsif nreset='1' then
                                state_s2p<=t9;
                 end if;     
   

           when t9=>
                 d<=shift;
 
                 if(nreset='0') then
                                state_s2p<=t0;
                 elsif nreset='1' then
                                state_s2p<=t1;
                 end if; 
           end case;
      end if;

     end if;

     end process s2p;

end architecture arc_i2c_core;



⌨️ 快捷键说明

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