Curso para iniciarse con FPGAs

PUES AQUI REPORTANDO RESULTADOS DE MIS PROYECTOS QUE GRACIAS A "ELVIC" Y A "YUCARDO" PUDE RESOLVER.
EL PRIMERO ES UN REGISTRO CONDESPLAZAMIENTO A LA IZQUIERDA O A LA DERECHA.

Código:
--DISENO DE UN REGISTRO CON DESPLAZAMIENTO
ENTITY REG_DESP IS
PORT(
	DIN_A, DIN_B: IN BIT_VECTOR(3 DOWNTO 0); --ENTRADAS DE REGISTRO	
	IN_SERIAL: IN BIT; --ENTRADA DE BIT POR DESPLAZAMIENTO
	CHARGE: IN BIT; --CARGADOR DE DATOS EN LOS REGISTROS
	SHIFT_LR: IN BIT; --CONTROL DE DESPLAZAMIENTO
	CLK: IN BIT; --SEÑAL DE RELOJ
	QOUT_A, QOUT_B: OUT BIT_VECTOR(3 DOWNTO 0) --SALIDA DE REGISTROS	
	);
END ENTITY REG_DESP;

ARCHITECTURE ARC OF REG_DESP IS

	SIGNAL REG_B, REG_A: BIT_VECTOR(3 DOWNTO 0);
	BEGIN
	REG: PROCESS(CLK)
	BEGIN
		IF CLK'EVENT AND CLK='1' THEN
			IF CHARGE='1' THEN REG_B <= DIN_A;
					   REG_A <= DIN_B;
				IF SHIFT_LR='0' THEN
					REG_A(0) <= IN_SERIAL;
					REG_A(1) <= REG_A(0);
					REG_A(2) <= REG_A(1);
					REG_A(3) <= REG_A(2);
					REG_B(0) <= REG_A(3);
					REG_B(1) <= REG_B(0);
					REG_B(2) <= REG_B(1);
					REG_B(3) <= REG_B(2);
				ELSE 
					REG_B(3) <= IN_SERIAL;
					REG_B(2) <= REG_B(3);
					REG_B(1) <= REG_B(2);
					REG_B(0) <= REG_B(1);
					REG_A(3) <= REG_B(0);
					REG_A(2) <= REG_A(3);
					REG_A(1) <= REG_A(2);
					REG_A(0) <= REG_A(1);			
				END IF;
			END IF;
	END IF;
	END PROCESS REG;
	QOUT_A <= REG_B;
	QOUT_B <= REG_A;
END ARCHITECTURE ARC;

EL SEGUNDO ES UN REGISTRO CON DESPLAZAMIENTO ROTACIONAL
Código:
--DISENO DE UN REGISTRO ROTACIONAL
ENTITY REG_DESP IS
PORT(
	DIN_A, DIN_B: IN BIT_VECTOR(3 DOWNTO 0); --ENTRADAS DE REGISTRO	
	CHARGE: IN BIT; --CARGADOR DE DATOS EN LOS REGISTROS
	SHIFT_LR: IN BIT; --CONTROL DE DESPLAZAMIENTO
	CLK: IN BIT; --SEÑAL DE RELOJ
	QOUT_A, QOUT_B: OUT BIT_VECTOR(3 DOWNTO 0) --SALIDA DE REGISTROS	
	);
END ENTITY REG_DESP;

ARCHITECTURE ARC OF REG_DESP IS

	SIGNAL REG_B, REG_A: BIT_VECTOR(3 DOWNTO 0);
	
BEGIN
	REG: PROCESS(CLK)
	BEGIN
		IF CLK'EVENT AND CLK='1' THEN
			IF CHARGE='1' THEN REG_B <= DIN_A;
					   REG_A <= DIN_B;
			ELSE 
				IF SHIFT_LR='0' THEN
					REG_A(0) <= REG_B(3);
					REG_A(1) <= REG_A(0);
					REG_A(2) <= REG_A(1);
					REG_A(3) <= REG_A(2);
					REG_B(0) <= REG_A(3);
					REG_B(1) <= REG_B(0);
					REG_B(2) <= REG_B(1);
					REG_B(3) <= REG_B(2);
				ELSE 
					REG_B(3) <= REG_A(0);
					REG_B(2) <= REG_B(3);
					REG_B(1) <= REG_B(2);
					REG_B(0) <= REG_B(1);
					REG_A(3) <= REG_B(0);
					REG_A(2) <= REG_A(3);
					REG_A(1) <= REG_A(2);
					REG_A(0) <= REG_A(1);					
				END IF;
			END IF;
		END IF;
	END PROCESS REG;	
	QOUT_A <= REG_B;
	QOUT_B <= REG_A; 
END ARCHITECTURE ARC;
POR ULTIMO UNA MAQUINA DE 8 ESTADOS O CONTADOR INSTANCIADA CON UNA MEMORIA ROM
Código:
--DISENAR UN CONTADOR HEXADECIMAL ASCENDENTE-DESCENDENTE CON RESET Y CONTADOR DE NUMEROS PRIMOS
ENTITY CNT_8 IS
PORT(
	CLK: IN BIT; --FLANCOS DE SUBIDA
	X, Y, Z: IN BIT;
	RESET: IN BIT; --PONE LA SALIDA EN 0's.
	DISPLAY: OUT BIT_VECTOR(6 DOWNTO 0); --SALIDA HEXADECIMAL
	BAR_LED: OUT BIT_VECTOR(2 DOWNTO 0) --SALIDA AL BAR LED
	);
END ENTITY CNT_8;
------------------------------------
------------------------------------

ARCHITECTURE ARC_CNT OF CNT_8 IS

	COMPONENT ROM_MXN IS
		PORT(
			M: IN BIT_VECTOR(2 DOWNTO 0); --ENTRADA A LA MEMORIA ROM
			N: OUT BIT_VECTOR(6 DOWNTO 0) --SALIDA DE MEMORIA ROM
			);
	END COMPONENT ROM_MXN;

    	SIGNAL HEX: BIT_VECTOR(2 DOWNTO 0);
	TYPE ESTADOS IS (A, B, C, D, E, F, G, H);
	SIGNAL EP, ES: ESTADOS;
	SIGNAL ADRESS: BIT_VECTOR(2 DOWNTO 0);

	
BEGIN

	--*************PARTE SINCRONA****************
	SINC: PROCESS(CLK)
	BEGIN
		IF CLK'EVENT AND CLK='1' THEN
			IF RESET='1' THEN
				EP <= A;
			ELSE
				EP <= ES;
			END IF;
		END IF;
	END PROCESS SINC;
	--*********FIN DE LA PARTE SINCRONA**********
	
	--***********PARTE COMBINACIONAL*************
	COMB: PROCESS(EP, X, Y, Z)
	BEGIN 
		CASE EP IS
		
		WHEN A => ADRESS <="000";
			IF X='0' THEN ES <= A;
			ELSIF X='1' AND Y='0' THEN ES <= B;
			ELSIF X='1' AND Y='1' AND Z='0' THEN ES <= H;
			ELSE ES <= B;
			-- X='1' AND Y='1' AND Z='1' THEN 
			END IF;
		WHEN B => ADRESS <="001";
			IF X='0' THEN ES <= B;
			ELSIF X='1' AND Y='0' THEN ES <= C;
			ELSIF X='1' AND Y='1' AND Z='0' THEN ES <= A;
			ELSE ES <= C;
			--X='1' AND Y='1' AND Z='1' THEN 
			END IF;
		WHEN C => ADRESS <="010";
			IF X='0' THEN ES <= C;
			ELSIF X='1' AND Y='0' THEN ES <= D;
			ELSIF X='1' AND Y='1' AND Z='0' THEN ES <= B;
			ELSE ES <= D;
			-- X='1' AND Y='1' AND Z='1' THEN 
			END IF;
		WHEN D => ADRESS <="011";
			IF X='0' THEN ES <= D;
			ELSIF X='1' AND Y='0' THEN ES <= E;
			ELSIF X='1' AND Y='1' AND Z='0' THEN ES <= C;
			ELSE ES <= F;
			-- X='1' AND Y='1' AND Z='1' THEN 
			END IF;
		WHEN E => ADRESS <="100";
			IF X='0' THEN ES <= E;
			ELSIF X='1' AND Y='0' THEN ES <= F;
			ELSIF X='1' AND Y='1' AND Z='0' THEN ES <= D;
			ELSE ES <= B;
			-- X='1' AND Y='1' AND Z='1' THEN 
			END IF;
		WHEN F => ADRESS <="101";
			IF X='0' THEN ES <= F;
			ELSIF X='1' AND Y='0' THEN ES <= G;
			ELSIF X='1' AND Y='1' AND Z='0' THEN ES <= E;
			ELSE ES <= H;
			--X='1' AND Y='1' AND Z='1' THEN 
			END IF;
		WHEN G => ADRESS <="110";
			IF X='0' THEN ES <= G;
			ELSIF X='1' AND Y='0' THEN ES <= H;
			ELSIF X='1' AND Y='1' AND Z='0' THEN ES <= F;
			ELSE ES <= B;
			-- X='1' AND Y='1' AND Z='1' THEN 
			END IF;
		WHEN H => ADRESS <="111";
			IF X='0' THEN ES <= H;
			ELSIF X='1' AND Y='0' THEN ES <= A;
			ELSIF X='1' AND Y='1' AND Z='0' THEN ES <= G;
			ELSE ES <= B;
			-- X='1' AND Y='1' AND Z='1' THEN 
			END IF;
		END CASE;
	END PROCESS COMB;
	--*******FIN DE LA PARTE COMBINACIONAL*******
	ROM: ROM_MXN 
		PORT MAP(
			M => ADRESS,
			N => DISPLAY
			);
	BAR_LED <= ADRESS;
	--******************************************
	
END ARCHITECTURE ARC_CNT;



	--***************MEMORIA ROM*****************
ENTITY ROM_MXN IS
PORT(
	M: IN BIT_VECTOR(2 DOWNTO 0); --ENTRADA A LA MEMORIA ROM
	N: OUT BIT_VECTOR(6 DOWNTO 0) --SALIDA DE MEMORIA ROM
	);
END ENTITY ROM_MXN;

ARCHITECTURE ARC OF ROM_MXN IS
BEGIN
	ROM: PROCESS(M)
	BEGIN
		CASE M IS
			WHEN "000" => N <= "0000001";	--A
			WHEN "001" => N <= "1010000";   --b
			WHEN "010" => N <= "0011010";	--C
			WHEN "011" => N <= "1100000";	--d
			WHEN "100" => N <= "0010010";	--E
			WHEN "101" => N <= "0010011";	--F
			WHEN "110" => N <= "0000100";	--g
			WHEN "111" => N <= "1000001";	--H
			WHEN OTHERS => N <= (OTHERS=>'0');
		END CASE;
	END PROCESS ROM;
END ARCHITECTURE ARC;
 
Estoy siguiendo el tema por encima, porqué me resultan muy interesantes las fpga's, una lastima que los dias no tengan mas horas y no tener mas recursos economicos. ¿hay algun programa que sirva para programar y simular las fpga's? Lo pregunto de cara a poder hacer pruebas sin tener ninguna fpga. Tambien he visto las placas aunque son muy caras.
 
Puedes usar el Quartus II Web Edition que es gratuito. Tiene un simulador incorporado que aunque no es gran cosa sí te permite simular bastante bien el código.
 
Bueno te digo tu puedes descargar el ISEWeb Pack 10.1 gratis desde la pagina de xilinx.

Yo lo tengo instalado. Lo unico que tienes es que registrarte.

El otro problema es que se instala on line. Tienes que dejar tu pc conectada mientras se instalan los aprox. 5 Gb.
 
Para implementar una máquina de Moore, se
muestra el ejemplo de un tren de lavado de carros
de la figura 9.

Para controlar el lavado se necesita:
- Tres motores:
- Un motor principal que mueve el tren a lo
largo del carril con dos señales de actuación
MP1 y MP2. Cuando se activa MP1 el tren
se mueve de izquierda a derecha. Cuando
se activa MP2 el tren se mueve de derecha a
izquierda.
- Un motor para los cepillos, con una única
señal de actuación MC.
- Un motor para el ventilador, con una única
señal de actuación MV.
- Una electro-válvula XV que permita la salida del
liquido del lavadero hacia el carro.
- Dos sensores fin de carrera S1 y S2 que detectan
la llegada del tren a los extremos del carril.
- Un sensor S3 que detecta la presencia del carro.
- Dos pulsadores M y P de marcha y paro
respectivamente.

Con estas variables se puede determinar las entradas
y salidas de nuestro diseño, así pues:

Las salidas del sistema son:
Mi = Motor que lleva el tren a la izquierda del
carril.
Md = Motor que lleva el tren a la derecha del
carril.
Mc = Motor de giro de los cepillos.
Mv = Motor de giro de los ventiladores.
Xv = Accionamiento de la salida de jabón.

Se intuye que en el funcionamiento del sistema, todos
los carros idealmente pasan por un mismo proceso,
por lo que cada una de las etapas del lavado será un
estado del sistema, se tendrá los siguientes estados:

- Estado 1: Inicialmente el sistema se encuentra en
el extremo izquierdo, con el sensor fin de carrera
izquierdo activado (S1 = 1) ya que ésta es la posición donde reposa el tren del lavadero. El sistema
se pone en marcha al activarse el pulsador (M
= 1) siempre y cuando haya un carro dentro del
lavado automático, es decir el sensor que indica
la presencia de un carro debajo del tren del lavadero
está activo (S3 = 1).

- Estado 2: Una vez accionado M, el tren del lavadero
comenzará a funcionar desplazándose hacia
la derecha (Md = 1), accionando el motor de los
cepillos (Mc = 1) y el jabón liquido (Xv = 1) hasta
llegar al final del carril derecho, activándose
(S2 = 1). En este momento se pasa al siguiente
estado.

- Estado 3: En este estado se regresa el tren del
lavadero hacia el carril derecho (Mi = 1) y se
mantienen los cepillos y la válvula de jabón encendidos
(Mc = 1 y Xv = 1). Cuando se llega al
final de carril izquierdo se activa (S1 = 1) y se
pasa al siguiente estado

- Estado 4: En este estado se regresa el tren del
lavadero nuevamente hacia el carril derecho (Md
= 1) con el ventilador encendido para secarlo (Mv
= 1), hasta llegar nuevamente al fin del carril derecho,
momento en que se vuelve a activar (S2 =
1) y se pasa al siguiente estado.

- Estado 5: Se regresa nuevamente el tren del lavadero
hacia el carril izquierdo (Mi = 1) manteniendo
el ventilador encendido (Mv = 1). Cuando
se llega a la posición final del carril izquierdo
(S1 = 1) se pasa al estado inicial quedando el trabajo
terminado.

- Estado 6: Cuando se acciona el pulsador de parada
(P = 1) en cualquier estado, el tren del lavadero
se dirige hacia el carril izquierdo (Mi = 1) y
se apagan todos los actuadores (Mc = Mv = Xv
= 0). Cuando éste llega al final del carril izquierdo,
se pasa al estado inicial.

Este ejercicio esta en una de las guias que yo puse para descargar.

Luego les publico el codigo que hice.
 

Adjuntos

  • diagrama_de_estados_840.jpg
    diagrama_de_estados_840.jpg
    47 KB · Visitas: 52
  • lavado_de_carros_123.jpg
    lavado_de_carros_123.jpg
    55.7 KB · Visitas: 41
saludos

pues bien, esperemos que se animen en seguir aportando ideas o códigos para implementar sobre un FPGA, por mi parte aun continuo en lo básico, así que no he podido aportar nada nuevo ó interesante, pero espero que no dejen caer el tema y continúen con sus aportaciones.
 
Aqui les dejo el codigo del problema del autolavado. Espero que les sea de utilidad.

Le adicione algo para que mostrara en display 7 segmento el numero del estado.

Código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity Lavado is
    Port ( S1 : in  STD_LOGIC;
           S2 : in  STD_LOGIC;
           S3 : in  STD_LOGIC;
           M : in  STD_LOGIC;
           P : in  STD_LOGIC;
           Mi : out  STD_LOGIC;
           Md : out  STD_LOGIC;
           Mc : out  STD_LOGIC;
           Mv : out  STD_LOGIC;
           Xv : out  STD_LOGIC;
			  en : out STD_LOGIC;
			  reset : in  STD_LOGIC;
           clk : in  STD_LOGIC;
			  display: out BIT_VECTOR (6 DOWNTO 0));
end Lavado;

architecture Moore of Lavado is

TYPE maq_estados IS (esta1, esta2, esta3, esta4, esta5, esta6); 

signal est, prox_est: maq_estados;

Begin

A: process(m,p,s1,s2,s3)
	begin 
	CASE est IS
	when esta1 =>
	if m='1' and s3='1' then
			prox_est<=esta2;
	else
			prox_est<=esta1;
	end if;
		when esta2 =>
	if p='1' then
		prox_est<=esta6;
	elsif s2='1' then
		prox_est<=esta3;
	else
		prox_est<=esta2;
	end if;
	when esta3 =>
	if p='1' then
		prox_est<=esta6;
	elsif s1='1' then
		prox_est<=esta4;
	else
		prox_est<=esta3;
	end if;
	when esta4 =>
	if p='1' then
		prox_est<=esta6;
	elsif s2='1' then
		prox_est<=esta5;
	else
		prox_est<=esta4;
	end if;
	when esta5 =>
	if p='1' then
		prox_est<=esta6;
	elsif s1='1' then
		prox_est<=esta1;
	else
		prox_est<=esta5;
	end if;
	when esta6 =>
	if s1='1' then
		prox_est<=esta1;
	else
		prox_est<=esta6;
	end if;
	when others =>
		prox_est<=esta1;
end CASE;
end process;
B: process (reset,clk)
begin
	if reset ='1' then
		est<=esta1;
	elsif (clk'EVENT AND clk='1') then
		est<=prox_est;
	end if;
	end process;
md<='1' when(est=esta2 or est=esta4)else '0';
mi<='1' when(est=esta3 or est=esta5 or est=esta6)else '0';
mc<='1' when(est=esta2 or est=esta3)else '0';
mv<='1' when(est=esta4 or est=esta5)else '0';
xv<='1' when(est=esta2 or est=esta3)else '0';

en<='0';
C: process
begin

CASE est IS
when esta1 => display<="1001111";
when esta2 => display<="0010010";
when esta3 => display<="0000110"; 
when esta4 => display<="1001100";			  	
when esta5 => display<="0100100";
when esta6 => display<="0100000";			  	
when others => display<="0000001"; 
end case;
end process;			
end Moore;

Pronto agregare un video con las pruebas
 
Última edición por un moderador:
Hola

Les dejo con abundantes comentarios explicativos un ejemplo que genera el efecto de las luces del coche fantástico. Simplemente necesitan asignar los pines de la señal de reloj, reset (activo a nivel bajo, o sea un '0' es reset y un '1' es funcionamiento normal), y 8 salidas de leds. Si tienen un número distinto de leds en la tarjeta, creo que es sencillo de ver las modificaciones a realizar...

Para cualquier duda sobre este u otro ejemplo den un toque por aquí

Código:
library ieee;
use ieee.std_logic_1164.all; 
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity efecto_leds is
    port (
        clka : in std_logic;                        -- Reloj 50MHz
        res  : in std_logic;                        -- Reset activo a nivel bajo
        led  : out std_logic_vector(7 downto 0)     -- LEDs
    );
 
end efecto_leds;
  
architecture rtl of efecto_leds is

-- Contador de tiempo. La idea es ir contando ciclos de reloj hasta llegar a un
-- número determinado, con el objetivo de medir tiempos. Mi placa tiene un reloj
-- de 50MHz, lo que equivale a un periodo de ciclo de 20 nanosegundos. Como quiero
-- medir tiempos de 100 milisegundos, la cantidad de ciclos que debo contar es de
-- 100*10^(-3) / 20*10^(-9) = 5.000.000
-- Por tanto el valor de la constante que indica cuándo se ha alcanzado ese número
-- debería ser igual a 5.000.000, pero he puesto 4.999.999, esto es porque el valor
-- "cero" del contador también vale, luego hay que restar 1 al número calculado si
-- quieren que el tiempo sea exaco (en este ejemplo el error sería sólo de 20ns,
-- pero según qué caso se podría cometer un error más gordo, sólo aviso para que
-- las cosas se hagan bien desde un principio...)
signal   contador :  STD_LOGIC_VECTOR(31 downto 0);
-- La función conv_std_logic_vector convierte un entero a un std_logic_vector del
-- número de bits que se le indique en el segundo argumento (32 en este caso)
constant CIEN_MS  :  STD_LOGIC_VECTOR(31 downto 0) := conv_std_logic_vector(4999999, 32);
-- Esta señal dará un pulso a '1' de duración 1 ciclo de reloj cada 100ms
signal   prsc     :  STD_LOGIC;
-- Dirección de los leds, a derecha o izquierda (según se mire la placa, claro)
signal   dir      :  STD_LOGIC;
-- Señal para uso interno. Esta señal se usa porque dentro del código VHDL se va a
-- "leer" el valor de los leds para saber cuál hay que encender según el estado en
-- que estén. Si tratan de leer una señal de tipo out, verán un lindo mensaje de
-- error. Por eso esta señal es necesaria, porque las señales "internas" sí se leen
-- sin problemas
signal   leds_i   :  STD_LOGIC_VECTOR(7 downto 0);

-- Bien, empecemos
begin

-- Se asigna en todo momento el valor de la señal interna de estado de los leds a
-- la salida de los 8 leds. Fíjense que es asíncrono, no depende de ningún reloj,
-- aunque la señal leds_i sí está dentro de un proceso síncrono
led <= leds_i;

-- Proceso que genera el prescaler, señal que se pone a '1' durante 1 ciclo de reloj
-- cada 100ms
PRESCALER : process(clka, res)
begin
    if (res = '0') then
        contador                       <= (others => '0');
        prsc                           <= '0';
    elsif rising_edge(clka) then
        if (contador = CIEN_MS) then   -- Si llega al final, pone el contador a cero y activa el prescaler
            prsc                       <= '1';
            contador                   <= (others => '0');
        else
            prsc                       <= '0';
            contador                   <= contador + x"00000001";
        end if;
    end if;    
end process;

-- Proceso que genera el efecto de los leds
LEDS_OUT : process(clka, res)
begin
    if (res = '0') then
        leds_i                         <= (0 => '1', others => '0'); -- El led de la derecha se inicializa encendido (¡es necesario inicializar un led encendido!)
        dir                            <= '0';
    elsif rising_edge(clka) then
        if (prsc = '1') then                                         -- Si llega el prescaler
            if (dir = '0') then                                      -- Si están moviéndose hacia la izquierda
                if (leds_i(7) = '1') then                            -- Y está activo el led de más a la izquierda
                    dir                <= '1';                       -- Se cambia la dirección
                    leds_i             <= "01000000";                -- Y se activa el led de su derecha
                else                                                 -- Si no está activo el led de más a la iquierda
                    leds_i             <= leds_i(6 downto 0) & '0';  -- Se desplazan todos una posición a la izquierda
                end if;
            else                                                     -- Si están moviéndose hacia la derecha
                if (leds_i(0) = '1') then                            -- Y está activo el led de más a la derecha
                    dir                <= '0';                       -- Se cambia la dirección
                    leds_i             <= "00000010";                -- Y se activa el led de su izquierda
                else                                                 -- Si no está activo el led de más a la derecha
                    leds_i             <= '0' & leds_i(7 downto 1);  -- Se desplazan todos una posición a la izquierda
                end if;
            end if;
        end if;
    end if;    
end process;

-- Y fin
end rtl;
 

Adjuntos

  • leds_189.zip
    361.2 KB · Visitas: 70
cristian_elect dijo:
Para hacer varios pwm en fpga se puede. Para controlar varios led rgb.

Claro que se puede, digamos que quitando el pin de reset y el de reloj, podrías sacar (más o menos) tantos pwm como pines tenga la FPGA... cada uno con una frecuencia y un ciclo de trabajo distintos :cool: Además un PWM en FPGA no es nada complicado de programar (un contador que establezca la frecuencia y un comparador para el ciclo de trabajo)
 
BIEN CONTINUANDO EN EL FORO LES DEJO UNOS PROYECTOS SIMPLES QUE REALICE EN MI UNI...

ESPERO Q A MAS DE UNO LES SIRVA COMO EJEMPLO.

Código:
--CIRCUITO ARITMETICO: MULTIPLICADOR DE 4 X 3 BITS MEDIANTE HARDWARE


ENTITY MUX IS
	PORT
	(
	MULTIPLICANDO: IN BIT_VECTOR(3 DOWNTO 0);  --MULTIPLICANDO N BITS
	MULTIPLICADOR: IN BIT_VECTOR(3 DOWNTO 0);  --MULTIPLICADOR DE M BITS
	PROD: OUT BIT_VECTOR(7 DOWNTO 0)  --DE M+N BITS
	);
END ENTITY MUX;

ARCHITECTURE ARQ OF MUX IS

	COMPONENT SC4B IS
	PORT
		(
		AIN, BIN: IN BIT_VECTOR(3 DOWNTO 0);
		CIN: IN BIT;
		SUMA: OUT BIT_VECTOR(3 DOWNTO 0);
		COUT: OUT BIT
		);
	END COMPONENT SC4B;

----SENALES NECESARIAS PARA EL CIRCUITO ARITMETICO----

	SIGNAL AL: BIT_VECTOR(3 DOWNTO 0);
	SIGNAL PP0, PP1, PP2, PP3: BIT_VECTOR(3 DOWNTO 0); --PARA PRODUCTOS PARCIALES
	SIGNAL CERO: BIT; 
	SIGNAL XY: BIT_VECTOR(4 DOWNTO 0);
	SIGNAL CABLE: BIT_VECTOR(4 DOWNTO 0);

BEGIN
---------------------------------------------------------------------------------------
	CERO<='0';
---------------------------------------------------------------------------------------
	
	-- PRODUCTOS PARCIALES
	PP0<=MULTIPLICANDO WHEN MULTIPLICADOR(0)='1' ELSE "0000";
	PP1<=MULTIPLICANDO WHEN MULTIPLICADOR(1)='1' ELSE "0000";
	PP2<=MULTIPLICANDO WHEN MULTIPLICADOR(2)='1' ELSE "0000";
	PP3<=MULTIPLICANDO WHEN MULTIPLICADOR(3)='1' ELSE "0000";
	
---------------------------------------------------------------------------------------
	--M - 1 SUMADORES DE N BITS CADA UNO
	--AQUI UTILIZAMOS LOS SUMADORES COMPLETOS DE 4 BITS
	
	PROD(0)<=PP0(0);
	AL(3)<='0'; 
	AL(2)<=PP0(3); 
	AL(1)<=PP0(2); 
	AL(0)<=PP0(1);
	
	--ES LO MISMO QUE
	--AL<='0' &PP0(3 DOWNTO 0);
	---------------------------------------
	---------------------------------------
	---------------------------------------
	SUMADOR1: SC4B PORT MAP(
		AIN=>AL, BIN=>PP1, CIN=>CERO,
		SUMA=>XY(3 DOWNTO 0), COUT=>XY(4));
		
	---------------------------------------
	PROD(1)<=XY(0);
	---------------------------------------
	---------------------------------------
	SUMADOR2: SC4B PORT MAP(
		AIN=>CABLE(4 DOWNTO 1), BIN=>PP2, CIN=>CERO,
		SUMA=> CABLE(3 DOWNTO 0), COUT=>CABLE(4));
	
	---------------------------------------
	---------------------------------------
        PROD(2)<=CABLE(0);
	---------------------------------------------------------
	SUMADOR3: SC4B PORT MAP	(
		AIN=>CABLE(4 DOWNTO 1),BIN=>PP3,CIN=>CERO,
		SUMA=> PROD(6 DOWNTO 3),COUT=>PROD(7));

END ARCHITECTURE ARQ;

-----------------------------------------------------------------
-----------------------------------------------------------------
-----------------SUMADOR COMPLETO DE 1 BIT-----------------------

ENTITY SC1B IS
	PORT
	(
	X,Y,CIN: IN BIT;
	S,COUT: OUT BIT
	);
END ENTITY SC1B;

ARCHITECTURE ARQ OF SC1B IS

BEGIN
	S<= X XOR Y XOR CIN;
	COUT<= (X AND Y) OR (X AND CIN) OR (Y AND CIN);
END ARCHITECTURE ARQ;

-----------------------------------------------------------------
-----------------------------------------------------------------
-----------------SUMADOR COMPLETO DE 4 BITS----------------------

ENTITY SC4B IS
	PORT
	(
	AIN,BIN: IN BIT_VECTOR(3 DOWNTO 0);
	CIN: IN BIT;
	SUMA: OUT BIT_VECTOR(3 DOWNTO 0);
	COUT: OUT BIT
	);
END ENTITY SC4B;

ARCHITECTURE ARQ OF SC4B IS
	COMPONENT SC1B IS
		PORT
		(
		X,Y,CIN:IN BIT;
		S,COUT: OUT BIT
		);
	END COMPONENT SC1B;
		
SIGNAL C:BIT_VECTOR(4 DOWNTO 0);

BEGIN

HO: FOR K IN 0  TO 3 GENERATE
HH:SC1B 
	PORT MAP
	(
	X=>AIN(K),Y=>BIN(K),CIN=>C(K),
	S=>SUMA(K),COUT=>C(K+1)
	);
	END GENERATE HO;
	
	C(0)<= CIN;
	COUT<= C(4);

END ARCHITECTURE ARQ;

UNO MAS
Código:
--DISEAR UN SUMADOR RESTADOR DE 4 BITS DE ANCHO MEDIANTE LA INSTANCIACION DE FA1B Y FA4B

ENTITY SUM_RES IS
	PORT(
		A: IN BIT_VECTOR(3 DOWNTO 0); --SUMANDO + MINUENDO
		B: IN BIT_VECTOR(3 DOWNTO 0); --SUMANDO + - SUSTRAENDO
		R_S: IN BIT; --'1' RESTA CON '0' SUMA
		SUMA: OUT BIT_VECTOR(3 DOWNTO 0); --SALIDA DE RESTA O SUMA
		COUT: OUT BIT --ACARREO DE SALIDA O PRESTAMO DE SALIDA(NEGADO)
		);
END ENTITY SUM_RES;

---------------------------------
ARCHITECTURE ARQ OF SUM_RES IS
	--DECLARAMOS FA4B DISENADA POR EL EQUIPO 2
COMPONENT FA4B IS
	PORT(
		A, B: IN BIT_VECTOR(3 DOWNTO 0);  --SUMADORES
		CIN: IN BIT;                      --BIT DE ARRASTRE
		SM: OUT BIT_VECTOR(3 DOWNTO 0);   --SALIDA DE TAMAO DE SUMADORES
		COUT: OUT BIT                     --SALIDA DE ARRASTRE
		);
		
END COMPONENT FA4B;

	SIGNAL MUX: BIT_VECTOR(3 DOWNTO 0);
BEGIN
	------------------------------------
	SM_0:FA4B PORT MAP(
		A=> A,
		B=>MUX,
		SM=>SUMA,
		CIN=>R_S,
		COUT=>COUT
		);
	----FIN DE LA INSTANCIANCION DE FA4B--------
	--DISENO DEL MUX
	MUX<=B WHEN R_S='0' ELSE NOT(B);
	-------FIN DEL MUX-----------
		
	------------------------------------
END ARCHITECTURE ARQ;



ENTITY FA1B IS
	PORT(
		X, Y: IN BIT;     --ENTRADA DE DATOS DE UN SOLO BIT
		CIN: IN BIT;      --ENTRADA DE ACARREO DE UNA ETAPA ANTERIOR
		S, COUT: OUT BIT  --SALIDAS.
		);
		
END ENTITY FA1B;

ARCHITECTURE ARC OF FA1B IS
BEGIN
	COUT<= (X AND Y) OR (X AND CIN) OR (Y AND CIN);
	-----------------------------------------------
	S<=(X XOR Y) XOR CIN;
	-----------------------------------------------
	
END ARCHITECTURE ARC; 



ENTITY FA4B IS
	PORT(
		A, B: IN BIT_VECTOR(3 DOWNTO 0);  --SUMADORES
		CIN: IN BIT;                      --BIT DE ARRASTRE
		SM: OUT BIT_VECTOR(3 DOWNTO 0);   --SALIDA DE TAMAO DE SUMADORES
		COUT: OUT BIT                     --SALIDA DE ARRASTRE
		);
		
END ENTITY FA4B;
------------------------------------
ARCHITECTURE ARC OF FA4B IS

	---------TRABAJO DEL EQUIPO 1-----------
	COMPONENT FA1B IS
	PORT(
		X, Y: IN BIT;     --ENTRADA DE DATOS DE UN SOLO BIT
		CIN: IN BIT;      --ENTRADA DE ACARREO DE UNA ETAPA ANTERIOR
		S, COUT: OUT BIT  --SALIDAS.
		);
		
           END COMPONENT FA1B;
           SIGNAL C: BIT_VECTOR(4 DOWNTO 0);
BEGIN
	-----------------------------------------
	
	U: FOR J IN 0 TO 3 GENERATE
		------------------------------------------
		H: FA1B PORT MAP (
			X=>A(j),
			Y=>B(j),
			CIN=>C(j),
			S=>SM(j),
			COUT=>C(j+1)
			);
		------------------------------------------
	
	
	
	
	
	END GENERATE U;	
	
	-----------------------------------------	
	
	
END ARCHITECTURE ARC;
 
Aqui les dejo el video con las pruebas que le realice a la aplicación del autolavado.

En la imagen del archivo adjunto se muestra los leds que indican el encendido de los motores y los swtchs que hacen la funcion de los sensore.



YouTube - Autolavado con FPGA
 

Adjuntos

  • autolavado_fpga_869.jpg
    autolavado_fpga_869.jpg
    73.8 KB · Visitas: 33
hola todos!

yo estoy comenzando a realizar puebas con ek kit de alteraa cyclone II

Eh realizado agunos jercicios como empezando desde los basico hasta lo mas complicado.
como por ejemplo ya eh manejado los leds, los display de 7- SEG, Pantalla LCD 16x2.
por ahora estoy comenzando a anejar la pantalla LCD de matriz en punto de alta deficion. despues quiero meterme a manejar las camaras.

yukardo como le puedo hacer para subir videos al foro
 
Saludos. Bienvenido a este post. Es bueno que se agreguen mas personas que colaboren con mas material.

Bueno para colocar un video solo tienes que subirlo a youtube y despues pones el link y listo. Cuando escribes hay una opción para colocar el link, usa esa para que se muestre.
 
buenas...
para un proyecto de la universidad necesito mover un motor paso a paso.....
pero el incoveniente es que tengo que utilizar Picoblaze de la spartan 3e
les agradeceria mucho a la persona que tuviera conocimiento de esto que me pudiera colaborar
la verdad es de urgencia..
gracias.....
 
Bueno yo en realidad aun no manejo esa aplicación de Picoblaze.

Lo que si me gustaria es hacer un contador ascendente/decendentes usando el FPGA.
 
hola queria preguntarles si alguien sabe donde puedo comprar una placa de desarollo en argentina, estube preguntando en casas de electronica y me responden: " que son los FPGA?" , desde ya muchas gracias!
 
Atrás
Arriba