Estudio del microprocesador Nios II

Estudio del microprocesador Nios II El "soft processor" Nios II de Altera Copyright © 2010 Jorge Rodríguez Araújo, grrod

Views 175 Downloads 3 File size 362KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Estudio del microprocesador Nios II El "soft processor" Nios II de Altera Copyright © 2010 Jorge Rodríguez Araújo, [email protected]

14 de marzo de 2010

Contenido 1.1 Memoria descriptiva......................................................................................1 1.1.1 Objeto.......................................................................................................................... 1 1.1.2 Antecedentes...............................................................................................................1 1.1.3 Justificación................................................................................................................. 1 1.1.4 Introducción.................................................................................................................1 1.1.5 El Nios II...................................................................................................................... 2 1.1.6 Gestión de excepciones..............................................................................................3 1.1.7 Conexión y acceso a memoria....................................................................................6 1.1.8 Conexión y acceso a periféricos..................................................................................7 1.1.9 Red Avalon..................................................................................................................8 1.1.10 Juego de instrucciones............................................................................................10 1.1.11 Programación del Nios II.........................................................................................12

Memoria del microprocesador Nios II

1. Memoria del microprocesador Nios II 1.1 Memoria descriptiva 1.1.1 Objeto El objeto de esta parte del proyecto es proporcionar una visión clara de las características y posibilidades del microprocesador Nios II. 1.1.2 Antecedentes En proyectos afines se había trabajado con microprocesadores de 8 bits configurables sobre FPGAs, pero no con procesadores de propósito general de 32 bits y alto rendimiento, unos 420 DMIPS. 1.1.3 Justificación El conocimiento del microprocesador resulta fundamental para completar el desarrollo de los periféricos de control de la etapa posterior. 1.1.4 Introducción El fabricante Altera proporciona una infraestructura completa para crear sistemas microprocesador embebidos, completamente a medida según las necesidades del diseñador, por medio de la combinación de una serie de componentes configurables sobre sus FPGAs. Para ello, proporciona un entorno específico, al que denomina SOPC Builder, que permite la definición y configuración a medida del sistema microprocesador Nios II, y que gracias a la herramienta de síntesis Quartus II puede ser implementado directamente sobre una FPGA de la marca. NIOS II SYSTEM NIOS II (CORE) Instruction Bus

Data Bus

AVALON (SYSTEM BUS)

MEMORY PROGRAM / DATA

PERIFERICS

INPUT / OUTPUT

Ilustración 1: Sistema microprocesador basado en Nios II

Este sistema microprocesador estará compuesto por: el núcleo procesador Nios II, memoria interna de programa y de datos, periféricos integrados e interfaces para memoria externa y/o entrad/salida. Al tratarse de un sistema flexible que puede ser adaptado a las necesidades específicas de cada diseño, no sólo posibilita ajustar su tamaño al de un determinado dispositivo, sino que deja decidir al diseñador cuando una implementación se debe realizar en software y cuando en hardware, permitiendo elevar el rendimiento y ajustar los costes. 1

Memoria del microprocesador Nios II

1.1.5 El Nios II El Nios II es un núcleo procesador configurable que se puede implementar en alguna de las tres versiones disponibles según se busque minimizar el consumo de recursos de la FPGA o maximizar el rendimiento del procesador: –

El Nios II/f (“fast”) es la versión diseñada para alto rendimiento, y que con un “pipeline” de 6 etapas proporciona opciones específicas para aumentar su desempeño, como memorias caché de instrucciones y datos, o una unidad de manejo de memoria (MMU, Memory Management Unit).



El Nios II/s (“standard”) es la versión con “pipeline” de 5 etapas que dotada de unidad aritméticológica (ALU, Arithmetic Logic Unit) busca combinar rendimiento y consumo de recursos.



El Nios II/e (“economy”) es la versión que requiere menos recursos de la FPGA, sin “pipeline” y muy limitada, dado que carece de las operaciones de multiplicación y división.

Cada una de estas versiones se completa con una serie de componentes, memoria y periféricos, por medio de su interconexión a través de un bus de sistema al que denominan “Avalon Switch Fabric”, para obtener un sistema Nios II completo en un chip (SOC, System On Chip). Características y arquitectura

El Nios II es un procesador de 32 bits de propósito general, basado en una arquitectura tipo Harvard, dado que usa buses separados para instrucciones y datos; y cuyas principales características son: –

Tamaño de palabra asignado de 32 bits



Juego de instrucciones RISC de 32 bits



32 registros de propósito general de 32 bits (r0 – r31)



6 registros de control de 32 bits (ctl0 - ctl5)



32 fuentes de interrupción externa



Capacidad de direccionamiento de 32 bits



Operaciones de multiplicación y división de 32 bits



Instrucciones dedicadas para multiplicaciones de 64 y 128 bits



Instrucciones para operaciones de coma flotante en precisión simple



Acceso a variedad de periféricos integrados e interfaces para manejo de memorias y periféricos externos

2

Memoria del microprocesador Nios II

Ilustración 2: Diagrama de bloques que define la arquitectura del Nios II

De este modo, se encuentra formado por una serie de unidades funcionales, dependiendo de la versión implementada. Entre estas, las principales son: los registros, la unidad aritmético-lógica, la interfaz para instrucciones definidas por el usuario, el controlador de excepciones, el bus de instrucciones, el bus de datos, la memoria caché de instrucciones y datos, la interfaz de acoplamiento directo de memoria de instrucciones y datos y el módulo de depuración JTAG. 1.1.6 Gestión de excepciones El controlador de excepciones es el circuito encargado de realizar las tareas ligadas a la atención de excepciones, que son aquellas situaciones anormales que interrumpen el flujo de ejecución de un programa, dado que requieren la atención del procesador. Las excepciones pueden ser: –

Excepciones software: –

Instrucción trap (“software trap”): se produce cuando en un programa aparece una instrucción trap. Lo que se utiliza para transferir el control a un programa diferente, como un sistema operativo.



Instrucción no implementada (“unimplemented instruction”): se produce cuando el procesador encuentra una instrucción válida que no ha sido implementada en hardware. Esto posibilita que se llame a una rutina que emule, en software, la operación requerida cuando no 3

Memoria del microprocesador Nios II

se encuentra implementada, en hardware. Como sería el caso de las instrucciones de multiplicar y dividir en una implementación del II/e. –

Excepciones hardware: –

Interrupción hardware (“hardware interrupt”): se produce cuando se da un evento sobre una de las 32 entradas de petición de interrupción de las que dispone el microprocesador (IRQ0 a IRQ31), lo que permite el acoplamiento asíncrono entre un periférico y el microprocesador.

Identificación de excepciones

Cuando se produce una excepción, el procesador transfiere la ejecución al controlador de excepciones que, en este caso, las gestiona a través de una única dirección. Esto provoca que la rutina de atención deba determinar que tipo de excepción se ha producido, empeorando el tiempo de respuesta (latencia), por medio de la realización de las siguientes tareas: 1. Comprobar el registro de interrupciones pendientes (IPENDING) para verificar que se ha producido una interrupción hardware y poder lanzar la rutina de atención apropiada. 2. Comprobar que la instrucción que estaba siendo ejecutada cuando se produjo la interrupción era una instrucción “trap”, siendo esta la correspondiente a la dirección de retorno de excepción (EA) menos 4, y poder lanzar la rutina apropiada. 3. De otro modo, la excepción habrá sido provocada por una instrucción no implementada, y se podrá programar un algoritmo que la emule. Controlador de interrupciones

El Nios II incluye en todas sus versiones un controlador interno de interrupciones (ICC), y ofrece la posibilidad de configurar un bloque controlador de interrupciones externo (EIC). El controlador de interrupciones interno gestiona las 32 entradas de petición de interrupción (IRQ0 a IRQ31) por medio de un único vector de interrupción, con lo que las tareas de identificación y resolución de prioridad deben ser resueltas por software. El controlador de interrupciones externo proporciona un control de interrupciones vectorizado (VIC, Vectored Interrupt Controller) con el que se da respuesta a las interrupciones a través de vectores de interrupción separados y según un determinado nivel de prioridad 1. Así, cuando se produce una interrupción se transfiere la ejecución directamente a la rutina de atención (ISR, Interrupt Service Rutine) apropiada, indicada por dicho vector a través de una instrucción de salto. Cuando se produce una petición de interrupción (IRQ, Interrupt ReQuest), se realiza el siguiente proceso: 1. Se cancela la ejecución de la instrucción en curso. 2. Se salva el estado de la CPU, valor del contador de programa e información de estado, para poder 1

Los niveles de prioridad se establecen para resolver el conflicto que aparece cuando se producen varias interrupciones de forma simultánea o mientras el microprocesador se encuentra atendiendo otra interrupción.

4

Memoria del microprocesador Nios II

reanudar el programa en el punto en el que se ha interrumpido. 3. Se deshabilitan las interrupciones externas al procesador. 4. Se cede el control al gestor de interrupciones para que identifique la fuente de interrupción y la marque en el registro de control de petición de interrupción, donde se reflejan las interrupciones que se encuentran pendientes de ser atendidas. 5. Se salta a la dirección donde se encuentra la rutina de atención de interrupción y se ejecuta, tras lo cual, se debe borrar la marca de petición de interrupción correspondiente. 6. Se reanuda la ejecución del programa, una vez finalizada la rutina de atención de interrupción. Hay que tener en cuenta que, para que se pueda generar una interrupción, se deben cumplir las siguientes tres condiciones: –

Que se encuentre activado el bit (PIE) del registro de estado que habilita las interrupciones de forma global.



Que se produzca una llamada a una de las entradas de atención de interrupción (IRQ).



Que se encuentre activado el bit correspondiente a dicha entrada en el registro de control de interrupciones habilitadas (IENABLE).

Ilustración 3: Diagrama de bloque de un ejemplo de sistema Nios II

5

Memoria del microprocesador Nios II

1.1.7 Conexión y acceso a memoria El Nios II utiliza 32 bits para realizar un direccionamiento por byte, poseyendo buses separados para instrucciones y datos, con lo que se corresponde con una arquitectura tipo Harvard. En este tipo de conexión, el bus de instrucciones se utiliza para leer el programa, situado en memoria, que debe ser ejecutado por el procesador, mientras que el bus de datos proporciona acceso a la diferentes bloques de memoria y a los periféricos del sistema. Sin embargo, existen tres modos posibles de conexión con memoria:

Tipos de memoria:

arquitecturas

de

conexión

con

Arquitectura Harvard: se utilizan buses independientes para comunicar la CPU con la memoria de instrucciones (programa) y con la memoria de datos, con lo que aunque se necesitan más terminales, se reducen los tiempos de acceso, al producirse el acceso simultáneo o instrucciones y datos. Arquitectura Von-Newmann: se utiliza un único bus tanto para instrucciones como para datos, lo que reduce el número de terminales a costa de la velocidad, dado que se encuentra limitada por el uso compartido del bus entre instrucciones y datos. Además, la longitud de las instrucciones está limitada por la longitud de los datos, con lo que el procesador debe realizar varios accesos a memoria para buscar instrucciones complejas.



Conexión de memoria a través de la red Avalon, tanto de memoria interna como externa.



Conexión directa de bloques de memoria interna, con lo que se proporciona un rápido acceso a memoria.



Conexión de memoria a través de caché (“cache memory”). Memoria caché

El Nios II puede incluir tanto caché de datos (Nios II/f) como de instrucciones (Nios II/f y Nios II/s), implementadas en los bloques de memoria del chip FPGA. La inclusión de estas memorias caché aumenta el rendimiento de forma significativa, sobre todo cuando la mayoría de la memoria principal se sitúa en un chip SDRAM externo.

6

Memoria del microprocesador Nios II

La memoria caché se organiza, al igual que la RAM, en un arreglo tipo tabla, formado por filas y columnas. En este caso, los tamaños de caché son configurables, aunque la caché de instrucciones se organiza en líneas de 8 bytes, mientras que la caché de datos se organiza en líneas de 4, 16 o 32 bytes. La gestión de caché se realiza por software, mediante las instrucciones definidas para este propósito según se trate de caché de instrucciones o datos. Se diferencian dos tipos de instrucción: para la carga y asociación de una línea de caché con una determinada dirección de memoria (“init”) y para llevar y vaciar el contenido de una línea de caché asociada con una determinada dirección de memoria (“flush”).

La memoria caché se organiza en una serie de filas o "líneas de caché" que representan la entidad básica de almacenamiento. De modo que en cada movimiento de caché se transfiere información suficiente para cubrir una línea. A cada línea de caché se le asocia un identificador (TAG) que indica la porción de la RAM a la que se encuentra asociada, constituyendo una memoria asociativa (CAM, Content Addressable Memory), dado que la búsqueda de información se realiza por la dirección de la RAM. Debido a que el tiempo de acceso, cuando la memoria caché es completamente asociativa, es muy elevado debido a que cada línea de caché se puede llenar con cualquier posición de la memoria RAM (porcentaje de acierto máximo), lo que se suele emplear es la caché asociativa en conjuntos de N líneas, donde a cada grupo de líneas le corresponde un determinado rango de memoria RAM. Así, una determinada posición de memoria sólo puede estar dentro de un determinado grupo de caché, con lo que se reduce el tiempo de búsqueda dentro del conjunto cuya caché es totalmente asociativa. Alcanzándose una solución óptima con la correcta selección del valor N.

Aunque por norma, se usará la caché cuando exista, es posible saltarse el acceso a través de caché y realizarlo de forma directa. Pero no deben mezclarse ambos métodos, dado que se puede provocar que la coherencia de los datos de memoria y caché se vea comprometida. 1.1.8 Conexión y acceso a periféricos En el Nios II, la memoria de datos y los periféricos comparten la capacidad de direccionamiento de 32 bits, y por tanto el bus. Así, el acceso de entrada/salida (I/O) se realiza a través del mapa de memoria, del mismo modo que cualquier otra dirección de memoria memoria (acceso a través de las mismas instrucciones).

7

Memoria del microprocesador Nios II Addresable memory FFFFFFFF

FFFFFFFF

PERIFERIC OUTPUT PERIFERIC

MEMORY INPUT 00000000

00000000

IB

DB

Ilustración 4: Organización de memoria y periféricos en el Nios II

Dado que el conjunto de periféricos y la capacidad de memoria son configurables, el mapa de direcciones de memoria y periféricos depende del sistema diseñado, estableciéndose en el momento de generar el sistema, al igual que las direcciones de reset e interrupción. Periféricos estándar

Altera proporciona un conjunto de periféricos comúnmente usados, como: temporizadores, interfaces de comunicación serie, entradas/salidas (I/O) de propósito general, controladores SDRAM y otras interfaces de memoria. Periféricos a medida

La verdadera potencia de los sistemas embebidos configurables, implementables sobre FPGA, aparece en el momento en que el diseñador tiene la posibilidad de decidir que partes del sistema serán implementadas en software y cuales en hardware. Así, todas aquellas tareas cuyo rendimiento sea crítico, pueden ser implementadas en hardware a través del desarrollo de un periférico a medida. Con lo que se obtiene un doble beneficio, un mayor desempeño gracias al carácter concurrente de la implementación hardware y se libera al procesador para realizar otras funciones en paralelo, mientras el periférico procesa los datos. La integración de periféricos a medida con el sistema procesador Nios II presenta una serie de alternativas según las necesidades específicas del diseño, pasando en la mayoría de los casos, por implementar una determinada interfaz de la red Avalon. Al igual que se pueden definir periféricos a medida, el Nios II también ofrece la posibilidad de añadir instrucciones propias a la unidad aritmético lógica (ALU), sobre todo pensando en aplicaciones de procesamiento digital de señales (DSP, Digital Signal Processing). 1.1.9 Red Avalon Para la interconexión de los diferentes componentes, o bloques de diseño, que conforman un

8

Memoria del microprocesador Nios II

sistema hardware se pueden identificar, tradicionalmente, cuatro arquitecturas de conexión diferentes: –

Conexión en “Bus”: se basa en la conexión de maestros y esclavos por medio de una unidad de arbitraje común, lo que permite operar a frecuencias relativamente altas a costa de perder la concurrencia.



Conexión “Full Crossbar Switch”: se basa en la conexión directa de maestros y esclavos por medio de una matriz de conexiones, lo que permite transacciones concurrentes entre los diferentes elementos del sistema, siendo uno de sus usos principales las aplicaciones de computación de alto rendimiento.



Conexión “Partial Crossbar Switch”: se basa en la conexión directa de un maestro con un determinado grupo de esclavos, lo que permite ahorrar recursos en la creación de la matriz de conexiones.



Conexión en “Streaming”: se basa en la conexión directa entre fuente (“source”) y sumidero (“sink”), creando un flujo de datos unidireccional para la transferencia de datos a alta velocidad, dado que elimina la unidad de arbitraje al crear una conexión punto a punto, siendo uno de sus principales usos el procesamiento de vídeo.

Altera, basándose en una arquitectura “Partial Crossbar Switch”, implementa una serie de interfaces, a las que designa como Avalon, que facilitan la interconexión de componentes en sistemas complejos, y permiten la interconexión de sistemas concurrentes, gracias a su estructura multimaestro. Así, un posible ejemplo de aplicación podría ser el siguiente: NIOS II

NIOS II

MEMORY PROGRAM / DATA

MASTER

SLAVE CONTROL BUS DATA BUS

SYSTEM BUS

STREAMING

SLAVE

SLAVE

MASTER

VIDEO SOURCE

FILTER

DMA VIDEO SINK

Ilustración 5: Ejemplo de aplicación de la red Avalon

En este ejemplo se tiene un sistema de procesamiento de vídeo donde, el procesador controla el funcionamiento del sistema por medio de una conexión en bus a través del mapa de memoria, los datos fluyen desde el dispositivo de entrada de vídeo hasta el de salida de forma paralela, permitiendo el preprocesado hardware de la imagen. Además, la imagen se transfiere a memoria por medio de un acceso directo a memoria (DMA, Direct Memory Access), lo que permite su procesado por medio de un algoritmo de alto nivel que se implementaría en el procesador. Con esta configuración se reduce la carga computacional del procesamiento de vídeo al realizar 9

Memoria del microprocesador Nios II

las etapas de preprocesado por hardware a través de una conexión en streaming, donde los datos se transfieren de forma secuencial y directa desde la fuente de vídeo hasta memoria. Por otro lado, la conexión al bus del sistema permite que el control sea realizado por el microprocesador y facilita el intercambio de información con memoria, posibilitando el postprocesado final de la imagen mediante su programación en un lenguaje de alto nivel, lo que eliminaría las dificultades y costes asociados a su desarrollo en hardware, y daría una mayor flexibilidad al sistema. Interfaces Avalon

Existen seis tipos diferentes de interfaz: –

La “Avalon Memory Mapped Interface” (Avalon-MM) es una interfaz de lectura/escritura basada en direcciones, típica de conexiones maestro-esclavo.



La “Avalon Streaming Interface” (Avalon-ST) es una interfaz que soporta un flujo de datos unidireccional, incluyendo streams multiplexados, paquetes y datos DSP.



La “Avalon Memory Mapped Tristate Interface” es una interfaz triestado de lectura/escritura basada en direcciones para el soporte de periféricos externos al chip. Así, múltiples periféricos pueden compartir buses de datos y direcciones para reducir el número de terminales de interconexión a la FPGA o el número de rutas en la PCB.



La “Avalon Clock” es una interfaz que envía o recibe señales de reloj y reset para sincronizar interfaces y proveer conectividad de reset.



La “Avalon Interrupt” es una interfaz que permite que los componentes envíen señales de eventos a otros componentes.



La “Avalon Conduit” es una interfaz que proporciona señales para ser llevadas fuera del nivel del SOPC Builder donde poder conectar otros módulos diseñados sobre la FPGA o a los terminales de la misma.

Así, un componente puede incluir una o varias de estas interfaces, o varias instancias de la misma interfaz, posibilitando la interacción de sistemas heterogéneos complejos. 1.1.10 Juego de instrucciones El procesador Nios II presenta un juego de instrucciones reducido (RISC, Reduced Instruction Set Computer), siendo la longitud de todas las instrucciones de 32 bits.

10

Memoria del microprocesador Nios II

Además de estas 64 instrucciones, su lenguaje ensamblador soporta una serie de seudoinstrucciones que se traducen en varias instrucciones en código máquina para agilizar el desarrollo de programas a bajo nivel. Las instrucciones se pueden agrupar en una serie de tipos: –

Instrucciones carga (“load”) y almacenamiento (“store”): realizan la transferencia de contenido entre memoria o interfaces de entrada/salida y los registros de propósito general, pudiendo leer y escribir al nivel de palabra (32 bits), media palabra (16 bits) o byte (8 bits).

Distintos tipos de juegos de instrucciones: - RISC (Reduced Instruction Set Computer): juego de instrucciones reducido, compuesto por operaciones simples de la unidad de control, donde cada instrucción puede operar con cualquier registro y modo de direccionamiento. Por lo general se encuentra asociado a estructuras Harvard con solapamiento de instrucciones (Instruction Pipelining). - CISC (Complex Instruction Set Computer): juego de instrucciones complejo, compuesto por operaciones complejas y específicas, motivo por el que pueden tener limitaciones de acceso a zonas de memoria o de modos de direccionamiento. - SISC (Specific Instruction Set Computer): juego de instrucciones específico, compuesto por operaciones específicas para tareas de control es un caso particular del CISC o del RISC.



Instrucciones aritméticas: realizan operaciones aritméticas (“add”, “sub”, “mul”, “div”) con los datos que se encuentran en los registros de propósito general o con un valor dado en la instrucción (valor inmediato). Hay que tener presente que las operaciones de suma y resta se realizan tanto con operandos con signo (“signed”) como sin el (“unsigned”), pero dado que el Nios II no dispone de mecanismo de detección de acarreo o desbordamiento, si se producen, deben ser detectados por software.



Instrucciones lógicas: realizan operaciones lógicas ("and", "or", "xor", "not") con los datos que se encuentran en los registros o con un valor dado.



Instrucciones de transferencia entre registros: seudoinstrucciones que copian el contenido de un registro en otro, o un valor indicado de forma inmediata.



Instrucciones de comparación: comparan el contenido de dos registros o el contenido de un registro y un valor inmediato, y escriben el resultado en el registro indicado.



Instrucciones de rotación y desplazamiento: rotan o desplazan el contenido de un registro.



Instrucciones de ruptura y salto: cambian el flujo de ejecución de un programa ya sea de forma condicional o no. Así, mientras con el salto incondicional se permite ubicar instrucciones en zonas de memoria con direcciones no consecutivas, con el salto condicional se permite modificar la secuencia de ejecución de instrucciones en función del resultado de las operaciones del programa.



Instrucciones de llamada a subrutina: permiten la llamada ("call") y el retorno ("ret") de subrutinas. De modo que, cuando se llama a una subrutina se carga en el contador de programa (PC) la dirección de salto y se memoriza la dirección de retorno (RA) para volver a cargarla en el

11

Memoria del microprocesador Nios II

PC cuando se retorno de la ejecución de la subrutina. –

Instrucciones de manejo de excepciones: permiten la generación de una interrupción software (“trap”) y el retorno (“eret”) de la rutina de atención de interrupción.



Instrucciones de control: instrucciones especiales para leer y escribir los registros de control. Modos de direccionamiento

El modo de direccionamiento es la forma en que el campo de dirección de la instrucción especifica la dirección efectiva, disponiéndose de cinco modos diferentes de direccionamiento:

Otros modos de direccionamiento no disponibles en le Nios II: - Direccionamiento relativo: la dirección efectiva se calcula sumando el contenido del campo de dirección de la instrucción al contenido del contador de programa (PC, Program Counter).



Direccionamiento inmediato: el operando se da de forma explícita en la instrucción como un valor de 16 bits.



Direccionamiento de registro: el operando se da a través del valor de un registro del procesador.



Direccionamiento con desplazamiento: la dirección efectiva del operando es la suma del contenido de un registro y un valor de desplazamiento, de 16 bits con signo, dado en la instrucción.



Direccionamiento indirecto de registro: la dirección efectiva del operando viene dada como el contenido de un registro especificado en la instrucción. Por tanto, es equivalente al modo con desplazamiento donde el valor de desplazamiento es igual a 0.



Direccionamiento absoluto: la dirección efectiva del operando se especifica directamente como parte de la instrucción, siendo su tamaño de tan sólo 16 bits.

- Direccionamiento indirecto: la dirección efectiva viene dada por el contenido de la posición de memoria indicada en la instrucción. - Direccionamiento indexado: la dirección efectiva se calcula sumando al contenido del campo de dirección de la instrucción el contenido del registro interno del microprocesador que se suele denominar registro de índice. - Direccionamiento en página: la memoria se estructura en una serie de bloques, páginas, cuya selección se realiza de forma implícita, y sobre la cual se realiza el direccionamiento, con lo que se reduce el número de direcciones necesarias.

1.1.11 Programación del Nios II Para la programación del Nios II se dispone de un entorno completo, basado en Eclipse, con el que Altera da soporte para el desarrollo de aplicaciones en C/C++. Al utilizar este entorno (“framework”) se emplea una capa de software (HAL, Hardware Abstraction Layer) que oculta los detalles de la configuración hardware, haciendo transparente al programador el desarrollo de aplicaciones. Además, esta capa HAL interpreta la prioridad de las interrupciones desde IRQ0 a IRQ3, para lo que requiere de la configuración de un temporizador. Para programar el Nios II directamente en ensamblador (“assembler”) se deben tener en en cuenta una serie de consideraciones y apreciaciones.

12

Memoria del microprocesador Nios II Identificación de periféricos

El carácter configurable del Nios II exige que en todo programa se presente una primera etapa en la que se han de definir todos y cada uno de los periféricos del sistema, por medio de las direcciones que se les asignaron durante la configuración. Esto facilita la comprensión del programa, aumenta su reusabilidad y, sobre todo, evita errores, al identificar cada uno de los periféricos con su correspondiente dirección de memoria, permitiendo su tratamiento como punteros de acceso a periféricos. # Refleja la posición de los interruptores # a través del estado de los indicadores .include "nios_macros.s" .equ .equ

pi8, 0x00003000 po8, 0x00003010

# interruptores # indicadores

.global _start _start: movia r2, pi8 movia r3, po8 loop: ldbio r4, 0(r2) stbio r4, 0(r3) br loop

# # # # # # # # # # #

// Programa equivalente en C // Refleja la posición de los interruptores (Switches) // a traés de los indicadores (LEDs) #define Switches (volatile char *) 0x0003000 #define LEDs (char *) 0x0003010 void main() { while (1) *LEDs = *Switches; }

Gestión de la pila

La pila (“stack”) es un segmento de memoria que se utiliza para almacenar la información sobre las llamadas a subrutinas que se encuentran en ejecución en un programa. Y aunque su propósito primario es almacenar las direcciones de retorno, con el uso de compiladores puede ser utilizada para funciones adicionales por medio del aumento del tamaño del bloque de apilamiento (“frame”). Cuando se llama a una subrutina (“call”) se almacena la dirección de retorno en el registro r31 (RA, Return Address) para volver cuando se finaliza la ejecución de la misma (“ret”). Por tanto, dado que la llamada a subrutinas no se gestiona a través de la pila (“stack”), si se pretende realizar llamadas anidadas a subrutinas habrá que realizar su gestión de forma manual.

13

Memoria del microprocesador Nios II Stack M anagement 00007000

STACK

SP0 SP

MEMORY

00003000

Ilustración 6: Gestión de la pila

Dado que la memoria se llena desde sus posiciones inferiores, para evitar errores en la gestión de la pila debido a su crecimiento sobre posiciones de datos, se recomienda inicializar el puntero de pila (SP, Stack Pointer) en la dirección más alta de memoria y hacerla crecer hacia direcciones inferiores. Así, para la manipulación explícita de la pila se ha de implementar la funcionalidad de apilar (“push”), para colocar un elemento en la pila, y de desapilar (“pop”), para retirar de la pila el último elemento almacenado. # Gestiona la pila para la llamada anidada de subrutinas .include "nios_macros.s" # Asignación de la dirección de inicialización de la pila (SP0) .equ SP0, 0x00007000 .equ .equ

PI8, 0x00003000 PO8, 0x00003010

.global _start _start: br main nop nop nop nop nop nop nop nop # Programa principal main: # Inicialización del puntero de pila (SP) movia SP, SP0 # Llamada a subrutina call subr0 # Programa movia r2, PI8 movia r3, PO8 loop: ldbio r4, 0(r2) stbio r4, 0(r3) br loop # Subrutinas

14

Memoria del microprocesador Nios II

subr0: # Gestión de la pila # Se apila la dirección de retorno (“push”) subi SP, SP, 4 # decrementa el puntero de pila stw RA, 0(SP) # almacena la dirección de retorno # Se llama a la subrutina (“call”) call subr1 # Se desapila la dirección de retorno (“pop”) ldw RA, 0(SP) # restaura la dirección de retorno addi SP, SP, 4 # incrementa el puntero de pila # Operación addi r6, r6, 1 ret subr1: # Gestión de la pila subi SP, SP, 4 stw ra, 0(SP) call subr2 ldw ra, 0(SP) addi SP, SP, 4 # Operación addi r6, r6, 1 ret subr2: addi r6, r6, 1 ret

Gestión de interrupciones

En el Nios II, el control de interrupciones se realiza por medio de los registros de control, que requieren del uso de unas instrucciones de lectura y escritura especiales, donde: –

La habilitación global de interrupciones se realiza por medio del primer bit del registro ctl0 (PIE).



La desinhibición de cada una de las interrupciones (IRQ0 a IRQ31) se controla a través de los bits del registro ctl3 (IENABLE).



Las interrupciones pendientes de atención se controlan a través de los bits del registro ctl4 (IPENDING).

La lectura y escritura de los registros de control se realiza por medio de las instrucciones rdctl y wrctl, de tal modo que: –

rdctl rC, ctlN: lee el valor del registro de control N y lo almacena en el registro rC.



wrctl ctlN, rA: escribe el valor del registro rA en el registro de control N.

Dado que cuando se produce una interrupción: primero se almacena la dirección de la próxima instrucción en el registro de retorno de excepción (EA) y segundo se cancela la ejecución de la instrucción en curso para, finalmente, saltar a la dirección de atención de interrupción; la dirección de retorno no refleja la posición real en la que debe reanudarse la ejecución del programa y hay que disminuir en 4 el valor del registro (EA), antes de salir de la rutina de atención de interrupción, para ejecutar la instrucción que fue abortada con anterioridad.

15

Memoria del microprocesador Nios II

# Refleja la posición de los interruptores # a través del estado de los indicadores .include "nios_macros.s" # Direcciones de entrada/salida .equ PI8, 0x00003000 .equ PO8, 0x00003010 # Máscara de interrupciones .equ PI8IM, 0x00003008 # Máscara de interrupciones # Dirección del puntero de pila .equ SP0, 0x00007000 .global _start _start: br main nop nop nop nop nop nop nop br interrupt

# dirección +0x0020

# Programa principal main: # Inicialización del puntero de pila movia sp, SP0 # Inicialización de la máscara de interrupción de PI8 movia r7, PI8IM movi r5, 0b1 stbio r5, 0(r7) # activa la interrupción para el interruptor 0 # Desinhibición de interrupciones (IRQ) movi r5, 0x0002 # desinhibición de la interrupción (ienable(1)=1) wrctl ienable, r5 movi r5, 0x0001 # desinhibición de interrupciones (PIE=1) wrctl status, r5 # Programa movia r2, PI8 movia r3, PO8 loop: ldbio r4, 0(r2) stbio r4, 0(r3) br loop # Atención de interrupciones interrupt: # Se encienden todos los LEDs movi r4, 0x00FF stbio r4, 0(r3) addi ea, ea, -4 eret

# corrige la dirección de retorno

16