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

📄 i2c_read.vhd

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

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

     sda: in std_logic;

     start,
     stop,
     read,
     write: in std_logic;

    -- load,
   --  shift: out std_logic;
 
      -- sdai:in std_logic;
     d: out std_logic_vector(7 downto 0);

     scl: out std_logic
    
);
end i2c_read;

architecture arc_i2c_core of i2c_read is

component s2p2 is
   port(
    nclr, 
    clock : IN std_logic;
    
    d: in std_logic;
    sr: out std_logic_vector( 7 downto 0)
  );
end component s2p2;


--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 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 latch
signal flag:std_logic;
signal ddin: std_logic;
--signal for i2c_core  for read
signal q :std_logic_vector(7 downto 0);


begin
-- generate serial data transfer to parallel data 
 shift:s2p2 port map(nreset,clk,sda,d);


-- 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';
            iscl:='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;
				
               
              --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
                
                 if  stop='1' then
                                state<=stop_a;
                 else
                   				state <= start_b;
                 end if;

			when start_b =>
                iscl:='1';
                isda:='1';
                
                 if  stop='1' then
                                state<=stop_a;
                 else
                   				state <= start_c;
                 end if;

		
			when start_c =>
				iscl:='1';
                isda:='0';
                
                 if  stop='1' then
                                state<=stop_a;
                 else
                   				state <= start_d;
                 end if;

             

			when start_d =>
                iscl:='0';
                isda:='0';
               -- icmd_ack := '1';
			   --if core_ack='1' then
                
                 if  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;
               -- 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:=sda;
                flag<='0';
             --   icmd_ack := '1';
                
                 if  stop='1' then
                                state<=stop_a;
                 else
                   				state <= rd_b;
                 end if;


			when rd_b =>
                iscl:='1';
                isda:=sda;
                
                 if  stop='1' then
                                state<=stop_a;
                 else
                   				state <= rd_c;
                 end if;

			

			when rd_c =>
                iscl:='1';
                isda:=sda;
                
                 if  stop='1' then
                                state<=stop_a;
                 else
                   				state <=rd_d;
                 end if;

				
				--store_sda := '1';

			when rd_d =>
                iscl:='0';
                isda:=sda;
                flag<='1';
           --     icmd_ack := '1';
                idcnt:=idcnt-1;
                
                 if  stop='1' then
                                state<=stop_a;
                 elsif idcnt=0  then
            				state <= nack_a;
				 else   
                            state<=rd_a;
			    end if;

           -- write
			when wr_a =>
                iscl:='0';
                isda:='1';--din;
               -- iflag<='0';
                
                 if  stop='1' then
                                state<=stop_a;
                 else
                                state <= wr_b;
                 end if;

			when wr_b =>
                iscl:='1';
               -- isda:=din;
                 if  stop='1' then
                                state<=stop_a;
                 else
                                state <= wr_c;
                 end if;

			when wr_c =>
                iscl:='1';
               -- isda:=din;
                 if  stop='1' then
                                state<=stop_a;
                 else
                                state <= wr_d;
                 end if;

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

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

           when nack_c=>
                 isda:='1';
                 iscl:='0';
                 if  stop='1' then
                                state<=stop_a;
                 else
                                state <= nack_d;
                 end if;
           
           when nack_d=>
                 isda:='1';
                 if  stop='1' then
                                state<=stop_a;
                 elsif(read='1') then
                          state<=rd_a;
                          idcnt:="111";
                          ishift<='1';
                 else
                         state<=idle;
                 end if; 
         
		end case;
        scl<=iscl;
       -- sdao<=isda;
        dcnt<=idcnt;
  end if;
          
  end process p1;



latch1:process(sda,flag)
 begin
  
     if(flag='1')           then
                        ddin<=sda;
     else 
                        ddin<=ddin;
     
     end if;
 
end process latch1;

end architecture arc_i2c_core;



⌨️ 快捷键说明

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