Está en la página 1de 8

Pontificia Universidad Javeriana

Departamento de Electrónica
SYSTEM ON CHIP

Taller: Interacción HPS Input/Output


Este taller está diseñado para ser implementado en una tarjeta Terasic De1-SoC y la versión
Quartus Prime 18.1, sin embargo, cualquier otra tarjeta con una familia distinta de FPGA puede
ser adaptada, modificando la FPGA a utilizar y teniendo en cuenta los pines del dispositivo
conectados a los periféricos que en este caso particular corresponden a los interruptores,
botones, displays 7 segmentos y LEDs en la tarjeta de desarrollo. Algunas diferencias en las
interfaces de Quartus podrán ser observadas si se utilizan otras versiones del software de
diseño.

Como se observó en el taller anterior, el proceso general para desarrollar un sistema completo
utilizando el paradigma SoC tiende a ser intrincado dada la cantidad de pasos involucrados en el
proceso. Sin embargo, una vez el hardware es diseñado, y se ha generado correctamente la
configuración de la tarjeta SD de arranque, el sistema puede ser utilizado para implementar
diferentes aplicaciones reutilizando la misma configuración. El presente taller tiene como
objetivo profundizar en la interacción con periféricos entrada/salida desde el Hard Processor
System (HPS), mediante el diseño de software capaz de leer y escribir de forma sincronizada en
los diferentes registros del hardware. Para ilustrar el proceso de interacción con los dispositivos
periféricos en la FPGA, se guiará el diseño de un sistema encargado del encendido y apagado de
dos LEDs (Flashing LED), los cuales se encenderán alternativamente a una frecuencia que estará
controlada por la posición de 10 interruptores. Posteriormente se proponen una serie de
problemas de diseño para trabajo personal.

Para el presente taller, se conservará el hardware diseñado en el taller anterior tal y como se
observa en la Figura 1, consistente en:
 PLL encargado de manejar el reloj de los periféricos en la porción de hardware
reconfigurable y un reloj externo destinado a ser integrado a la memoria SDRAM
conectada a la FPGA a través de un controlador de memoria.
 Procesador ARM Cortex A9,
 LEDS, interruptores, botones y displays 7-segmentos manejados a través de periféricos
Parallel I/O conectados al bus.

Los pasos requeridos para la construcción del hardware y la configuración del HPS, fueron
desarrollados en el taller anterior y corresponden la siguiente secuencia:
 Crear un Proyecto de hardware en Quartus Prime.
 Crear un Sistema que incluye el procesador ARM Cortex A9 utilizando la herramienta
Platform Designer.
 Crear una entidad de alto nivel que instancie el sistema HPS.
 Compilar el sistema en Quartus Prime.
 Configurar la tarjeta SD de acuerdo a los pasos descritos en el taller anterior:
o Generación del Preloader.
o Generación del Bootloader.

1
o Configuración del Kernel de Linux
o Compilación del sistema operativo UBUNTU CORE ROOT FILESYSTEM.
o Creación de particiones en la tarjeta SD y escritura de los archivos de generados.
o Conexión Serial con la Tarjeta DE1-SoC
o Conexión ssh con la Tarjeta DE1-SoC
 Desarrollar el software requerido para el funcionamiento del Sistema.
 Construir (build/make) el proyecto y correr el software en el procesador.

Recuerde que la configuración de la tarjeta DSD de arranque ha sido automatizada mediante un


script de Linux que desarrolla los pasos descritos. Para comenzar el taller, conecte la tarjeta DE1-
SoC debidamente configurada mediante conexión ssh.

Figura 1. SoC HPS-FPGA en Platform Designer

1. Aplicación en C-Linux
Revisaremos el código de la aplicación la cual se encarga de del encendido y apagado de dos
LEDs (Flashing LED), los cuales se encenderán alternativamente a una frecuencia que estará

2
controlada por la posición de 10 interruptores. Recuerde que los periféricos anteriores se
encuentran conectados directamente a la FPGA y su lectura y escritura estará a cargo del ARM
a través del HPS-to-FPGA Ligth Weight Bridge.

El archivo “flashing_led.c”, deberá incluir la sección de includes y definiciones, similar a la


aplicación desarrollada en el taller anterior, tal y como se observa en la Figura 2.

Figura 2. Código flashing_led.c - Includes and definitions

En esta práctica, desarrollaremos funciones específicas para la lectura del PIO conectados a los
interruptores y la escritura del PIO conectado a los LEDs. Recuerde que las constantes
correspondientes a las direcciones base de los periféricos pueden variar a los mostrados en la
Figura 2. Los valores que debe incluir los puede consultar en la Platform Designer, o en el archivo
hps_soc_system.h generado en la ejecución del script “create_linux_system.sh”. También
puede incluir el header en lugar de declarar las constantes en este archivo. De esta manera, a
continuación en la Figura 3, se observan las declaraciones de los prototipos de ambas funciones.

3
Figura 3. Código flashing_led.c – Declaración de prototipos de funciones.

La función sw_get_command() lee el valor de los interruptores, almacenando su valor en la


variable prd. El código se muestra en la. Dado que el PIO de los interruptores tiene 10 bits de
ancho, usamos una máscara 0x000003FF para poner los bits no relacionados en 0.

Figura 4. Código flashing_led.c – función sw_get_command().

La función led_flash() espera el intervalo especificado y alterna dos LED. El código se muestra en
la Figura 5. Dado que los datos de 8 bits corresponden a la unidad más pequeña en C, utilizamos
una variable de 8 bits, led_pattern, tipo char, para almacenar el patrón de LEDs. Se declara como
una variable estática para que su valor pueda mantenerse entre llamadas a funciones. Los dos
bits menos significativos se alternan mediante una función lógica XOR con la máscara 0x03
cuando se ejecuta esta función. El retraso se logra mediante un dummy loop for.

Figura 5. Código flashing_led.c – función led_flash()

Se utiliza el factor 350,000 para lograr un número de iteraciones que generen una interacción
visible para el usuario. El retraso obtenido por este método no es no es muy preciso y solo
presenta estimaciones aproximadas cuando se realiza un cálculo. La cantidad de ciclos de reloj
necesarios para cada instrucción en un procesador ARM Cortex-V9 puede variar según varios
factores, incluida la microarquitectura específica, la profundidad del pipeline, la jerarquía de
caché y cualquier optimización implementada en el diseño del procesador. Para obtener
tiempos específicos utilizando este método se debe consultar la documentación técnica o el

4
manual de referencia del procesador para obtener información precisa sobre la sincronización
del ciclo, ya que puede ser muy específica del procesador e incluso depender de versiones
específicas de la arquitectura Cortex.

El programa principal, main (), de este sistema de luces LED se muestra en la Figura 6. Sigue la
arquitectura básica del un programa embebido donde se realiza una inicialización seguido de un
loop infinito.

Figura 6. Código flashing_led.c – main()

5
La función main() declara en primera instancia las diferentes variables que serán requeridas por
el programa. Se declaran una serie de apuntadores para almacenar la dirección base del HPS-
FPGA Lightweight Bridge, así como los offsets correspondientes a los PIO de los displays 7-
segementos, interruptores, leds y botones de la tarjeta, similar a lo realizado en taller anterior.

Linux representa todo como un archivo, incluidos todos los dispositivos. En particular, el archivo
especial "/dev/mem" representa el contenido de la memoria física del sistema. Este es el archivo
que el comando mmap() utiliza para acceder a las regiones de memoria que nos interesan. Dado
que estamos mapeando la memoria de un archivo, el primer paso es abrir este archivo. La línea
119 muestra cómo abrir el archivo “/dev/mem”, el cual otorga acceso a la memoria física, por
lo tanto, se requerirá ejecutar la aplicación con privilegios de root.

Una vez abierto el archivo de memoria física, es posible mapear en memoria un subconjunto del
mismo, en el espacio de direcciones virtuales de nuestro proceso. El código muestra cómo se
hace el mapeo de memoria de los periféricos conectados al HPS incluido el HPS-FPGA
Lightweight Bridge donde se conectaron los periféricos de la FPGA. Tenga en cuenta que debe
conocer el desplazamiento de su periférico dentro del archivo de memoria física, así como la
cantidad de memoria que desea que se asigne en memoria a partir de ese desplazamiento. En
nuestro caso, comenzaremos el mapeo de memoria desde el desplazamiento del periférico HPS-
FPGA Lightweight Bridge y se elige mapear el tamaño del periférico completo (HW_REGS_SPAN).
Cuando utilice mmap() para mapear los periféricos de la FPGA, se debe especificar un
desplazamiento dentro del archivo que se va a mapear, así como la cantidad de memoria a
mapear. El manual del comando mmap() establece que el desplazamiento proporcionado DEBE
SER MÚLTIPLE DEL TAMAÑO DE LA PÁGINA DEL SISTEMA, que es 0x1000 bytes en nuestro caso.

Finalmente, el loop infinito contiene únicamente las dos rutinas explicadas anteriormente,
sw_get_command() y led_flash(), las cuales serán llamadas iterativa e indefinidamente.

2. Ejecutar el programa
Es necesario generar el archivo “flashing_le.c” con el código de la aplicación previamente
discutida. Para tal fin tiene varias opciones:
 Instalar algún editor de texto (vi, gedit) y escribir el código anterior.
 Copiar el archivo editado en su host PC a la tarjeta DE1_SoC vía ssh, utilizando el
comando scp:
$ sudo scp /home/user/WorkspaceSoC/DE1_SoC_demo/sw/hps/application/linux_hps.c
ubuntu@192.168.1.27:/home/ubuntu/SoC_apps

 Una vez tenga el archivo fuente generado, compile y ejecute su aplicación utilizando el
siguiente comando:
$ gcc flashing_led.c -o flashing_led
$ sudo ./flashing_led

3. Ejercicios
A continuación, se proponen cuatro ejercicios para ser desarrollados utilizando un SoC que
incluya un procesador ARM y puertos E/S (PIO module) implementados en la FPGA. Se busca
con el desarrollo de los siguientes experimentos familiarizarse con el flujo de diseño SoC, el uso
de periféricos con interfase al exterior y el uso de la tarjeta DE1-SoC. El hardware del presente
proyecto, el similar al utilizado en el taller anterior.

6
Circuito “Chasing LED”
La tarjeta DE1-SoC115 posee 10 LEDs de propósito general para ser utilizados por la FPGA en
aplicaciones de usuario. Un circuito “Chasing LED” enciende un solo LED en un momento dado,
y en secuencia encenderá uno tras otro los demás LEDs de tal forma de que la luz parece en
movimiento a lo largo de la hilera de LEDs. Diseñe un sistema HPS-FPGA con los siguientes
requerimientos:
1. Los 10 LEDs son utilizados como salida, únicamente se enciende uno de ellos al tiempo.
2. La luz se mueve secuencialmente en cualquier dirección, y cambia de dirección cuando
llega a cualquiera de las posiciones extremas.
3. Utilice el botón marcado como KEY0 para inicializar el sistema, de tal forma que la luz
comience en el extremo derecho de la hilera mientras el botón esté oprimido.
4. Los primeros cinco interruptores SW0-SW4 deben ser utilizados para controlar la
velocidad de la luz. La velocidad más alta debe ser suficiente para realizar una inspección
visual del funcionamiento del sistema.

Colisión de LEDs
Similar al circuito “Chasing LED”, un circuito de colisión de LEDs, enciende dos LEDs
simultáneamente en una hilera. Los dos LEDs se mueven independientemente a la derecha y a
la izquierda cambiando de dirección al llegar a cada uno de los extremos y presentando colisión
en el centro para cambiar de dirección nuevamente. Diseñe un sistema HPS-FPGA con los
siguientes requerimientos:
1. Los 10 LEDs será usados como salida del sistema.
2. Los LEDs se moverán secuencial y sincronizadamente en cualquier dirección para
encontrarse justo en el centro.
3. Utilice el botón nombrado como KEY0 para inicializar el sistema, encendiendo los dos
LEDs extremos mientras el botón esté oprimido.
4. Los primeros cinco interruptores SW0-SW4 deben ser utilizados para controlar la
velocidad de ambas luces. La velocidad más alta debe ser suficiente para realizar una
inspección visual del funcionamiento del sistema.
Rotando un cuadro
Diseñe un sistema HPS-FPGA que genere un patrón de un cuadro sobre la matriz de 7-segmentos
disponible en la tarjeta DE1-SoC, de tal forma se enciendan únicamente los segmentos a, b, f y
g o los segmentos c, d, e y g. Se requiere que el cuadro circule por la matriz con una velocidad
variable que estará determinada por los primeros 5 interruptores SW0-SW4 disponibles en la
tarjeta. El sistema puede variar la dirección de rotación y ser pausado utilizando los
interruptores nombrados SW16 y SW17 respectivamente.

Figura 7. Patrón de un cuadro sobre la matriz de 7-segmentos disponible en la tarjeta DE1-SoC

7
LED Banner
Diseñe un sistema HPS-FPGA que permita desplegar un mensaje rotativo en el display 7-
segmentos de cuatro dígitos disponible en la tarjeta. Por ejemplo, asuma que un mensaje de 10
dígitos es 0123456789. El display podrá entonces mostrar el mensaje como: “012345”,
“123456”, “234567”,..., "567890", "678901", "789012", etc. El circuito debe tener como
entradas un interruptor que habilite o pause el despliegue del mensaje, y otro interruptor que
determine la dirección de despliegue a la derecha o a la izquierda.

También podría gustarte