TEMA 6 PROGRAMACION DE LOS PROCESADORES DIGITALES DE SEÑAL ADSP-2106x CURSO 2010/2011 TEMA 6 1. Herramientas de programación de los Procesadores ADSP-2106x SHARC 1.1. Entorno de Programación VisualDSP++ 1.2. Programa Ensamblador easm21k 2. Programación Elemental 2.1. Código Fuente (.asm) 2.2. Directivas del Programa Ensamblador 3. Modos de Direccionamiento: 3.1. Modo de Direccionamiento Inmediato 3.2. Modo de Direccionamiento Directo 3.3. Modo de Direccionamiento Indirecto a Registro 4. Juego de Instrucciones 1 PROGRAMACION ELEMENTAL ¾ El programa ensamblador de la familia de procesadores ADSP21xxx “easm21k.exe” se puede ejecutar desde: 9 La línea de comandos del sistema operativo. 9 El entorno integrado de desarrollo VisualDSP++ ¾ El programa ensamblador procesa ficheros fuente (.asm), ficheros de datos (.dat) y ficheros cabecera (.h) y genera ficheros objeto (.doj). ¾ El modo de operación del ensamblador depende de dos tipos de controles: 9 Directivas del ensamblador 9 Opciones del ensamblador PROGRAMACION ELEMENTAL ¾ Las directivas están codificadas junto con el programa fuente y nos permiten: 9 Definir variables en el programa 9 Configurar características del hardware 9 Definir secciones en el programa que serán ubicadas en la memoria del DSP ¾ Las opciones del ensamblador se especifican en la línea de comandos desde el sistema operativo o en el cuadro de diálogo “Proyect Options” dentro del VisualDSP++. Estas opciones permiten al programador controlar en qué modo el ensamblador procesa los programas. Estas opciones nos permiten: 9 Seleccionar rutas de búsqueda 9 Seleccionar los nombres de los ficheros de salida 2 PROGRAMACION ELEMENTAL ¾ Antes de ensamblar el preprocesador procesa el código ensamblador (.asm) y los ficheros de datos (.dat). ¾ El fichero de código fuente suele contener también comandos del preprocesador como #include que hace que el preprocesador incluya ficheros cabecera en el programa fuente. ¾ El preprocesador genera como salida un fichero intermedio (.is), que es realmente la entrada del programa ensamblador. CODIGO FUENTE (.ASM) ¾ Las sentencias del fichero de código fuente en ensamblador están formadas por: 9 Instrucciones del juego de instrucciones de los DSPs 9 Directivas del programa ensamblador 9 Comandos del preprocesador ¾ Las instrucciones de los DSPs son traducidas a código máquina, mientras que las directivas y comandos modifican el proceso de ensamblado. INSTRUCCIONES ¾ Cada instrucción comienza con un nemónico y termina con ”;” . ¾ Para marcar la dirección de una instrucción se pueden colocar etiquetas al comienzo de la línea de instrucción o en la línea precedente, terminando el nombre de la etiqueta con “:”. 3 CODIGO FUENTE (.ASM) ¾ Podemos hacer referencia a esta posición de memoria en el programa utilizando la etiqueta en lugar de su dirección absoluta correspondiente: inicio: R0 = fuente; bucle: DM(I0, M6) = F8; DIRECTIVAS DEL ENSAMBLADOR ¾ Las directivas del ensamblador empiezan con “.” y terminan con “;”. El punto debe ser el primer carácter de la línea que contiene la directiva. ¾ El programa ensamblador no diferencia las directivas escritas en mayúsculas o en minúsculas, aunque normalmente se suelen escribir en mayúsculas para distinguirlas del resto de sentencias del ensamblador: .PRECISION = 40; .ROUND_ZERO; DIRECTIVAS DEL ENSAMBLADOR 4 DIRECTIVAS DEL ENSAMBLADOR .EXTERN ¾ La directiva .EXTERN importa símbolos que han sido declarados como .GLOBAL en otros ficheros. Sintáxis: .EXTERN symbolName, symbolName,…..; donde symbolName es el nombre del símbolo global que se va a importar. Ejemplo: .EXTERN coeficientes; // // // // Declara la variable coeficientes como externa, suponiendo que ha sido declarada en otro fichero como .GLOBAL DIRECTIVAS DEL ENSAMBLADOR .GLOBAL ¾ La directiva .GLOBAL cambia el alcance de un símbolo de local a global, permitiendo que dicho símbolo pueda referenciarse en otros ficheros que vayan a ser linkados juntos. Sintáxis: .GLOBAL symbolName1 [, symbolName2,….]; donde symbolName es el nombre del símbolo global. Ejemplo: .VAR coeficientes[10]; // Declara un buffer .VAR etapas = 100; // Declara una variable .GLOBAL coeficientes, etapas; // Variables visibles en otros ficheros 5 DIRECTIVAS DEL ENSAMBLADOR DIRECTIVAS DEL ENSAMBLADOR 6 DIRECTIVAS DEL ENSAMBLADOR .PORT ¾ La directiva .PORT asigna nombre simbólico a los puertos de Entrada/Salida. Los nombres simbólicos de los puertos son símbolos globales y se corresponden con los puertos de Entrada/Salida mapeados en memoria y definidos en el Fichero de Descripción de la Arquitectura de Memoria (.LDF). Sintáxis: .PORT portName; donde portName es el nombre del puerto. Ejemplo: .PORT p1; // Declara el puerto de E/S p1 .PORT p2; // Declara el puerto de E/S p2 DIRECTIVAS DEL ENSAMBLADOR .PRECISION ¾ La directiva .PRECISION controla como el programa ensamblador interpreta los datos en coma flotante, tanto en la declaración de constantes como en la inicialización de variables. Sintáxis: .PRECISION [=] 32; .PRECISION [=] 40; donde los valores 32 ó 40 especifican el número de bits significativos de los datos en coma flotante. El signo igual [=] es opcional. Ejemplo: .PRECISION = 32; // Selecciona precisión simple, estándar IEEE .PRECISION // Selecciona precisión extendida de 40 bits 40; 7 DIRECTIVAS DEL ENSAMBLADOR DIRECTIVAS DEL ENSAMBLADOR .ROUND_mode ¾ La directiva .ROUND_ controla como el programa ensamblador interpreta los datos en coma flotante una vez definida la precisión (.PRECISION). La directiva .ROUND_ determina como el programa ensamblador manipula los datos en coma flotante, tanto en la declaración de constantes como en la inicialización de variables Sintáxis: .ROUND_mode; donde mode especifica el modo de redondeo usado para almacenar un valor en el formato especificado. Estos modos están definidos en el estándar IEEE: .ROUND_NEAREST; // Redondeo al más próximo .ROUND_PLUS; // Redondeo al mayor más próximo .ROUND_MINUS; // Redondeo al menor más próximo .ROUND_ZERO; // Redondeo a cero (truncar) 8 DIRECTIVAS DEL ENSAMBLADOR .SECTION ¾ La directiva .SECTION marca el comienzo de una sección de memoria de programa o de una sección de memoria de datos que consiste en un conjunto de posiciones contiguas de memoria. Las sentencias dispuestas entre una directiva .SECTION y la siguiente directiva .SECTION o el final del fichero especifican el contenido de esa sección. Sintáxis: .SECTION / type sectionName; donde / type especifica el tipo de memoria y sectionName el nombre de la sección. Los nombres usados para las secciones se deben corresponder con los definidos en el fichero de Definición de la Arquitectura de Memoria (.LDF). Ejemplo: .SECTION /DM seg_dmda; // Define sección en memoria de datos .SECTION /PM seg_pmco; // Define sección en memoria de programa DIRECTIVAS DEL ENSAMBLADOR 9 DIRECTIVAS DEL ENSAMBLADOR .VAR ¾ La directiva .VAR declara y opcionalmente inicializa variables y buffers de datos (una variable ocupa una única posición de memoria y un buffer de datos ocupa una serie de posiciones consecutivas de memoria). Sintáxis: .VAR varName1 [, varName2, …]; .VAR varName1, varName2, … = initExpression1, initExpression2, …; .VAR bufferName[ ] = initExpression1, initExpression2, …; .VAR bufferName[ ] = “fileName.dat”; .VAR bufferName[ length ] = “fileName.dat”; .VAR bufferName1[ length ] [, bufferName2 [ length ] , …]; .VAR bufferName[ length ] = initExpression1, initExpression2, …; DIRECTIVAS DEL ENSAMBLADOR .VAR Ejemplo: . VAR muestras[ ] = 10, 11, 12, 13, 14; // Buffer inicializado . VAR muestras[ ] = “ onda.dat”; // Buffer inicializado desde fichero . VAR muestras[ 100 ] = “onda.dat”; . VAR entrada, salida, etapas; // Variables no inicializadas . VAR etapas = 100; // Variable inicializada .VAR temporal = 0x157001; También se pueden definir variables ASCII: Ejemplo: .VAR texto[ 12 ] = ‘Hola Mundo!‘ , 0; .VAR texto[ ] = ‘Hola Mundo!‘ , 0; 10 CODIGO FUENTE (.ASM) COMANDOS DEL PREPROCESADOR ¾ Los comandos del preprocesador comienzan con “#” y terminan con un retorno de carro. El signo “#” debe ser el primer carácter de la línea que contiene el comando. ¾ Al contrario que las otras sentencias del ensamblador, los comandos del preprocesador deben escribirse en minúsculas: #include “def21061.h” /* Incluye el contenido de un fichero */ #define PI 3.14159 /* Define una macro */ CODIGO FUENTE (.ASM) FORMATOS NUMERICOS 11 CODIGO FUENTE (.ASM) COMMENTARIOS CODIGO FUENTE (.ASM) Ejemplo: #include “def21061.h” /* Incluye el contenido de un fichero */ .PRECISION = 32; /* Define la precisión */ .ROUND_NEAREST; /* Define el modo de redondeo*/ .SECTION / DM seg_dmda; /* Sección de datos */ .VAR muestras[ n ]; .SECTION / PM seg_pmco; /* Sección de código */ B5 = muestras; L5 = length (muestras); M6 = 1; LCNTR = length (muestras), DO bucle UNTIL LCE; F0 = DM (I5, M6); Bucle: 12 FICHERO .LDF MEMORY { // the following memory regions are reserved by the ADSP 21061 EZ-KIT Lite montior // do not use memory in these regions // seg_newrth { TYPE(PM RAM) START(0x00021974) END(0x00021992) WIDTH(48) } // seg_rsvd_rth { TYPE(PM RAM) START(0x00021993) END(0x00021a12) WIDTH(48) } // seg_post { TYPE(PM RAM) START(0x00021a13) END(0x00021a52) WIDTH(48) } // seg_jmp { TYPE(PM RAM) START(0x00021a53) END(0x00021a59) WIDTH(48) } // seg_rsvd_pmco { TYPE(PM RAM) START(0x00021a5a) END(0x00021da0) WIDTH(48) } // seg_rsvd_pmda { TYPE(PM RAM) START(0x00021da1) END(0x00021fff) WIDTH(48) } // seg_rsvd_dmda { TYPE(DM RAM) START(0x00027ffd) END(0x00027fff) WIDTH(32) } seg_rth { TYPE(PM RAM) START(0x00020000) END(0x0002008e) WIDTH(48) } seg_init { TYPE(PM RAM) START(0x00020100) END(0x00020108) WIDTH(48) } seg_pmco { TYPE(PM RAM) START(0x00020110) END(0x00020800) WIDTH(48) } seg_pmda { TYPE(PM RAM) START(0x00025000) END(0x000254ff) WIDTH(32) } #ifdef __cplusplus seg_ctdm { TYPE(DM RAM) START(0x00024000) END(0x000240ff) WIDTH(32) } seg_ctdmend { TYPE(DM RAM) START(0x00024100) END(0x000241ff) WIDTH(32) } seg_dmda { TYPE(DM RAM) START(0x00024200) END(0x00025fff) WIDTH(32) } #else seg_dmda { TYPE(DM RAM) START(0x00024000) END(0x00024fff) WIDTH(32) } #endif seg_heap { TYPE(DM RAM) START(0x00026000) END(0x00026fff) WIDTH(32) } seg_stak { TYPE(DM RAM) START(0x00027000) END(0x00027ffc) WIDTH(32) } } FICHERO #include "def21061.h" #define N 64 .ASM /* Memory Mapped IOP register definitions */ /* Constant for number of points in input */ .PRECISION=32; .ROUND_NEAREST; .SECTION/DM seg_dmda; /* Declare variables in data memory */ .VAR input[N]= "test64.dat"; .VAR real[N]; .VAR imag[N]; .SECTION/PM seg_pmda; .VAR sine[N]= "sin64.dat"; /* Declare variables in program memory */ /* Cosine is derived using a shifted */ /* pointer to this circular buffer.*/ .SECTION/PM seg_rth; /* The reset vector resides in this space */ nop; nop; nop; nop; NOP; USTAT2= 0x108421; /* 1st instr. to be executed after reset */ DM(WAIT)=USTAT2; /* Set external memory waitstates to 0 */ JUMP start; .SECTION/PM seg_pmco; /* Example setup for DFT routine */ start: M1=1; M9=1; B0=input; L0=LENGTH(input); /* Input buffer is circular */} 13 MODOS DE DIRECCIONAMIENTO ¾ En las instrucciones básicamente hay tres modos de direccionamiento: 9 Modo Inmediato: el operando está contenido en la palabra de instrucción: F10 = 0.1234567; DM(I0, M0) = 0xffff1234; 9 Modo Directo: la dirección del operando está contenida en la palabra de instrucción: 9 Modo Absoluto: la instrucción contiene la dirección absoluta de memoria: DM(0x000015F0) = ASTAT; IF NE JUMP etiqueta; 9 Modo Relativo al PC: se especifica en la instrucción un desplazamiento respecto al registro PC: CALL (PC,10), R0 = R6 + R3; DO (PC, longitud) UNTIL SZ; MODOS DE DIRECCIONAMIENTO 9 Modo Indirecto a Registro: (usando los registros de los DAGs) 9 Modo Posmodificado con el registro M y actualización de I: F5 =PM(I9, M12); DM(I0, M3) = R3, R1 = PM(I15, M10); 9 Modo Premodificado con el registro M y sin actualización de I: R1 = PM(M10, I15); JUMP (M13, I11); 9 Modo Posmodificado con un valor inmediato y actualización de I: F15 = DM(I0, 6); IF AV R1 = PM(I15, 0x11); 9 Modo Premodificado con un valor inmediato y sin actualización de I: IF AV R1 = PM(0x11, I15); DM(127, I5) = 0x01234567; 14 JUEGO DE INSTRUCCIONES ¾ Las instrucciones del juego de instrucciones se agrupan en 4 categorias: I. Instrucciones de Cálculo y Movimiento o Modificación de Datos: realizan una operación de cálculo en paralelo con uno o dos movimientos de datos o una modificación de un registro índice. II. Instrucciones de Control del Flujo del Programa: realizan varios tipos de saltos, llamadas a subrutinas, retornos de subrutinas y bucles. Algunas de estas istrucciones pueden también realizar una operación de cálculo y/o un movimiento de datos. III. Instrucciones de Movimiento de Datos Inmediatos: son instrucciones que utilizan los campos inmediatos de la instrucción como operandos o utilizan los campos inmediatos de la instrucción para el direccionamiento. IV. Instrucciones Varias: como modificación o comprobación de bits de los registros del sistema, NOP, IDLE, etc… ¾ Algunas instrucciones pueden ser condicionales. En estas instrucciones el nemónico está precedido por IF + condición. En las instrucciones condicionales la ejecución de la instrucción completa depende de la condición especificada. JUEGO DE INSTRUCCIONES ¾ Grupo I: Cálculo y Movimiento de Datos 1. Transferencias en paralelo entre memoria de datos y memoria de programa con el banco de registros, opcionalmente realizan también una operación de cálculo: 2. Operación de Cálculo, opcionalmente una condición: 3. Transferencias de Datos entre memoria de programa o memoria de datos y un registro universal, opcionalmente condición y también opcionalmente una operación de cálculo: 15 JUEGO DE INSTRUCCIONES ¾ Grupo I: Cálculo y Movimiento de Datos 4. Transferencias entre memoria de programa o memoria de datos y el banco de registros con un modificador inmediato de 6 bits. Opcionalmente condición y también opcionalmente una operación de cálculo: 5. Transferencias entre dos registros universales, opcionalmente condición y opcionalmente una operación de cálculo: JUEGO DE INSTRUCCIONES ¾ Grupo I: Cálculo y Movimiento de Datos 6. Instrucciones del Desplazador con un dato inmediato, opcionalmente condición y también opcionalmente una transferencia de datos entre la memoria de programa o de datos y el banco de registros: 7. Modificación de registros Indice, opcionalmente condición y también opcionalmente una operación de cálculo: 16 JUEGO DE INSTRUCCIONES ¾ Grupo II: Control del Flujo del Programa 8. Instrucciones de Salto y Llamada a Subrutina con direccionamiento absoluto o relativo al PC, opcionalmente condición: 9. Instrucciones de Salto y Llamada a Subrutina con direccionamiento indirecto o relativo al PC, opcionalmente condición y también opcionalmente operación de cálculo. JUEGO DE INSTRUCCIONES ¾ Grupo II: Control del Flujo del Programa 10. Instrucciones de Salto Indirecto o Relativo al PC y opcionalmente condición y operación de cálculo con transferencia de datos entre memoria de datos y el banco de registros: 11. Instrucciones de Retorno de Subrutina Software o Subrutina de atención a Interrupción, opcionalmente condición y también opcionalmente operación operación de cálculo: 17 JUEGO DE INSTRUCCIONES ¾ Grupo II: Control del Flujo del Programa 12. Bucles de Instrucciones: carga del contador del bucle y repetir hasta que contador igual a cero: 13. Bucles de instrucciones: repetir hasta que se cumpla una condición de terminación: JUEGO DE INSTRUCCIONES ¾ Grupo III: Movimiento de Datos Inmediatos 14. Instrucciones de Transferencia entre memoria de datos o de programa y registros universales con direccionamiento directo absoluto: 15. Instrucciones de transferencias de datos entre memoria de datos o de programa y registros universales con direccionamiento indirecto y modificador inmediato: 18 JUEGO DE INSTRUCCIONES ¾ Grupo III: Movimiento de Datos Inmediatos 16. Instrucciones de escritura de un dato inmediato en memoria de datos o de programa: 17. Instrucciones de carga de un registro universal con un dato inmediato: ¾ Grupo IV: Varias 18. Instrucciones de Manipulación de bits de Registros del Sistema: JUEGO DE INSTRUCCIONES ¾ Grupo IV: Varias 19. Instrucciones de Modificación de los registros I con un dato inmediato con o sin bit inverso: 20. Operaciones PUSH y POP en las Pilas de Bucles y/o Estado: 21. Otras: 19 JUEGO DE INSTRUCCIONES ¾ Notación del Juego de Instrucciones JUEGO DE INSTRUCCIONES ¾ Condiciones y Códigos de Terminación (IF & DO UNTIL) 20 JUEGO DE INSTRUCCIONES JUEGO DE INSTRUCCIONES 21 JUEGO DE INSTRUCCIONES JUEGO DE INSTRUCCIONES 22 JUEGO DE INSTRUCCIONES JUEGO DE INSTRUCCIONES 23