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

📄 libreria_i2c.vhd

📁 用VHDL实现视频控制程序,实现对图像的采集和压缩,
💻 VHD
📖 第 1 页 / 共 3 页
字号:
library IEEE;
use IEEE.std_logic_1164.all;
package libreria_i2c is
-- Divisor, generador de SCL. 
-- Divide los 50 MHz del reloj del sistema por 256 utilizando
-- un contador de 8 bits y tomando como salida al MSB.
	component divisor port (
	        reset: in STD_LOGIC;
	        reloj: in STD_LOGIC;
       	        clear: in STD_LOGIC;
        	set: in STD_LOGIC;
        	SCL: buffer STD_LOGIC
        );
        end component;

-- Buffer triestado de salida para SCL.
-- Controla el estado de alta impedancia (pull-up) de la linea
-- de reloj serie (SCL).
	component bufferZ port (
        	ent : in STD_LOGIC;
        	OE  : in STD_LOGIC;
        	sal : out STD_LOGIC
        );
        end component;

-- Definimos un registro que servira tanto para mantener la
-- subdireccion del registro interno del procesador de video
-- donde deseamos escribir el dato como al propio dato (lo 
-- instanciaremos dos veces en el TOP).
        component registro port (
		reset: in STD_LOGIC;
		reloj: in STD_LOGIC;
	    	LE: in STD_LOGIC;
	        dat_in: in STD_LOGIC_VECTOR (7 downto 0);
	        dat_out: out STD_LOGIC_VECTOR (7 downto 0)
	);
        end component;

-- Definimos un multiplexor 3(x8):1(x8) que nos servira para 
-- seleccionar a cada uno de los tres bytes que son necesarios
-- para la escritura de un registro interno del procesador de
-- video via I2C.
	component mux_byte port (
		byte2: in STD_LOGIC_VECTOR (7 downto 0);
		byte1: in STD_LOGIC_VECTOR (7 downto 0);
		byte0: in STD_LOGIC_VECTOR (7 downto 0);
		sel: in STD_LOGIC_VECTOR (1 downto 0);
		byte_sal: out STD_LOGIC_VECTOR (7 downto 0)
	);
	end component;
	
-- Definimos un contador de 2 bits que hara de puntero para
-- seleccionar mediante el multiplexor anterior, el byte
-- que vamos a transmitir.
        component contador_byte port (
      		reset: in STD_LOGIC;
      		reloj: in STD_LOGIC;
      		clear: in STD_LOGIC;
      		inc: in STD_LOGIC;
        	cont: out STD_LOGIC_VECTOR (1 downto 0)
        );
        end component;

-- Definimos un multiplexor 8:1 que usaremos como serializador.
-- Tomara uno a uno los bits de la salida del multiplexor 
-- 3(x8):1(x8) comenzando por el bit mas significativo para 
-- respetar el protocolo de transferencia I2C. 
        component mux port (
        	ent: in STD_LOGIC_VECTOR (7 downto 0);
 	        sel: in STD_LOGIC_VECTOR (2 downto 0);
        	sal: out STD_LOGIC
        );
        end component;

-- Definimos un contador que hara de puntero para determinar
-- el bit que sera seleccionado por cada multiplexor. De nuevo,
-- este componente lo instanciaremos dos veces en el TOP (una
-- por cada multiplexor).
        component contador port (
      		reset: in STD_LOGIC;
      		reloj: in STD_LOGIC;
      		inc: in STD_LOGIC;
        	cont: out STD_LOGIC_VECTOR (2 downto 0)
        );
        end component;
        
-- Maquina de estados que controla el protocolo I2C.
-- Solo hay que suministrarle los 3 bytes a enviar. La maquina
-- los envia respetando las reglas del protocolo I2C.
	 component FSM_I2C port (
		reloj: in STD_LOGIC;
		reset: in STD_LOGIC;
		trans: in STD_LOGIC;
		fin_espera64: in STD_LOGIC;
		fin_espera128: in STD_LOGIC;
		puntero: in STD_LOGIC_VECTOR (2 downto 0);
		SDAent: in STD_LOGIC;
		SCL: in STD_LOGIC;
		punt_byte: in STD_LOGIC_VECTOR (1 downto 0);
		load_new: out STD_LOGIC;
		inc_punt: out STD_LOGIC;
		inc_sel_byte: out STD_LOGIC;
		reset_sel_byte: out STD_LOGIC;
		ENespera64: out STD_LOGIC;
		ENespera128: out STD_LOGIC;
		ready: out STD_LOGIC;
		preset_div: out STD_LOGIC;
		reset_div: out STD_LOGIC;
		OESCL: out STD_LOGIC;
		reset_bit: out STD_LOGIC;
		load_bit: out STD_LOGIC;
		OESDA: out STD_LOGIC								
	);
      	end component;

-- Biestable que contiene el bit que se esta Tx.
-- Este componente sirve para mantener el bit a transmitir.
        component tx_bit port (
	        reset: in STD_LOGIC;
	        reloj: in STD_LOGIC;
        	clear: in STD_LOGIC;
        	D: in STD_LOGIC;
        	LE: in STD_LOGIC;
		Q: out STD_LOGIC
	);
        end component;

-- Pad de entrada/salida para SDA. 
-- Controla el estado de alta impedancia (pull-up) de salida
-- de la linea SDA permitiendo asi la recepcion del ACK por 
-- parte del procesado
        component IOpad port (
        	OE: in STD_LOGIC;
        	SAL: in STD_LOGIC;
        	ENT: out STD_LOGIC;
        	PAD: inout STD_LOGIC
        );
	end component;

-- Contador de espera. Espera 64 Tclk tras
-- bajar el reset para generar una senal de 
-- fin de cuenta.
	component cont_espera64 port (
    		reset: in STD_LOGIC;
    		reloj: in STD_LOGIC;
        	enable: in STD_LOGIC;
        	fin: out STD_LOGIC
        );
        end component;

-- Contador de espera. Espera 128 Tclk tras
-- bajar el reset para generar una senal de 
-- fin de cuenta.
	component cont_espera128 port (
    		reset: in STD_LOGIC;
    		reloj: in STD_LOGIC;
        	enable: in STD_LOGIC;
        	fin: out STD_LOGIC
        );
        end component;
        
-- Definimos otra FSM encargada de generar los datos a enviar
-- mediante I2C al procesador de video. Su funcion sera la de
-- generar dichos datos y proporcionar la senal de inicio de
-- transferencia, asi como, evaluar el resultado de la misma.
	component FSM_gen_datos 
		port (
	        	reloj: in STD_LOGIC;
	        	reset: in STD_LOGIC;
	        	inicio: in STD_LOGIC;
	        	ready: in STD_LOGIC;
	        	punt_byte: in STD_LOGIC_VECTOR (1 downto 0);
	        	fin_espera128: in STD_LOGIC;
	        	punt_mem: in STD_LOGIC_VECTOR (6 downto 0);
	        	trans: out STD_LOGIC;
	        	dir: out STD_LOGIC_VECTOR (7 downto 0);
	        	dato: out STD_LOGIC_VECTOR (7 downto 0);
	               	ENespera128: out STD_LOGIC;
	               	reset_punt_mem: out STD_LOGIC;
	               	inc_punt_mem: out STD_LOGIC;
	               	resultado: out STD_LOGIC_VECTOR (3 downto 0);
	               	conf_valida: out STD_LOGIC
	        );
	end component;

-- Definimos otro contador-puntero de 7 bits para direccionar la memoria basada
-- en registros que contiene los datos de configuracion del procesador de video.
        component contador_REG port (
      		reset: in STD_LOGIC;
      		reloj: in STD_LOGIC;
      		clear: in STD_LOGIC;
      		inc: in STD_LOGIC;
        	cont: out STD_LOGIC_VECTOR (6 downto 0)
        );
        end component;
-- Maquina de estados que controla la recepcion de los asentimientos acki 
-- procedentes de los decodificadores de video. Se encarga de generar una 
-- unica senal ACK que indicara a la maquina fsm_i2c que la transferencia 
-- ha sido correcta.
	component FSM_ACK port (
    		reloj: in STD_LOGIC;
        	reset: in STD_LOGIC;
        	ack1: in STD_LOGIC;
        	ack2: in STD_LOGIC;
        	ack3: in STD_LOGIC;
       	 	ACK: out STD_LOGIC
    	);
	end component;
end libreria_i2c;


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
entity divisor is
    port (
	reset: in STD_LOGIC;
        reloj: in STD_LOGIC;
        clear: in STD_LOGIC;
        set: in STD_LOGIC;
        SCL: out STD_LOGIC
    );
end divisor;

architecture divisor_arch of divisor is
signal cuenta: std_logic_vector(7 downto 0);
begin
process (reset,reloj,clear,set)
begin
	if (reset = '1') then
   		cuenta <= (others => '0');
   	else
   	   	if (reloj'event and reloj = '1') then
   			if(clear='1') then
   				cuenta<=(others=>'0');
   			elsif(set='1') then
   				cuenta<= "10000000";
   			else
   			   	cuenta <= cuenta + '1';
			end if;
   		end if;
	end if;
end process;
SCL<=cuenta(7);
end divisor_arch;


library IEEE;
use IEEE.std_logic_1164.all;
entity bufferZ is
    port (ent : in STD_LOGIC;
          OE  : in STD_LOGIC;
          sal : out STD_LOGIC
    );
end bufferZ;

architecture bufferZ_arch of bufferZ is
begin
process (ent,OE)
begin
	if (OE='1') then 
		sal <= ent;
	else
		sal <= 'Z';
	end if;
end process;
end bufferZ_arch;	


library IEEE;
use IEEE.std_logic_1164.all;
entity registro is
    port (
	reset: in STD_LOGIC;
        reloj: in STD_LOGIC;
    	LE: in STD_LOGIC;
        dat_in: in STD_LOGIC_VECTOR (7 downto 0);
        dat_out: out STD_LOGIC_VECTOR (7 downto 0)
    );
end registro;

architecture registro_arch of registro is
begin
process(reset,reloj,LE)
begin
	if (reset = '1') then 
		dat_out <= (others => '0');
	else
	 	if (reloj'event and reloj = '1') then
  			if (LE = '1') then
  				dat_out<=dat_in;
  			end if;
	  	end if;
	end if;
end process;
end registro_arch;


library IEEE;
use IEEE.std_logic_1164.all;
entity mux_byte is
	port (
		byte2: in STD_LOGIC_VECTOR (7 downto 0);
		byte1: in STD_LOGIC_VECTOR (7 downto 0);
		byte0: in STD_LOGIC_VECTOR (7 downto 0);
		sel: in STD_LOGIC_VECTOR (1 downto 0);
		byte_sal: out STD_LOGIC_VECTOR (7 downto 0)
	);
end mux_byte;

architecture mux_byte_arch of mux_byte is
begin
with sel select
	byte_sal <= byte2 when "10",
		    byte1 when "01",
		    byte0 when others;
end mux_byte_arch;		    	
	
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
entity contador_byte is
	port (
      		reset: in STD_LOGIC;
      		reloj: in STD_LOGIC;
      		clear: in STD_LOGIC;
      		inc: in STD_LOGIC;
        	cont: out STD_LOGIC_VECTOR (1 downto 0)
        );
end contador_byte;

architecture contador_byte_arch of contador_byte is
signal cuenta: std_logic_vector (1 downto 0);
begin
process(reset,reloj,clear,inc)
begin
  	if (reset = '1') then
  		cuenta <= (others => '0');
  	elsif (reloj'event and reloj = '1') then
		if (clear = '1') then
			cuenta <= (others => '0');			
		elsif (inc = '1') then
  			cuenta <= cuenta + '1';
  		end if;
  	end if;
end process;
cont <= cuenta;
end contador_byte_arch;


library IEEE;
use IEEE.std_logic_1164.all;
entity mux is
    port (
        ent: in STD_LOGIC_VECTOR (7 downto 0);
        sel: in STD_LOGIC_VECTOR (2 downto 0);
        sal: out STD_LOGIC
    );
end mux;

architecture mux_arch of mux is
begin
with sel select
  	sal <= ent(7) when "000",
  	       ent(6) when "001",
  	       ent(5) when "010",
  	       ent(4) when "011",
  	       ent(3) when "100",
  	       ent(2) when "101",
  	       ent(1) when "110",
  	       ent(0) when  others;
end mux_arch;


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
entity contador is
    port (
	reset: in STD_LOGIC;
        reloj: in STD_LOGIC;
        inc: in STD_LOGIC;
        cont: out STD_LOGIC_VECTOR (2 downto 0)
    );
end contador;

architecture contador_arch of contador is
signal cuenta: std_logic_vector (2 downto 0);
begin
process(reset,reloj,inc)
begin
  	if (reset = '1') then
  		cuenta <= (others => '0');
  	elsif (reloj'event and reloj = '1') then
		if (inc = '1') then
  			cuenta <= cuenta + '1';
  		end if;
  	end if;
end process;
cont <= cuenta;
end contador_arch;


library IEEE;
use IEEE.std_logic_1164.all;
entity FSM_I2C is 
	port(
		reloj: in STD_LOGIC;
		reset: in STD_LOGIC;
		trans: in STD_LOGIC;
		fin_espera64: in STD_LOGIC;
		fin_espera128: in STD_LOGIC;
		puntero: in STD_LOGIC_VECTOR (2 downto 0);
		SDAent: in STD_LOGIC;
		SCL: in STD_LOGIC;
		punt_byte: in STD_LOGIC_VECTOR (1 downto 0);
		load_new: out STD_LOGIC;
		inc_punt: out STD_LOGIC;
		inc_sel_byte: out STD_LOGIC;
		reset_sel_byte: out STD_LOGIC;
		ENespera64: out STD_LOGIC;
		ENespera128: out STD_LOGIC;
		ready: out STD_LOGIC;
		preset_div: out STD_LOGIC;
		reset_div: out STD_LOGIC;
		OESCL: out STD_LOGIC;
		reset_bit: out STD_LOGIC;
		load_bit: out STD_LOGIC;
		OESDA: out STD_LOGIC								
	);
end FSM_I2C;

architecture FSM_I2C_arch of FSM_I2C is
type TipoEstado is (reposo,captura_datos,cond_start,esp_SCL0,
		    espera_64,envia_bit,esp_SCL1,hold_bit,
		    nuevo_bit,mira_puntero,incrementa_puntero,
		    espera_cargar_bit,reset_puntero,
		    comprueba_ACK1,comprueba_ACK2,comprueba_ACK3,
		    sig_byte,esp_SCL0_sigbyte,esp_sig_dato,
		    carga_nuevo_bit,set_punt_byte,STOP1,STOP2,
		    STOP3,STOP4,STOP5,STOP6
		   );
signal actual,siguiente: TipoEstado;
begin
transiciones:process(actual,trans,SCL,fin_espera64,puntero,
		     SDAent,punt_byte,fin_espera128)
	begin
	case actual is
		when reposo => 
			-- En este estado, tanto SCL como SDA
			-- estan en alta impedancia (pull-up).
			-- Hemos de preparar el divisor que 
			-- usamos para generar SCL, para que
			-- comience desde '1' y no desde '0'.
			-- La generacion de SCL no comienza 
			-- mientras preset_div o reset_div 
			-- esten a '1'.
			-- En cuanto a SDA, mantenemos la linea
			-- en alta impedancia, pero cargamos

⌨️ 快捷键说明

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