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

📄 i2c_main_blk.vhd

📁 IIC的IP.这是经过验证的源代码
💻 VHD
📖 第 1 页 / 共 2 页
字号:
   end if;
 end process;        
 
 I2C_Load_SR_Process:process(MPU_CLK, Reset, load,shift)
 begin
   if(Reset = '0') then
     Trans_Buffer_SR     <= "00000000";        
     Value               <= '0';     
          
   elsif(rising_edge(MPU_CLK)) then 
     case load is
       when "01" =>
         Trans_Buffer_SR(7 downto 0) <= Low_Address_Reg(6 downto 0) & Low_Address_Reg(7);
         Value                       <= Low_Address_Reg(7); --write out msb to lsb
       when "10" =>
         Trans_Buffer_SR(7 downto 0) <= Trans_Buffer(6 downto 0) & Trans_Buffer(7);
         Value <= Trans_Buffer(7);
       when "11" =>
         if(shift = '0') then
           Trans_Buffer_SR(7 downto 0) <= Trans_Buffer_SR(7 downto 0);
           Value <= Value;
         else
           Trans_Buffer_SR(7 downto 0) <= Trans_Buffer_SR(6 downto 0) & Trans_Buffer_SR(7);         
           Value                       <= Trans_Buffer_SR(7); --write out msb to lsb           
         end if;   
       when others =>
         Trans_Buffer_SR(7 downto 0) <= Trans_Buffer_SR(7 downto 0);
         Value <= Value;
      end case;
   end if;
 end process;
     


 I2C_drive_sda_Process:process(MPU_CLK, MCS(0),MCS(1),WCS(2),WCS(3),WCS(4),Bit_Cnt_Flag,Reset, value)
 begin
   if(Reset = '0') then
     SDA_EN1 <= '0';
         
   elsif(rising_edge(MPU_CLK)) then    
     if(RCS(4) = '1') then
       SDA_EN1 <= '1';
     elsif(det_low = '1') then   
       if(MCS(0) = '1' or MCS(1) = '1'  or 
         ((WCS(2) = '1' or WCS(3) = '1' or WCS(4) = '1') and Bit_Cnt_Flag = '1')) then
         SDA_EN1 <= '0';
       else 
         if(Value = '1') then  -- Write out MSB to LSB and address first       
           SDA_EN1   <= '0'; -- write out high
         else
             SDA_EN1   <= '1'; -- write out low
         end if;
       end if;
     end if;  --want the data to stay the same until next low scl or sclh
   end if;
 end process;

 I2C_Write_Process:process(MPU_CLK, Reset,MCS(2),MCS(3),WCS(0), Bit_Count, det_low)
 begin
   if(Reset = '0') then
     load  <= "11";
     shift <= '0';     
    
   elsif(rising_edge(MPU_CLK)) then 
     if((MCS(2) = '1') and (WCS(0) = '1') and (Bit_Count = "000") and (det_low = '1')) then
       load <= "01";
       shift <= '0';
     elsif((MCS(3) = '1') and (WCS(0) = '1') and (Bit_Count = "000") and (det_low = '1')) then
       load <= "10";
       shift <= '0';
     elsif((MCS(2) = '1' or MCS(3) = '1') and (Bit_Count = "000") and (det_low = '1') ) then
       load <= load;
       shift <= '0';
     elsif((MCS(2) = '1' or MCS(3) = '1') and (WCS(0) = '1') and (det_low = '1') ) then
       load <= "11";
       shift <= '1';
     else --do nothing
       load <= load;
       shift <= '0';
     end if;
   end if;  
 end process; 
  

 I2C_Read_Process:process(MPU_CLK, Reset, Bit_Count, det_high, RCS, SDA)

 begin
   if(Reset = '0') then
     Read_SR     <= "00000000";        
 
   elsif(rising_edge(MPU_CLK)) then 
     if(MCS(4) = '1' and RCS(0) = '1' and Bit_Count = "001" and det_high = '1') then  
       if(SDA = '1') then
          Read_SR <= "0000000" & '1';
       else
          Read_SR <= "00000000";
       end if;      

     elsif(MCS(4) = '1' and (RCS(0) = '1' or RCS(2) = '1') and det_high = '1') then 
       if(SDA = '1') then
         Read_SR <= Read_SR(6 downto 0) & '1';
       else
         Read_SR <= Read_SR(6 downto 0) & '0';
       end if;      
     else
       Read_SR <= Read_SR;
     end if;
   end if;  
 end process;

 I2C_WSM: process(MPU_CLK, Reset,Next_WCS)
 begin
   if(Reset = '0') then
     WCS       <= Write_State;     
   elsif(rising_edge(MPU_CLK)) then 
     WCS       <= Next_WCS;        
   end if;
 end process;
     
 I2C_WSM_Process: process(WCS, det_low, det_high, Lost_Arb, Bit_Cnt_Flag, MCS_Write_Flag, SDA)
 begin
   case WCS is
     when Write_State =>
       if(Lost_Arb = '0') then
         if(det_low = '1' and MCS_Write_Flag = '1') then
             Next_WCS <= Delay_Write_State;  -- wait for the SCLH clock to transition one cycle    
                                                       -- and write out next bit 
         else
           Next_WCS <= Write_State;
         end if;
       else
         Next_WCS <= Error_Write_State;         
       end if;  

     when Delay_Write_State =>
          if(det_high = '1' and Bit_Cnt_Flag = '1') then -- wait for the clock to go high again
            Next_WCS <= Delay_Ack_Write_State;                 -- if bit_count is up goto ack state
          elsif(det_high = '1' and Bit_Cnt_Flag = '0') then
            Next_WCS <= Write_State;
          else
            Next_WCS <= Delay_Write_State;      
          end if;        

     when Delay_Ack_Write_State =>
          if(det_low = '1') then
            Next_WCS <= Ack_Write_State;
          else
            Next_WCS <= Delay_Ack_Write_State;      
          end if;        

     when Ack_Write_State =>
       if(det_high = '1') then
         if(SDA = '0') then  -- acknowlege recieved /A
           Next_WCS <= Write_State;        
         else --failed ack
           Next_WCS <= Error_Write_State;                   
         end if;  
       else
         Next_WCS <= Ack_Write_State; -- wait for the SCL or SCLH clock to go high, thus data is stable
       end if;

     when Error_Write_State =>       
       Next_WCS <= Error_Write_State;                   
              
     when others =>
       Next_WCS <= Write_State;        
   end case;
 end process;

 I2C_RSM: process(MPU_CLK, Reset,Next_RCS)
 begin
   if(Reset = '0') then
     RCS       <= Read_State;     
   elsif(rising_edge(MPU_CLK)) then 
     RCS       <= Next_RCS;        
   end if;
 end process;

 I2C_RSM_Process: process(RCS, Lost_Arb, Bit_Cnt_Flag,
                           det_low, SDA, det_high, MCS_Read_Flag)
 begin
   case RCS is
     when Read_State =>
       if(Lost_Arb = '0') then
         if(det_high = '1' and MCS_Read_Flag = '1') then
              Next_RCS <= Delay_Read_State;  -- wait for the SCLH clock to transition one cycle    
                                                       -- and read in next bit 
          else
            Next_RCS <= Read_State;  
          end if;  
        else -- lost arb
          Next_RCS <= Error_Read_State;      
        end if;

     when Delay_Read_State =>
       if(det_low = '1') then -- wait for the clock to go high again
         if(Bit_Cnt_Flag = '1') then 
           Next_RCS <= Delay_Ack_Read_State; -- done reading byte
         else
           Next_RCS <= Read_State;  -- wait for the SCLH clock to transition one cycle    
                                                      -- and read in next bit 
         end if;
       else
         Next_RCS <= Delay_Read_State;      
       end if;        

     when Delay_Ack_Read_State =>
          if(det_high = '1') then
            Next_RCS <= Delay_Ack_Read_State2;
          else
            Next_RCS <= Delay_Ack_Read_State;      
          end if;        

     when Delay_Ack_Read_State2 =>
          if(det_low = '1') then
            Next_RCS <= Ack_Read_State;
          else
            Next_RCS <= Delay_Ack_Read_State2;      
          end if;        

     when Ack_Read_State =>
       if(det_high = '1') then 
         if(SDA = '0') then  -- acknowlege recieved /A
           Next_RCS <= Read_State;        
         else --failed ack
           Next_RCS <= Error_Read_State;                   
         end if;  
       else
         Next_RCS <= Ack_Read_State; -- wait for the SCL or SCLH clock to go high, thus data is stable
       end if;

     when Error_Read_State =>       
       Next_RCS <= Error_Read_State;                   
              
     when others =>
       Next_RCS <= Read_State;        
   end case;
 end process;
   
 I2C_MSM_Process: process(MPU_CLK, Reset, MCS,Byte_Cnt_Flag, I2C_RW_Bit,
                           SCL, Start_Det, go)
 begin
   if(Reset = '0') then
     MCS       <= Idle_State;     
     
   elsif(rising_edge(MPU_CLK)) then 
     case MCS is
       when Idle_State =>
         if(I2C_Bus_Busy = '0' and go = '1') then
          if(SCL = '1') then
             MCS <= Delay_Start_EN_State;                  
           else
             MCS <= Idle_State;
           end if;
         else
           MCS <= Idle_State;
         end if;
      
       when Delay_Start_EN_State =>
         if(Start_Det = '1')  then 
           MCS <= Write_Slv_Addr_State;
         else
           MCS <= Delay_Start_EN_State;            
         end if;

       when Write_Slv_Addr_State =>
         if(WCS(3) = '1' ) then   -- ack state in write sm
           if(I2C_RW_Bit = '0') then
             MCS <= Main_Write_State;
           else
             MCS <= Main_Read_State;
           end if;
         else
           MCS <= Write_Slv_Addr_State; -- wait for write sm to finish
         end if;

       when Main_Write_State =>
         if(Byte_Cnt_Flag = '1' and WCS(3) = '1') then -- continue writing until transaction complete
           MCS <= Idle_State;
         else          
           MCS <= Main_Write_State;        
         end if;                
             
       when Main_Read_State =>
         if(Byte_Cnt_Flag = '1') then -- continue reading until transaction complete
           MCS <= Idle_State;
         else          
           MCS <= Main_Read_State;        
         end if;                

       when others =>
         MCS <= Idle_State;
     end case;
   end if;
 end process;

end I2C_Main_Behave;

--------------------------------- E O F --------------------------------------

⌨️ 快捷键说明

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