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

📄 i2c_master_bit_ctrl.vhd

📁 Opencore提供的I2C代码
💻 VHD
📖 第 1 页 / 共 2 页
字号:
	            dSCL <= sSCL;	            dSDA <= sSDA;	          end if;	        end if;	    end process synch_SCL_SDA;	    -- detect start condition => detect falling edge on SDA while SCL is high	    -- detect stop condition  => detect rising edge on SDA while SCL is high	    detect_sta_sto: process(clk, nReset)	    begin	        if (nReset = '0') then	          sta_condition <= '0';	          sto_condition <= '0';	        elsif (clk'event and clk = '1') then	          if (rst = '1') then	            sta_condition <= '0';	            sto_condition <= '0';	          else	            sta_condition <= (not sSDA and dSDA) and sSCL;	            sto_condition <= (sSDA and not dSDA) and sSCL;	          end if;	        end if;	    end process detect_sta_sto;	    -- generate i2c-bus busy signal	    gen_busy: process(clk, nReset)	    begin	        if (nReset = '0') then	          ibusy <= '0';	        elsif (clk'event and clk = '1') then	          if (rst = '1') then	            ibusy <= '0';	          else	            ibusy <= (sta_condition or ibusy) and not sto_condition;	          end if;	        end if;	    end process gen_busy;	    busy <= ibusy;	    -- generate arbitration lost signal	    -- aribitration lost when:	    -- 1) master drives SDA high, but the i2c bus is low	    -- 2) stop detected while not requested (detect during 'idle' state)	    gen_al: process(clk, nReset)	    begin	      if (nReset = '0') then	        cmd_stop  <= '0';	        ial       <= '0';	      elsif (clk'event and clk = '1') then	        if (rst = '1') then	          cmd_stop  <= '0';	          ial       <= '0';	        else	          if (clk_en = '1') then	            if (cmd = I2C_CMD_STOP) then	              cmd_stop <= '1';	            else	              cmd_stop <= '0';	            end if;	          end if;	          if (c_state = idle) then	            ial <= (sda_chk and not sSDA and isda_oen);	          else	            ial <= (sda_chk and not sSDA and isda_oen) or (sto_condition and not cmd_stop);	          end if;	        end if;	      end if;	    end process gen_al;	    al <= ial;	    -- generate dout signal, store dout on rising edge of SCL	    gen_dout: process(clk)	    begin	      if (clk'event and clk = '1') then	        if (sSCL = '1' and dSCL = '0') then	          dout <= sSDA;	        end if;	      end if;	    end process gen_dout;	end block bus_status_ctrl;	-- generate statemachine	nxt_state_decoder : process (clk, nReset, c_state, cmd)	begin	    if (nReset = '0') then	      c_state  <= idle;	      cmd_ack  <= '0';	      iscl_oen <= '1';	      isda_oen <= '1';	      sda_chk  <= '0';	    elsif (clk'event and clk = '1') then	      if (rst = '1' or ial = '1') then	        c_state  <= idle;	        cmd_ack  <= '0';	        iscl_oen <= '1';	        isda_oen <= '1';	        sda_chk  <= '0';	      else	        cmd_ack <= '0'; -- default no acknowledge	        if (clk_en = '1') then	          case (c_state) is	             -- idle	             when idle =>	                case cmd is	                  when I2C_CMD_START => c_state <= start_a;	                  when I2C_CMD_STOP  => c_state <= stop_a;	                  when I2C_CMD_WRITE => c_state <= wr_a;	                  when I2C_CMD_READ  => c_state <= rd_a;	                  when others        => c_state <= idle; -- NOP command	                end case;	                iscl_oen <= iscl_oen; -- keep SCL in same state	                isda_oen <= isda_oen; -- keep SDA in same state	                sda_chk  <= '0';      -- don't check SDA	             -- start	             when start_a =>	                c_state  <= start_b;	                iscl_oen <= iscl_oen; -- keep SCL in same state (for repeated start)	                isda_oen <= '1';      -- set SDA high	                sda_chk  <= '0';      -- don't check SDA	             when start_b =>	                c_state  <= start_c;	                iscl_oen <= '1'; -- set SCL high	                isda_oen <= '1'; -- keep SDA high	                sda_chk  <= '0'; -- don't check SDA	             when start_c =>	                c_state  <= start_d;	                iscl_oen <= '1'; -- keep SCL high	                isda_oen <= '0'; -- set SDA low	                sda_chk  <= '0'; -- don't check SDA	             when start_d =>	                c_state  <= start_e;	                iscl_oen <= '1'; -- keep SCL high	                isda_oen <= '0'; -- keep SDA low	                sda_chk  <= '0'; -- don't check SDA	             when start_e =>	                c_state  <= idle;	                cmd_ack  <= '1'; -- command completed	                iscl_oen <= '0'; -- set SCL low	                isda_oen <= '0'; -- keep SDA low	                sda_chk  <= '0'; -- don't check SDA	             -- stop	             when stop_a =>	                c_state  <= stop_b;	                iscl_oen <= '0'; -- keep SCL low	                isda_oen <= '0'; -- set SDA low	                sda_chk  <= '0'; -- don't check SDA	             when stop_b =>	                c_state  <= stop_c;	                iscl_oen <= '1'; -- set SCL high	                isda_oen <= '0'; -- keep SDA low	                sda_chk  <= '0'; -- don't check SDA	             when stop_c =>	                c_state  <= stop_d;	                iscl_oen <= '1'; -- keep SCL high	                isda_oen <= '0'; -- keep SDA low	                sda_chk  <= '0'; -- don't check SDA	             when stop_d =>	                c_state  <= idle;	                cmd_ack  <= '1'; -- command completed	                iscl_oen <= '1'; -- keep SCL high	                isda_oen <= '1'; -- set SDA high	                sda_chk  <= '0'; -- don't check SDA	             -- read	             when rd_a =>	                c_state  <= rd_b;	                iscl_oen <= '0'; -- keep SCL low	                isda_oen <= '1'; -- tri-state SDA	                sda_chk  <= '0'; -- don't check SDA	             when rd_b =>	                c_state  <= rd_c;	                iscl_oen <= '1'; -- set SCL high	                isda_oen <= '1'; -- tri-state SDA	                sda_chk  <= '0'; -- don't check SDA	             when rd_c =>	                c_state  <= rd_d;	                iscl_oen <= '1'; -- keep SCL high	                isda_oen <= '1'; -- tri-state SDA	                sda_chk  <= '0'; -- don't check SDA	             when rd_d =>	                c_state  <= idle;	                cmd_ack  <= '1'; -- command completed	                iscl_oen <= '0'; -- set SCL low	                isda_oen <= '1'; -- tri-state SDA	                sda_chk  <= '0'; -- don't check SDA	             -- write	             when wr_a =>	                c_state  <= wr_b;	                iscl_oen <= '0'; -- keep SCL low	                isda_oen <= din; -- set SDA	                sda_chk  <= '0'; -- don't check SDA (SCL low)	             when wr_b =>	                c_state  <= wr_c;	                iscl_oen <= '1'; -- set SCL high	                isda_oen <= din; -- keep SDA	                sda_chk  <= '1'; -- check SDA	             when wr_c =>	                c_state  <= wr_d;	                iscl_oen <= '1'; -- keep SCL high	                isda_oen <= din; -- keep SDA	                sda_chk  <= '1'; -- check SDA	             when wr_d =>	                c_state  <= idle;	                cmd_ack  <= '1'; -- command completed	                iscl_oen <= '0'; -- set SCL low	                isda_oen <= din; -- keep SDA	                sda_chk  <= '0'; -- don't check SDA (SCL low)	             when others =>	          end case;	        end if;	      end if;	    end if;	end process nxt_state_decoder;	-- assign outputs	scl_o   <= '0';	scl_oen <= iscl_oen;	sda_o   <= '0';	sda_oen <= isda_oen;end architecture structural;

⌨️ 快捷键说明

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