Curso para iniciarse con FPGAs

Hola amigos, como desde mi patatuz y problemas con el ritmo cardiaco el último año tengo problemas concentrarme por tiempo prolongado en un tema, varío para seguir entrenando mi ordenador biológico entre las 2 orejas y así también me estoy metiendo en el diseño digital, que a la larga es lo que se mete como resultado en un PLD.

Una cosa que me había molestado durante bastante tiempo, probablemente por lo metódico que mi mente con genética alemana requiere, es lo que en inglés llaman el "workflow" o processo de desarrollo, usando por ejemplo el Webpack de Xilinx.

Como estoy metiendome en lo profundo de la electrónica análoga estudiando el curso "Real Analog: Circuit 1", aproveche tiempos de recuperación estudiando los otros cursos ofrecidos a través del sitio de "Diligent" y me encontré con estos 2 tutoriales sobresalientes que entre otras describen en detalle el proceso de un proyecto en el entorno del webpack de Xilinx. "Real Digital - A hands-on approach to digital design"y "Introduction to Diligent Digital Design: From VHDL to FPGAs".

Lo que quiero resaltar es, que el proceso de programar un PLD es, como waltergallego muy bien escribe aquí en el foro, mas que el escribir código en VHDL o Verilog y lograr programar un PLD con el resultado. Es un proceso que requiere sistematizar el proceso para lograr resultados estables y en caso ideal reutilisables. Estos cursos de forma sistemática pasan de introducir el webpack de Xilinx, de generar un circuito usando un esquema dentro del entorno del webpack a la generación automática del código VHDL, para así demostrar que el entrar el código usando el lenguaje VHDL, el que se agrega al entorno del código que se definió al iniciar el proceso relacionado a un proyecto en el Webpack. Todas las iniciaciones relacionadas a la componente seleccionada, etcétera, son generadas por el entorno y el código deseado solo se agrega en el sitio evidente en el código de inicialización automáticamente generado por el webpack.

Luego introduce otros elementos del proceso, hasta que, lo que a mí me faltaba, aunque parezca elemental, el como generar una test bench. Test bench es un archivo que aplica al circuito diseñado los pulsos deseados en las entradas, lo que permite verificar que el circuito diseñado realmente hace lo que era la intención. Y así sigue en el proceso hasta acabar ir aplicando el resultado al PLD seleccionado.

Yo pienso comprarme la placa Nexys™4 Artix-7 FPGA Board de Digilent pues también permite usar el nuevo entorno de Vivado y a condiciones académicas solo cuesta unos 120.- Euros. Es la ventaja de estar jubilado y tener el tiempo para estas investigaciones!

Vale la pena estudiar los cursos ofrecidos en el sitio de Diligentinc.com bajo la ceja "classroom". Ojalá hubiera tenido tales oportunidades cuando visité la universidad aquí en Alemania.
 
Última edición:
este se puede emplear con la tarjeta basys
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;
 
Hola amigos, finalmente mi pedido de cosas para estudiar electrónica análoga están con Fedex en Alemania y me llegarán la próxima semana. Como he sido incapaz de encontrar mi protoboard me compré una nuevo en ebay. Estudiando material disponible en el sitio de Analog Devices entre otras aprendí que para realmente entender el comportamiento de circuitos armados en un protoboard hay que tomar en consideración el efecto de tener pistas adyacentes, lo que equivale a un capacitador. Metido en esto me decidí finalmente armarme en ese protoboard un circuito que quiero realizar usando un CPLD de Xilinx, el tipo es XC9536XL. Después de intensas investigaciones pude averiguar que la última versión del Webpack de Xilinx que apoya esa componente es la versión 13.3, siendo 14.7 la actual.

Tengo pensado, cosa que va a ocurrir esta primavera, es armar una placa para experimentar con el CPLD XC9536XL. las componentes ya las tengo y voy a armar una plaquita en la cual el XC9536XL podrá ser encajado en el protoboard. Haré un paso a paso que quizá interese a alguno, entre otras porque el costo es mínimo y con la protoboard súper flexible. Creo, como escribió alguien en este hilo refiriéndose a un CPLA de Altera, lo que me imagino es equivalente a los CPLDs de Xilinx, los FPGA son excesivamente grandes. Creo que realmente para aprender y para aprovecharse de las capacidades de un CPLD y realizar circuitos simples pero útiles en la práctica las densidades ofrecidas mas que alcanzan!

Confieso que no soy bueno en eso de ecuaciones lógicas, pero como en todo, usarlas y experimentar me dará el acceso. Ademas pienso comprar la Suite académica de Matlab y Simulink y me meteré en los asuntos matemáticos!
 
Última edición:
Buenas noches, intento hacer un codigo con ps2 y que la tecla que teclee la arroje en un monitor, estoy ocupando una FPGA ALTERA DE2 y mi programación es en verilog, ocupo el modulo ps2 y el vga, tienen algun codigo que me puedan prestar para visualizarlo y ver que me sirve, Gracias de antemano.
 
hola a TODOS una consulta...
soy nuevo en esto de los FPGAs y tengo un proyecto para realizar la cual incluye varios puntos...

pero primero quisiera saber como es que puedo garantizar la TX y RX mediante el puerto ethernet con protocolo UDP del chip DM9000A?? me digeron que se lo programa pero no entiendo mucho este codigo que esta en el guia
UINT16 IOaddr; /* UINT32 IOaddr=0x19000000; for example defined in ARM-base HPI BANK3*/

void iow ( UINT16 register, UINT8 dataB )
{
outb (register, IOaddr); /* I/O output a Byte to INDEX port, select the register */
outb (dataB, IOaddr+ 4); /* I/O output a Byte to DATA port, WRITE the register data */
}

UINT8 ior ( UINT16 register )
{
outb (register, IOaddr); /* I/O output a Byte to INDEX port, select the register */
return inb (IOaddr + 4); /* I/O input a Byte from DATA port, READ the register data */
}

o si tuvieras otra forma de programarlo seria magnifico

saludos
 
Hola, como estan?
Estos ultimos meses he estado practicando con las FPGA´s y la programacion en VHDL, lo hacia con las tarjetas que prestan en la universidad pero ya ue estoy en vacaciones me gustaria adquirir una, pero estoy entre la BASYS 3 de Xilinx y la NEXYS 4 tambien de Xilinx

cual me recomiendan para aplicar y seguir estudiando?

se que la nexys es mucho mejor, pero quiero saber su opinion de si esta es la apropiada para mi ya que basicamente hasta ahora estoy entrando a fondo en el tema o me voy por la basys que es mas simploncita?

no se fijen en el precio

GRACIAS!!!:)

pdt: no puedo poner los links por que soy todavia muy nuevo :D
 
Yo me compre esta

Mojo V3

https://embeddedmicro.com/mojo-v3.html

Trae sólo lo mínimo indispensable para programar un Spartan 6, y por eso es perfecto para adaptarlo a cualquier aplicación.


mojov3front_2.png
 
Última edición:
Hola a todos,

Perdón por subir el hilo...,
Estoy intentando usar el ip core aurora 8b/10b con una spartan 6 para transmision de datos por SFP+, pero ando un poco perdido..., Alguien tiene experiencia en ello? Alguna recomendación?

Saludos!
 
Hola a todos,

Perdón por subir el hilo...,
Estoy intentando usar el ip core aurora 8b/10b con una spartan 6 para transmision de datos por SFP+, pero ando un poco perdido..., Alguien tiene experiencia en ello? Alguna recomendación?

Saludos!
Sin saber tu nivel de conocimiento previo es dificil contestarte ya que no se trata de un proyecto simple.

Yo comenzaria por revisar los diseños de ejemplo que provee Xilinx.
 
hola gente soy nuevo en esto de los foros( mas aun aqui en foros de electronica) he estado trabajando con la placa de terasic De0 nano que incorpora un cyclone IV, estoy buscando informacion sobre todo de como se usan los modulos que incorpora( memoria, acelorometro, adc etc) tambien dispongo de una placa DE2 115 de la universidad pero es la misma historia, he hecho proyectos y todo pero hasta ahoraa solo habia usado la fpga nada mas, incluso tambien poyectos con adc, pero adc paralelos como el adc0804, lo qu quiero es uasr los odulos que incorpara la tajeta, pero no encunetro info respcto a ello, estan los ejemplos de terasic pero todos ellos los hacen usando el procesador NIOSII, ¿es la unica forma de hacerlo? donde podria encontrar codigos en vhdl para poder manejar estos perifericos, desde ya gracias por la respuesta que me puedan dar.



Les dejo un pequeño proyecto que hice, un contador de 0 a 9999 con visualizacion en un diplay de 7 segmentos de 4 digitos multiplexado, espero les sirva. Trabaja con Clock de 48MHZ

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

entity contador_9999 is 
	port(	clk: in std_logic;
			display: out std_logic_vector(7 downto 0);
			ena: out std_logic_vector(3 downto 0));
end contador_9999;

architecture circuito of contador_9999 is
	signal clk_1hz: std_logic;
	signal clk_mux: std_logic;
	signal cuenta1: std_logic_vector(24 downto 0);
	signal cuenta2: std_logic_vector(17 downto 0);
	signal sel: std_logic_vector(1 downto 0);
	signal Q: std_logic_vector(3 downto 0);
	signal q1:std_logic_vector(3 downto 0);
	signal q2:std_logic_vector(3 downto 0);
	signal q3:std_logic_vector(3 downto 0);
	signal q4:std_logic_vector(3 downto 0);
	
begin
	process(clk)
	begin
		if clk='1' and clk'event then
			cuenta1<=cuenta1+1;
			if cuenta1=23999999 then
				cuenta1<=(others=>'0');
				clk_1hz<= not clk_1hz;
			end if;
		end if;
	end process;
	
	process(clk)
	begin
		if clk='1' and clk'event then
			cuenta2<=cuenta2+1;
			if cuenta2=23999 then
				cuenta2<=(others=>'0');
				clk_mux<= not clk_mux;
			end if;
		end if;
	end process;
	
	process(clk_1hz)
	begin
		if clk_1hz='1' and clk_1hz'event then
			q1<=q1+1;
			if q1=9 then
				q1<="0000";
				q2<=q2+1;
				if q2=9 then
					q2<="0000";
					q3<=q3+1;
					if q3=9 then
						q3<="0000";
						q4<=q4+1;
						if q4=9 then
							q4<="0000";
						end if;
					end if;
				end if;
			end if;
		end if;
	end process;
	
	process(clk_mux)
	begin
		if clk_mux='1' and clk_mux'event then
			sel<=sel+1;
			if sel=3 then
				sel<="00";
			end if;
		end if;
	end process;
	
	with sel select Q<= q1 when "00",
							  q2 when "01",
							  q3 when "10",
							  q4 when others;
	
	with sel select ena<="1110" when "00",
								"1101" when "01",
								"1011" when "10",
								"0111" when others;
								
	with Q select display <= "00000011" when "0000",
									 "10011111" when "0001",
								    "00100101" when "0010",
								    "00001101" when "0011",
								    "10011001" when "0100",
								    "01001001" when "0101",
								    "01000001" when "0110",
								    "00011111" when "0111",
								    "00000001" when "1000",
								    "00001001" when "1001",
								    "11111111" when others;	
	
end circuito;
 
Última edición:
Atrás
Arriba