2012
Capítulo 06.
Unidades operativas y
segmentación encauzada
Contenido
Copia de un segmento de la hoja de cálculo sirve de índice.
Unidades operativas
Ejercicio
Segmentación encauzada
Unidades operativas
El formato de una instrucción de 32 bits para el TM320C6713 es como sigue
etiqueta [condición∣condición] mnemónico .unidadOperativa oprandos ; comentarios
Nótese que en el formato de instrucción hay unos bits reservados para especificar la unidad operativa que va a ejecutar la instrucción. El TMS320C6713 consta de 8 unidades operativas, tal como ya se mencionó en capítulos anteriores. Estas 8 unidades pueden ser divididas en dos grupos de nominados “Register file” o simplemente fichero. Cada fichero consta de cuatro unidades. Esta distribución se ilustra en la figura 1. Un resumen de la denominación y funcionalidad de las unidades operativas puede verse en la tabla 6.1.
El archivo [SPRU733A], en su apéndice A contiene un listado de las instrucciones y de las unidades de ejecución respectivas a cada instrucción. Adicionalmente, el apéndice A contiene la cantidad de “Delay Slots”, también llamado “ciclos de ejecución” de cada instrucción.
A continuación se realizará una descripción de las unidades operativas correspondientes a algunas de las instrucciones que se han usado hasta el momento.
Tabla 6.1. Unidades funcionales y operaciones ejecutadas [SPRU733A]
Unidad funcional Operaciones en punto flotante Operaciones en punto fijo
Compare
.L unit (.L1, .L2) 32/40-bit arithmetic and compare operations Arithmetic operations
32-bit logical operations DP → SP, INT → DP, INT → SP con-version operations
Leftmost 1 or 0 counting for 32 bits Normalization count for 32 and 40 bits .S unit (.S1, .S2) 32-bit arithmetic operations
32/40-bit shifts and 32-bit bit-field operations REciprocal an reciprocal square-root operations
32-bit logical operations Absolute value operatios
Branches SP->DP conversion operations
Constant generation SP and DP adds and substracts Register transfers to/from control register file
(.S2 only)
SP and DP reverse substracts (src2-src1)
.M unit (.M1, .M2) 16 × 16-bit multiply operations Floating-point multiply operations 32 × 32-bit multiply operations Mixed-pr4cision multiply operations .D unit (.D1, .D2) 32-bit add, subtract, linear and circular
address calculation offset
Load double word with 5-bit constant offset.
Movimiento de constantes signadas a un registro
Sintaxis
MVKL .S1 cst,Ax MVKL .S2 cst,Bx
Delay slots
0
Ejemplo
.def _c_int00
cteA .set 0x04
.data
varA .int 0
.text
;A0<-cteA
_c_int00 MVKL .S1 cteA,A0 MVKH .S1 cteA,A0
;A3<-&varA
MVKL .S1 varA,A3 MVKH .S1 varA,A3
Saltos usando un desplazamiento
Sintaxis
B (.unit) label
.unit : .S1 ó .S2
Delay slots: 5
Lectura de un word desde memoria con un offset constante de 5 bits o un registro
offset
Sintaxis desde [SRPU733A]
LDW .unit *+baseR [ ucst5 ] , dst LDW .unit *++baseR [ ucst5 ] , dst LDW .unit *baseR ++ [ ucst5 ] , dst
LDW .unit *+baseR [ offsetR ] , dst LDW .unit *++baseR [ offsetR ] , dst LDW .unit *baseR ++ [ offsetR ] , dst
dst : Registro destino
ucst5 : constante sin signo de 5 bits
offsetR : Registro con un desplazamiento de 32 bits baseR : Registro puntero
.unit : .D1 ó .D2
Sintaxis
LDW .D1 *++Ax , Ax
LDW .D1 *Ax++ , Ax
LDW .D1 *+Ax[d] , Ax
LDW .D1 *++Ax[d] , Ax
LDW .D1 *Ax++[d] , Ax
LDW .D1 *+Ax[Ay] , Ax
LDW .D1 *++Ax[Ay] , Ax
LDW .D1 *Ax++[Ay] , Ax
Sintaxis
LDW .D2 *++Bx , Bx
LDW .D2 *Bx++ , Bx
LDW .D2 *+Bx [d] , Bx
LDW .D2 *++Bx [d] , Bx
LDW .D2 *Bx++ [d] , Bx
LDW .D2 *+Bx [By] , Bx
LDW .D2 *++Bx [By] , Bx LDW .D2 *Bx++ [By] , Bx
“d” es una constante numérica de 5 bits sin signo “x”=0..15
“y”=0..15
Escritura de un word a memoria con un offset constante de 5 bits o un registro offset
Sintaxis desde [SRPU733A]
STW .unit src , *+baseR [ ucst5 ]
STW .unit src , *++baseR [ ucst5 ]
STW .unit src , *baseR ++ [ ucst5 ]
STW .unit src , *+baseR [ offsetR ]
STW .unit src , *++baseR [ offsetR ]
STW .unit src , *baseR ++ [ offsetR ]
src : Registro fuente o con el contenido a transferir ucst5 : constante sin signo de 5 bits
offsetR : Registro con un desplazamiento de 32 bits baseR : Registro puntero
.unit : D1 ó .D2
Sintaxis
STW .D1 Ax , *++Ax
STW .D1 Ax , *Ax++
STW .D1 Ax , *+Ax [d]
STW .D1 Ax , *++Ax [d]
STW .D1 Ax , *Ax++ [d]
STW .D1 Ax , *+Ax [Ay]
STW .D1 Ax , *++Ax [Ay]
STW .D1 Ax , *Ax++ [Ay]
Sintaxis
STW .D2 Bx , *++Bx
STW .D2 Bx , *Bx++
STW .D2 Bx , *+Bx [d]
STW .D2 Bx , *++Bx [d]
STW .D2 Bx , *Bx++ [d]
STW .D2 Bx , *+Bx [By]
STW .D2 Bx , *++Bx [By]
STW .D2 Bx , *Bx++ [By]
“d” es una constante numérica de 5 bits sin signo “Ax”=A0..A15
“Ay”=A0..A15
Multiplicación de dos valores en punto flotante en precisión simple
Sintaxis desde [SPRU733A]
MPYSP .unit src1 , src2 , dst
src1 : registro del núcleo del DSP: A0..A15, B0..B15 src1 : registro del núcleo del DSP: A0..A15, B0..B15 dst : registro del núcleo del DSP: A0..A15, B0..B15 .unit : .M1 .M2
Delay slots : 4
Suma de dos valores en punto flotante en precisión simple
Sintaxis desde [SPRU733A]
ADDSP .unit src1 , src2 , dst
src1 : registro del núcleo del DSP: A0..A15, B0..B15 src1 : registro del núcleo del DSP: A0..A15, B0..B15 dst : registro del núcleo del DSP: A0..A15, B0..B15 .unit : .L1 .L2
Delay slots : 4
Resta de dos valores enteros
Sintaxis desde [SPRU733A]
SUB .unit src1 , src2 , dst ; dst <- src1 - src2
src1 : registro del núcleo del DSP: A0..A15, B0..B15 src1 : registro del núcleo del DSP: A0..A15, B0..B15 dst : registro del núcleo del DSP: A0..A15, B0..B15 .unit : .L1 .L2 .S1 .S2
Delay slots : 0
Ejercicio
;CONTRATO
; ENTRADA: Dos vectores de tres dimensiones en punto flotante ; SALIDA: El producto punto de los vectores
;************************************************
.def _c_int00
;Secciòn de variables
;************************************************ .data
vctA .float 1.0, 2.0, 3.0 ;Vector A vctB .float 2.0, 2.0, 2.0 ;Vector B
AB .float 0.0 ;Producto punto
.text _c_int00
;Inicializando el acumulador MVKL 0,A0
;A1 <- &vctA : Carga la direcciòn de la variable A (se realiza sin ciclos muertos) MVKL vctA,A1 ;Carga los 16 bits menos significativos del vector A.
MVKH vctA,A1 ;Carga los 16 bits mas significativos del vector A.
;A2 <- &vctB : Carga la dirección de la variable B (se realiza sin ciclos muertos) MVKL vctB,A2 ;Carga los 16 bits menos significativos del vector B.
MVKH vctB,A2 ;Carga los 16 bits mas significativos del vector B.
;Contador de productos MVKL 3,B0
;Multiplicando
_ciclo LDW *A1++[1],A3 ;A3 <- vctA[A1++1] NOP 4
LDW *A2++[1],A4 ;A4 <- vctA[A2++1] NOP 4
MPYSP A3,A4,A5 ;A3*A4->A5 ;Multiplica las dimensiones NOP 4
ADDSP A0,A5,A0 ;A0+A5->A0 ;Acumula el producto en el registro A NOP 4
;Decrementado el contador de productos SUB B0,1,B0
[B0] B _ciclo
NOP 6 ;Espera a que se ejecute el salto
;Almacenando el resultado
MVKL AB,A6 ;A6 <- &ABR MVKH AB,A6
STW A0,*A6 ;AB[A6] <- A0
;Ciclo para detener al micro
_fin B _fin
NOP 6
La tubería de ejecución del C67
El paquete de búsqueda
Considere esto, el C67 tiene 8 unidades operativas con las cuales puede ejecutar hasta instrucciones en paralelo. Ahora bien, para lograr alimentar las 8 unidades operativas, el C67 debe traer de memoria 8 instrucciones de 32 bits en una sola operación de lectura. Estas 8 instrucciones es lo que se llama “fetch packet” o paquete de búsqueda. La figura 6.3 ilustra.
Procesamiento por lotes contra procesamiento encauzado
En general, el procesamiento de una instrucción requiere de varias etapas, básicamente esta son:
• “Fetch”: Recuperar una instrucción desde memoria de programa.
• “Decode”: La decodificación de la instrucción implica la configuración de las unidades operativas y los buses.
• “Execute”: Ejecución del código de operación.
Un procesador por lotes procesa una instrucción ejecutando paso tras paso de tal forma que tres instrucciones requieren de 9 ciclos. La tabla 6.1 ilustra este proceso.
A diferencia, en un procesador encauzado (en inglés se escribe “pipelined”), las instrucciones se procesan como en una linea de montaje, es decir, el proceso de una instrucción está dividido en etapas independientes que trabajan en paralelo: cada etapa del procesamiento de una instrucción es atendida por un circuito diferente, cada etapa recibe una entrada y la salida la pasa a la siguiente etapa. La tabla 6. 2 ilustra como trabaja un procesador encauzado.
Etapa de “fetch” del C67
En el C67 la etapa “Fetch” requiere de cuatro subetapas, cada una se ejecuta en un ciclo de reloj. Esta etapa se subdivide como sigue:
• F1: generar la dirección de búsqueda • F2: enviar la dirección a memoria • F3: esperar por el dato
• F4: Leer el código de operación de la memoria y empaquetar en el “fetch packet”
Etapa de “decoding” del C67
Para poder ilustrar un poco lo que se hace en esta etapa, considere la ALU de la figura 6.4.a Toda operación requiere que los operandos estén almacenados en registros y el resultado de la operación se almacena en otro registro.
• D1: La instrucción se recupera del “fetch packed”
• D2: Según indica el código de operación, se forman las rutas que conectan físicamente los registros con la ALU. Observe la figura 6.4.b
Etapa de ejecución del C67
La etapa de “Execution” puede requerir desde una subetapa hasta seis subetapas, dependiendo de la instrucción a ejecutar. Así entonces, esta etapa se subdivide en E1, E2, E3, E4, E5, E6. Las etapas E2 a E6 se llaman retardos. En la última subetapa de ejecución se escribe la salida de la ALU en el registro destino.
Tabla 6.2 Segmentación por lotes contra segmentación encauzada
F1 D1 E1 F2 D2 E2 F3 D3 E3
F1
F2
F3
D1
D2
D3
E1
E2
E3
T1 T2 T3 T4 T5 T6 tiempo
Segmentación por lotes
Segmentación en-cauzada
Ejemplos de otras instrucciones son:
• La instrucción MPY para multiplicar enteros toma un retardo, es decir, implicará a las subetapas E1 y E2. Es en la subetapa E2 que se escribe el resultado del producto.
• La instrucción LDH para leer datos desde memoria a un registro, toma 3 retardos, es decir, implicará a las subetapas E1, E2, E3 y E4. Es en la subetapa E4 que se escribe el dato en tal registro.
• La instrucción B tomará 5 retardos, es decir, implicará a las subetapas E1 a E6. Es en la subetapa E6 que se actualiza el registro con la dirección de la próxima instrucción a ejecutar.
Una consecuencia de que la cantidad de subetapas de ejecución sea diferente para cada instrucción implica que el C67 puede comenzar la ejecución de otra instrucción sin haber terminado la ejecución de la instrucción anterior, esto se llama “ejecución desordenada”. Considere el caso siguiente, dadas dos instrucciones consecutivas en las cuales, el operando de la segunda es el resultado de ejecución de la primera, el C67 podría ejecutar la segunda instrucción sin tener listo el operando.
Ejemplo de ejecución de un código
En este ejemplo se pretende multiplicar os variables y almacenar el producto en una tercer variable. Para realizar debe seguirse el siguiente algoritmo
• Recupera el valor de la variable varA en el registro A3 • Recupera el valor de la variable varB en el registro A4 • Multiplica los registros: A5←A3×A4
• Acumula el producto en el registro A0: A←A0×A5
• Copia el contenido del registro A0 en la variable varC
La tabla 6.3 ilustra el código así como los tiempos de procesamiento de cada insturcción.
Para recuperar el valor de la variable varA en el registro A3 se requieren de dos pasos:
A1← &varA A3←∗A1
El respectivo código con sus ciclos es entonces:
Las dos primeras lineas recuperan la dirección de la variable varA en el registro A1 .Note que este proceso termina en el instante T8 . La tercer linea, que debe usar el registro A1 como puntero a la variable varA ,
.def .data
.float 1.0 .float 2.0 .float 0.0
.text T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 T16 T17 T18
MVKL A1 F1 F2 F3 F4 D1 D2 E1
MVKH A1 F1 F2 F3 F4 D1 D2 E1
LDW *A1 A3 F1 F2 F3 F4 D1 D2 E1 E2 E3 E4 E5
MVKL A2 F1 F2 F3 F4 D1 D2 E1
MVKH A2 F1 F2 F3 F4 D1 D2 E1
LDW *A2 A4 F1 F2 F3 F4 D1 D2 E1 E2 E3 E4 E5
MPYSP A3 A4 A5 F1 F2 F3 F4 D1 D2 E1 E2 E3 E4 E5 ADDSP A0 A5 A0 F1 F2 F3 F4 D1 D2 E1 E2 E3 E4 E5
MVKL A1 F1 F2 F3 F4 D1 D2 E1
MVKH A1 F1 F2 F3 F4 D1 D2 E1
STW A0 *A1 F1 F2 F3 F4 D1 D2 E1
.end
Tabla 6.3. Código para multiplicar dos variables y acumular el producto. '_c_int00 varA varB varC '_c_int00 varA varA varB varB varC varC
T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13
MVKL A1 F1 F2 F3 F4 D1 D2 E1
MVKH A1 F1 F2 F3 F4 D1 D2 E1
LDW *A1 A3 F1 F2 F3 F4 D1 D2 E1 E2 E3 E4 E5
El respectivo código con sus ciclos es entonces:
Note que la instrucción anterior tiene listo el operando en el registro A4 en el instante T16 . En tanto la instrucción de multiplicación empieza su ejecución en el instante T13 , es decir, algunos instantes atrás. La consecuencia es obvia, al finalizar el programa no se tendrá el resultado esperado.
Una forma de arreglar la falta de sincronización entre la instrucción LDW y la instrucción MPYSP es agregando ciclos “NOP” de tal forma que se retarde la ejecución de la instrucción MPYSP.
El paso siguiente es acumular el producto en el registro A0 , es decir
A5←A0+A4
El respectivo código con sus ciclos es entonces:
Puede notarse que la multiplicación tendrá listo el operando en el registro A5 hasta el instante T17 , no obstante, la instrucción ADDSP comienza su ejecución en el instante T14 . A consecuencia, la operación de acumulación funcionará con los operandos equivocados.
En conclusión, puede notarse en todo el código que las instrucciones tienen una dependencia con instrucciones anteriores debido a los operandos. Para sobrellevar estos problemas puede recurrirse a dos estrategias:
• Agregar ciclos de espera NOP
• Reacomodar las instrucciones en un orden que permita reducir los ciclos de espera NOP.
La tabla 6.4 contiene el código ya corregido mediante la inserción de ciclos de espera “NOP”. El respectivo análisis de tiempos de cada instrucción ya está incluido a la derecha del código: podrá notarse que se han agregado 10 ciclos de espera.
Note en el código de la tabla 6.4, que cada instrucción “NOP” es equivalente a varias lineas de código que hacen nada.
T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 T16 LDW *A2 A4 F1 F2 F3 F4 D1 D2 E1 E2 E3 E4 E5
MPYSP A3 A4 A5 F1 F2 F3 F4 D1 D2 E1 E2 E3 E4
.def .data
.float 1.0
.float 2.0
.float 0.0
.text T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 T16 T17 T18 T20 T21 T22 T23 T24 T25 T26 T27
MVKL A1 F1 F2 F3 F4 D1 D2 E1
MVKH A1 F1 F2 F3 F4 D1 D2 E1
LDW *A1 A3 F1 F2 F3 F4 D1 D2 E1 E2 E3 E4 E5
MVKL A2 F1 F2 F3 F4 D1 D2 E1
MVKH A2 F1 F2 F3 F4 D1 D2 E1
LDW *A2 A4 F1 F2 F3 F4 D1 D2 E1 E2 E3 E4 E5
NOP 4 F1 F2 F3 F4 D1 D2 F1 F2 F3 F4 D1 D2
F1 F2 F3 F4 D1 D2 F1 F2 F3 F4 D1 D2
MPYSP A3 A4 A5 F1 F2 F3 F4 D1 D2 E1 E2 E3 E4 E5
NOP 4 4 F1 F2 F3 F4 D1 D2
F1 F2 F3 F4 D1 D2 F1 F2 F3 F4 D1 D2
F1 F2 F3 F4 D1 D2
ADDSP A0 A5 A0 F1 F2 F3 F4 D1 D2 E1 E2 E3 E4 E5
NOP 2 F1 F2 F3 F4 D1 D2 F1 F2 F3 F4 D1 D2
MVKL A1 F1 F2 F3 F4 D1 D2 E1
MVKH A1 F1 F2 F3 F4 D1 D2 E1
STW A0 *A1 F1 F2 F3 F4 D1 D2
.end
Bibliografía
[Nasser]
TMS320C67x/C67x+DSP CPU and Instruction SetReference Guide
Nasser Kehtarnavaz, Namjin Kim, “Real Time Sigital Signal processing base on the TMS320C6000”, Elsevier, 2005
Los números de versión
Tercer número
Correcciones ortográficas
Las definiciones, teoremas y demás proposiones se mantienen sin alterar
Total compatibilidad
Segundo número
Correcciones de algunas definiciones, teoremas, etc.
se agregan definiciones y teoremas
La compatibilidad con versiones anteriores es parcial
Primer número
Se está cambiando el contexto del archivo:
Se cambia de editor de textos