Autor Tema: Experiencias con board Cyclone II EP2C8 (VHDL, Nios II...)  (Leído 7567 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Experiencias con board Cyclone II EP2C8 (VHDL, Nios II...)
« en: 14 de Mayo de 2012, 00:11:50 »
Hace poco tiempo he adquirido una placa de desarrollo que tiene lo mínimo indespensable como para comenzar a desarrollar algunas cositas  ;D Lo que pretendo compartir en este post son unos programas sencillos que nos permitan ir familiarizando con el entorno y con la placa:


FPGA: CycloneII EP2C8Q208C8
FLASH: 16Mbit SPI Flash EPCS16
Memory: 8MByte 16bit SDRAM K4S641632H
Onboard 50MHz oscillator
Onboard 3.3V/1.2V LDO
Onboard power switch
One JTAG download and debug port
One user button and one status LED
Total 132 avaliable user IOs


Para trabajar con el entorno recomiendo los siguientes vídeos, entre los dos van a lograr construir un proyecto, compilar, simular, asignar las señales a los pines del FPGA y finalmente grabar.



Nota: Si tienen problema con el USB Blaster las opciones son, ejecutar Quartus II en modo administrador, re-grabar la eeprom del USB Blaster (FTDI), o buscar los driver de una versión anterior. A mi la 10.0 me funciono joya.

Una vez que logramos armar el proyecto y compilarlo, el paso siguiente es simularlo o directamente grabarlo en el FPGA. Para este último paso necesitamos indicarle que pines del FPGA van a ser utilizados y aquí es importante tener el esquemático de la placa a mano.

Como primer ejemplo podemos hacer un divisor de frecuencia, ya que tenemos un oscilador de 50MHz y un led en la misma placa. Se toma la señal de oscilador, la dividimos tantas veces como sea necesario para producir una señal de 1 Hz y la conectamos al led. En VHDL podria implementarse lo siguiente:

Código: VHDL
  1. -- Declaracion de librerias
  2. library IEEE;
  3. use IEEE.STD_LOGIC_1164.ALL;
  4. use IEEE.STD_LOGIC_UNSIGNED.ALL;
  5.  
  6. -- Declaracion de la entidad ---
  7. entity DivisorFrecuencia is
  8.         generic(
  9.                 RESOLUCION: integer:=25;
  10.                 DIVISION: integer:=25000000
  11.         );
  12.         Port (
  13.                 CLK_i : in std_logic;
  14.                 CLK_o: out std_logic
  15.         );
  16. end DivisorFrecuencia;
  17. -- Declaracion de la arquitectura ---
  18. architecture behavior of DivisorFrecuencia is
  19.         signal sgCLK_o: STD_LOGIC;
  20. begin
  21.         CLK_o<=sgCLK_o;
  22.         ProcessDIV:
  23.         process(CLK_i)
  24.                 variable  count: std_logic_vector(RESOLUCION-1 downto 0):= (others => '0');
  25.         begin
  26.                 if(rising_edge(CLK_i))then
  27.                         count:= count + 1;
  28.                         if(count=DIVISION)then
  29.                                 count:= (others => '0');
  30.                                 sgCLK_o <= not sgCLK_o ;
  31.                         end if;
  32.                 end if;
  33.         end process;
  34. end;


Bien, ahora para probar este simple ejemplo recurrimos al esquemático de la placa, donde podemos ver que la señal de 50 MHz ingresa en el PIN_132 y que el led está conectado en PIN_208. Con esos datos vamos a Assignment/Assignment Editor o Assignment/Pin Planner y colocamos lo siguiente:


Guardamos y compilamos de nuevo. Solo queda grabar y ver como titila el led   :-/  Tools/Programmer ... Seleccionar programador ( USB-Blaster [USB-0]), JTAG y Start.

Bien, como sabemos un FPGA es un dispositivo volátil, entonces se necesita configurarla cada vez que se enciende. Aquí entra en juego el uso del EPCS16 (M25P16) que dispone la placa. Para grabar este dispositivo los pasos son los siguientes:

  • Luego de compilar vamos a File/Convert Programming File
  • Seleccionamos *.JIC como tipo de archivo de salida.
  • Seleccionamos EPCS16
  • Seleccionamos el FPGA utilizado y el archivo *.SOF.
  • Generamos archivo.

Luego de ello abrimos nuevamente el programador y agregamos el archivo *.jic creado en el paso anterior, marcamos Program/Configure y Start.


Listo, ahora cada vez que encendamos la placa "ejecutara" esta aplicación  :-)

El próximo será configurar un NIOS II para los elementos que disponemos en esta placa  :)
« Última modificación: 14 de Mayo de 2012, 00:15:10 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Experiencias con Cyclone II EP2C8 (Nios II, un microprocesador a la medida)
« Respuesta #1 en: 14 de Mayo de 2012, 19:05:16 »
Altera proporciona los elementos necesarios para diseñar un microprocesador a la medida (SOPC Builder) y luego mediante Quartus II compilarlo e implementarlo en el FPGA. Para leer un poco más de que se trata revisar el siguiente documento: Estudio del microprocesador Nios II.

Aquí lo que se pretende es realizar un microprocesador mínimo e implementarlo en la board que se dispone, configurar el controlador SDRAM, instanciar el CPU, seleccionar adecuadamente los pines a utilizar y probar un simple firmware.


Para el correcto funcionamiento de la SDRAM se le debe proporcionar una señal de clock ligeramente desfasada de la señal de clock del CPU, esto lo logramos utilizando uno de los PLL. El siguiente vídeo muestra esos pasos:


NiosII.vhdl
Código: VHDL
  1. -- Declaracion de librerias
  2. library IEEE;
  3. use IEEE.STD_LOGIC_1164.ALL;
  4.  
  5. -- Declaracion de la entidad ---
  6. entity NiosII is
  7.         Port (
  8.                 CLK_i : in std_logic;
  9.                 RESET_i: in std_logic;
  10.                
  11.                 PORT_o : out std_logic_vector (7 downto 0); -- Se declara la salida
  12.                
  13.                 ADDR_SDRAM_o : OUT STD_LOGIC_VECTOR (11 DOWNTO 0);
  14.                 BA_SDRAM_o : OUT STD_LOGIC_VECTOR (1 DOWNTO 0);
  15.                 CAS_SDRAM_o : OUT STD_LOGIC;
  16.                 CKE_SDRAM_o : OUT STD_LOGIC;
  17.                 CS_SDRAM_o : OUT STD_LOGIC;
  18.                 DQ_SDRAM_io : INOUT STD_LOGIC_VECTOR (15 DOWNTO 0);
  19.                 DQM_SDRAM_o : OUT STD_LOGIC_VECTOR (1 DOWNTO 0);
  20.                 RAS_SDRAM_o : OUT STD_LOGIC;
  21.                 WE_SDRAM_o : OUT STD_LOGIC;
  22.                 CLK_SDRAM_o: OUT STD_LOGIC
  23.         );
  24. end NiosII;
  25.              
  26. architecture behavior of NiosII is
  27.                 component altpll0 is
  28.                         port(
  29.                                 inclk0 : IN STD_LOGIC;
  30.                                 c0 : OUT STD_LOGIC;
  31.                                 c1 : OUT STD_LOGIC
  32.                         );
  33.                 end component altpll0;
  34.                 component SkuP is
  35.                         port(
  36.                                   -- 1) global signals:
  37.                                          signal clk_0 : IN STD_LOGIC;
  38.                                          signal reset_n : IN STD_LOGIC;
  39.                                   -- the_pio
  40.                                          signal out_port_from_the_pio : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
  41.                                   -- the_sdram   
  42.                                          signal zs_addr_from_the_sdram : OUT STD_LOGIC_VECTOR (11 DOWNTO 0);
  43.                                          signal zs_ba_from_the_sdram : OUT STD_LOGIC_VECTOR (1 DOWNTO 0);
  44.                                          signal zs_cas_n_from_the_sdram : OUT STD_LOGIC;
  45.                                          signal zs_cke_from_the_sdram : OUT STD_LOGIC;
  46.                                          signal zs_cs_n_from_the_sdram : OUT STD_LOGIC;
  47.                                          signal zs_dq_to_and_from_the_sdram : INOUT STD_LOGIC_VECTOR (15 DOWNTO 0);
  48.                                          signal zs_dqm_from_the_sdram : OUT STD_LOGIC_VECTOR (1 DOWNTO 0);
  49.                                          signal zs_ras_n_from_the_sdram : OUT STD_LOGIC;
  50.                                          signal zs_we_n_from_the_sdram : OUT STD_LOGIC
  51.                                   );
  52.                 end component SkuP;
  53.                 signal sgCLK_uP: std_logic;
  54.         begin
  55.                 U0: altpll0 port map(
  56.                         inclk0 => CLK_i,
  57.                         c0 => CLK_SDRAM_o,
  58.                         c1 => sgCLK_uP
  59.                 );
  60.                 U1: SkuP port map(
  61.                         clk_0 => sgCLK_uP,                                                      -- 50 MHZ del PLL.-
  62.                         reset_n => RESET_i,                                             -- Switch para resetear.-
  63.                         out_port_from_the_pio => PORT_o,                        -- Salida, PIO.-
  64.                         zs_addr_from_the_sdram => ADDR_SDRAM_o,
  65.                         zs_ba_from_the_sdram => BA_SDRAM_o,
  66.                         zs_cas_n_from_the_sdram => CAS_SDRAM_o,
  67.                         zs_cke_from_the_sdram => CKE_SDRAM_o,
  68.                         zs_cs_n_from_the_sdram => CS_SDRAM_o,
  69.                         zs_dq_to_and_from_the_sdram => DQ_SDRAM_io,
  70.                         zs_dqm_from_the_sdram => DQM_SDRAM_o,
  71.                         zs_ras_n_from_the_sdram => RAS_SDRAM_o,
  72.                         zs_we_n_from_the_sdram => WE_SDRAM_o
  73.                 );
  74.                
  75. end architecture;

En diagramas de bloques lo que se hace en NiosII.vhdl es lo siguiente:


Nota: Se adjunta excel con la disposición de los pines para esta placa.

Bien, ahora que el FPGA está grabado queda armar un proyecto y probar el funcionamiento, esto se muestra en el siguiente video:


Por ahora eso es todo, espero sea de utilidad  ;)


Saludos!
« Última modificación: 15 de Mayo de 2012, 10:57:12 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado dom124

  • PIC10
  • *
  • Mensajes: 42
Re: Experiencias con board Cyclone II EP2C8 (VHDL, Nios II...)
« Respuesta #2 en: 15 de Mayo de 2012, 09:46:38 »
Hola Suky, esta muy buena la placa!... te consulto... donde la conseguiste??? a que precio?

Quisiera analizar la posibilidad de adquirir una y empezar con estas guias que propones...

saludos

muy buena tu iniciativa... te felicito

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Experiencias con board Cyclone II EP2C8 (VHDL, Nios II...)
« Respuesta #3 en: 15 de Mayo de 2012, 10:54:53 »
En Ebay, allí hay varias opciones.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Experiencias con board Cyclone II EP2C8 (Creando un módulo para Nios II...)
« Respuesta #4 en: 17 de Mayo de 2012, 19:33:45 »
En este caso dejo un ejemplo sencillo de como cree un módulo PWM para ser agregado en un microprocesador de diseño propio  :-)

Código: VHDL
  1. library IEEE;
  2. use IEEE.STD_LOGIC_1164.all;
  3. use IEEE.STD_LOGIC_UNSIGNED.ALL;
  4.  
  5. entity PWM is
  6.         generic(
  7.                 RESOLUCION: integer:=32
  8.         );
  9.         port (
  10.                 -- Entradas
  11.                 clk: in std_logic;             
  12.                 reset_n: in std_logic;
  13.                 chip_select: in std_logic;
  14.                 write: in std_logic;
  15.                 address: in std_logic_vector (1 downto 0);                              -- Direcciona periodo, ciclo trabajo o bandera int.
  16.                 writedata: in std_logic_vector (RESOLUCION-1 downto 0); -- Para escribir periodo o ciclo de trabajo
  17.                 -- Salida
  18.                 pwm_o: out std_logic;   -- Salida a pin
  19.                 int_o: out std_logic    -- generador de interrupcion
  20.         );
  21. end PWM;
  22.  
  23. architecture behavior of PWM is
  24.   --variable  out_temp: std_logic:= '0';  
  25.   signal sg_pwm: std_logic :='0';
  26.   signal sg_int: std_logic :='0';
  27.   signal sg_period: std_logic_vector (RESOLUCION-1 downto 0):= (others => '0');
  28.   signal sg_duty_cycle: std_logic_vector (RESOLUCION-1 downto 0):= (others => '0');
  29.   signal sg_duty_cycle_a: std_logic_vector (RESOLUCION-1 downto 0):= (others => '0');
  30.   signal sg_wen,sg_wr_period,sg_wr_duty,sg_clr_int: std_logic;
  31. begin  
  32.  
  33.   process(clk,reset_n)  
  34.   variable  count: std_logic_vector(RESOLUCION-1 downto 0):= (others => '0');
  35.  
  36.   begin
  37.         if(reset_n='0')then
  38.                 sg_pwm<='0';
  39.                 sg_int<='0';
  40.                 sg_period<=(others => '0');
  41.                 sg_duty_cycle<=(others => '0');
  42.                 sg_duty_cycle_a<=(others => '0');
  43.     elsif rising_edge(clk) then
  44.                 count:= count + 1;             
  45.                 if(count >= sg_period) then
  46.                         count:= (others => '0');
  47.                         sg_duty_cycle_a<=sg_duty_cycle; -- Actualiza ciclo de trabajo
  48.                         sg_int<='1';                                    -- interrupcion
  49.                 end if;        
  50.                 if(count >= sg_duty_cycle_a) then
  51.                         sg_pwm<='0';
  52.                 else
  53.                         sg_pwm<='1';
  54.                 end if;
  55.                 if(sg_wr_period='1')then
  56.                         sg_period<=writedata;
  57.                 end if;
  58.                 if(sg_wr_duty='1')then
  59.                         sg_duty_cycle<=writedata;
  60.                 end if;
  61.                 if(sg_clr_int='1')then
  62.                         sg_int<='0';
  63.                 end if;
  64.     end if;    
  65.   end process;
  66.  
  67.   sg_wen <= '1' when chip_select='1' and write='1' else '0';
  68.   sg_wr_period <= '1' when address="00" and sg_wen='1' else '0';
  69.   sg_wr_duty <= '1' when address="01" and sg_wen='1' else '0';  
  70.   sg_clr_int <= '1' when address="10" and sg_wen='1' else '0';
  71.  
  72.   pwm_o<=sg_pwm;
  73.   int_o<=sg_int;
  74.  
  75. end behavior;

chip_select: permite seleccionar el módulo para realizar algún tipo de tarea.
write: permite habilitar la escritura de algún registro sobre el módulo.
address: permite direccionar entre los registros que configuran el módulo. En este caso 0 seria para escribir el periodo, 1 para escribir el ciclo de trabajo y 2 parra borrar  la señal de interrupción.
writedata: es el bus para enviar la data correspondiente al periodo o ciclo de trabajo.


Una vez creado el VHDL y probado su correcto funcionamiento, los pasos realizados para crear un módulo para NIOS II han sido los siguientes:

Salida sería un New Conduit y interrupt_pwm un New Interrupt Sender. Eso se selecciona dentro de la columna  interface, luego en la solapa interfaces se les cambia el nombre a gusto.

Información sobre que es cada tipo de señal, leer Avalon Interface Specifications

Con ello ya podemos agregarlo en nuestro proyecto:



Luego en el firmware para poder configurar el módulo he implementado las siguientes definiciones:

Código: C
  1. #include "system.h"
  2. #include "alt_types.h"
  3.  
  4. #define __PWM_CALC_ADDRESS_NATIVE(BASE, REGNUM) ((void *)(((alt_u8*)BASE) + ((REGNUM) * (SYSTEM_BUS_WIDTH/8))))
  5. #define PWM_WR(BASE, REGNUM, DATA)  __builtin_stwio(__PWM_CALC_ADDRESS_NATIVE ((BASE), (REGNUM)), (DATA))
  6. #define PWM0_WR_PERIOD(DATA) PWM_WR(SK_PWM_BASE, 0, DATA)
  7. #define PWM0_WR_DUTY(DATA) PWM_WR(SK_PWM_BASE, 1, DATA)
  8. #define PWM0_CLR_INT() PWM_WR(SK_PWM_BASE, 2, 0)

Ello permite acceder a cada registro del módulo, entonces para generar (Clk=50 MHz) una señal de 1 Hz con CT en 50% se hace:

Código: C
  1. int main(void){
  2.  
  3.         PWM0_WR_PERIOD(50000000);
  4.         PWM0_WR_DUTY(25000000);
  5.         while(1){
  6.         }
  7. }


Saludos!
« Última modificación: 19 de Mayo de 2012, 17:25:16 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: Experiencias con board Cyclone II EP2C8 (VHDL, Nios II...)
« Respuesta #5 en: 26 de Octubre de 2012, 03:57:08 »
Que chevere Suky. Yo quiero comprarme una tarjeta asi pero de Xilinx, como creo que no hay, creo que comprare una cmo la tuya. Solo que tambien debo comprar el USB Blaster no?

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Experiencias con board Cyclone II EP2C8 (VHDL, Nios II...)
« Respuesta #6 en: 26 de Octubre de 2012, 15:54:21 »
Que chevere Suky. Yo quiero comprarme una tarjeta asi pero de Xilinx, como creo que no hay, creo que comprare una cmo la tuya. Solo que tambien debo comprar el USB Blaster no?

Si, no queda otra.

Saludos!
No contesto mensajes privados, las consultas en el foro


 

anything