Universidad de Costa Rica Facultad de Ingeniería Escuela de

Anuncio
Universidad de Costa Rica
Facultad de Ingeniería
Escuela de Ingeniería Eléctrica
Procedimiento de diseño e implementación de circuitos digitales utilizando herramientas EDA de
código abierto
Por:
Gerardo Castro Jiménez
Ciudad Universitaria Rodrigo Facio
Junio del 2008
Procedimiento de diseño e implementación de circuitos digitales utilizando herramientas EDA de
código abierto
Por:
Gerardo Castro Jiménez
Sometido a la Escuela de Ingeniería Eléctrica
de la Facultad de Ingeniería
de la Universidad de Costa Rica
como requisito parcial para optar por el grado de:
LICENCIADO EN INGENIERÍA ELÉCTRICA
Aprobado por el Tribunal:
_________________________________
Ing. Enrique Coen Alfaro, M.Sc.
Representante del Director, Escuela de Ingeniería Eléctrica
_________________________________
Ing. Randolph Steinvorth Fernández, PhD.
Director, Comité Asesor
_________________________________
Ing. Jorge Romero Chacón, PhD.
Miembro, Comité Asesor
Director, Escuela de Ingeniería Eléctrica
_________________________________
Lic. Roberto Rodríguez Rodríguez
Miembro, Comité Asesor
_________________________________
Ing. José Luis López Sauma, M.Sc.
Miembro del Tribunal
ii
DEDICATORIA
A Dios por guiarme y por ser la luz de mi camino.
A mi familia por estar siempre conmigo, por su apoyo y ser incondicionales.
A mis amigos por las experiencias que hemos vivido.
“Creo más en la imaginación que en el conocimiento”
iii
RECONOCIMIENTOS
A todos los educadores y personas que invirtieron tiempo valioso de sus vidas para transmitirme sus conocimientos y experiencias.
Este trabajo es el reflejo de todo lo que me enseñaron.
Que Dios los bendiga.
iv
ÍNDICE GENERAL
ÍNDICE DE FIGURAS................................................................................ viii
ÍNDICE DE TABLAS......................................................................................x
NOMENCLATURA........................................................................................xi
RESUMEN.................................................................................................... xiii
CAPÍTULO 1: Introducción ...........................................................................1
1.1
1.2
Alcances..................................................................................................................1
Objetivos.................................................................................................................1
1.2.1
Objetivo general..............................................................................................1
1.2.2
Objetivos específicos ......................................................................................1
1.3
Justificación ............................................................................................................1
1.4
Planteamiento del problema....................................................................................2
1.5
Metodología ............................................................................................................3
CAPÍTULO 2: Desarrollo teórico ..................................................................6
2.1 Historia y estado del arte de los FPGAs ...........................................................................6
2.2 Antecedentes en la UCR ...................................................................................................6
2.3 FPGAs...............................................................................................................................7
2.4 Flujo de diseño mediante FPGAs utilizando las herramientas de Xilinx .......................11
2.5 Introducción a la codificación de predicción lineal (LPC) de la voz humana................14
CAPÍTULO 3: Planteamiento de un procedimiento basado en
herramientas de código abierto ....................................................................17
CAPÍTULO 4: Diseño del codificador/decodificador de voz.....................21
4.1 Descripción general ........................................................................................................21
4.2 Componentes ..................................................................................................................21
4.3 Diagrama de estados general ..........................................................................................23
4.4 Descripción de los circuitos digitales .............................................................................25
4.5 Arquitectura de las máquinas de estado y de la asignación de registros ........................28
4.5.1 Protocolo de comunicación entre circuitos..........................................................28
4.5.2 Protocolo de cambio de estado y asignación de estado .......................................29
CAPÍTULO 5: Compilación y Simulación Funcional ................................30
5.1
5.2
Descripción en Verilog .........................................................................................30
Etapa de Compilación y Simulación Funcional....................................................32
5.2.1
Simulación funcional ....................................................................................32
v
CAPÍTULO 6: Síntesis en Icarus Verilog....................................................36
6.1
6.2
Descripción del proceso de síntesis con Icarus Verilog .......................................36
Descripción del proceso de síntesis para la arquitectura Virtex ...........................37
6.2.1
Características del sintetizador de Icarus Verilog.........................................37
6.2.2
Verilog sintetizable para la arquitectura Virtex ............................................39
6.2.3
Adición de parámetros y restricciones en el proceso de síntesis para la
arquitectura Virtex ........................................................................................................47
CAPÍTULO 7: Implementación, Programación y Simulaciones postimplementación...............................................................................................50
7.1 Proceso de implementación ...........................................................................................50
Proceso de Traducción: Translate.................................................................................50
7.1.2 Proceso de Mapeo: Map ......................................................................................52
7.1.3 Proceso de Posicionamiento y Enrutamiento: Place and Route ..........................54
7.1.4
Programación del FPGA y pruebas en circuito ............................................55
CAPÍTULO 8: Conclusiones y recomendaciones .......................................56
BIBLIOGRAFÍA............................................................................................58
APÉNDICE A: Diagrama de estados de los circuitos ................................60
A.1 Controlador A/D ............................................................................................................60
A.1.1 Registros: ............................................................................................................60
A.1.2 Diagrama de Estado: ...........................................................................................60
A.2 Controlador D/A ............................................................................................................61
A.2.1 Registros: ............................................................................................................61
A.2.2 Diagrama de Estado: ...........................................................................................61
A.3 Controlador de Memoria................................................................................................62
A.3.1 Registros: ............................................................................................................62
A.3.2 Diagrama de Estado: ...........................................................................................63
A.4 Controlador de Reproducción ........................................................................................64
A.4.1 Registros .............................................................................................................64
A.4.2 Diagrama de Estado ............................................................................................64
A.5 Controlador de Codificación..........................................................................................66
A.5.1 Registros .............................................................................................................66
A.5.2 Diagrama de Estado ............................................................................................67
A.6 Sonido con/sin Voz ........................................................................................................69
A.6.1 Registros .............................................................................................................69
A.6.2 Diagrama de Estado ............................................................................................70
A.7 Detección del Pitch ........................................................................................................71
A.7.1 Registros .............................................................................................................72
A.7.2 Diagrama de Estado ............................................................................................72
A.8 Coeficientes R ................................................................................................................74
vi
A.8.1 Registros .............................................................................................................74
A.8.2 Diagrama de Estado ............................................................................................75
A.9 Coeficientes LPC ...........................................................................................................76
A.9.1 Registros .............................................................................................................76
A.9.2 Diagrama de Estado ............................................................................................77
A.10 Filtro de Análisis..........................................................................................................79
A.10.1 Registros ...........................................................................................................79
A.10.2 Diagrama de Estado ..........................................................................................80
A.11 Filtro de Síntesis ..........................................................................................................82
A.11.1 Registros ...........................................................................................................82
A.11.2 Diagrama de Estado ..........................................................................................83
A.12 Sumador/Restador........................................................................................................85
A.12.1 Registros ...........................................................................................................85
A.12.2 Diagrama de Estado ..........................................................................................85
A.13 Multiplicador................................................................................................................87
A.13.1 Registros ...........................................................................................................87
A.13.2 Diagrama de Estado ..........................................................................................87
A.14 Divisor..........................................................................................................................88
A.14.1 Registros ...........................................................................................................88
A.14.2 Diagrama de Estado ..........................................................................................88
A.15 Raíz Cuadrada..............................................................................................................89
A.15.1 Registros ...........................................................................................................89
A.15.2 Diagrama de Estado ..........................................................................................90
APÉNDICE B: Modelos Matemáticos y Algoritmos de LPC ....................92
APÉNDICE C: Código en Matlab, equivalente en Software del circuito
diseñado...........................................................................................................96
APÉNDICE D: Problemas de temporización durante la etapa de
implementación.............................................................................................102
D.1 Problema de convergencia de la arquitectura microprogramada .................................102
D.2 Problema de alineación entre relojes ...........................................................................103
APÉNDICE E: Guía del procedimiento de diseño e implementación de
circuitos digitales utilizando herramientas EDA de código abierto........106
vii
ÍNDICE DE FIGURAS
Figura 1.1: Flujo de diseño e implementación mediante FPGAs [8] ...................................3
Figura 1.2: Metodología de diseño .....................................................................................4
Figura 2.1: Diagrama de un FPGA [8] .................................................................................7
Figura 2.2: Estructuras de FPGAS [8]..................................................................................8
Figura 2.3: Estructuras de CLB [8] ......................................................................................8
Figura 2.4: Líneas de interconexión [9] ...............................................................................9
Figura 2.5: Fabricantes de FPGAs [8] ................................................................................10
Figura 2.6: Flujo de diseño mediante FPGAs [8] ...............................................................11
Figura 2.7: Modelo del tracto vocal [3] ..............................................................................14
Figura 2.9: Esquema de decodificación LPC [3] ...............................................................16
Figura 3.1 Flujo de diseño basado en herramientas EDA de código abierto....................18
Figura 4.1 Diagrama de bloques del diseño......................................................................23
Figura 4.2 Diagrama de estado general del diseño ...........................................................24
Figura 4.3 Arquitectura de la asignación de registros ......................................................28
Figura 4.4 Protocolo de comunicación entre los circuitos................................................29
Figura 4.5 Protocolo de cambio de estado y asignación de estado..................................29
Figura 5.1 Estructura de la descripción en Verilog para los circuitos diseñados ............30
Figura 5.2 Estructura jerárquica establecida para el proyecto .........................................31
Figura 5.3 Esquema jerárquico para simulación funcional...............................................32
Figura 5.4 Simulación funcional del controlador de memoria DRAM en GTKWave ....33
Figura 5.5 Simulación funcional del divisor de 32bits ....................................................34
Figura 5.6 Simulación funcional del codificador/decodificador de voz en GTKWave...35
Figura 6.1 Proceso de Síntesis con Icarus Verilog ..........................................................36
Figura 6.2 Archivo EDIF para multiplexor 4 a 1 (if-else) ................................................43
Figura 6.3 Esquemático del archivo de síntesis para multiplexor 4 a 1 (if-else) ..............43
Figura 6.4 Archivo EDIF, sección para multiplexor 4 a1 (case) .....................................44
viii
Figura 6.5 Esquemático del archivo de síntesis para multiplexor 4 a 1 (case) .................44
Figura 6.6 Esquemático de celdas de tipo PAD en la arquitectura Virtex........................48
Figura 7.1 Resumen de recursos utilizados en el FPGA, circuito completo ....................54
Figura 7.2 Reporte final de relojes del WebPack, circuito completo ...............................54
Figura 6. Filtro de análisis de voz.....................................................................................94
Figura 7. Filtro IIR todo polos para síntesis de voz..........................................................94
Figura D.1 Arquitectura microprogramada ....................................................................102
Figura D.2 Arquitectura one-hot.....................................................................................103
Figura D.3 Diagrama temporal, problema de alineación de relojes ...............................104
Figura D.4 Diagrama temporal, solución al problema de alineación de relojes .............105
ix
ÍNDICE DE TABLAS
Tabla 4.1 Circuitos diseñados para el codificador/decodificador de voz .........................22
Tabla 5.1 Nombre de los módulos en Verilog para cada circuito....................................31
Tabla 6.1 Celdas de la librería Virtex que maneja Icarus Verilog....................................40
Tabla A.1 Diagrama de Estado del Controlador A/D.......................................................61
Tabla A.2 Diagrama de Estado del Controlador D/A.......................................................62
Tabla A.3 Diagrama de Estado del Controlador de Memoria ..........................................64
Tabla A.4 Diagrama de Estado del Controlador de Reproducción...................................66
Tabla A.5 Diagrama de Estado del Controlador de Codificación ....................................69
Tabla A.6 Diagrama de Estado de Sonido con/sin Voz....................................................71
Tabla A.7 Diagrama de Estado de Detección del Pitch....................................................74
Tabla A.8 Diagrama de Estado de Coeficientes R............................................................76
Tabla A.9 Diagrama de Estado de Coeficientes LPC.......................................................79
Tabla A.10 Diagrama de Estado del Filtro de Análisis ....................................................82
Tabla A.11 Diagrama de Estado del Filtro de Síntesis .....................................................85
Tabla A.12 Diagrama de Estado del Sumador/Restador ..................................................87
Tabla A.13 Diagrama de Estado del Multiplicador ..........................................................88
Tabla A.14 Diagrama de Estado del Divisor ....................................................................89
Tabla A.15 Diagrama de Estado de la Raíz Cuadrada......................................................91
x
NOMENCLATURA
CLB Configurable Logic Block – Bloque Lógico Configurable
CMOS Complementary Metal Oxide Semiconductor – Semiconductor de Óxido Metálico Complementario
EDA Electronic Design Automation - Automatización del Diseño Electrónico
EDIF Electronic Design Interchange Format - Formato de Intercambio de Diseño
Electrónico
EEPROM Electric Erasable Programmable Read Only Memory - Memoria de Solo
Lectura Eléctricamente Borrable
EPROM Erasable Programmable Read Only Memory – Memoria de Solo Lectura
Borrable
FPGA Field Programmable Gate Array - Arreglo de Puertas Programables por
Campo
FPLA Field Programmable Logic Array – Arreglo de Lógica Programable por
Campo
GAL Gate Array Logic – Arreglo de Puertas Lógicas
HDL Hardware Description Language – Lenguaje de Descripción de Hardware
IIR Infinite Impulse Response – Respuesta Infinita al Impulso
IOB Input/Output Block - Bloque Entrada/Salida
LPC Linear Prediction Coding – Codificación por Predicción Lineal
LPM Library of Parameterized Modules – Librería de Módulos Parametrizable
PAL Programmable Array Logic – Arreglo de Lógica Programable
PCM Pulse Code Modulation – Codificación por modulación de pulsos
xi
PEEL Programmable Electric Erasable Logic – Lógica Programable Eléctricamente Borrable
PLD Programmable Logic Device – Dispositivo Lógico Programable
RAM Random Access Memory – Memoria de Acceso Aleatorio
VLSI Very Large Scale Integration – Integración a Escala Muy Alta
xii
RESUMEN
Este trabajo presenta un procedimiento de diseño e implementación
de circuitos digitales utilizando herramientas de código abierto. Para
su desarrollo se utilizó el diseño de un codificador/decodificador de
voz. Como herramientas de código abierto se emplearon Icarus Verilog como simulador y sintetizador en HDL Verilog y GTKWave
como visor de ondas en combinación con la herramienta propietaria
WebPack de Xilinx. Se describieron en Verilog un conjunto de circuitos digitales de forma conductual y jerárquica que utilizaban codificación predictiva lineal para codificar y decodificar la voz. Se
realizaron simulaciones funcionales y con Icarus Verilog se sintetizó
el circuito completo para la arquitectura Virtex de Xilinx. La implementación se realizó para un FPGA SPARTAN3E de Xilinx. Se programó físicamente el circuito diseñado con resultados de
funcionamiento exitosos. Durante este proceso se revelaron las capacidades y limitaciones de las herramientas de código abierto. Como
resultado se obtiene una guía detallada del procedimiento para que
sea utilizada en trabajos futuros y en cursos en la Universidad.
Se concluye que el procedimiento y las herramientas tienen la capacidad suficiente para el desarrollo de circuitos digitales, pero se recomienda completar y mejorarlas para que el procedimiento sea más
robusto.
xiii
CAPÍTULO 1: Introducción
1.1 Alcances
En este proyecto se presenta un procedimiento de diseño e implementación de circuitos digitales utilizando herramientas EDA de código abierto.
El procedimiento se desarrolló a través de una aplicación de procesamiento digital de
señales. La aplicación que se seleccionó fue un codificador/decodificador de voz, cuyo diseño parte del modelo teórico de predicción lineal de la voz humana. No constituyó un objetivo de este proyecto el analizar u optimizar el algoritmo utilizado ya que
este fue únicamente un vehículo para demostrar el procedimiento de diseño que se
presenta.
Se utiliza Verilog, como lenguaje de descripción de hardware estándar, para describir
la arquitectura del circuito digital.
Las etapas de compilación, simulación y síntesis se realizaron mediante herramientas
EDA de código abierto y con formatos estándar que permiten intercambiar la información con otras herramientas disponibles en la industria. Las herramientas EDA de
código abierto están disponibles al público en general sin costo alguno. Esto constituye la base del procedimiento y su principal distinción.
Se obtuvo un circuito digital en el FPGA: SPARTAN3E de Xilinx como resultado final del procedimiento desarrollado.
1
1.2 Objetivos
1.2.1
Objetivo general
Desarrollar un procedimiento de diseño e implementación de circuitos digitales basa-
do en herramientas EDA de código abierto, utilizando como ejemplo un codificador/decodificador de voz
1.2.2
•
Objetivos específicos
Diseñar la arquitectura de un circuito digital que realice en hardware el algoritmo de
codificación/decodificación de voz a partir del método de codificación de predicción lineal de la voz humana.
•
Describir el circuito digital del codificador/decodificador de voz mediante el lenguaje de descripción de hardware Verilog.
•
Utilizar herramientas de código abierto de uso general que permitan construir el circuito digital en cualquier dispositivo independientemente del fabricante del mismo.
•
Establecer la etapa de síntesis del procedimiento de diseño para que se pueda programar en el FPGA SPARTAN3E de Xilinx.
•
Verificar mediante pruebas cualitativas que el circuito programado en el FPGA realiza el algoritmo de codificación de voz utilizado.
•
Documentar el procedimiento de diseño propuesto para que pueda ser utilizado ampliamente y permita profundizar en el estudio de los dispositivos lógicos programables.
1.3 Justificación
El proyecto surgió a partir de la dependencia que tiene el flujo de diseño e implementación en FPGAs de Xilinx. El flujo actual utiliza herramientas y formatos
propietarios del fabricante limitando así la portabilidad de los diseños a otras plataformas. Esto motivó a buscar un procedimiento que utilice herramientas EDA de có1
2
digo abierto y formatos estándar de la industria que lograra obtener mayor flexibilidad. Con el uso de herramientas EDA de código abierto se obtiene independencia del
fabricante y libertad para modificar y mejorar sus capacidades por parte de la Universidad de Costa Rica. Los formatos estándar, que no dependen del fabricante, permiten
que el diseño se pueda transportar a otras marcas o tipos de dispositivos programables
y hasta a VLSI. Está claro que existen etapas del flujo que siempre van a depender de
la marca del dispositivo pero lograr una independencia en la mayoría de las fases es
el principio para diseñar e implementar en cualquier tipo y marca de dispositivo programable.
Por otro lado, las ventajas que presentan los FPGAs en el diseño de circuitos digitales
y su potencial a nivel académico, se ve limitado por los pocos proyectos realizados en
la Universidad de Costa Rica. Esta situación genera la necesidad de ampliar la documentación y profundizar en este campo. La documentación de este procedimiento dará una mayor referencia y podría ser de utilidad para futuros proyectos de graduación
y cursos en la Universidad en esta área.
1.4 Planteamiento del problema
El flujo de diseño e implementación general de un circuito digital FPGA consiste del diagrama de bloques mostrado a continuación [8]:
3
Figura 1.1: Flujo de diseño e implementación mediante FPGAs [8]
Actualmente todas las etapas del proceso se realizan mediante el conjunto de
herramientas EDA de Xilinx conocidas como: ISE Webpack (versión gratuita con limitaciones) o ISE Foundation (versión completa). Estas herramientas están orientadas
hacia dispositivos FPGA de esta marca por lo que no son útiles para otras plataformas, esto hace que el flujo sea poco flexible. Durante el proceso se crean y se utilizan
archivos con formatos propietarios de Xilinx, lo cual impide se puedan utilizar en
otro tipo de herramientas o aplicaciones. Es decir que etapas ya realizadas se volverán
a repetir si se cambia de plataforma.
Por otro lado, la poca documentación que se encuentra acerca de la utilización
de FPGAs como método para implementar circuitos digitales, provoca que los dispositivos no se puedan utilizar en los cursos impartidos en la Universidad ya que no se
tiene la suficiente experiencia en el uso de ellos.
1.5 Metodología
4
Para cumplir con los objetivos planteados, se contó con las herramientas de código libre Icarus Verilog y GTK Wave. Icarus Verilog es un simulador de Verilog y
sintetizador [17] y GTK Wave se utilizó para análisis temporal [16].
La metodología constó de 7 etapas que se enuncian a continuación:
1. A partir del método de predicción lineal para codificación de la voz, se extrajo
las especificaciones arquitectónicas y elementos básicos para el diseño del codificador/decodificador de voz.
2. Con base en las fórmulas del modelo matemático se construyeron los módulos
en Verilog que describían el circuito digital. Se utilizó la metodología que se
muestra en la figura 2, donde se define el circuito completo y dentro de este se
encuentran circuitos complejos que a su vez contienen circuitos sencillos.
Figura 1.2: Metodología de diseño
3. Cada circuito simple pasó por una simulación funcional en Icarus Verilog y un
análisis temporal mediante GTKWave.
4. Obtenida una descripción funcional en Verilog de los circuitos simples, estos
se sintetizaron en el formato estándar EDIF mediante Icarus Verilog y se implementaron mediante la herramienta ISE Webpack de Xilinx.
5. Al finalizar este proceso para cada circuito simple, se continuó con los circuitos complejos que pasaron por las etapas 3 y 4. De esta forma el procedimiento se ejercitó en cada iteración.
5
6. Finalmente, el circuito completo formado por los circuitos complejos y sencillos se sometió a las etapas 3 y 4, donde se obtuvo una síntesis general del circuito.
7. Seguidamente, se hizo la programación del circuito completo en el FPGA,
donde se realizaron las pruebas en circuito. SPARTAN3E de Xilinx fue el
FPGA utilizado el cual se encontraba disponible en la bodega de la Escuela de
Ingeniería Eléctrica.
8. Finalmente, se documentó el procedimiento en forma de guía, donde se detalla
cada etapa.
CAPÍTULO 2: Desarrollo teórico
2.1 Historia y estado del arte de los FPGAs
En 1984, Ross Freeman funda Xilinx y crea el circuito del tipo FPGA, distinto de
otros dispositivos lógicos programables (PLD). Estos circuitos tuvieron un gran éxito en el
mercado y permitieron el desarrollo de la que hoy es empresa líder del sector de FPGAs [7].
Por otra parte, en esta época se fundaron otras dos empresas. Atmel se fundó en 1984,
fabricando PLDs y FPGAs [7]. Actel se fundó en 1985, desarrollando FPGAs con tecnología
basada en antifusibles y convirtiéndose en los líderes de esta tecnología desde 1994, presentando además la segunda cuota más grande del mercado de FPGAs [7]. Por su parte, Altera también introdujo circuitos del tipo FPGA, de arquitectura cuadrícula, siendo
actualmente el tercer fabricante en cuota de mercado [7].
Actualmente, los fabricantes introducen mejoras en las nuevas FPGAs como [7]:
•
Reconfiguración parcial en el sistema (“Field partial reconfiguration”), es decir, de
sólo una parte de la FPGA, en lugar de su totalidad como es habitual actualmente.
•
Incremento de la capacidad lógica, es decir, mayor número de puertas lógicas equivalentes.
•
Incremento de la capacidad de interconexión y disminución de los retardos de propagación, con el fin de alcanzar un mayor aprovechamiento de la capacidad de lógica y aumento en la velocidad del FPGA.
2.2 Antecedentes en la UCR
Los trabajos realizados en la Universidad de Costa Rica en el área de los dispositivos
lógicos programables no son muchos. Se ha sintetizado e implementado la CPUCR [2] [5], un
filtro digital
[4]
y un probador de escaneo controlado por una PC para realizar pruebas es-
tructurales a microprocesadores [1]. Para el desarrollo de todas estas aplicaciones se han utilizado PLD’s de la marca Xilinx modelo SPARTAN2E. Como herramienta principal EDA
6
7
se ha utilizado ISE Webpack del fabricante en combinación con algunas otras herramientas
propietarias como Verilogger y ModelSim.
2.3 FPGAs
Un FPGA es un dispositivo lógico programable o PLD (“Programmable Logic Device”),
cuyas características pueden ser modificadas y almacenadas mediante programación [9]. Poseen una estructura interna formada por: matriz de bloques lógicos configurables CLB
(“Configurable Logic Block”) que se comunican entre sí y con los bloques de Entrada/Salida I/OB (“Input/Output Block”) a través de canales de ruteo horizontal.
Figura 2.1: Diagrama de un FPGA [8]
Estructura de una FPGA
Dependiendo del fabricante se pueden encontrar diferentes soluciones. Las FPGAs
que existen actualmente en el mercado, dependiendo de la estructura que adoptan los bloques lógicos que tengan definidos, se pueden clasificar como pertenecientes a cuatro grandes familias [9]:
1. Matriz Simétrica (“Symmetrical Array”).
2. Basada en Filas (“Row Based”).
3. Mar de puertas (“Sea-of-Gates”).
4. PLDs Jerárquicos (Hierarchical PLD).
8
Figura 2.2: Estructuras de FPGAS [8]
CLBs: Bloques Lógicos Configurables
Cada CLB presenta una sección de lógica combinacional programable y registros de
almacenamiento:
Figura 2.3: Estructuras de CLB [8]
Los registros de almacenamiento sirven como herramientas en la creación de lógica
secuencial. La sección de lógica combinacional suele consistir en una LUT (“Look Up Table”), que permite implementar cualquier función booleana a partir de sus variables de entrada. Se presentan también multiplexores y conmutadores, como elementos adicionales de
direccionamiento de los datos del CLB, los cuales permiten variar el tipo de salidas (com-
9
binacionales o registradas), facilitan caminos de realimentación, o permiten cambiar las entradas de los biestables.
Bloques entrada/Salida (I/OBs)
La periferia del FPGA está constituida por bloques de entrada/salida configurables
por el usuario. Cada bloque puede ser configurado independientemente para funcionar como entrada, salida o bidireccional, admitiendo también la posibilidad de control triestado.
Los IOBs pueden configurarse para trabajar con diferentes niveles lógicos (TTL,
CMOS,…). Además, cada IOB incluye flip-flops que pueden utilizarse para registrar tanto
las entradas como las salidas.
Líneas de interconexión
Constituyen un conjunto de caminos que permiten conectar las entradas y salidas de
los diferentes bloques. Están constituidas por líneas metálicas de dos capas que recorren
horizontal y verticalmente las filas y columnas existentes entre los CLBs.
Dos elementos adicionales participan activamente en el proceso de conexión:
Puntos de Interconexión Programable PIP (“Programmable Interconnection Point”)
que permiten la conexión de CLBs e IOBs a líneas metálicas cercanas.
Matrices de interconexión SW (“ Switch Matrix o Magic Box”) que son dispositivos de conmutación distribuidos de forma uniforme por la FPGA.
Figura 2.4: Líneas de interconexión [9]
Los diferentes modelos comerciales se diferencian en [8]:
•
Arquitectura: Gate Array (Filas), Mar de puertas, Matriz simétrica.
•
Tipo de CLB: Puertas lógicas, multiplexores, tabla de búsqueda (LUT).
10
•
Arquitectura de las interconexiones: Canales de routing, red de interconexión.
•
Tecnología de la programación: antifusibles, memoria no volátil (EPROM,
EEPROM), memoria FLASH (RAM, FLASH).
A continuación se presentan una tabla con los principales fabricantes de FPGAs y sus
características [8]:
Figura 2.5: Fabricantes de FPGAs [8]
Ventajas y Desventajas de los FPGAs con respecto a otras tecnologías
Las ventajas que poseen los FPGAs en el área de diseño de circuito digital son las siguientes [15]:
•
Reducción del tiempo de introducción al mercado de productos.
•
Habilidad de ser reprogramados después de haber salido al mercado a fin de corregir posibles errores, y reducir los costos de investigación, diseño y pruebas de un
nuevo producto.
•
Facilidad de diseño, en la mayoría de las FPGAs se pueden encontrar funciones de
alto nivel (como sumadores y multiplicadores) embebidas en la propia matriz de interconexiones, así como bloques de memoria.
•
Mayor densidad de los elementos lógicos programables en puertas lógicas equivalentes, en el orden de cientos de miles hasta millones de ellas, que otras tecnologías.
•
Mayor flexibilidad debido a su arquitectura y la enorme libertad disponible en la interconexión.
11
Las desventajas que poseen los FPGAs en el área de diseño de circuito digital son las
siguientes [15]:
•
Son generalmente más lentos.
•
No pueden soportar diseños muy complejos.
•
Consumen más energía.
2.4 Flujo de diseño mediante FPGAs utilizando las herramientas de
Xilinx
La figura muestra el diagrama de flujo para el diseño de sistemas implementados sobre FPGAs de Xilinx. El proceso de diseño se divide en cuatro fases: descripción del modelo, síntesis, implementación y programación [8].
Figura 2.6: Flujo de diseño mediante FPGAs [8]
Al finalizar cada una de las fases es preciso comprobar la validez del diseño mediante
simulación, utilizando distintos tipos de simulación en cada una de ellas [11]:
•
Simulación funcional RTL para validar el modelo creado.
•
Simulación funcional post-síntesis a nivel de puertas para validar el modelo sintetizado.
•
Simulación temporal post-implementación para validar la implementación del modelo implementado.
12
•
Verificación en circuito.
El banco de pruebas creado para validar el modelo es único, siendo utilizado en todos
los tipos de simulación mencionados. Las dos últimas son simulaciones a nivel de puertas,
ya que el diseño esta expresado como una descripción estructural HDL en términos de las
celdas de la tecnología destino para la que se va a implementar.
Creación del modelo
El primer paso consiste en crear un modelo RTL del diseño que se pretende realizar.
Para ello se puede utilizar:
•
Un lenguaje de descripción de Hardware HDL (“Hardware Description Language”)
como: Verilog, VHDL y ABEL.
•
Un esquemático.
El diseño puede contener:
•
Código HDL genérico que describe lógica independiente de la tecnología donde se
va a implementar.
•
Componentes con instancias propias de la arquitectura del dispositivo en el que se
va a implementar.
Para el caso de utilización de componentes propios de la arquitectura del dispositivo
el sintetizador obtiene la descripción de dichos componentes de la biblioteca de celdas de la
tecnología destino. El formato de esta biblioteca dependerá de la herramienta de síntesis
utilizada.
Antes de proceder a la síntesis del diseño es preciso verificar el modelo creado mediante una simulación funcional la cual se puede construir con Test Bench Wave Form Editor (Editor de Formas de Onda de Prueba) de Xilinx. También se pueden crear archivos
con restricciones temporales o espaciales para la síntesis.
Síntesis del modelo
13
Una vez validado el modelo creado se procede a la síntesis de éste para lo cual se utiliza la herramienta de síntesis de Xilinx: XST [18]. El resultado de la síntesis es una lista de
conexiones en formato NGC propio de Xilinx (anteriormente XNF). Si en el proceso de
síntesis se fijan restricciones de diseño (topológicas o temporales) que afectan al proceso de
implementación éstas se exportan en la propia lista de conexiones.
Para comprobar los resultados de la síntesis es preciso realizar una simulación funcional (retardos unitarios) a nivel de puertas. El procedimiento a seguir es similar a la simulación funcional RTL.
Implementación del modelo
Una vez sintetizado el diseño se procede a su implementación. La implementación en
Xilinx consta de cuatro pasos [18]:
1. Traslate – Traducción: En esta fase, se enlazan los ficheros de lista de conexiones
(EDIF, NGC, XNF) creando un único fichero de salida en el que queda reflejada la
jerarquía citada. El formato de este fichero de salida se denomina: NGD (Native
Generic Design) y contiene componentes lógicos: puertas lógicas, biestables,
RAMs, etc.
2. Map – Mapeo: En esta etapa se mapean los componentes lógicos en los componentes físicos de que dispone la FPGA: tablas LUT, biestables, buffers triestado, etc. A
continuación se encapsulan estos componentes físicos en bloques configurables
(CLBs e IOBs), creando un fichero de salida en formato NCD (Native Circuit Design).
3. Place and Route – Posicionamiento y Ruteo: En esta etapa se pasa a realizar el posicionamiento e interconexión de los bloques configurables en el FPGA y se genera
un fichero de lista de conexiones en formato NCD. Una vez finalizado este proceso
se dispone de toda la información de retardos internos (elementos activos e interconexiones) y se puede realizar de nuevo un análisis estático de tiempos esta vez con
todos los datos de retardos internos. Después de realizar estas fases se obtiene la información para realizar simulaciones temporales del diseño completo y se puede
14
crear un archivo HDL estructural con base en los componentes físicos de la FPGA y
un fichero SDF con los retardos internos del FPGA. Utilizando estos ficheros se
puede realizar la verificación del diseño final mediante una simulación temporal
HDL post-síntesis.
4. Programming File Generation – Generación del archivo de programación: Finalmente en esta fase se genera el fichero BIT de configuración de la FPGA.
Programación
Una vez que se genera el archivo BIT se procede a configurar el dispositivo. Durante
la configuración se descargan los archivos de programación desde una computadora anfitriona al dispositivo FPGA de Xilinx.
2.5 Introducción a la codificación de predicción lineal (LPC) de la voz
humana
Este método de predicción lineal se utiliza para el análisis y síntesis de la voz humana. Este modelo supone que el tracto vocal se puede describir de la siguiente forma [3]:
Frecuencia del Pitch
Generador
de pulsos
periódicos
Selector de voz con
o sin sonido
Filtro IIR
todo polos
Señal
de voz
Generador
de Ruido
Blanco
Figura 2.7: Modelo del tracto vocal [3]
El filtro lineal IIR todo polos, tiene la siguiente función de transferencia:
H ( z) =
G
M
1 − ∑ ai z
i =1
(1)
−i
15
Donde i es el número de polos, G la ganancia del filtro y ai son los parámetros de los polos.
A este filtro se le conoce también como filtro LPC (Lineal Predictive Coding) [18].
Existen dos funciones de excitación mutuamente exclusivas que modelan los sonidos
con voz (periódica con periodo igual al pitch) y los sonidos sin voz (ruido blanco). Se supone que cada muestra es una combinación lineal de las muestras anteriores. Los coeficientes del filtro se calculan para minimizar el error cuadrático entre la muestra actual y su
predicción.
Se trabaja sobre bloques de 20 ms de voz, sobre lo que se conoce como modelo corto,
donde las características de la voz se suponen que no varían con el tiempo en intervalos pequeños. Esos bloques se analizan para determinar los coeficientes de predicción. Estos se
cuantifican y se envían al receptor junto con otros parámetros.
Los parámetros que se envían son: los coeficientes del filtro (coeficientes de predicción y ganancia), la intensidad de la excitación, un bit que indica si la excitación es un sonido sin voz ó un sonido con voz, y, en caso de ser este último, la frecuencia de la
excitación del formante (pitch) [3].
Figura 2.8: Esquema de codificación LPC [3]
Con esta información el decodificador puede reconstruir la señal fuente, la cual hace
pasar por el filtro, obteniéndose la voz sintetizada.
En el decodificador, los sonidos con voz se obtienen al pasar una serie de impulsos
periódicos con la misma frecuencia e intensidad de la formante por el filtro (caracterizado
por los coeficientes de predicción). Los sonidos sin voz se obtienen al pasar por el filtro
ruido aleatorio con la amplitud de la excitación [3].
16
Figura 2.9: Esquema de decodificación LPC [3]
Típicamente, el periodo del pitch requiere 6 bits y el parámetro de la ganancia se
puede representar con 5 bits. Los coeficientes de predicción requieren entre 8 y 10 bits por
coeficiente para una representación precisa. Si se utiliza un modelo de décimo orden el número de bits asignado por segmento es 82, con segmentos de 20ms se obtiene un bit rate de
4,6 kbps que es muy bajo con respecto a PCM (64Kbps), donde se observa la compresión
que se obtiene con este procesamiento [3] .
Hoy día se puede codificar la voz con LPC a velocidades entre 2.4 y 4.8 kbps con una
señal de voz reconstruida con una calidad razonable. LPC basa su funcionamiento en dos
tipos de sonidos: con voz y sin voz, sin embargo otros tipos de sonidos existentes no se
pueden reproducir con este método, resultando esto en la producción de una voz artificial y
es imposible reconocer, a partir de la voz sintetizada, a la persona que la origina [10].
CAPÍTULO 3: Planteamiento de un procedimiento basado en
herramientas de código abierto
En la sección 1.4, se presentó el flujo de diseño de los FPGA de Xilinx. Este procedimiento presenta ciertamente varias ventajas:
•
Estabilidad: las herramientas que se utilizan han sido ampliamente probadas y
se encuentran en una etapa estable donde es difícil encontrar un error de programación y el fabricante provee soporte en caso de encontrar alguna falla.
•
Optimización: las herramientas fueron diseñadas por el fabricante para obtener
el máximo provecho de las capacidades del FPGA.
Sin embargo, está claro que el procedimiento fue concebido para FPGAs de la marca
Xilinx, de donde surgen las siguientes desventajas:
•
Falta de compatibilidad y portabilidad: las herramientas se diseñaron específicamente para FPGAs de Xilinx, durante las diferentes etapas del flujo se generan archivos con formatos propietarios, esto impide que los resultados se
puedan utilizar con otras herramientas EDA de otro fabricante y que los diseños no se puedan redireccionar a otras marcas o tecnologías.
•
Falta de flexibilidad: no es posible modificar las herramientas para obtener
nuevos resultados durante el flujo de diseño. Desde el punto de vista académico no permite que la Universidad desarrolle y aporte conocimientos en esta
área. El estudiante aprende solo a desarrollar circuitos digitales para FPGAs
de Xilinx.
A partir de estas desventajas se plantea un procedimiento para diseño e implementación de circuitos digitales concebido en forma generalizada, en el cual sea posible seleccionar la tecnología en la cual se va a implementar el diseño y que los resultados obtenidos
durante el proceso sean estándares de la industria que provean de portabilidad y flexibilidad. Además este procedimiento debe permitir que el estudiante pueda realizar modificaciones y mejoras a las herramientas.
Bajo estas ideas se presenta el siguiente flujo de diseño:
17
18
Creación del Diseño
Compilación
(Icarus Verilog)
Simulación Funcional
(Icarus Verilog - GTK Wave)
Síntesis
(Icarus Verilog)
VLSI
ASIC’s
CPLD
FPGA
Xilinx
Altera, Amtel,
Actel,Lattice,
otros
Simulación Lógica
(Icarus Verilog / GTK Wave)
Implementación
(Xilinx WebPack)
Verificación Temporal
(GTK Wave)
Programación
(Xilinx WebPack)
Verificación en circuito
Figura 3.1 Flujo de diseño basado en herramientas EDA de código abierto
El flujo se inicia con una etapa de diseño, compilación y simulación funcional. Se
crea un modelo ideal independiente de la tecnología donde vaya a implementar el circuito
digital. En la etapa de síntesis se presenta la principal característica del flujo, donde es posible seleccionar la tecnología para implementar el proyecto. En esta etapa de síntesis se
decide la tecnología en la que se va a implementar el proyecto y se realiza el proceso mediante las especificaciones de la tecnología seleccionada.
Una vez que se obtenga la síntesis del diseño, se continuará con los pasos necesarios
para la implementación física que dependerá de la tecnología seleccionada.
19
Como se observa en la figura 3.1, se seleccionaron dos herramientas EDA para el desarrollo de este flujo: Icarus Verilog y GTKWave. Estas herramientas se seleccionaron ya
que satisfacían las necesidades del procedimiento planteado.
Icarus Verilog es una herramienta de simulación y síntesis de Verilog, lenguaje de
HDL estándar (IEEE-1364). Para el proceso de síntesis utiliza un formato estándar llamado
EDIF independiente de la tecnología. También permite la generación de archivos VCD, un
formato estándar especificado en IEEE-1364 para análisis de modelos de simulación de Verilog.
GTKWave es un analizador de formas de ondas. Permite visualizar las formas de ondas de simulaciones en diferentes formatos, como el formato VCD. Esta herramienta complementa a Icarus Verilog para simulaciones funcionales, lógicas y temporales.
Ambas herramientas son de código abierto y están asociadas al proyecto de herramientas EDA open source: gEDA. Está condición da la libertad a la UCR para modificar y
mejorar las herramientas con el fin de conseguir una mayor eficiencia y aportar en la automatización del desarrollo de circuitos digitales.
Ambas herramientas, se encuentran disponibles para: Windows, Linux y otras plataformas.
Sin embargo estas herramientas poseen ciertas debilidades como toda herramienta de
código abierto:
•
Estas herramientas no poseen soporte y se utilizan bajo propio riesgo.
•
No están completamente terminadas y es posible encontrar errores de programación.
Este proyecto utiliza las herramientas de forma exhaustiva para verificar que tienen la
capacidad para desarrollar circuitos digitales de cualquier tipo y tamaño. Para cumplir con
este propósito se seleccionó el desarrollo de un codificador/decodificador de voz que utiliza
el modelo de predicción lineal de la voz humana. Esta aplicación contaba con las condiciones necesarias de tamaño y complejidad para estresar las herramientas y revelar sus limitaciones.
20
Como primer paso, en este proyecto se utilizó este procedimiento y las herramientas
para la tecnología FPGA de Xilinx para comprobar que se puede llegar a resultados equivalente a los obtenidos con las herramientas propias del fabricante. En lo posterior, se presentan los resultados obtenidos en cada etapa del procedimiento y que permitieron elaborar la
guía presentada en el apéndice E. Esta guía documenta con detalle cada paso del flujo y el
uso de las herramientas Icarus Verilog y GTKWave. Además se explican las limitaciones y
las soluciones a los errores que se pueden presentar durante el proceso.
CAPÍTULO 4: Diseño del codificador/decodificador de voz
En este capítulo se presenta en alto nivel la arquitectura del codificador/decodificador
de voz que se diseñó para ejecutar el procedimiento planteado. Se revisan las características, los componentes y los flujos principales del diseño. Para mayor detalle se puede revisar el apéndice A y los archivos de Verilog adjuntados.
4.1 Descripción general
Se diseñó un codificador/decodificador de voz, que permite realizar grabaciones de
voz por ocho minutos y hacer reproducciones mediante dos tipos de codificaciones: PCM y
codificación predictiva lineal (LPC). La voz es filtrada mediante un filtro pasivo RC de un
polo para limitar el ancho de banda y muestreada de forma uniforme a una frecuencia de
muestreo de 8kHz (satisface el teorema de Nyquist). Se utilizaron 14 bits para la conversión
analógica-digital y las muestras se almacenaron en una memoria RAM dinámica.
Para realizar la codificación predictiva lineal se utilizaron tramas de voz de 20 milisegundos y diez coeficientes de predicción lineal. Todos los cálculos se realizan en punto flotante en precisión simple (32bits) bajo el estándar IEEE 754.
Para la reproducción se utilizaron 12 bits para la conversión digital-analógica y un retenedor de orden cero.
4.2 Componentes
El codificador/decodificador de voz posee los siguientes componentes:
•
Pre-amplificador programable, modelo LTC6912-1, marca Linear Technology.
•
Convertidor analógico-digital, modelo LTC1407A-1, marca Linear Technology.
•
Convertidor digital-analógico, modelo LTC2624, marca Linear Technology.
•
Memoria RAM dinámica, modelo MT46V32M16, marca Micron.
•
Oscilador de reloj, modelo SG-8002JF, marca EPSON.
•
FPGA, modelo XC3S1600E-FG320-4, marca Xilinx
21
22
Todos estos elementos se encuentran interconectados en la tarjeta de desarrollo: Spartan-3E
Starter-kit de Xilinx.
Dentro del FPGA se desarrollaron los siguientes circuitos digitales que permitieron
verificar el procedimiento planteado:
Para control de interfaces y almacenamiento
Controlador A/D
Controlador
Controlador de
Controlador de Re-
Memoria RAM está-
D/A
Memoria
producción
tica 160X32
Coeficientes R
Coeficientes LPC
Para codificación/decodificación predictiva lineal
Controlador de Codifi-
Sonido con/sin
Detección del
cación
voz
pitch
Filtro de análisis
Filtro de síntesis
Para cálculo en punto flotante en 32 bits (FPU)
Sumador/Restador
Multiplicador
Divisor
Raíz Cuadrada
Tabla 4.1 Circuitos diseñados para el codificador/decodificador de voz
A continuación se presenta un diagrama de bloques del diseño:
23
Figura 4.1 Diagrama de bloques del diseño
4.3 Diagrama de estados general
A continuación se presenta el diagrama estado general del codificador/decodificador
de voz:
24
S0: Estado Inicialización
S1: Estado Listo
S2: Estado Grabando
S3: Estado Codificacion/Decodificación Automática
S4: Estado Reproducción PCM Rotativa
S5: Estado Reproducción LPC Rotativa
Reset
S0
S1
S3
Listo
no
si
Grabar
?
si
Memoria
Llena
?
S2
no
no
Reproducir
?
no
Continuar
?
si
si
Codificar
?
si
no
S4
Continuar
?
no
S5
si
Continuar
?
si
no
Figura 4.2 Diagrama de estado general del diseño
La señal Reset inicializa el sistema y se entra al estado S0 donde se inicializan las
máquinas de estado y se configuran los dispositivos externos al FPGA. Cuando se termina
esta fase se pasa en forma incondicional al S1 donde el sistema se encuentra listo para operar y se indica con la señal Listo. En este estado se revisan las señales Grabar y Reproducir. Si la señal Grabar está en alto, se pasa al estado S2 donde se graba y almacena las
muestras de voz hasta que se llene la memoria o que se finalice la grabación bajando la señal Grabar. Inmediatamente se continúa al estado S3 donde se realiza una codificación
predictiva lineal de las muestras, seguidamente se decodifican y se almacenan listas para
reproducirse.
Si la señal Reproducir está en alto, se revisa la señal Codificar. Si la señal Codificar
esta en bajo, se pasa al estado S4 donde se reproduce la voz con la codificación PCM hasta
que la señal Reproducir baje. Si la señal Codificar está en alto, se pasa al estado S5 donde
25
se reproduce la voz con la codificación LPC hasta que la señal Reproducir baje. Se reproduce en forma repetida hasta que la señal Reproducir baje.
La señal Grabar tiene prioridad sobre la señal Reproducir si ambas están en alto al
mismo tiempo. No es posible grabar y reproducir al mismo tiempo.
4.4 Descripción de los circuitos digitales
A continuación se describen los circuitos digitales que se diseñaron:
Para control de interfaces y almacenamiento:
Controlador del convertidor analógico-digital
Consiste en una máquina de estado y una asignación de registros, que inicializa y
configura el pre-amplificador programable y el convertidor analógico-digital. Controla la
frecuencia de muestreo a 8kHz de la señal de voz entrante y posee la interfaz para introducir las muestras de voz de 14 bits del convertidor A/D al FPGA.
Controlador del convertidor digital-analógico
Consiste en una máquina de estado y una asignación de registros, que inicializa y
configura el convertidor digital-analógico. Controla la frecuencia de reproducción a 8kHz
de la voz saliente y posee la interfaz para llevar las muestras de voz de 12 bits del FPGA al
convertidor D/A.
Controlador de memoria RAM dinámica
Consiste en una máquina de estado y una asignación de registros, que inicializa y
configura la memoria RAM dinámica para el almacenamiento de muestras de voz. Realiza
el proceso de inicialización de la memoria. Controla los periodos de refrescamiento de la
memoria. Permite realizar escrituras y lecturas de datos, solo un dato a la vez.
Controlador de reproducción
Consiste en una máquina de estado y una asignación de registros, posee la interfaz
con las señales de control disponibles para el usuario. Se encarga de almacenar las muestras
que provee el controlador de convertidor A/D en el banco 1 de la memoria RAM a través
del controlador de memoria durante la grabación. Controla el controlador de codificación
26
para que se ejecute el procedimiento de predicción lineal. Durante la reproducción según la
codificación seleccionada lleva las muestras del banco 1 (PCM) o 2 (LPC) de la DRAM al
controlador de convertidor D/A.
Memoria RAM estática 160X32
Consiste en una memoria Ram estática de 160x32, que permite el almacenamiento
temporal de 160 muestras de voz en 32 bits, que corresponde a la trama de voz que es analizada. Posee una escritura sincrónica y una lectura asincrónica.
Para codificación/descodificación predictiva lineal:
Controlador de codificación.
Consiste en una máquina de estado y una asignación de registros, que convierte tramas de voz de 20 ms (160 muestras a 8kHz) almacenadas en la memoria DRAM en 14 bits,
al formato de punto flotante en 32 bits. Se encarga de mover cada trama de voz convertida
a la memoria RAM estática para aplicarle el procedimiento LPC. Controla las máquinas de
estado para realizar el procedimiento de codificación predictiva lineal, tanto la codificación
como la decodificación.
Sonido con/sin voz
Consiste en una máquina de estado y una asignación de registros, que analiza la trama
de voz en la memoria RAM estática con el procedimiento llamado “Cruce por cero” para
determinar si la muestra de voz se caracteriza como un sonido con voz o sin voz. Se utiliza
un umbral de 25 cruces para su identificación. Si el resultado es un sonido con voz, controla la máquina de estado “Detección del pitch”.
Detección del pitch
Consiste en una máquina de estado y una asignación de registros, que analiza la trama
de voz en la memoria RAM estática con el procedimiento llamado AMDF (Average Magnitude Difference Function) para determinar el periodo del pitch de la muestra de voz.
Coeficientes R: Cálculo de los coeficientes de autocorrelación
27
Consiste en una máquina de estado y una asignación de registros, que analiza la trama
de voz en la memoria RAM estática y calcula los coeficientes de autocorrelación. Se obtienen 11 coeficientes. Esta máquina controla la máquina de estado “Coeficientes LPC”.
Coeficientes LPC: Cálculo de los coeficientes de predicción lineal
Consiste en una máquina de estado y una asignación de registros, que utiliza los coeficientes R de autocorrelación y calcula los 10 coeficientes de predicción lineal mediante
el método Levinson-Durbin.
Filtro de análisis
Consiste en una máquina de estado y una asignación de registros, constituye el filtro
de análisis del método LPC. Filtra la trama de voz en la memoria RAM estática y obtiene el
error y la ganancia a partir de los coeficientes de predicción lineal.
Filtro de síntesis
Consiste en una máquina de estado y una asignación de registros, constituye el filtro
de síntesis del método LPC. Utiliza los parámetros obtenidos para decodificar la trama de
voz que fue analizada. Se construye el filtro mediante los coeficientes LPC y la ganancia.
La entrada del filtro puede consistir en ruido gaussiano que se encuentra pre-almacenado en
una ROM o una señal de pulsos con la frecuencia del pitch. La selección de la entrada se
realiza con la detección de un sonido con/sin voz. Convierte los resultados obtenidos de 32
bits a 14 bits y lo almacenada en el banco 2 de la DRAM para reproducción.
Para cálculo en punto flotante en 32 bits:
Sumador/Restador/Multiplicador/Divisor/Raíz Cuadrada
Consisten en una máquina de estado y una asignación de registros por cada operación
aritmética, que ejecuta la operación correspondiente de dos operandos en 32 bits, excepto la
raíz cuadrada que ocupa solo un operando de 32 bits. Se utiliza el estándar IEEE754 de
precisión simple para realizar el cálculo de los resultados. El resultado es truncado y se da
en el mismo formato que los operandos. Se puede ejecutar una operación a la vez. Las operaciones que generan overflows o los underflows se resuelven dando como resultado el numero más grande y el numero más pequeño respectivamente que permite el estándar. En el
28
caso de la división por cero se resuelve dando como resultado el número más grande posible.
4.5 Arquitectura de las máquinas de estado y de la asignación de registros
Para el diseño de las máquinas de estado se utilizaron dos tipos de arquitectura: un
flip-flop por estado (“One-hot”) y microprogramación. La arquitectura micro-programada
se utilizó para los circuitos cuya frecuencia de reloj no era importante como el controlador
A/D y D/A ya que la frecuencia de muestreo es muy baja. Para los demás circuitos se utilizó la arquitectura one-hot para obtener una frecuencia de reloj alta para el procedimiento de
predicción lineal a cambio de más flip-flops por máquina y mayor consumo de potencia.
Entrada n
Estado n
Entrada 1
Estado 1
Entrada 0
Estado 0
Para la asignación de registros (datapath), se usó la siguiente arquitectura:
Figura 4.3 Arquitectura de la asignación de registros
4.5.1 Protocolo de comunicación entre circuitos
Para la comunicación entre circuitos digitales se utilizó un Full Handshake completamente sincrónico con el reloj de referencia como se muestra a continuación:
29
Figura 4.4 Protocolo de comunicación entre los circuitos
Las máquinas se pueden utilizar si la señal listo está en alto. Se inician con la señal
inicio. La máquina iniciada indica su estado ocupado bajando la señal listo y la máquina
que la controla puede bajar la señal inicio. Cuando la máquina termina lo indica subiendo
listo, todos los cambios se realizan en los flancos negativos del reloj de referencia.
4.5.2 Protocolo de cambio de estado y asignación de estado
Se definió la siguiente convención: Todas las máquinas de estado cambian de estado
en los flancos positivos del reloj de referencia y las asignaciones de los registros se realizan
en los flancos negativos de reloj. A continuación se muestra la convención definida:
Figura 4.5 Protocolo de cambio de estado y asignación de estado
CAPÍTULO 5: Compilación y Simulación Funcional
En este capítulo se explica la forma en que se realizó la compilación y simulación
funcional de los circuitos digitales descritos en Verilog por separado y después en conjunto.
5.1 Descripción en Verilog
El diseño del codificador/decodificador de voz se describió en Verilog. La descripción se realizó en forma conductual y de forma jerárquica. Cada circuito se describió, en
general, utilizando dos módulos de la siguiente forma:
Figura 5.1 Estructura de la descripción en Verilog para los circuitos diseñados
El primer módulo consiste en la máquina de estados con la arquitectura correspondiente y el segundo con la asignación de registros. A continuación se presenta los nombres
de módulos en Verilog:
Nombre del Circuito
Módulos en Verilog
Controlador A/D
AD_controlador.v
AD_registros.v
Controlador D/A
DA_controlador.v
DA_registros.v
Controlador de Memoria
mem_controlador.v
mem_registros.v
Controlador de Reproducción
repro_controladorv2.v
repro_registros.v
Controlador de Codificación
CODE_controlador.v
CODE_registros.v
Sonido con/sin Voz
Cruce_controlador.v
Cruce_registros.v
Detección del Pitch
Pitch_controlador.v
Pitch_registros.v
Coeficientes R
R_controlador.v
R_registros.v
Coeficientes LPC
C_controlador.v
C_registros.v
Filtro de Análisis
FG_controlador.v
FG_registros.v
Filtro de Síntesis
FPR_controlador.v
FPR_registros.v
Sumador/Restador
microcontrolador.v
asignacion_registros.v
Multiplicador
multiplicador_controlador.v
multiplicador_registros.v
Divisor
divisor_controlador.v
divisor_registros.v
30
31
Raíz Cuadrada
raiz_controlador.v
ROM de Ruido
ruido.v
Memoria RAM Estática 160x32
ram.v
raiz_registros.v
Tabla 5.1 Nombre de los módulos en Verilog para cada circuito
La estructura jerárquica que se estableció fue la siguiente:
Controlador A/D
Controlador D/A
Controlador de
Memoria
Controlador de
Memoria
Controlador de
Reproducción
Controlador de
Codificación
Filtro de análisis
Módulo principal
Módulo
Coeficientes R
y LPC
Módulo FPU
Sumador/
Restador
Multiplicador
Divisor
Raíz Cuadrada
Coeficientes R
Coeficientes
LPC
Módulo Sonido
y Pitch
Sonido con/sin
Voz
Detección del
Pitch
Filtro de síntesis
ROM Ruido
Figura 5.2 Estructura jerárquica establecida para el proyecto
En un principio la descripción en Verilog se realizó con las reglas básicas que se deben respetar para cualquier proceso de síntesis en Verilog. A continuación se mencionan [6]:
•
No modificar una variable en dos procesos diferentes.
•
En una asignación procedural, todas las variables de las que dependa la asignación
deben aparecer en la lista de sensibilidad, para evitar inferencia equivocada de latches.
•
No realizar asignaciones al mismo tiempo donde una depende de la otra.
•
No se admiten procesos initial.
•
No se admiten algunos operadores como la división.
En esta etapa se utilizaron estas reglas con el fin de asegurar una síntesis exitosa. Pos-
teriormente se encontraron problemas con el sintetizador de Icarus Verilog donde se tuvo
que modificar la descripción en Verilog y el diseño para resolverlos. La estructura jerárquica establecida permitió aislar fácilmente los problemas.
32
En el capítulo 6, se hace una caracterización del sintetizador en Icarus Verilog y se
discute las limitaciones y problemas que se encontraron en la herramienta.
5.2 Etapa de Compilación y Simulación Funcional
En esta etapa se comprobó en forma individual y grupal que los módulos en Verilog
no tuvieran ningún error de sintaxis y alguna directiva no soportada por Icarus Verilog. Para este proyecto se utilizó la versión 8.6 para Windows. Todos los comandos se ejecutaron
en la consola, como por ejemplo para la compilación del circuito completo:
%iverilog –o REP.vvp –c REP.prj
Donde iverilog invoca a la herramienta Icarus Verilog, REP.prj es el nombre del archivo
con las direcciones a los archivos fuente .v y la opción -o define el nombre del archivo que
va a contener el ejecutable de simulación que este caso se va a llamar REP.vvp.
5.2.1
Simulación funcional
La simulación funcional verifica que la descripción en Verilog del circuito digital sea
la correcta y que su comportamiento funcional satisface las especificaciones. Para realizar
las simulaciones funcionales se utilizó el siguiente esquema:
Figura 5.3 Esquema jerárquico para simulación funcional
Se creó un módulo llamado banco de pruebas para cada circuito diseñado. De esta
forma todas las sentencias que tenían que ver con la simulación quedaron definidas dentro
de este módulo y posteriormente se utilizó solo el módulo con el diseño para el proceso de
síntesis.
Cada banco de pruebas posee un conjunto de estímulos que simula el entorno alrededor del circuito. Se ejercitó cada circuito por separado para comprobar su funcionalidad de
33
forma ideal ya que no emplearon retardos temporales, esto para que las simulaciones durante la implementación coincidieran.
Para los circuitos de control de interfaces y almacenamiento, los bancos de pruebas
se desarrollaron de forma tal que simularan el comportamiento del dispositivo externo. En
el caso de la memoria DRAM se utilizaron las descripciones en Verilog que provee el fabricante, Micron, que facilitó y aseguró la simulación funcional del controlador de memoria.
Para cada circuito se obtuvo un archivo VCD y se utilizó para comprobar que los
cambios de estados y las asignaciones a registros fueran correctos en la simulación.
Figura 5.4 Simulación funcional del controlador de memoria DRAM en GTKWave
Para los circuitos de cálculo en punto flotante en 32 bits (FPU) se emplearon pruebas
para ejecutar operaciones con casos esquinas básicas y conjuntos de operaciones aleatorias.
No se hizo una validación exhaustiva puesto que se salía de los objetivos del proyecto.
Para las pruebas con operaciones aleatorias se utilizó Matlab para generar los archivos
binarios en precisión simple y se consideró como el resultado ideal. Sin embargo los resultados de Matlab eran redondeados a diferencia de los circuitos diseñados cuyo resultado es
truncado. Por lo que en los resultados de las simulaciones se aceptaron errores por redondeo con respecto al resultado ideal (Matlab). A continuación se muestra los resultados de
las simulaciones para el divisor:
34
Figura 5.5 Simulación funcional del divisor de 32bits
Similarmente, para los circuitos de codificación/decodificación predictiva lineal se desarrollaron bancos de pruebas que utilizaban tramas de 20ms de señales senoidales.
Además de las simulaciones individuales, se desarrollaron dos simulaciones intermedias:
•
Los circuitos de predicción predictiva lineal en conjunto para comprobar el algoritmo LPC.
•
Los circuitos de interfaz y almacenamiento en conjunto para comprobar la grabación, almacenamiento y reproducción.
Finalmente se realizó una simulación del circuito completo para comprobar el funcionamiento global del sistema. Para este tipo de simulaciones se tuvo que limitar los niveles
en las jerarquías de los módulos que se iban a acceder para la creación del archivo VCD, ya
que el archivo se volvía muy grande debido a la duración de la simulación y la cantidad de
señales por jerarquía. También, para disminuir el tiempo y tamaño de la simulación se utilizaron tramas de voz pequeñas, se aumentó la frecuencia de muestreo y solo se simuló una
trama a la vez por simulación. Según el tamaño del archivo VCD (entre 0.5 y 1 GB), así duraba la aplicación GTKWave en abrirlo y se veía limitado por la memoria de la computadora donde se corría la aplicación (para el proyecto se utilizó una computadora portátil con 1
GB de memoria RAM, un procesador Pentium M de 1.8 GHz).
35
Figura 5.6 Simulación funcional del codificador/decodificador de voz en GTKWave
Estas etapas de descripción, compilación y simulación funcional se realizaron reiteradamente debido a los cambios ocasionados por el proceso de síntesis.
CAPÍTULO 6: Síntesis en Icarus Verilog
En este capítulo se describe el proceso de síntesis con Icarus Verilog y específicamente para la arquitectura Virtex de Xilinx para la cual se realizó este proyecto. Se presentan las características del sintetizador y
las limitaciones que se encontraron en la
herramienta. Se hace referencia la implementación sobre el FPGA SPARTAN-3E y la tarjeta de desarrollo SPARTAN-3E Starter-Kit Board.
6.1 Descripción del proceso de síntesis con Icarus Verilog
La síntesis es el proceso de mapear y optimizar una descripción en HDL de alto nivel
a una tecnología de compuertas (compuertas lógicas, latches, flip-flops, etc.). A continuación se presenta este proceso en general de síntesis para la herramienta Icarus Verilog que
se definió como resultado de este proyecto:
Figura 6.1 Proceso de Síntesis con Icarus Verilog
Descripción en HDL: consiste en la descripción del diseño en Verilog. Se debe utilizar un subconjunto de instrucciones soportadas por el sintetizador de Icarus Verilog.
Librería de tecnología: el sintetizador de Icarus Verilog posee información acerca de
la descripción funcional de celdas para la arquitectura Virtex (Xilinx), Virtex2 (Xilinx) y
LPM (estándar genérico). El fabricante de la arquitectura provee documentación de la librería y de las celdas disponibles. En este caso, el sintetizador es limitado y conoce un subcon36
37
junto de las celdas de la arquitectura por lo que el resultado no siempre está optimizado.
También no posee información temporal de la arquitectura por lo que no se obtienen resultados de análisis temporal.
Restricciones y Parámetros: Es información adicional acerca de las características físicas del diseño, como asignación de pines, estándar de voltaje de salida y entrada, periodo
de reloj, ubicación de celdas, entre otros. Esta información es provista por el fabricante de
la arquitectura. Icarus Verilog permite indicar ciertos parámetros y restricciones en forma
limitada directamente en el archivo de Verilog.
Netlist: es un archivo de texto que describe los componentes y la conexión física entre
ellos para la implementación del diseño y es el resultado final del proceso. Icarus Verilog
utiliza el formato estándar EDIF, versión 2. Debido a las limitaciones de Icarus Verilog y a
las características propias del circuito digital, es posible que el archivo EDIF resultante sea
incompleto y que sea necesario editarlo para completar la síntesis. Esta edición principalmente se hace para agregar parámetros y restricciones no soportados.
6.2 Descripción del proceso de síntesis para la arquitectura Virtex
6.2.1
Características del sintetizador de Icarus Verilog
La herramienta Icarus Verilog posee un compilador para sintetizar un código en Veri-
log y transformarlo a formato EDIF.
El compilador trabaja a nivel de sentencias always, asignaciones continuas y compuertas lógicas en Verilog. Por esta razón, estructuras como for, task, while, wait, repeat,
initial no son sintetizables. Aún con estas limitaciones, se puede sintetizar diseños jerárquicos con circuitos combinacionales y secuenciales. Esto debido a que la sentencia always
modela casi todo tipo de lógica digital. Por defecto se intenta sintetizar todas las instrucciones, sin embargo mediante directivas se identifica las estructuras que se desean sintetizar y
cuales no.
Desde el punto de vista formal de lenguaje, se probó con la descripción en Verilog del
diseño que Icarus Verilog sintetiza para la arquitectura Virtex:
38
•
Procesos always.
1. Operadores binarios aritméticos: suma (+) y resta (-).
2. Operadores relacionales: >=, <=, !=, ==.
3. Operadores lógicos: !, &&, ||.
4. Operadores lógicos de bit ~, &, |, ^.
5. Concatenaciones {,}.
6. Desplazamiento hacia la izquierda o derecha, con adición de ceros.
7. Estructuras de control: if-else y case (con anidaciones).
8. Asignaciones procedurales no bloqueantes.
9. Eventos de nivel y de flanco positivo.
•
Asignaciones continuas:
1. Operadores binarios aritméticos: suma (+) y resta (-).
2. Operadores relacionales: >=, <=, !=, ==.
3. Operadores lógicos: !, &&, ||.
4. Operadores lógicos de bit: ~, &, |, ^.
5. Concatenaciones: {,}.
6. Desplazamiento hacia la izquierda o derecha, con adición de ceros.
7. Condicional: ?: .
•
Compuertas lógicas: and, or, xor, nor, xnor, buf, not.
•
Utilización de parámetros.
•
Utilización de variables tipo: reg, wire, input, output, inout.
Por otro lado, se probó mediante códigos de prueba en Verilog que Icarus Verilog no sintetiza:
•
Procesos initial.
•
Operadores aritméticos: multiplicación (*), división (/), modulo (%).
•
Operadores relacionales: >,<.
•
Operadores lógicos: ~|, ~&, ~^, ^~.
39
•
Operadores lógicos de reducción: &, |, ^, ~&, ~|, ~^, ^~.
•
Eventos de flanco negativo.
•
Estructuras de control: for, while, repeat, wait.
•
Asignaciones procedurales bloqueantes.
•
Estructuras: Task y Function.
•
Compuertas lógicas: nand, bufif, notif.
6.2.2
Verilog sintetizable para la arquitectura Virtex
Como se mencionó anteriormente existen ciertas normas para lograr una descripción
sintetizable en Verilog. Según el sintetizador y el nivel de complejidad el código será sintetizable. Como resultado de este proyecto se presenta las capacidades que posee el sintetizador de Icarus Verilog. Para la comprobación de las capacidades del sintetizador se revisó
los archivos EDIF de síntesis. La verificación se realizó manualmente puesto que no se encontró ninguna herramienta de código abierto que permitiera transformar el archivo EDIF a
esquemático de forma satisfactoria. Esto constituye una de las debilidades del procedimiento planteado y una oportunidad para la Universidad para desarrollar una herramienta para
este fin.
Para empezar un proceso de síntesis dirigido a la arquitectura Virtex, se encontró que
Icarus Verilog soporta un subconjunto de celdas de la librería de la arquitectura Virtex.
La librería de celdas la provee Xilinx y se puede encontrar en el sitio web de Xilinx.
El estudio de los esquemáticos y las funciones de las celdas ayudó a comprobar que el archivo EDIF de la síntesis utilizaba las celdas esperadas y que no aparecían celdas mal inferidas del código en Verilog.
A continuación se presenta una lista de celdas que maneja Icarus Verilog según el código fuente de la herramienta:
Celda
Descripción
BUFE BUFT
Buffer tri-estado con habilitador activo en alto y en bajo respectivamente
IBUF, OBUF,
Buffer de entrada y salida individuales respectivamente
40
IPAD
Puerto de entrada, salida y entrada/salida respectivamente
BUF, INV
Buffer e inversor de propósito general respectivamente
FDCE, FDRE, FDCPE
Flip-flop D de flanco positivo con habilitador de reloj
VCC, GND
Conexión a fuente y a tierra respectivamente
LUT2,3,4
Tablas de búsqueda de salida general de 2,3,4 bits y salida general
XORCY
XOR con lógica de acarreo con salida general
MUXCY_L , MUXF5,6 MUXCY
BUFG *
MULT_AND*
Multiplexores 2 a 1
Buffer global de reloj
AND de multiplicación rápida
Tabla 6.1 Celdas de la librería Virtex que maneja Icarus Verilog
Las celdas BUFG y AND_MULT son celdas que no se infieren directamente durante
la síntesis sino que hay que indicarle al sintetizador que se va a utilizar este tipo de celda.
Por otro lado no se encuentran disponibles celdas complejas presentes en la documentación del fabricante como: RAM16X1D, ROM16X1, DCM, OBUFT, MULT18X18SIO,
ADD4 entre otras.
En general, el subconjunto de celdas presentado que posee Icarus Verilog es suficiente para sintetizar la mayoría de circuitos digitales, sin embargo no se aprovecha al máximo
la arquitectura. Para este proyecto fue necesario utilizar celdas no soportadas por Icarus
Verilog. Sin embargo se encontró que la herramienta permite resolver el problema mediante directivas especiales.
Descripciones sintetizables de lógica combinacional utilizando compuertas lógicas.
El proceso de síntesis para compuertas lógicas con Icarus Verilog es muy directo, basta con describir la función lógica que se desea como en cualquier sintetizador. Icarus Verilog implementa funciones lógicas como: and, or, xor, nor, xnor, buf, not, excepto funciones
con compuertas nand, bufif, notif. Sin embargo, este tipo de descripción prácticamente no
se utilizó en la descripción del codificador/decodificador de voz. Este tipo de descripción se
utilizó solo si se deseaba ser explícitos en la lógica y se quería utilizar una celda especial,
como se verá más adelante.
41
Descripciones sintetizables de lógica combinacional utilizando asignaciones continuas.
La otra forma de sintetizar funciones lógicas en Verilog es mediante asignaciones
continuas. Es importante destacar que descripciones equivalentes con asignaciones continuas y con compuertas lógicas, conllevan a resultados distintos durante la síntesis. Según la
descripción el sintetizador puede utilizar más compuertas durante el mapeo tecnológico que
puede ocupar más espacio e influir en la velocidad del circuito durante la implementación.
Descripciones sintetizables de lógica combinacional utilizando procesos always.
Además de asignaciones continuas y compuertas lógicas para especificar lógica combinacional, en Verilog se puede utilizar sentencias de proceso como always, aunque la descripción parezca secuencial. Existen reglas básicas para describir lógica combinacional
mediante sentencias always en Verilog. Se encontró que para Icarus Verilog se deben cumplir las siguientes:
1. El evento de la sentencia always de contener todas las variables de entrada de
la función combinacional, conocida como lista de sensibilidad.
2. En caso de utilizar condiciones if, se deben anidar de forma tal que siempre
sea if seguido de else-if y finalizar con else. No se permite utilizar if seguido
de if o olvidar el else. Si se utiliza una estructura case se deben presentar todos los casos o utilizar el caso por defecto para completar las posibilidades.
Si no se cumplen estas dos condiciones, Icarus Verilog genera un error en el proceso
de síntesis, lo cual indica que la herramienta no infiere latches lo cual no tuvo ningún impacto en el diseño, ya que se utilizó solamente flip-flops.
A continuación se presenta un ejemplo de la descripción en Verilog de un multiplexor
4 a 1 con ancho de palabra parametrizado sintetizable por Icarus Verilog:
module mux4x1 (salida, seleccion,in0,in1,in2,in3);
parameter
ancho_palabra = 0;
output [ancho_palabra:0] salida;
reg [ancho_palabra:0] salida;
42
input [ancho_palabra:0] in0,in1,in2,in3;
input
[1:0] seleccion;
always @(seleccion or in0 or in1 or in2 or in3)
begin
if (seleccion == 2'b00)
salida <= in0;
else if (seleccion == 2'b01)
salida <= in1;
else if (seleccion == 3'b10)
salida <= in2;
else
salida <= in3;
end
endmodule
Esta descripción presenta un proceso always donde en la lista de sensibilidad se encuentran todas variables de entrada del multiplexor (seleccion e in0..4). Seguidamente se
presentan condiciones definidas por la variable seleccion. En este caso esta variable tiene
un tamaño de 2 bits, por lo que existen 4 condiciones diferentes correspondientes a cada entrada del multiplexor. Se observa que se utiliza una estructura if, else-if y else donde se
presentan todos los casos posibles. Es importante aclarar que aunque la variable salida es
declarada como un registro, el sintetizador trata el proceso como lógica combinacional.
También, para efectos de síntesis en Icarus Verilog siempre sintetiza las asignaciones
procedurales como no bloqueantes, y no distingue entre asignaciones bloqueantes (=) y no
bloqueantes (<=) aunque en simulación se obtengan resultados distintos al utilizar alguna
de las dos formas. A continuación se muestra la sección contents del archivo EDIF y el esquemático correspondiente:
43
Figura 6.2 Archivo EDIF para multiplexor 4 a 1 (if-else)
Figura 6.3 Esquemático del archivo de síntesis para multiplexor 4 a 1 (if-else)
El multiplexor presentado anteriormente se puede describir utilizando una sentencia
case, como se muestra a continuación:
module mux4x1 (salida, seleccion,in0,in1,in2,in3);
parameter
ancho_palabra = 0;
output [ancho_palabra:0] salida;
reg [ancho_palabra:0] salida;
input [ancho_palabra:0] in0,in1,in2,in3;
input
[1:0] seleccion;
always @(seleccion or in0
begin
case (seleccion)
0: salida =
1: salida =
2: salida =
3: salida =
endcase
or in1 or in2 or in3)
in0;
in1;
in2;
in3;
44
end
endmodule
Si se revisa el archivo EDIF de síntesis, la utilización de la sentencia case hace que el
archivo de síntesis resultante sea más simple ya que se infieren celdas específicas de multiplexación, lo cual hace el circuito resultante mas óptimo en relación a retardos y espacio en
comparación con la descripción basada en estructuras if anidadas como el ejemplo anterior.
A continuación se muestra la sección contents del archivo EDIF y el esquemático correspondiente:
(interface
(port in0 (direction INPUT))
(port in1 (direction INPUT))
(port in2 (direction INPUT))
(port in3 (direction INPUT))
(port salida (direction OUTPUT))
(port (rename PORT5 "seleccion[0]") (direction INPUT))
(port (rename PORT6 "seleccion[1]") (direction INPUT))
)
(contents
(instance U3 (viewRef net (cellRef MUXF5 (libraryRef VIRTEX))))
(instance U2 (viewRef net (cellRef LUT3 (libraryRef VIRTEX))) (property INIT (string "CA
(instance U1 (viewRef net (cellRef LUT3 (libraryRef VIRTEX))) (property INIT (string "CA
(net N0 (joined (portRef O (instanceRef U2)) (portRef I1 (instanceRef U3))))
(net N1 (joined (portRef O (instanceRef U1)) (portRef I0 (instanceRef U3))))
(net N2 (joined (portRef S (instanceRef U3)) (portRef PORT6)))
(net N3 (joined (portRef I2 (instanceRef U2)) (portRef I2 (instanceRef U1)) (portRef PORT
(net N4 (joined (portRef O (instanceRef U3)) (portRef salida)))
(net N5 (joined (portRef I1 (instanceRef U2)) (portRef in3)))
(net N6 (joined (portRef I0 (instanceRef U2)) (portRef in2)))
(net N7 (joined (portRef I1 (instanceRef U1)) (portRef in1)))
(net N8 (joined (portRef I0 (instanceRef U1)) (portRef in0)))
)
Figura 6.4 Archivo EDIF, sección para multiplexor 4 a1 (case)
U1
in0
N8
I0
in1
N7
I1
O
N1
U3
LUT3
(init=CA)
I0
I2
Seleccion[0] N3
in2
in3
N6
N5
I0
I1
N4
salida
S
O
LUT3
(init=CA)
O
I1
U2
N0
N2
Seleccion[1]
I2
Figura 6.5 Esquemático del archivo de síntesis para multiplexor 4 a 1 (case)
Conocer este comportamiento propio del sintetizador y las inferencias que realiza según el código, permitió analizar la descripción en Verilog del diseño para utilizar la más
conveniente.
45
Sin embargo, se encontró que Icarus Verilog tiene una limitación en la síntesis de estructuras case para la arquitectura Virtex, ya que permite sintetizar multiplexores de máximo 4 entradas de tamaño M, esto implica que el selector de entradas puede tener a lo sumo
2 entradas (2 bits). Esta limitación produce que por ejemplo la descripción en Verilog de un
multiplexor 8 entradas no sea sintetizable aunque la descripción sea correcta para síntesis.
Para corregir esta limitación era posible modificar el código fuente de la herramienta, no
obstante para este proyecto no se realizó ya que se escapaba de los objetivos del proyecto.
Esta limitación implica que se deben construir niveles de multiplexación para obtener
multiplexores de mayor número de entradas o utilizar una descripción mediante sentencias
if. Icarus Verilog soporta estructuras case y if-else anidadas para síntesis sin limitación. Esta situación resultó muy incómoda para realizar una descripción de una máquina de estados
utilizando sentencias case.
Durante el proceso de síntesis, existió un problema cuando se utilizan desplazamientos variables ya sea hacia la derecha o hacia la izquierda ya que si la variable de desplazamiento era muy grande se producía un error de síntesis. No se encontró una regla clara para
saber cuando Icarus Verilog iba a generar el error por lo que este tipo de estructuras se
eliminaron en la descripción del diseño y se utilizaron desplazamientos fijos dentro de lazos
para ejecutarlos cuantas veces fuera necesario.
También, existe una limitación con los operadores relacionales, las relaciones condicionales mayor que (>) y menor que (<) no son sintetizables. Esta limitación se solucionó
combinando los operadores relacionales mayor igual que (>=) y menor igual que (<=) con
diferente de (!=) mediante un operador “Y” (&&), para obtener mayor y menor estricto y
que fuera sintetizable en la arquitectura Virtex.
Inferencia de flip-flops
Los flip-flops en Verilog no se especifican explícitamente, sino que son inferidos por
su comportamiento para su síntesis y existen plantillas para especificarlos.
Sin embargo, Icarus Verilog posee una limitación que le impide inferir flip-flops de
flanco negativo y se debe a que en la lista de celdas de arquitectura Virtex que maneja, se
encuentran elementos secuenciales solamente de flanco positivo. Esta limitación implicó
46
que se tuviera que agregar un inversor e invertir la señal de reloj en la descripción en Verilog del diseño propuesto para resolver esta limitación
Inferencia de memorias RAM
Para este proyecto se diseñó una memoria RAM estática cuya descripción en Verilog
debía ser sintetizable, sin embargo Icarus Verilog no infiere memorias RAM, ya que su motor de síntesis no infiere una descripción en Verilog de este tipo de dispositivo y además no
posee ninguna celda de la arquitectura Virtex para realizar el mapeo tecnológico durante la
síntesis. Sin embargo mediante directivas especiales se logró sintetizar la memoria que necesitaba el diseño.
Direccionamiento a celdas especiales de arquitectura
Para este proyecto era imprescindible utilizar celdas especiales como: memoria RAM
y celdas de reloj específicas de la arquitectura Virtex (BUFG, DCM). Se encontró que existen dos métodos para hacer referencia de celdas de arquitectura especiales para que se utilicen durante el proceso de síntesis.
El primer método consiste en hacer referencia a alguna celda específica mediante la siguiente sintaxis:
$attribute(Nombre de la instancia, "cellref", "Tipo de celda :Nombre
de puertos,… ");
Esta directiva “cellref” presentó el problema, en la última versión de Icarus Verilog, que
no está completamente terminada y las únicas celdas de referencia especiales que se pueden
direccionar son IBUF, OBUF, BUFG y MULT_AND.
El segundo método es mucho más robusto pero más complicado y se utilizó con la
celda especial DCM y con la memoria RAM estática debido a las limitaciones del método
anterior. Consiste en crear módulos en Verilog cuyo nombre e interfaz corresponden a alguna celda de librería en combinación con la directiva para el sintetizador
ivl_synthesis_cell *).
(*
47
6.2.3
Adición de parámetros y restricciones en el proceso de síntesis para la arquitectura Virtex
Hasta el momento no se ha discutido la adición de parámetros y restricciones en el
proceso de síntesis. Los parámetros y restricciones permiten especificar completamente las
características físicas del circuito digital diseñado. Esta información es dependiente de la
arquitectura, del modelo, del empaquetado y de la velocidad del FPGA en el cual se va a
implementar el diseño. Para este proyecto se utilizó un FPGA SPARTAN3E, modelo
X3S1600E, empaquetado FG320 y velocidad 4 con un Starter-Kit. Algunos de los parámetros y restricciones que se utilizaron en el diseño fueron los siguientes:
•
Asignación de pines de entrada y salida.
•
Estándar de niveles lógicos de voltaje de salida y de entrada.
•
Corriente de salida.
•
Periodo de reloj.
•
Resistencias de pull-up y pull-down.
El formato EDIF que se utiliza en los archivos de síntesis tiene la capacidad para incluir estos parámetros y restricciones, por lo que no es necesario crear un archivo por separado, sino que el archivo de síntesis puede contener todas las especificaciones del circuito de forma
implícita.
Asignación de pines de entrada y salida
Para que un circuito digital sintetizado se pueda implementar en la arquitectura Virtex, es necesario que las entradas y salidas posean ciertas características para que sea posible la asignación de pines ya sea por el usuario o por la herramienta de implementación de
forma aleatoria. En general:
Las entradas deben poseer una celda de tipo puerto de entrada (IPAD) y una
celda de tipo buffer de entrada (IBUF) antes de entrar al sistema.
Las salidas deben poseer una celda de tipo puerto de salida (OPAD) y una
celda de tipo buffer de salida (OBUF) al salir del sistema.
48
Las salidas tri-estado deben poseer una celda de tipo puerto entrada-salida
(IOPAD), una celda tipo buffer tri-estado de salida (por ejemplo: OBUFT o
BUFE) en conjunto con un buffer de entrada (IBUF).
Si el circuito posee elementos secuenciales, debe poseer una entrada con una
celda adicional tipo buffer de reloj (BUFG o BUFGMUX) para la entrada general del reloj.
Las celdas tipo IPAD, OPAD o IOPAD se le debe asignar el nombre del pin
físico del chip mediante el parámetro: LOC correspondiente a la entrada o salida que se desea utilizar.
A continuación se presenta un diagrama general:
Figura 6.6 Esquemático de celdas de tipo PAD en la arquitectura Virtex
Icarus Verilog permite asignar las celdas tipo PAD y el parámetro LOC mediante la
directiva $attribute a las señales de entrada y de salida. El archivo EDIF de síntesis resultante hace referencia a las celdas tipo IPAD, OPAD, IOPAD IBUF, OBUF, cuando se
usan estas directivas. Además cada instancia tipo PAD posee un parámetro LOC con el
nombre del pin deseado. En general en el formato EDIF, las restricciones y parámetros se
hacen mediante la sentencia property, de la siguiente forma:
(property PARAMETRO (string ”VALOR” ))
Para la asignación de pines en salidas tri-estado, se encontró que es necesario agregar
el buffer de entrada de forma explícita mediante a un direccionamiento especial a la celda
IBUF, ya que Icarus Verilog no lo crea durante el proceso de síntesis y ocasiona un error
49
durante la implementación. También, Icarus Verilog no posee ninguna celda de librería triestado de salida, por lo que se tuvo que editar manualmente el archivo de síntesis.
La directiva $attribute ciertamente tiene el potencial para realizar asignaciones de parámetros y restricciones directamente en la descripción en Verilog. Sin embargo por el
momento en la última versión de Icarus Verilog (8.6), el único parámetro de arquitectura
que el usuario puede utilizar es LOC a través del parámetro PAD sobre celdas tipo PAD.
Aunque con este solo parámetro, se obtiene un archivo EDIF que cumple con las condiciones necesarias de interfaz, para ser implementado por la herramienta WebPack de
Xilinx, se le dejaba al WebPack la selección aleatoria de algunos parámetros de las entradas
como iostandard (estándar de voltaje), slew rate (velocidad), driver (corriente de salida),
pull-up o pull-down (resistencias de pull-up o pull-down). Estas características eran muy
importantes en este proyecto ya que el FPGA se debía conectar con dispositivos externos
como: DAC, ADC, DRAM y el oscilador que se debían seleccionar adecuadamente para
mantener la integridad de estos. También era necesaria la utilización de restricciones internas del diseño sobre celdas y conexiones como period (periodo de reloj), uselowskewlines
(uso de conexiones de bajo retardo de reloj).
Para agregar restricciones no soportadas sobre señales de interfaz se engañó a la directiva
$attribute incluyendo información extra en el nombre del pin y luego se editó el archivo
EDIF. Este método resolvió la limitación para incluir parámetros o restricciones a la interfaz del circuito (celdas PAD). No obstante, otro tipo de celdas internas solo se pudo realizar
mediante la edición del archivo EDIF, siguiendo la sintaxis de este formato.
Para este punto, el proceso de síntesis había finalizado, obteniéndose un archivo
EDIF que posee toda la información del circuito y se encontraba listo para continuar con la
etapa de implementación.
Una limitación del proceso de síntesis de Icarus Verilog es que no posee información
temporal de las compuertas para proveer un análisis temporal estático y conocer si las expectativas que se tienen se pueden cumplir.
CAPÍTULO 7: Implementación, Programación y Simulaciones
post-implementación.
En este capítulo se utiliza la herramienta WebPack de Xilinx para implementar
el archivo EDIF de síntesis. Se generan los archivos en Verilog para la simulación lógica y
la simulación temporal que completan el flujo de diseño. Además se programa el circuito
digital en el FPGA.
7.1 Proceso de implementación
En el proyecto que creó el WebPack, se seleccionó que se iba a utilizar un archivo
EDIF de síntesis para implementar el proyecto. Como se mencionó anteriormente, todas las
restricciones y parámetros del diseño se incluyeron en el archivo EDIF por lo que no era
necesario un archivo de restricciones del diseño. El formato EDIF permite que toda la información vaya implícita.
También, era importante revisar que la familia, el modelo, el empaquetado y la velocidad del FPGA en el cual se iba a programar el proyecto concordaran con el dispositivo
para el cual se realizó el proceso de síntesis.
Proceso de Traducción: Translate
En el proceso de translate, se toma el archivo EDIF de síntesis y se convierte a un
formato propietario de Xilinx llamado: NGD (Native Generic Design) contiene componentes lógicos: puertas lógicas, biestables, RAMs, etc. En este proceso se revisa que el archivo
EDIF no contenga errores, de ser así se detiene el proceso. Todos los mensajes de información, de error y de advertencia son escritos en el archivo de texto Translation Report.
Los errores se producen por una incorrecta escritura del archivo o por problemas propios del circuito diseñado como cortocircuitos, conexiones sin carga, entre otros.
Se encontraron en el archivo Translation Report, mensajes de información como el
siguiente:
50
51
INFO:NgdBuild:889 - Pad net 'clk' is not connected to an external port in
this design. A new port 'clk' has been added and is connected to this
signal.
Donde se están creando los puertos del circuito y aparece uno por cada puerto de entrada o salida del circuito.
También aparecieron mensajes de error como el siguiente:
ERROR:NgdBuild:455 - logical net 'N602' has multiple driver(s):
pin Q on block U322 with type FDCE,
pin Q on block U306 with type FDCE
Este error indicaba que existía una conexión que es manejada por más de una celda y significaba una contención (cortocircuito) en el circuito sintetizado. Este tipo de errores no son
identificados por Icarus Verilog durante el proceso de síntesis. Solucionar este error fue difícil, ya que se conocía la conexión y las instancias que lo generaban en el archivo EDIF,
pero no el código en Verilog, ni el módulo de donde se inferían. Básicamente Icarus Verilog asigna nombres genéricos a las conexiones, excepto en los puertos de salida o entrada,
en vez de nombres relacionados a la descripción en Verilog, esta situación constituye una
debilidad del proceso de síntesis y de la herramienta que se debe mejorar.
Para solucionar estos errores, se tuvo que sintetizar cada módulo en Verilog del diseño por separado y realizar la etapa de traslate con cada uno de ellos. Esto permitió aislar el
módulo en Verilog que causaba la contención y posteriormente revisarlo exhaustivamente
hasta encontrar el error de diseño o de escritura.
Durante la etapa de traslate, se puede generar un módulo en Verilog del circuito sintetizado que describe en bajo nivel el circuito diseñado y utiliza la librería de Xilinx de
primitivas de Verilog. No representa la verdadera implementación del circuito y no es sintetizable, pero es un modelo funcional del circuito sintetizado por Icarus Verilog.
Simulación Lógica
El archivo anterior permitió realizar la simulación lógica para comprobar que el archivo de síntesis no poseía ningún error y que concordaba con las especificaciones del di-
52
seño. No obstante, esta simulación era ideal pues todavía no se posee información de los retardos de cada compuerta y de enrutamiento.
Este archivo constituyó la forma de comprobar que Icarus Verilog, sintetizaba correctamente las descripciones en Verilog de cada circuito en forma individual. La simulación
para el circuito completo se logró compilar sin embargo no se utilizó debido al tamaño del
archivo y al tiempo de simulación. Además, se tenían las simulaciones individuales de los
circuitos para verificar el proceso de síntesis de Icarus Verilog.
Como se mencionó anteriormente, este archivo necesita de la librería de Verilog de
Xilinx para su compilación, pero además se debe incluir un archivo extra llamado glbl.v
que contiene el módulo glbl. Para realizar simulaciones con este archivo de translate era
necesario modificar el módulo principal con el siguiente código:
reg GSR;
assign glbl.GSR =GSR;
initial
begin
GSR =1;
#100 GSR = 0;
end
Este código se utiliza para simular el tiempo de inicialización del FPGA. Con el proceso initial se indica que el tiempo de inicialización es de 100 unidades hasta que la señal
GSR sea cero. También, se debía modificar el banco de pruebas adecuadamente para que se
inicien las pruebas 100 unidades de tiempo después ya que durante el tiempo de inicialización el circuito no va a responder en la simulación hasta que GSR sea cero.
Cuando se realizaba la compilación con Icarus Verilog, la librería de Verilog de
Xilinx contenía expresiones que eran no soportadas por la herramienta. Por lo que se optó
por copiar el directorio de la librería para cambiar las expresiones que generaban los errores
por otras equivalentes soportadas por Icarus Verilog, para luego utilizar el nuevo directorio
para la compilación con Icarus Verilog para obtener una compilación exitosa.
7.1.2 Proceso de Mapeo: Map
53
En esta etapa se mapean mediante los componentes lógicos en los componentes físicos de que dispone la FPGA las tablas LUT, los biestables, los buffers triestado, etc. Se encapsulan estos componentes físicos en bloques configurables (CLBs e IOBs), creando un
fichero de salida en formato NCD (Native Circuit Design). Todos los errores, advertencias
y mensajes de información durante esta etapa se escriben en el archivo de texto: Map Report.
En el Map Report, se encontraron los siguientes mensajes de información:
INFO:MapLib:535 - The following Virtex BUFG(s) is/are being retargetted
to
Virtex2 BUFGMUX(s) with input tied to I0 and Select pin tied to constant 0:
BUFG symbol "U9" (output signal=N0)
INFO:MapLib:159 - Net Timing constraints on signal clk are pushed forward
through input buffer.
Este primer mensaje indicaba que se va a utilizar la celda BUFGMUX en vez de la
celda BUFG para manejar la señal de reloj. Esto ocurre porque el SPARTAN3E solo posee
BUFGMUX y el cambio no afectaba el circuito. El segundo mensaje indicaba que se identificó una restricción de tiempo en la señal clk que corresponde al periodo de reloj establecido.
En esta etapa era importante revisar que se identificaron correctamente las restricciones y parámetros de los puertos de entrada y salida del circuito. A continuación se presenta
la utilización de recursos:
Design Summary
-------------Number of errors:
Number of warnings:
0
29
Logic Utilization:
Number of Slice Flip Flops:
Number of 4 input LUTs:
4,327 out of
29,504
14%
10,466 out of
29,504
35%
Logic Distribution:
Number of occupied Slices:
7,476 out of
Number of Slices containing only related logic:
14,752
7,476
100%
0 out of
7,476
0%
Number of Slices containing unrelated logic:
*See NOTES below for an explanation of the effects of unrelated logic
Total Number 4 input LUTs:
11,870 out of
50%
7,476 out of
29,504
40%
54
Number used as logic:
Number used as a route-thru:
10,466
1,084
Number used for 32x1 RAMs:
320
(Two LUTs used per 32x1 RAM)
Number of bonded IOBs:
68 out of
IOB Flip Flops:
250
27%
38
Number of GCLKs:
2 out of
24
8%
Number of DCMs:
1 out of
8
12%
Total equivalent gate count for design:
160,733
Figura 7.1 Resumen de recursos utilizados en el FPGA, circuito completo
7.1.3 Proceso de Posicionamiento y Enrutamiento: Place and Route
En esta etapa se pasa a realizar el posicionamiento e interconexión de los bloques
configurables en el FPGA y se genera un fichero de lista de conexiones en formato NCD.
Una vez finalizado este proceso se dispone de toda la información de retardos internos
(elementos activos e interconexiones).
Todos los resultados obtenidos son escritos en el archivo de texto: Place and Route
Report. En este reporte era importante el Clock Report, que muestra las conexiones de reloj,
y se podía revisar si se cumplían con las restricciones temporales del diseño. Este reporte
muestra el periodo de reloj solicitado y el periodo de reloj obtenido. En caso que no cumplan, se muestra el máximo de niveles lógicos que existen entre los elementos secuenciales
de la conexión, muestra el tiempo faltante para cumplir con las restricciones y el número de
caminos que no satisfacen el periodo de reloj.
**************************
Generating Clock Report
**************************
-----------------------------------------------------------------------------------------------------Constraint
| Requested | Actual
| Logic | Absolute
|Number of
|
|
| Levels | Slack
|errors
-----------------------------------------------------------------------------------------------------* PERIOD analysis for net "N37717" derived | 20.000ns
| 19.923ns
| 1
| 0.077ns
| 0
from NET "N37742" PERIOD = 20 ns HIGH 50 |
|
|
|
|
%
|
|
|
|
|
-----------------------------------------------------------------------------------------------------PERIOD analysis for net "N37723" derived | 200.000ns | 197.003ns | 5
| 2.997ns
| 0
from NET "N37742" PERIOD = 20 ns HIGH 50 |
|
|
|
|
%
|
|
|
|
|
-----------------------------------------------------------------------------------------------------NET "N37742" PERIOD = 20 ns HIGH 50%
| N/A
| N/A
| N/A
| N/A
| N/A
------------------------------------------------------------------------------------------------------
Figura 7.2 Reporte final de relojes del WebPack, circuito completo
55
Este reporte de reloj constituyó la única forma de conocer si las especificaciones de
diseño se cumplían. En esta etapa, ocurrió que las máquinas de estado con arquitectura microprogramada no convergían cuando se tenían muchos estados, razón por la cual se optó
por la arquitectura one-hot y se tuvo que realizar un ajuste en la alineación de los diferentes
relojes para llegar a obtener un circuito libre de errores temporales.
Simulación Temporal
Después de realizar esta fase, se tiene la información para realizar simulaciones temporales del diseño completo. Se puede generar un archivo en Verilog con base en los componentes físicos de la FPGA y un fichero SDF con los retardos internos del FPGA.
Sin embargo, Icarus Verilog en su última versión, no posee soporte para utilizar el archivo
SDF (Standard Delay Format) que contiene los retardos correspondientes para cada compuerta. Lo cual impidió realizar simulaciones post-implementación de retardos reales. Esta
limitación hizo que la simulación en esta etapa fuera solamente lógica como en la etapa de
translate y complicó la identificación de los problemas de temporización de diseño. Para
más detalle revisar el apéndice D.
7.1.4
Programación del FPGA y pruebas en circuito
Para esta etapa se programó el FPGA con el archivo .bit obtenido. Se preparó en Ma-
tlab un código equivalente al circuito diseñado para realizar comparaciones cualitativas que
se puede encontrar en el apéndice C.
Durante las pruebas del circuito real, se obtuvieron resultados exitosos, ya que el circuito
logró grabar, almacenar y reproducir voz en PCM y LPC exitosamente. Los resultados fueron sustancialmente equivalentes al equivalente en software del circuito elaborado en Matlab.
CAPÍTULO 8: Conclusiones y recomendaciones
Este capítulo presenta las principales conclusiones y recomendaciones a las que se
llegó una vez finalizado el proyecto.
Conclusiones con respecto a los objetivos del proyecto:
•
Se desarrolló un procedimiento de diseño e implementación de circuitos digitales
mediante herramientas EDA de código abierto. Se utilizaron herramientas de código
abierto de uso general que permiten construir el circuito digital en cualquier dispositivo con una dependencia en el fabricante para el proceso de implementación. El
procedimiento fue extensamente documentado y como resultado del proyecto se obtuvo una guía detallada para que sea utilizada ampliamente.
•
Se diseñó y se describió en Verilog la arquitectura de un circuito digital que realiza
en hardware la codificación/decodificación de predicción lineal de la voz humana.
•
Se estableció la etapa de síntesis para la arquitectura Virtex y se programó en el
FPGA SPARTAN3E de Xilinx, obteniéndose un circuito digital real con un funcionamiento exitoso.
Conclusiones con respecto al procedimiento planteado:
•
El procedimiento y las herramientas utilizadas tienen la capacidad de desarrollar
circuitos digitales de forma generalizada. Sin embargo se debilita conforme aumenta el tamaño del circuito que se desea implementar y se tiene como límite la capacidad de la computadora anfitriona donde se lleve acabo.
•
Existen vacíos durante el flujo principalmente en el análisis temporal y la visualización de esquemáticos donde se depende de la herramienta del fabricante.
Recomendaciones para trabajos futuros:
56
57
•
Solucionar las limitaciones y errores de Icarus Verilog presentados en este proyecto
para el proceso de síntesis en la arquitectura Virtex mediante modificaciones en el
código fuente.
•
Adicionar soporte para SDF al proceso de compilación para simulaciones no ideales.
•
Mejorar el proceso de síntesis para que sea más robusto: Agregar información temporal de la arquitectura para análisis y reportes de temporización, obtención de un
archivo EDIF resultante que posea una correspondencia con el código en Verilog.
Incluir estimaciones de consumo de potencia.
•
Desarrollar una aplicación para la visualización en forma parcial o completa de esquemático a partir de un archivo en formato EDIF.
•
Ejecutar y verificar el procedimiento para otro tipo de dispositivo programable de
otro fabricante y analizar su posible aplicación para VLSI.
BIBLIOGRAFÍA
Libros y tesis:
[1] Alvarado, M. “-PC2SCT- Implementación de Interfaz para Pruebas Estructu-
rales en Microprocesadores”, Proyecto Eléctrico, Universidad de Costa Rica, 2004
[2] Arellano, R. Cartin, Cruz J. “Modelado y Síntesis de la CPUCR”, Proyecto Electrico, Universidad de Costa Rica, 2003
[3] Ingle, V. “Digital Signal Processing Using MATLAB”, Brooks/Cole Publishing
Company, 2000.
[4] Murillo, D. “Filtro Digital implementado en un PLD”, Proyecto Eléctrico, Universidad de Costa Rica, 2004.
[5] Rodríguez, R. “Dispositivos lógicos programables, características, flujo de dise-
ño e implementación de la CPUCR utilizando un FPGA”, Tesis de licenciatura en
ingeniería eléctrica, Universidad de Costa Rica, 2004.
[6] Thomas, D. “The Verilog Hardware Description Language”, Tercera Edición,
Kluwer Academic Publishers, Estados Unidos de América, 1996.
Artículos:
[7] Álvarez, L. “Historia de los circuitos digitales configurables”,
http://www.dte.uvigo.es/logica_programable/documentos/curso_disenho_digital_con_C
DCs/Documento_historia_PLDs.pdf.
[8] Barriga, A. “Taller de diseño de sistemas electrónicos basados en FPGA”, Instituto de Microelectrónica de Sevilla – UCR, 2006.
[9] Buj, R. “Procedimiento de diseño de circuitos digitales mediante FPGAs”,
www.recercat.net/bitstream/2072/3834/1/Buj.pdf, 2007.
[10] Fernández, L. “Difusión y Multimedia”,
www.neutron.ing.ucv.ve/comunicaciones/Asignaturas/DifusionMultimedia/Difus&Mul
timedia04.pps, Universidad Central de Venezuela.
58
59
[11] Mateos, R. “DISEÑO EN VHDL PARA FPGAs”,
http://www.depeca.uah.es/docencia/INGECA/dse/lab/course_projects/p2/enunciado.pdf.
[12] Morales, M. “Introducción a los FPGAs y el Cómputo Reconfigurable”,
http://ccc.inaoep.mx/~mmorales/documents/FPGAsyReconfig.pdf, 2006.
[13] Oregon State University, “Chapter 7 Linear Predictive Speech Processing”,
www.engineer.tamuk.edu/SPark/chap7.pdf, 2004.
Sitios Web:
[14] Curso audiovisual interactivo de codificación de voz,
http://ceres.ugr.es/~alumnos/luis/codif.htm, Septiembre del 2007.
[15] FPGA, http://es.wikipedia.org/wiki/FPGA, Septiembre del 2007.
[16] GTKWave, http://home.nc.rr.com/gtkwave/, Septiembre 2007.
[17] Icarus Verilog, http://www.icarus.com/eda/verilog/, Septiembre 2007.
[18] ISE-Help, http://toolbox.xilinx.com/docsan/xilinx7/help/iseguide/iseguide.htm,
Septiembre 2007.
[19] Speech Compression, http://www.data-compression.com/speech.shtml , Septiembre del 2007.
[20] Wideband Speech Coding with Linear Predictive Coding (LPC),
http://www.ee.ucla.edu/~spapl/projects/ee214aW2002/1/report.html, Septiembre del
2007.
APÉNDICE A: Diagrama de estados de los circuitos
A.1 Controlador A/D
A.1.1 Registros:
Muestra1 => Almacena la muestra recibida invertida.
Ganancia => Almacena la ganancia del pre-amplificador.
Listo => Almacena el estado del circuito: controlador A/D.
Listo_muestra => Almacena el estado de la muestra recibida.
DAC_CS => Almacena el estado del chip select del DAC.
AMP_CS => Almacena el estado del chip select del pre-amplificador.
Cont => Contador para desplazar bits de la ganancia del pre-amplificador.
AD_CONV =>Almacena el estado de la señal de disparo de muestreo del ADC.
Muestra =>Almacena la muestra recibida.
Est2_8 =>Almacena estados auxiliares para los contadores.
Est2_4 => Almacena estados auxiliares para los contadores.
Est2_9 => Almacena estados auxiliares para los contadores.
Cont2 => Contador para desplazar bits de la muestra recibida.
Cont3 => Contador para controlar frecuencia de muestreo.
SPI_SS_B => Almacena estado de dispositivo externo que comparte el bus tri-estado en la tarjeta de desarrollo del FPGA.
SF_CEO => Almacena estado de dispositivo externo que comparte el bus tri-estado en la tarjeta de desarrollo del FPGA.
FPGA_INIT_B => Almacena estado de dispositivo externo que comparte el bus tri-estado en la tarjeta de desarrollo del
FPGA.
AMP_SHDN => Almacena estado de encendido del pre-amplificador.
A.1.2 Diagrama de Estado:
Estado Presente Descripción del estado
Condición
60
Próximo Estado
61
Verdadera=1
Estado0
AMP_CS =1, AD_CONV =0
Reset==1?
Estado1
Estado1
DAC=0
Estado2
Estado2
AMP_CS=0, SPI_MOSI=ganancia[7], cont=0
Estado3
Estado3
SPI_MOSI=ganancia[7]<<1, cont++
Cont==7?
Estado4
Estado4
AMP_CS=1, cont=0, cont2 =0, cont3=0, DAC=1 Estado5
Estado5
listo =1
Muestrear==1? Estado6
Estado6
AD_CONV=1
Estado7
Estado7
Cont++, AD_CONV=0,
Cont==2?
Estado8
Estado8
SPI_MISO => muestra, cont=0, cont2++
cont2==13?
Estado9
Estado9
cont2 =0, cont3++, listo_muestra=1
Cont3==606?
Estado10
Estado10
cont3=0
Estado5
Tabla A.1 Diagrama de Estado del Controlador A/D
A.2 Controlador D/A
A.2.1 Registros:
DA_registro => Almacena la muestra enviada.
Listo => Almacena el estado del circuito: controlador D/A.
Listo_muestra => Almacena el estado de la muestra enviada.
DAC_CS => Almacena el estado del chip select del pre-amplificador.
Cont => Contador para desplazar bits de la muestra enviada.
Cont2 => Contador para controlar frecuencia de reproducción.
DAC_CLR => Almacena estado de encendido del DAC.
A.2.2 Diagrama de Estado:
Falso=0
Estado0
Estado3
Estado5
Estado7
Estado8
Estado9
-
62
Estado Presente
Descripción del estado
Estado0
Estado1
Estado2
SD_CKE =0
DAC_CS_AD
Listo=1
SPI_MISO<=DA_registro[23], cont =0,
Estado3
listo=0, cont2=0
Estado4
DAC_CS=0
Estado5
SPI_MISO<=DA_registro[23]<<1, cont=32?
Estado6
DAC_CS=1, listo_muestra=1,
Estado7
Tabla A.2 Diagrama de Estado del Controlador D/A
Condición
Próximo Estado
Verdadero=1
Reset==1?
Estado1
DAC_CS_AD==0? Estado2
Reproducir==1?
Estado3
Falso=0
Estado0
Estado1
Estado2
-
Estado4
-
Cont==32?
Cont2==598?
-
Estado5
Estado6
Estado7
Estado2
Estado5
Estado6
-
A.3 Controlador de Memoria
A.3.1 Registros:
SD_CKE => almacena el estado de la señal SD_CKE de la memoria DRAM.
CLK_EN => almacena el estado de la señal CLK_EN de la memoria DRAM.
Cont1 => contador de comandos Nop.
Cont2 => contador de comandos Nop.
Cont3 => contador de tiempo de refrescamiento, comando=>Autorefresh..
Comando => almacena la operación que ejecuta la DRAM.
Dirección => almacena la dirección que se esta accesando para escritura o lectura.
Bandera_escritura => almacena el modo en que se está utilizando la DRAM.
Lectura_pb => almacena la parte baja del dato leído de la DRAM.
Lectura_pa => almacena la parte alta del dato leído de la DRAM.
63
Listo => Almacena el estado del circuito.
A.3.2 Diagrama de Estado:
Estado Presente
Estado0
Estado1
Estado2
Estado3
Estado4
Estado5
Estado6
Estado7
Estado8
Estado9
Estado10
Estado26
Estado11
Estado12
Estado13
Estado14
Estado15
Estado16
Estado17
Estado18
Descripción del estado
Condición
Próximo Estado
Verdadero=1
Inicialización CKE=0
Reset==1?
Estado1
Habilitar clk y clk# a la memoria inicializar cont1=0 Estado2
Esperar cont1=20000ciclos
cont1==20000?
Estado3
Comando=Nop CKE=1
Estado4
Comando=Precharge all
Estado5
Comando=LMR BA=01 E=0000000000000
Estado6
Comando=LMR, BA=00 E=00000101100001
Estado7
Comando=Precharge all
Estado8
Comando=autorefresh, cont2=0
Estado9
Comando=Nop
Cont2==7?
Estado10
Comando=Autorefresh, cont3=0
Estado26
Listo=1, esperar 200 ciclos de reloj
Cont1=
=200? Estado11
Revisar tiempo restante para autorefresh
Cont3==750?
Estado14
Iniciar
Iniciar==1?
Estado13
Saltar a estado11
Estado11
Comando=Autorefresh, cont2=0, cont3=0
Estado15
Comando=Nop
cont2==7?
Estado16
Saltar al estado11
Estado11
Comando=Active, listo=0
Estado18
Comando=Nop
Escritura?
Estado22
Falso=0
Estado0
Estado2
Estado9
Estado26
Estado12
Estado17
Estado15
Estado19
64
Estado19
Comando=Read
Estado20
Comando=Precharge all, lectura
Estado21
Saltar al estado11
Estado22
Comando=Write, cont2 =0, bandera_escritura=1
Estado23
Comando=Nop
Estado24
Comando=Precharge all, bandera_escritura=0
Estado25
Comando=Nop, saltar al estado11
Tabla A.3 Diagrama de Estado del Controlador de Memoria
cont2==3?
-
Estado20
Estado21
Estado11
Estado23
Estado24
Estado25
Estado11
Estado24
-
A.4 Controlador de Reproducción
A.4.1 Registros
SD_banco => Almacena el banco de la memoria DRAM que se esta accediendo.
SD_fila => Almacena la fila de la memoria DRAM que esta accediendo.
SD_columna => Almacena la columna de la memoria DRAM que esta accediendo.
SD_escribir => Almacena el modo en que se esta accediendo la memoria DRAM.
REP_fila => Almacena la fila final de la grabación.
REP_columna => Almacena la columna final de la grabación.
SD_iniciar => Almacena el estado de inicio del controlador de memoria.
AD_muestrear => Almacena el estado de muestreo del controlador A/D
DA_reproducir => Almacena el estado de reproducción del controlador D/A
REP_listo => Almacena el estado del circuito.
CODE_iniciar => Almacena el estado de inicio del controlador de codificación.
A.4.2 Diagrama de Estado
Estado
Descripción del estado
Condición
Próximo Estado
65
Presente
Estado0
Estado1
Estado2
Estado3
Estado4
Estado6
Reset Ex negado
AD & DA & SD listo
Listo=1
Reproducir
Saltar a revisar Grabar
Listo=0, BA:00, Fila:0, Columna:0,
Escribir=1
AD:muestrear=1
Estado7
Esperar AD:listo muestra
Estado8
Estado9
Estado10
Estado12
Estado13
Estado14
Estado15
Estado16
SD_dato<=AD:muestra
SD:Iniciar=1
Esperar SD:listo=0
SD:iniciar=0,
Saltar si es columna es 1022 (máximo)
Columna+2
saltar si es fila es 8191 (máximo)
Fila++, columna=0
Saltar memoria llena
Esperar SD:listo
Estado17
Esperar AD:listo_muestra
Estado18
Revisar grabar
AD:muestrear=0, REP_fila<=SD_fila,
REP_columna<=SD_columna
CODE: Iniciar=1
Esperar CODE:listo
Estado5
Estado11
Estado19
Estado20
Estado21
Reset==1?
AD & DA & SD listo==1?
Grabar==1?
Reproducir==1?
-
Verdadero=1
Estado1
Estado2
Estado5
Estado24
Estado2
Falso=0
Estado0
Estado1
Estado3
Estado4
-
-
Estado6
-
AD:listo_muestra
==1?
SD:listo==0?
Estado7
-
Estado8
Estado7
Estado9
Estado10
Estado11
Estado10
Columna==1022?
Estado13
Estado12
Fila==8191?
SD:listo==1?
AD:listo_muestra
==0?
Grabar==1?
Estado16
Estado15
Estado16
Estado19
Estado17
Estado14
-
Estado18
Estado17
Estado7
Estado19
-
Estado20
-
CODE:listo==0?
Estado21
Estado22
Estado21
Estado16
66
Estado22
Estado23
CODE:iniciar=0
CODE:listo==1?
saltar a revisar grabar
Listo=0,BA:Codificado, Fila:0, Columna:0,
Estado24
Escribir=0
Estado25 SD: Iniciar=1
Estado26 Esperar SD:listo
SD:listo==0?
Estado27 SD:iniciar=0,Esperar SD:listo
SD:listo==1?
Estado28 Copiar dato a DA
Estado29 DA: Iniciar=1
Estado30 Esperar DA: listo
DA: listo==0?
DA:iniciar=0,
Estado31
Columna==1022?
Saltar si es columna es 1022 (máximo)
Estado32 Columna+2
Estado33 saltar si es fila es 8191 (máximo)
Fila==8191?
Estado34 Fila++, columna=0
Estado35 Saltar memoria llena
Estado36 Fila menor igual que Fila grabada?
SD_Fila menor <= REP_Fila?
Estado37 Columna menor igual que Columna grabada? SD_columna <= REP_columna?
Estado38 Esperar DA:listo
DA:listo==1?
Estado39 Revisar Reproducir
Reproducir==1?
Estado40 Saltar a inicio
Tabla A.4 Diagrama de Estado del Controlador de Reproducción
A.5 Controlador de Codificación
A.5.1 Registros
Cont => contador de datos accedidos en la DRAM.
Estado23
Estado2
Estado22
-
Estado25
-
Estado26
Estado27
Estado28
Estado29
Estado30
Estado31
Estado26
Estado27
Estado30
Estado33
Estado32
Estado36
Estado35
Estado36
Estado40
Estado37
Estado36
Estado39
Estado25
Estado2
Estado34
Estado38
Estado38
Estado38
Estado40
67
Dato_temporal => Almacena dato para escribir de la DRAM a la RAM.
SD_banco => Almacena el banco que se está accediendo en la DRAM.
SD_fila => Almacena la dirección fila que se está accediendo en la DRAM.
SD_columna => Almacena la dirección columna que se está accediendo en la DRAM.
SD_escribir => Almacena estado para escritura en la DRAM.
SD_iniciar => Almacena estado de inicio del circuito: controlador de memoria.
RAM_dir => Almacena dirección de la RAM que está accediendo.
RAM_escribir => Almacena estado para escritura en la RAM.
CODE_listo => Almacena estado del circuito.
CRUCE_iniciar => Almacena estado de inicio del circuito: Sonido con/sin voz.
LD_iniciar => Almacena estado de inicio del circuito: Coeficientes R.
FG_iniciar => Almacena estado de inicio del circuito: filtro de síntesis.
FPR_iniciar => Almacena estado de inicio del circuito: filtro de análisis.
A.5.2 Diagrama de Estado
Estado
Descripción de estado
Presente
Condición
Estado0
Estado1
Estado2
Estado3
Estado4
Estado5
Estado6
SD_iniciar =0, dato_temporal=0
Listo=1
Listo=0, SD_BA=00, SD_Fila=0,
SD_Columna=0, Escribir=0, cont=0, RAM_dir=cont
SD: Iniciar=1
Esperar SD:listo
SD:iniciar=0
Mantisa_dato_temporal[13:0]= dato DRAM,
Próximo Estado
Reset==1?
Iniciar==1?
Verdadero=1
Estado1
Estado2
Falso=0
Estado0
Estado1
-
Estado3
-
SD:listo==0?
SD:listo==1?
-
Estado4
Estado5
Estado6
Estado7
Estado4
Estado5
-
68
Estado7
Estado8
exp_dato_temporal=23
Dato_temporal[13:0]=0
Dato_temporal=0
Estado9
Dato_temporal[13:0] negativo
Estado10
Estado11
Estado12
Estado13
Estado14
Estado15
Estado16
Estado17
Estado18
Estado19
Estado20
Estado21
Dato_temporal[13:0]=~Dato_temporal+1,
Dato_temporal_signo=1
Dato_temporal normalizado
Mantisa_dato_temporal<<1, exp_dato_temporal-RAM_escribir=1
No se usa
No se usa
No se usa
No se usa
No se usa
CODEcolumna+2,
Saltar si es columna es 1022 (maximo) ,
RAM_escribir=0
Columna+2
Fila++ columna=0
Estado22 Columna menor igual que Columna grabada
Estado23 Fila menor igual que Fila grabada
Estado24
Estado25
Estado26
Estado27
Estado28
saltar a inicio
Cont
cont++ saltar a inicio
Cruce:Iniciar=1
Esperar Cruce:listo
Dato_temporal==0?
Dato_temporal[13:0]
es negativo?
Estado8
Estado13
Estado9
-
Estado10
Estado11
-
Estado11
-
Dato_temporal normalizado?
-
Estado13
Estado11
Estado19
-
Estado12
-
Columna==1022?
Estado21
Estado20
Columna <=
Columna grabada?
Fila menor igual
que Fila grabada?
cont==159?
Cruce:listo==0?
Estado22
Estado22
-
Estado23
Estado25
Estado24
Estado25
Estado1
Estado26
Estado27
Estado28
Estado29
Estado27
Estado26
Estado28
-
69
Estado29 Cruce:iniciar=0, Esperar Cruce:listo
Cruce:listo==1?
Estado30 LD:Iniciar=1
Estado31 LD:listo
LD:listo==0?
Estado32 LD:iniciar=0,Esperar LD:listo
LD:listo==1?
Estado33 FG:Iniciar=1
Estado34 Esperar FG:listo
FG:listo==0?
Estado35 FG:iniciar=0, Esperar FG:listo
FG:listo==1?
Estado36 FPR:Iniciar=1
Estado37 Esperar FPR:listo
FPR:listo==0?
Estado38 FPR:iniciar=0,Esperar FPR:listo
FPR:listo==1?
Estado39 cont=0, columna=0, saltar inicio
Tabla A.5 Diagrama de Estado del Controlador de Codificación
A.6 Sonido con/sin Voz
A.6.1 Registros
Bandera => almacena el estado de la dirección del ultimo cruce por cero.
Cont => contador de direcciones accedidas en la memoria RAM.
Cont_CRUCE => contador de cruces por cero de la trama de voz de 20 ms.
Resultado => Almacena el resultado del circuito: Sumador o Divisor.
RAM_dir => Almacena dirección de la RAM que está accediendo.
RAM_escribir => Almacena estado para escritura en la RAM.
Sumador_iniciar => Almacena el estado de inicio del circuito: Sumador.
Sumar_restar =>Almacena el modo de suma o resta del circuito: Sumador.
Div_iniciar => Almacena el estado de inicio del circuito: Divisor.
Op1 => Almacena el operando1 para enviar al circuito: Sumador o Divisor.
Op2 => Almacena el operando2 para enviar al circuito: Sumador o Divisor.
Estado30
Estado31
Estado32
Estado33
Estado34
Estado35
Estado36
Estado37
Estado38
Estado39
Estado3
Estado29
Estado31
Estado32
Estado34
Estado35
Estado37
Estado38
-
70
Pitch_iniciar => Almacena el estado de inicio del circuito: Detección de Pitch.
Cruce_listo => Almacena el estado del circuito.
Pitch => Almacena el valor del pitch de la trama de voz.
A.6.2 Diagrama de Estado
Estado Presente
Descripción del estado
Estado0
Estado1
Estado2
Estado3
Estado4
Estado5
Estado6
Estado7
Estado8
Estado9
Estado10
Estado11
Estado12
Estado13
RAM_dir=cont, RAM_escribir=0, cont_160=0
Listo=1
Listo=0,promedio=0, cruce=0,bandera=0,PITCH=0
RAM lectura
No se usa
No se usa
Op2=RAM_dato
No se usa
No se usa
No se usa
No se usa
Sumador:Iniciar=1, Sumar_restar=1
Esperar Sumador:listo
Sumador:iniciar=0, Sumar_restar=0
Promedio=sumador_resultado,
op1=sumador_resultado, op2=160
cont
cont++, saltar a inicio
Div:Iniciar=1, cont=0
Estado14
Estado15
Estado16
Estado17
Condición
Próximo Estado
Reset==1?
Iniciar==1?
Sumador:listo==0?
Sumador:listo==1?
Verdadero=1
Estado1
Estado2
Estado3
Estado6
Estado11
Estado12
Estado13
Estado14
Falso=0
Estado0
Estado1
-
-
Estado15
-
Cont==159?
-
Estado17
Estado3
Estado18
Estado16
-
Estado12
Estado13
71
Estado18
Estado19
Estado20
Estado21
Estado22
Estado23
Estado24
Estado25
Estado26
Estado27
Estado28
Estado29
Estado30
Estado31
Estado32
Esperar Div:listo
Div:iniciar=1, Esperar Div:listo
Promedio=divisor_resultado
RAM_dato
No se usa
No se usa
op1= RAM_dato
No se usa
No se usa
No se usa
No se usa
Sumador:Iniciar=1, Sumar_restar=2
Esperar Sumador:listo
Sumador:iniciar=0, Sumar_restar=0,
Esperar Sumador:listo
bandera igual signo sumador_resultado
Estado33
bandera = signo sumador_resultado, cruce++
Estado34
cont
Estado35
cont_160++, saltar a inicio2
Estado36
Cont_CRUCE mayor a 20?
Estado37
Pitch:Iniciar=1, PITCH=1
Estado38
Esperar Pitch:listo
Estado39
Pitch:iniciar=0, Esperar Pitch:listo
Estado40
cont=0, saltar a inicio
Tabla A.6 Diagrama de Estado de Sonido con/sin Voz
A.7 Detección del Pitch
Div:listo==0?
Div:listo==1?
Sumador:listo==0?
Estado19
Estado20
Estado21
Estado24
Estado29
Estado30
Estado31
Estado18
Estado19
Estado30
Sumador:listo==1?
Estado32
Estado31
Estado33
Estado34
Estado34
Estado35
Estado21
Estado37
Estado38
Estado39
Estado40
Estado40
Estado36
Estado40
Estado38
Estado39
-
bandera igual ==
sumador_resultado?
Cont==159?
Cont_CRUCE >= 20?
Pitch:listo==0?
Pitch:listo==1?
-
72
A.7.1 Registros
Cont => contador de direcciones accedidas en la memoria RAM.
Cont_K => contador de la variable K del procedimiento AMDF.
Resultado => Almacena el resultado del circuito: Sumador o Divisor.
RAM_dir => Almacena dirección de la RAM que está accediendo.
RAM_escribir => Almacena estado para escritura en la RAM.
Sumador_iniciar => Almacena el estado de inicio del circuito: Sumador.
Sumar_restar =>Almacena el modo de suma o resta del circuito: Sumador.
Div_iniciar => Almacena el estado de inicio del circuito: Divisor.
Op1 => Almacena el operando1 para enviar al circuito: Sumador o Divisor.
Op2 => Almacena el operando2 para enviar al circuito: Sumador o Divisor.
AMDF => Almacena el valor del AMDF mínimo obtenido en la trama de voz.
Kfinal => Almacena el valor de K donde se dio el menor AMDF.
Bandera => Almacena el estado de la existencia de un AMDF.
PITCH_listo => Almacena el estado del circuito.
A.7.2 Diagrama de Estado
Estado Presente
Descripción del estado
Estado0
Estado1
Estado2
Estado3
Estado4
Estado5
cont=0, RAM_dir =cont
Listo=1
Listo=0, cont_K=20,resultado=0, AMDF=0
RAM_lectura
No se usa
No se usa
Condición
Reset==1?
Iniciar==1?
-
Próximo Estado
Verdadero=1
Estado1
Estado2
Estado3
Estado6
-
Falso=0
Estado0
Estado1
-
73
Estado6
Estado28
Estado29
Estado30
Estado31
Estado32
Estado33
Estado34
Estado35
Estado7
Estado8
Estado9
Estado10
Estado11
Estado12
Estado13
Estado14
Estado15
Estado16
Estado17
Estado18
Estado19
Estado20
Estado21
Estado22
Estado23
Estado24
Estado25
RAM_dir=cont+K, Op1=RAM dato
No se usa
No se usa
No se usa
No se usa
No se usa
No se usa
No se usa
No se usa
RAM lectura
No se usa
No se usa
Op2=RAM_dato, RAM_dir=cont
Sumador:Iniciar=1, Sumar_restar=1
Esperar Sumador:listo
Sumador:iniciar=0, Sumar_restar=0,
Esperar multi:listo
op1=resultado y op2=sumador_resultado
sumador:Iniciar=1
Esperar sumador:listo
Sumador:iniciar=0,Esperar sumador:listo
resultado=sumador_resultado
cont=159-K?
cont++, saltar a inicio
cont=0, op1=resultado, op2=160-K
op2_normalizado?
op2_mantisa<<1, op2_exp-1
Div:Iniciar=1
Esperar Div:listo
Sumador:listo==0?
Estado11
Estado10
Estado11
Estado12
Estado13
Estado12
Sumador:listo==1?
Estado14
Estado13
suamdor:listo==0?
suamdor:listo==1?
cont==159-K?
Div:listo==0?
Estado15
Estado16
Estado17
Estado18
Estado19
Estado20
Estado3
Estado22
Estado24
Estado22
Estado25
Estado26
Estado16
Estado17
Estado21
Estado23
Estado25
74
Estado26
Div:iniciar=0, Esperar Div:listo
Estado27
bandera=0?
Estado36
AMDF=div_resultado, KFINAL=k, bandera=1,
Estado37
div_resultado<=AMDF?
Estado38
AMDF =div_resultado, KFINAL=k
Estado39
k<160?
Estado40
k++ saltar a inicio, resultado=0
Tabla A.7 Diagrama de Estado de Detección del Pitch
Div:listo==1?
Bandera==0?
Div_resultado<=AMDF?
k<160?
-
A.8 Coeficientes R
A.8.1 Registros
Cont => contador de direcciones accedidas en la memoria RAM.
Cont_R => contador de la variable R de los coeficientes de auto correlación.
Resultado => Almacena el resultado del circuito: Sumador o Multiplicador.
RAM_dir => Almacena dirección de la RAM que está accediendo.
RAM_escribir => Almacena estado para escritura en la RAM.
Sumador_iniciar => Almacena el estado de inicio del circuito: Sumador.
Sumar_restar =>Almacena el modo de suma o resta del circuito: Sumador.
Multi_iniciar => Almacena el estado de inicio del circuito: Multiplicador.
Op1 => Almacena el operando1 para enviar al circuito: Sumador o Multiplicador.
Op2 => Almacena el operando2 para enviar al circuito: Sumador o Multiplicador.
R0..10 => Almacena el valor de los coeficientes de auto correlación.
C_iniciar => Almacena el estado de inicio del circuito: Coeficientes LPC.
R_listo => Almacena el estado del circuito.
Estado27
Estado37
Estado39
Estado38
Estado39
Estado1
Estado3
Estado26
Estado36
Estado39
Estado40
-
75
A.8.2 Diagrama de Estado
Estado Presente
Estado0
Estado1
Estado2
Estado3
Estado4
Estado5
Estado6
Estado28
Estado29
Estado30
Estado31
Estado32
Estado33
Estado34
Estado35
Estado7
Estado8
Estado9
Estado10
Estado11
Estado12
Estado13
Estado14
Descripción del estado
cont=0, RAM_Dir=cont
Listo=1
Listo=0,R=0,resultado=0
RAM lectura
No se usa
No se usa
Op1=RAM dato RAM_dir=cont+R
No se usa
No se usa
No se usa
No se usa
No se usa
No se usa
No se usa
No se usa
RAM_lectura
No se usa
No se usa
Op2=RAM_dato, RAM_dir=cont
multi:Iniciar=1
Esperar multi:listo
Bajar multi:iniciar,Esperar multi:listo
op1=multi_resultado y op2=resultado
Condición
Reset==1?
Iniciar==1?
multi:listo==0?
multi:listo==1?
-
Próximo Estado
Verdadero=1
Estado1
Estado2
Estado3
Estado6
Estado7
Estado10
Estado11
Estado12
Estado13
Estado14
Estado15
Falso=0
Estado0
Estado1
Estado12
Estado13
-
76
Estado15
sumador:Iniciar=1
Estado16
Esperar sumador:listo
Estado17
Bajar sumador:iniciar,Esperar ALU:listo
Estado18
Resultado=sumador_resultado
Estado19
cont=159-R?
Estado20
cont++, saltar a inicio
Estado21
R=10?
Estado22
R[cont_R]=resultado
Estado23
resultado=0,cont=0,R++, saltar inicio
Estado24
C:Iniciar=1, cont=0, R[cont_R]=resultado
Estado25
Esperar C:listo
Estado26
C:iniciar=0,Esperar C:listo
Estado27
Saltar a R_iniciar
Tabla A.8 Diagrama de Estado de Coeficientes R
Sumador:listo==1?
Sumador:listo==0?
Cont==159-R?
R==10?
C:listo==0?
C:listo==1?
-
Estado16
Estado17
Estado18
Estado19
Estado20
Estado3
Estado22
Estado23
Estado3
Estado25
Estado26
Estado27
Estado1
A.9 Coeficientes LPC
A.9.1 Registros
M => Almacena la variable M del método Levinson-Durbin.
I => Almacena la variable I del método Levinson-Durbin.
Sumador_iniciar => Almacena el estado de inicio del circuito: Sumador.
Sumar_restar =>Almacena el modo de suma o resta del circuito: Sumador.
Multi_iniciar => Almacena el estado de inicio del circuito: Multiplicador.
Div_iniciar => Almacena el estado de inicio del circuito: Divisor.
Resultado => Almacena el resultado del Sumador, Divisor o Multiplicador.
Op1 => Almacena el operando1 para enviar al circuito: Sumador, Multiplicador o Divisor.
Op2 => Almacena el operando2 para enviar al circuito: Sumador, Multiplicador Divisor.
Estado16
Estado17
Estado21
Estado24
Estado25
Estado26
-
77
E => Almacena el valor del error de predicción lineal del Método Levinson-Durbin.
K => Almacena el valor de K del Método Levinson-Durbin.
A1..10 => Almacena el valor de los coeficientes de predicción lineal de la trama de voz.
Temp1..9 => Almacena resultados parciales del método Levinson-Durbin.
C_listo => Almacena el estado del circuito.
A.9.2 Diagrama de Estado
Estado
Presente
Estado0
Estado1
Estado2
Estado3
Estado4
Estado5
Estado6
Estado7
Estado8
Estado9
Estado10
Estado11
Estado12
Estado13
Estado14
Estado15
Descripción del Estado
Condición
Próximo Estado
Verdadero=1
Reset
Reset==1?
Estado1
Listo=1
Iniciar==1?
Estado2
Op1= R1, Op2=R0
Estado3
Div:Iniciar=1
Estado4
Esperar Div:listo
Div:listo==0?
Estado5
Div:iniciar=0, Esperar Div:listo
Div:listo==1?
Estado6
op1=op2=Divisor_resultado, a11= Divisor_resultado
Estado7
Multi:Iniciar=1
Estado8
Esperar Multi:listo
Multi:listo==0?
Estado9
Multi:iniciar=0, Esperar Multi:listo
Multi:listo==1?
Estado10
op1=1, op2=Multi_resultado
Estado11
Sumador:Iniciar=1, Sumar_restar=10
Estado12
Esperar Sumador:listo
Sumador:listo==0? Estado13
Sumador:iniciar=0, Sumar_restar=00, Esperar Sumador:listo Sumador:listo==1? Estado14
op1=Eo=R0, op2=Sumador_resultado
Estado15
Multi:Iniciar==1
Estado16
Falso=0
Estado0
Estado1
Estado4
Estado5
Estado8
Estado9
Estado12
Estado13
-
78
Estado16
Estado17
Estado18
Estado19
Estado20
Estado21
Estado22
Estado23
Estado24
Estado25
Estado26
Estado27
Estado28
Estado29
Estado30
Estado31
Estado32
Estado33
Estado34
Estado35
Estado36
Estado37
Estado38
Estado39
Estado40
Estado41
Estado42
Estado43
Estado44
Esperar Multi:listo
Multi:iniciar=1, Esperar Multi:listo
m=2, i=1, E=Multi_resultado
R[m-i], a[i], resultado=R[m] si i=1
Multi:Iniciar=1
Esperar Multi:listo
Bajar Multi:iniciar,Esperar Multi:listo
temporal[i]=multi_resultado
i=m-1?
i++ saltar a estado19
op2=copiar temporal[i], op1=resultado
Sumador:Iniciar=1, Sumar_restar=10
Esperar Sumador:listo
Sumador:iniciar, Sumar_restar=00, Esperar Sumador:listo
q[m]=Sumador_resultado
i=1?
i-op1=resultado, op2=E
Div:Iniciar=1
Esperar Div:listo
Bajar Div:iniciar, Esperar Div:listo
a[m] =k= div_resultado op1=op2=div_resultado
Multi:Iniciar=1
Esperar Multi:listo
Bajar Multi:iniciar,Esperar Multi:listo
op1=1, op2=Multi_resultado
Sumador:Iniciar=1, Sumador_restar=10
Esperar Sumador:listo
Bajar Sumador:iniciar, bajar restar, Esperar Sumador:listo
Multi:listo==0?
Multi:listo==1?
Multi:listo==0?
Multi:listo==1?
i==m-1?
Sumador:listo==0?
Sumador:listo==1?
i==1?
Div:listo==0?
Div:listo==1?
Multi:listo==0?
Multi:listo==1?
Sumador:listo==0?
Sumador:listo==1?
Estado17
Estado18
Estado19
Estado20
Estado21
Estado22
Estado23
Estado24
Estado26
Estado19
Estado27
Estado28
Estado29
Estado30
Estado31
Estado33
Estado26
Estado34
Estado35
Estado36
Estado37
Estado38
Estado39
Estado40
Estado41
Estado42
Estado43
Estado44
Estado45
Estado16
Estado17
Estado21
Estado22
Estado25
Estado28
Estado29
Estado32
Estado35
Estado36
Estado39
Estado40
Estado43
Estado44
79
Estado45 copiar op1=Sumador_resultado, op2=E
Estado46 Multi:Iniciar=1
Estado47 Esperar Multi:listo
Estado48 Bajar Multi:iniciar,Esperar Multi:listo
Estado49 E=multi_resultado si i=1, op1=a[i], op2=K
Estado50 Multi:Iniciar=1
Estado51 Esperar Multi:listo
Estado52 Bajar Multi:iniciar,Esperar Multi:listo
Estado53 temporal[i]=multi_resultado
Estado54 i=m-1?
Estado55 i++ saltar a estado49
Estado56 op2= temporal[i], op1=a[m-i]
Estado57 Sumador:Iniciar=1, Sumar_restar=10
Estado58 Esperar Sumador:listo
Estado59 Sumador:iniciar=0, Sumar_restar=10, Esperar Sumador:listo
Estado60 a[m-i]=Sumador_resultado
Estado61 i=1?
Estado62 i--, saltar a estado56
Estado63 m=10?
Estado64 m++ saltar a estado19
Tabla A.9 Diagrama de Estado de Coeficientes LPC
A.10 Filtro de Análisis
A.10.1 Registros
Cont => contador de direcciones accedidas en la RAM.
Cont_K => contador de operaciones del filtro.
Multi:listo==0?
Multi:listo==1?
Multi:listo==0?
Multi:listo==1?
i==m-1?
Sumador:listo==0?
Sumador:listo==1?
i==1?
m==10?
-
Estado46
Estado47
Estado48
Estado49
Estado50
Estado51
Estado52
Estado53
Estado54
Estado56
Estado49
Estado57
Estado58
Estado59
Estado60
Estado61
Estado62
Estado56
Estado1
Estado19
Estado47
Estado48
Estado51
Estado52
Estado53
Estado55
Estado58
Estado59
Estado63
Estado64
-
80
Resultado => Resultado => Almacena el resultado del Sumador, Multiplicador, Divisor.
RAM_dir => Almacena dirección de la RAM que está accediendo.
RAM_escribir => Almacena estado para escritura en la RAM.
Sumador_iniciar => Almacena el estado de inicio del circuito: Sumador.
Sumar_restar =>Almacena el modo de suma o resta del circuito: Sumador.
Multi_iniciar => Almacena el estado de inicio del circuito: Multiplicador.
Div_iniciar => Almacena el estado de inicio del circuito: Divisor.
Op1 => Almacena el operando1 para enviar al circuito: Sumador, Multiplicador, Divisor, Raíz cuadrada.
Op2 => Almacena el operando2 para enviar al circuito: Sumador o Multiplicador.
u1..10 => Almacena la entradas pasadas del filtro.
Error => Almacena el error de predicción.
Temp1..10 => Almacena las multiplicaciones parciales del filtro.
RAIZ_iniciar => Almacena el estado de inicio del circuito: Raíz Cuadrada.
FG_listo => Almacena el estado del circuito.
A.10.2 Diagrama de Estado
Estado Presente
Estado0
Estado1
Estado2
Estado3
Estado4
Estado5
Estado6
Estado7
Descripción del estado
Reset
Listo=1
resultado=0, k=1, y[1…10]=0, cont=0, error=0
op1=u[k], op2= a[k]
Multi:Iniciar=1
Esperar Multi:listo
Multi:iniciar=0,Esperar Multi:listo
temporal[k]=Multi_resultado
Condición
Reset==1?
Iniciar==1?
Multi:listo==0??
Multi:listo==1?
-
Próximo Estado
Verdadero=1
Estado1
Estado2
Estado3
Estado4
Estado5
Estado6
Estado7
Estado8
Falso=0
Estado0
Estado1
Estado5
Estado6
-
81
Estado8
Estado9
Estado10
Estado11
Estado12
Estado13
Estado14
Estado15
Estado16
Estado17
Estado18
Estado19
Estado20
Estado21
Estado22
Estado23
Estado24
Estado25
Estado26
Estado27
Estado28
Estado29
Estado30
Estado31
Estado32
Estado33
k=10?
k++ saltar a estado3
op2=temporal[k], op1=resultado, u(k-1)=u(k)
Sumador:Iniciar=1, Sumar_restar=01
Esperar Sumador:listo
Sumador:iniciar=0, Sumar_restar=00,
Esperar Sumador:listo
resultado=Sumador_resultado
k=1?
k--, saltar a estado10
RAM lectura
No se usa
No se usa
op1= RAM_dato, op2=resultado
No se usa
No se usa
No se usa
No se usa
Sumador:Iniciar=1, Sumar_restar=10, u1=op1
Esperar Sumador:listo
Sumador:iniciar=0, Sumar_restar=0,
Esperar Sumador:listo
op1=Sumador_resultado, op2=Sumador_resultado,
i=0
No se usa
No se usa
No se usa
No se usa
Multi:Iniciar=1
k==10?
Sumador:listo==0?
Estado10
Estado3
Estado11
Estado12
Estado13
Estado9
Estado12
Sumador:listo==1? Estado14
Estado13
k==1?
-
Estado15
Estado17
Estado10
Estado20
Estado21
Estado26
Sumador:listo==0? Estado27
Estado16
Estado26
Sumador:listo==1? Estado28
Estado27
-
Estado33
-
-
Estado34
-
82
Estado34
Estado35
Estado47
Estado48
Estado49
Esperar Multi:listo
Multi:iniciar=0, Esperar Multi:listo
op1=error, op2=Multi_resultado
Sumar:Iniciar=1, Sumar_restar=01
Esperar Sumar:listo
Sumar:iniciar=0, Sumar_restar=00,
Estado50
Esperar Sumar:listo
Estado36
error=Sumar_resultado
Estado37
cont=160?
Estado38
cont++, resultado=0
Estado39
op1=error, op2=R0
Estado40
Div:Iniciar=1
Estado41
Esperar Div:listo
Estado42
Div:iniciar=0, Esperar Div:listo
Estado51
op1=Div_resultado
Estado43
RAIZ: Iniciar=1
Estado44
Esperar RAIZ:listo
Estado45
RAIZ:iniciar=0,Esperar RAIZ:listo,
Estado46
Saltar a estado1
Tabla A.10 Diagrama de Estado del Filtro de Análisis
Multi:listo==0?
Multi:listo==1?
Sumar:listo==0?
Estado35
Estado47
Estado48
Estado49
Estado50
Estado34
Estado35
Estado49
Sumar:listo==1?
Estado36
Estado50
cont==160?
Div:listo==0?
Div:listo==1?
RAIZ:listo==0?
RAIZ:listo==1?
-
Estado37
Estado39
Estado3
Estado40
Estado41
Estado42
Estado51
Estado43
Estado44
Estado45
Estado46
Estado1
Estado38
Estado41
Estado42
Estado44
Estado45
-
A.11 Filtro de Síntesis
A.11.1 Registros
Cont => contador de direcciones accedidas en la ROM de ruido.
Cont_K => contador de operaciones del filtro.
Cont_rotar => Almacena el desplazamiento al valor que se va almacenar en la DRAM.
83
SD_banco => Almacena el banco que se está accediendo en la DRAM.
SD_fila => Almacena la dirección fila que se está accediendo en la DRAM.
SD_columna => Almacena la dirección columna que se está accediendo en la DRAM.
SD_escritura => Almacena el dato que se va a enviar a la DRAM.
SD_escribir => Almacena estado para escritura en la DRAM.
SD_iniciar => Almacena estado de inicio del circuito: controlador de memoria.
Sumador_iniciar => Almacena el estado de inicio del circuito: Sumador.
Sumar_restar =>Almacena el modo de suma o resta del circuito: Sumador.
Multi_iniciar => Almacena el estado de inicio del circuito: Multiplicador.
Resultado => Almacena el resultado del Sumador o Multiplicador.
Op1 => Almacena el operando1 para enviar al circuito: Sumador o Multiplicador.
Op2 => Almacena el operando2 para enviar al circuito: Sumador o Multiplicador.
y1..10 => Almacena la salidas pasadas del filtro.
Cont_pulso =>contador para generar los pulsos a la frecuencia del pitch.
Temp1..10 => Almacena las multiplicaciones parciales del filtro.
FPR_listo => Almacena el estado del circuito.
A.11.2 Diagrama de Estado
Estado
Presente
Descripción del estado
Condición
Estado0
Estado1
Estado2
Estado3
Estado4
Estado5
columna=0,fila=0,banco=01
Listo=1
resultado=0, k=1, y[1…10]=0, cont=0
op1=y[k], op2= a[k]
Multi:Iniciar=1
Esperar Multi:listo
Reset==1?
Iniciar==1?
Multi:listo==0?
Próximo Estado
Verdadero=1
Estado1
Estado2
Estado3
Estado4
Estado5
Estado6
Falso=0
Estado0
Estado1
Estado5
84
Estado6
Estado7
Estado8
Estado9
Estado10
Estado11
Estado12
Estado13
Estado14
Estado15
Estado16
Estado17
Estado18
Estado19
Estado20
Estado21
Estado22
Estado23
Estado24
Estado25
Estado26
Estado27
Estado28
Estado29
Estado30
Estado31
Estado32
Estado43
Multi:iniciar=0, Esperar Multi:listo
temporal[k]=multi_Resultado
k=10?
k++ saltar a estado3
op2=temporal[k], op1=resultado, y(k-1)=y(k)
Sumador:Iniciar=1, Sumar_restar=01
Esperar Sumador:listo
Bajar Sumador:iniciar, bajar sumar, Esperar Sumador:listo
resultado=Sumador_resultado
k=1?
k--, saltar a estado10
op1=entrada(segun Pitch) y op2=Ganancia
Multi: Iniciar=1,
Esperar Multi:listo
Bajar Multi:iniciar,Esperar Multi:listo,
op1=Multi_resultado, op2=resultado
Sumador: Iniciar=1, Sumar_restar=01
Esperar Sumador:listo
Bajar Sumador:iniciar,Esperar Sumador:listo,
SD_escritura=Sumador_resultado, rotar= (140-exponente),
cont_rotar=0
rotar=negativo?
SD_escritura=ffff
rotar>13?
SD_escritura=0
cont_rotar=rotar?
SD_escritura>>1, cont_rotar++
signo?
~SD_escritura+1
Multi:listo==1?
k==10?
Sumador:listo==0?
Sumador:listo==1?
k==1?
Multi:listo==0?
Multi:listo==1?
Sumador:listo==0?
Sumador:listo==1?
Estado7
Estado8
Estado10
Estado3
Estado11
Estado12
Estado13
Estado14
Estado15
Estado17
Estado10
Estado18
Estado19
Estado20
Estado21
Estado22
Estado23
Estado24
Estado25
Estado6
Estado9
Estado12
Estado13
Estado16
Estado19
Estado20
Estado23
Estado24
-
Estado26
-
rotar==negativo?
rotar>13?
cont_rotar==rotar?
signo?
-
Estado27
Estado32
Estado29
Estado33
Estado31
Estado30
Estado43
Estado33
Estado28
Estado30
Estado32
Estado33
-
85
Estado33 SD: Iniciar=1, SD_escribir=1
Estado34 Esperar SD:listo
Estado35 Bajar SD:iniciar,
Estado36 Saltar si es columna es 1022 (máximo)
Estado37 Columna+2 saltar a estado41
Estado38 No se usa
Estado39 Fila++, columna=0
Estao40
No se usa
Estado41 cont=160?
Estado42 cont_pulso++,cont++, resultado=0
Tabla A.11 Diagrama de Estado del Filtro de Síntesis
SD:listo==0?
SD:listo==1?
SD_columna= 1022
cont==160?
-
Estado34
Estado35
Estado36
Estado39
Estado41
Estado41
Estado1
Estado3
A.12 Sumador/Restador
A.12.1 Registros
Op1 => almacena el sumando1 o minuendo.
Op2 => almacena el sumando2 o sustraendo.
Signo => almacena el signo del resultado.
Exponente => almacena el exponente del resultado.
Mantisa => almacena la mantisa del resultado.
Listo => almacena el estado de Sumador/Restador.
A.12.2 Diagrama de Estado
Estado Pre-
Descripción del estado
Condición
Próximo Estado
Estado34
Estado35
Estado37
Estado42
-
86
sente
Estado0
Estado1
Estado2
Estado3
Estado4
Estado5
Estado23A
Estado24A
Estado8
Estado9
Estado10
Estado11
Estado12
Estado13
Estado14
Estado15
Estado16
Estado17
Estado18
Estado19
Estado20
Estado21
Estado22
Estado23
Estado24
Estado25
Estado26
Reset
Reset==1?
op1=Operando1, op2=Operando2
Iniciar==1?
Suma
Suma==1?
Resta
Resta==1?
op1=0?
op1==0?
resultado=op2
op2=0?
op2==0?
resultado=op1
Alineacion? Exponentes iguales?
Exp_op1==exp_op2?
Signo op1?
Op1 negativo?
op1= ~op1+1
Signo op2?
Op2 negativo?
op2= ~op2+1
Mantisa_resultado=mantisa_op1+ mantisa_op2 mantisa=cero?
mantisa==cero?
Resultado negativo?
Resultado negativo?
~Mantisa_resultado+1, signo_resultado=1
Rebase?
Rebase?
Exp_resultado_max?
Exp_resultado_max?
listo
Normalizado?
Normalizado?
Exp_resultado_min?
Exp_resultado_min?
Normalizar
Error overflow
Resta cambio signo_op2=~signo_op2
Op1==0?
Exp1_op1 > exp2_op2
Exp1_op1 > exp2_op2?
mantisa_op2>>1, exp_op2++
-
Verdadero=1
Estado1
Estado2
Estado4
Estado24
Estado5
Estado1
Estado24A
Estado1
Estado9
Estado10
Estado11
Estado12
Estado13
Estado13
Estado28
Estado16
Estado17
Estado18
Estado23
Estado1
Estado21
Estado22
Estado20
Estado1
Estado4
Estado26
Estado8
Falso=0
Estado0
Estado1
Estado3
Estado1
Estado23A
Estado8
Estado25
Estado11
Estado13
Estado15
Estado17
Estado20
Estado19
Estado1
Estado29
Estado30
Estado27
-
87
Estado27
Mantisa_exp1>>1, Exp_op1++
Estado28
resultado =0
Estado29
Error underflow
Estado30
Cambio signo_op2=~signo_op2
Tabla A.12 Diagrama de Estado del Sumador/Restador
-
Estado8
Estado1
Estado1
Estado4
-
A.13 Multiplicador
A.13.1 Registros
Cont => almacena la cuenta de multiplicaciones parciales.
Op1 => almacena el multiplicando.
Op2 => almacena el multiplicador.
Signo => almacena el signo del resultado.
Exponente => almacena el exponente del resultado.
Mantisa => almacena la mantisa del resultado.
Listo => almacena el estado de multiplicador.
A.13.2 Diagrama de Estado
Estado
Presente
Estado0
Estado1
Estado2
Estado3
Estado4
Descripcion del Estado
Condicion
Reset
Copiar operandos, listo=1
exp1+exp2
Resultado=0
XOR signos, exp_resultado-127, mantisa_resultado =0
Reset==1?
Iniciar==1?
op1 OR op2 ==0?
-
Proximo Estado
Verdadero=1 Falso=0
Estado1
Estado0
Estado2
Estado1
Estado3
Estado4
Estado16
Estado5
-
88
Estado5
revisar si nuevo exponente rebase arriba
Estado6
revisar si nuevo exponente rebase abajo, cont=0
Estado7
mantisa_resultado + (op1&op2[22]), cont++
Estado8
Estado9
op2 <<1 y mantisa_resultado<<1
Estado10 No se usa
Estado11 Resultado Normalizado
Estado12 mantisa_resultado>>1,exp_resultado++
Estado13 No se usa
Estado14 Error, exp_resultado rebase arriba
Estado15 Error, exp_resultado rebase abajo
Estado16 Listo
Tabla A.13 Diagrama de Estado del Multiplicador
A.14 Divisor
A.14.1 Registros
Op1 => almacena el dividendo.
Op2 => almacena el divisor.
Signo => almacena el signo del resultado.
Exponente => almacena el exponente del resultado.
Mantisa => almacena la mantisa del resultado.
Listo => almacena el estado de divisor.
A.14.2 Diagrama de Estado
exp_resultado_max?
exp_resultado_min?
cont ==24?
Resultado normalizado?
-
Estado14
Estado15
Estado8
Estado11
Estado7
Estado12
Estado11
Estado16
Estado16
Estado1
Estado6
Estado7
Estado9
Estado16
-
89
Estado Presente
Descripción del Estado
Estado0
Estado 1
Estado 2
Reset
Copiar operandos, listo=1
op1_exp1-op2_exp2
XOR signos, exp_resultado+127, mantisa_resultado
Estado 3
=0
Estado 4
op1<op2
Estado 5
exp_resultado-- , Op1<<1
Estado 6
exp_min
Estado 14
exp_max
Estado 7
op1>=op2
Estado 8
op1-op2, mantisa_resultado +1
Estado 9
op1<<1
Estado 10
Mantisa_resultado<<1 y saltar a 1
Estado 11
Error
Estado 12
Resultado =0
Estado 13
Listo=1
Tabla A.14 Diagrama de Estado del Divisor
A.15 Raíz Cuadrada
A.15.1 Registros
Cont => contador de rotaciones de op1.
Reset==1?
Iniciar==1?
Op2==0?
Próximo Estado
Falso
Verdadero=1
=0
Estado1
Estado0
Estado2
Estado1
Estado3
Estado11
Op1==0?
Estado4
Estado12
Op1>=op2?
exp_resultado_min?
exp__resultado_max?
op1>=op2?
Resultado Normalizado?
-
Estado6
Estado6
Estado12
Estado11
Estado8
Estado9
Estado13
Estado7
Estado13
Estado13
Estado1
Estado5
Estado14
Estado7
Estado9
Estado10
-
Condición
90
Rotaciones => contador de rotaciones de op2.
Op1 => almacena el radicando.
Op2 => almacena el operando auxiliar para obtener la raíz cuadrada.
Signo => almacena el signo del resultado.
Exponente => almacena el exponente del resultado.
Mantisa => almacena la mantisa del resultado.
Listo => almacena el estado del circuito.
A.15.2 Diagrama de Estado
Estado
Descripción del Estado
Estado0
Estado1
Estado2
Estado3
Estado4
Estado5
Estado6
Estado7
Estado8
Estado9
Reset
Op1=operando1
op1 ==0
resultado=0
Exp_op1-127
Exp_op1_par?
Mantisa_op1>>1
Exp_op1_neg?
Exp_op1>>1 completado con 1
Exp_op1>>1
Mantisa_resultado=0,
Estado10
op2=01000000000000000000000000
Estado11 mantisa_op1=mantisa_op1-mantisa_op2
Estado12 mantisa_op1 negativo?
Condición
Próximo Estado
Reset==1?
Iniciar==1?
op1 ==0?
op1_exp es par?
op1_exp es negativo?
-
Verdadero=1
Estado1
Estado2
Estado3
Estado1
Estado5
Estado6
Estado7
Estado8
Estado10
Estado10
Falso=0
Estado0
Estado1
Estado4
Estado7
Estado9
-
-
Estado11
-
mantisa_op1
negativo?
Estado12
-
Estado14
Estado13
91
Estado13 mantisa_resultado++, cont-Estado14 mantisa_op1=mantisa_op1+mantisa_op2
Estado15 Mantisa_op1<<2
Estado16 Resultado normalizado?
Estado17 Mantisa_resultado<<1
Estado18 Mantisa_op2= mantisa_resultado<<1+1,rotaciones=0
Estado19 rotaciones==cont?
Estado20 Mantisa_op2<<2, rotaciones++
Tabla A.15 Diagrama de Estado de la Raíz Cuadrada
Resultado normalizado?
rotaciones==cont?
-
Estado16
Estado15
Estado16
Estado1
Estado18
Estado19
Estado11
Estado19
Estado17
Estado20
-
APÉNDICE B: Modelos Matemáticos y Algoritmos de LPC
Para el método de codificación predictiva lineal se parte de la siguiente ecuación en diferencias:
M
~
x (n) = a1 x(n − 1) + a 2 x(n − 2) + ... + a M x(n − M ) = ∑ ai x(n − i )
(1)
i =1
Esta ecuación indica que la muestra presente de la señal de voz x(n) se puede predecir mediante ~
x (n) a partir de una combinación lineal de M muestras pasadas x(n-i) donde
los ai son los coeficientes lineales de predicción. La cantidad de muestras pasadas que se
utiliza define el orden del filtro IIR. Este sistema es no causal puesto que si se evalúa la expresión (1) en n=0, se observa que se requieren de muestras en un tiempo negativo, esto se
resuelve acumulando el número de muestras necesarios para realizar la primera predicción,
lo cual provoca un retardo en la transmisión y procesamiento de la señal de voz.
El error entre la muestra actual y la predicha se puede expresar de la siguiente forma:
M
ε (n) = x(n) − ~x (n) = x(n) − ∑ ai x(n − i )
(2)
i =1
Entre menor sea el error, mejor es la predicción del modelo. Por lo que se busca que
los coeficientes ai minimicen la suma del error cuadrático:
M


E = ∑ ε ( n) = ∑  x ( n) − ∑ a i x ( n − i ) 
n
n 
i =1

2
2
(3)
Para minimizar el error cuadrático, se debe derivar E con respecto a cada uno de los
coeficientes ai, utilizando la regla de la cadena e igualando cada ecuación a cero. La expresión resultante es la siguiente:
M


2∑ x(n − k ) x(n) − ∑ a i x(n − i )  = 0 Para k= 1,2,3,…,M
n
i =1


(4)
De la expresión anterior se obtienen M incógnitas y M ecuaciones de la siguiente
forma:
92
93
a1 ∑ x(n − k ) x(n − 1) + a 2 ∑ x(n − k ) x(n − 2) + ... + a M ∑ x(n − k ) x(n − M ) = ∑ x(n − k ) x(n)
n
n
n
(5)
n
Para k=1,2,3,…,M
Se considera que la señal de voz es dividida en segmentos con N muestras. El tamaño de los segmentos es lo suficientemente corto que se puede considerar que el segmento está estacionario, es decir el tracto vocal va estar fijo durante este periodo de tiempo,
debido al comportamiento de la voz, anteriormente mencionado. El tamaño de cada segmento usualmente se escoge entre 20 a 30 ms. Para este proyecto se la señal de voz se
muestreó a 8000Hz y con un tamaño de segmento de 20ms, por lo tanto se tuvieron segmentos de 160 muestras.
Si hay N muestras en cada segmento con valores desde 0 a N-1, es decir x(0), x(1),
x(2), x(3)…x(N-1), la expresión (5) se puede expresar de forma aproximada en términos de
una matriz ecuación de la siguiente manera:
(6)
Con r(k) igual:
r (k ) =
N −1− k
∑ x ( n) x ( n + k )
(7)
n=0
Donde se puede despejar a utilizando la matriz inversa de R:
a=R-1 r
(8)
Esta ecuación se decidió resolver mediante el algoritmo recursivo Levinson-Durbin,
sin la necesidad de la inversión de matriz.
94
Después de resolver la ecuación se obtienen los coeficientes de predicción ai, que
permite obtener la secuencia de error ε(n), donde x(n) es la entrada y ε(n) las salida, esto es
conocido como filtro de análisis:
Figura 6. Filtro de análisis de voz
Donde A(z) viene dado por la siguiente expresión:
M
A( z ) = 1 − ∑ ai z −i
(9)
i =1
La ecuación (1) se puede reescribir como una ecuación de un filtro digital donde ε(n)
es la entrada y la salida es x(n):
M
x ( n) = ∑ a i x ( n − i ) + ε ( n )
(10)
i =1
La implementación de la ecuación (9) es llamada el filtro de síntesis:
Figura 7. Filtro IIR todo polos para síntesis de voz
En ambos filtros, de análisis y de síntesis, se tiene disponible los coeficientes de
predicción lineal y la secuencia de error residual, la señal de voz se puede reconstruir utilizando el filtro de síntesis. En la práctica la mayoría de sistemas, necesitan que los coeficientes y el error sea comprimido antes de al transmisión. Por está razón en vez de
cuantizar el error, muestra por muestra, se transmiten solo parámetros importantes como el
periodo del pitch, tipo de sonido y la intensidad de la excitación.
Para estimar el periodo del Pitch se utilizó la función de diferencia de la magnitud
promedio (AMDF). Este método supone que una señal x(n) es periódica con periodo T. La
diferencia entre dos muestras x(n)-x(n+k) va a ser cero par k = 0, ±T, ±2T y así sucesiva-
95
mente. Un sonido con voz no exactamente periódico, por lo que se define una función de
corto tiempo de la diferencia de la magnitud promedio:
AMDF (k ) =
1
N −k
N −1− k
∑ x ( n) − x ( n + k ) , k > 0
(11)
n =0
Para determinar si el segmento de muestras que se analiza es un sonido con o sin voz,
se utilizó la razón de cruce por cero. El razón de cruce por cero se obtiene contando los
cambios de signos (en ambos sentidos) en las muestras de voz sucesivas. La razón de cruce
por cero (ZCR) de un sonido con voz es menor que la de un sonido sin voz.
Finalmente el último parámetro de interés es la ganancia de del filtro digital IIR todo polos. Para el cálculo de la ganancia se utilizó la secuencia de error de la siguiente forma:
N −1
G 2 = ∑ ε 2 (n)
n =0
(12)
APÉNDICE C: Código en Matlab, equivalente en Software del circuito diseñado
%////////////////////////////////////////////////////////////////////////////////////////////////
%Universidad de Costa Rica. Junio 2008
%Proyecto de Licenciatura
%Procedimiento de diseno e implementacion de circuitos digitales utilizando herramientas EDA de codigo abierto
%Gerardo Castro Jimenez
%A31287
%////////////////////////////////////////////////////////////////////////////////////////////////
%Descripcion:
%
Codigo en Matlab equivalente en Software al Codificador/Decodificador de voz disenado.
%
%////////////////////////////////////////////////////////////////////////////////////////////////
clear;
tiempo =20; %Tamano de trama de voz 20ms
polos =10; %Numero de polos utilizados en la prediccion lineal
%Grabacion de voz a codificar mediante LPC
[x,fs,bit]=wavread('prueba_hombre_pcm8khz_16bit')
%Numero de segmentos de la señal a sintetizar
N=fs*(tiempo/1000);
N= round(N);
%Ruido gaussiano predefinido (equivalente a ROM de Ruido)
ra=zeros(1,N);
g=1;
while (g<161)
ra(1,g)=randn;
if (abs(ra(1,g))<=1)
g=g+1;
end
end
j=1;
i=1;
%numero de segmento a analizar
%numero de muestras
%Numero de segmentos de acuerdo al tamaño del archivo de prueba
Seg = round(length(x)/N)-1;
%-------------------------------------
96
97
%
Codificación LPC
%------------------------------------for i=1:Seg;
y1=x(j:j+N-1); % se define el segmento a codificar
y=y1;
promedio= sum (y1)/length(y1);
y1=y1-promedio;
%-----------------------------------------------------------------------%Procedimiento Cruces por cero para determinar si el segmento
%corresponde a un sonido con voz o sin voz
%-----------------------------------------------------------------------% se define el primer valor como maximo
bandera =0;
%variable
contador=0;
% se define el contador de segmentos
% Cuenta el numero de veces que la señal cambia de positiva a negativa y
% viceversa
for s=1:N
if y1(s)<0
if bandera ==0;
contador = contador +1;
bandera =1;
end
end
if y1(s)>=0
if bandera ==1
contador = contador +1;
bandera=0;
end
end
end
%Toma el valor del contador y lo pone en una variable
%cruces por cero = zcrs
zcrs(i)=contador;
if zcrs(i)>25 %Implica sonido sin voz. Se utiliza una frontera de 25
%cruces por segmento para determinar de un sonido con voz
resultado(i)=1;
else
% implica sonido sin voz
resultado(i)=2;
end
98
%-----------------------------------------------------------------------%Procedimiento Levinson-Durbin para encontrar los coeficientes de prediccion lineal
%-----------------------------------------------------------------------R=zeros(1,11);
a1=zeros(1,10);
for i1=1:1:11
for i2=1:1:160-i1
R(1,i1)= R(1,i1) + (y(i2)*y(i2+i1-1));
end
end
R2(i,1)=R(1,1);
E=R(1,1);
k=R(1,2)/E;
a1(1,1)=k;
E=E*(1-k*k);
for m=2:1:10
temp=0;
for i1=1:1:m-1
temp= temp + a1(1,i1)*R(1,m-i1+1);
end
q= R(1,m+1) - temp;
k=q/E;
E=E*(1-k*k);
b=zeros(1,10);
for i1=1:1:m-1
b(1,i1)=a1(1,i1)-k*a1(1,m-i1);
end
a1=b;
a1(1,m)=k;
end
a(i,1:(polos))= a1;
%-----------------------------------------------------------------------%Filtro de Analisis
%-----------------------------------------------------------------------error=zeros(1,N);
error(1,1)
error(1,2)
error(1,3)
error(1,4)
=
=
=
=
y(1);
y(2)-a(i,1)*y(1);
y(3)-a(i,1)*y(2)-a(i,2)*y(1);
y(4)-a(i,1)*y(3)-a(i,2)*y(2)-a(i,3)*y(1);
99
error(1,5) = y(5)-a(i,1)*y(4)-a(i,2)*y(3)-a(i,3)*y(2)-a(i,4)*y(1);
error(1,6) = y(6)-a(i,1)*y(5)-a(i,2)*y(4)-a(i,3)*y(3)-a(i,4)*y(2)-a(i,5)*y(1);
error(1,7) = y(7)-a(i,1)*y(6)-a(i,2)*y(5)-a(i,3)*y(4)-a(i,4)*y(3)-a(i,5)*y(2)-a(i,6)*y(1);
error(1,8) = y(8)-a(i,1)*y(7)-a(i,2)*y(6)-a(i,3)*y(5)-a(i,4)*y(4)-a(i,5)*y(3)-a(i,6)*y(2)-a(i,7)*y(1);
error(1,9) = y(9)-a(i,1)*y(8)-a(i,2)*y(7)-a(i,3)*y(6)-a(i,4)*y(5)-a(i,5)*y(4)-a(i,6)*y(3)-a(i,7)*y(2)-a(i,8)*y(1);
error(1,10) = y(10)-a(i,1)*y(9)-a(i,2)*y(8)-a(i,3)*y(7)-a(i,4)*y(6)-a(i,5)*y(5)-a(i,6)*y(4)-a(i,7)*y(3)-a(i,8)*y(2)a(i,9)*y(1);
for c=11:1:N
error(1,c) = y(c)-a(i,1)*y(c-1)-a(i,2)*y(c-2)-a(i,3)*y(c-3)-a(i,4)*y(c-4)-a(i,5)*y(c-5)-a(i,6)*y(c-6)-a(i,7)*y(c7)-a(i,8)*y(c-8)-a(i,9)*y(c-9)-a(i,10)*y(c-10);
end
error2=0;
for f=1:1:N
error2=error2+error(1,f).*error(1,f);
end
%Calculo de la ganancia
ganancia(i)=sqrt(error2);
%-----------------------------------------------------------------------%Procedimiento AMDF para la deteccion del Pitch
%-----------------------------------------------------------------------for k=1:N
Amdf(k) =0;
for n = 1:N-k;
Amdf(k) = Amdf(k) + abs(y(n)-y(n+k));
end;
Amdf(k) = (Amdf(k)/(N-k+1));
end
[Y,I]=min(Amdf(20:N));
pitch(i) = (I(1)+19);
%------------------------------------%
Decodificación LPC
%------------------------------------if (resultado(i)==2)
impgen= zeros (1,N);
cont=1;
while pitch(i)*cont < N;
impgen (1,cont*pitch(i)) = 1;
cont=cont+1;
end
impgen (1,1) = 1;
100
else
impgen=ra;
end
%-----------------------------------------------------------------------%Filtro de Sintesis
%-----------------------------------------------------------------------salida=zeros(1,N);
salida(1,1) = impgen(1,1)*ganancia(i);
salida(1,2) = impgen(1,2)*ganancia(i)+ salida(1,1)*a(i,1);
salida(1,3) = impgen(1,3)*ganancia(i)+ salida(1,2)*a(i,1) + salida(1,1)*a(i,2);
salida(1,4) = impgen(1,4)*ganancia(i)+ salida(1,3)*a(i,1) + salida(1,2)*a(i,2) + salida(1,1)*a(i,3);
salida(1,5) = impgen(1,5)*ganancia(i)+ salida(1,4)*a(i,1) + salida(1,3)*a(i,2) + salida(1,2)*a(i,3) + salida(1,1)*a(i,4);
salida(1,6) = impgen(1,6)*ganancia(i)+ salida(1,5)*a(i,1) + salida(1,4)*a(i,2) + salida(1,3)*a(i,3) + salida(1,2)*a(i,4) +
salida(1,1)*a(i,5);
salida(1,7) = impgen(1,7)*ganancia(i)+ salida(1,6)*a(i,1) + salida(1,5)*a(i,2) + salida(1,4)*a(i,3) + salida(1,3)*a(i,4) +
salida(1,2)*a(i,5) + salida(1,1)*a(i,6);
salida(1,8) = impgen(1,8)*ganancia(i)+ salida(1,7)*a(i,1) + salida(1,6)*a(i,2) + salida(1,5)*a(i,3) + salida(1,4)*a(i,4) +
salida(1,3)*a(i,5) + salida(1,2)*a(i,6) + salida(1,1)*a(i,7);
salida(1,9) = impgen(1,9)*ganancia(i)+ salida(1,8)*a(i,1) + salida(1,7)*a(i,2) + salida(1,6)*a(i,3) + salida(1,5)*a(i,4) +
salida(1,4)*a(i,5) + salida(1,3)*a(i,6) + salida(1,2)*a(i,7) + salida(1,1)*a(i,8);
salida(1,10) = impgen(1,10)*ganancia(i)+ salida(1,9)*a(i,1) + salida(1,8)*a(i,2) + salida(1,7)*a(i,3) + salida(1,6)*a(i,4)
+ salida(1,5)*a(i,5) + salida(1,4)*a(i,6) + salida(1,3)*a(i,7) + salida(1,2)*a(i,8) + salida(1,1)*a(i,9);
for c=11:N
salida(c) = impgen(1,c)*ganancia(i)+ salida(1,c-1)*a(i,1) + salida(1,c-2)*a(i,2) + salida(1,c-3)*a(i,3) + salida(1,c-4)*a(i,4) + salida(1,c-5)*a(i,5) + salida(1,c-6)*a(i,6) + salida(1,c-7)*a(i,7) + salida(1,c-8)*a(i,8) + salida(1,c9)*a(i,9) + salida(1,c-10)*a(i,10);
end
final(j:j+N-1)=salida;
j=N+j;
% Aumento para el proximo segmento
end;
% Grafico la señal de entrada y la señal de Salida de audio
subplot (2,1,1);
plot(x,'g');
title ('Sonido Original');
subplot(2,1,2);
plot(final,'r');
title ('Sonido Codificado');
101
sound(final, fs); %Reproduccion
wavwrite(final,'prueba_hombre_pcm8khz_16bit_matlab'); %Creacion de un archivo .wav
APÉNDICE D: Problemas de temporización durante la etapa de
implementación.
D.1 Problema de convergencia de la arquitectura microprogramada
En un principio, las máquinas de estado del codificador/decodificador de voz se diseñaron
con un controlador microprogramado como se muestra a continuación:
Figura D.1 Arquitectura microprogramada
Las máquinas de estado debían funcionar a una frecuencia de reloj de 50 MHz, sin embargo
la frecuencia de reloj de esta arquitectura disminuía conforme la memoria ROM se hacia
102
103
más grande, es decir cuando se agregaban más estados o micro instrucciones. Esto porque
los multiplexores de selección debían direccionar más posiciones de memoria, aumentando
la lógica próximo de estado, los niveles lógicos y los retardos. Por esta razón se utilizó la
arquitectura one-ho,t que minimiza lo lógica de próximo estado, con el fin de cumplir con
la frecuencia deseada de 50MHz.
Figura D.2 Arquitectura one-hot
D.2 Problema de alineación entre relojes
El codificador/decodificador posee un reloj de referencia de 50 MHz que proviene del oscilador presente en la tarjeta de desarrollo del SPARTAN3E. El circuito se comunica con 3
dispositivos externos: ADC, DAC y DRAM. Los dispositivos ADC y DAC utilizan un reloj
de 5 MHz y la DRAM utiliza dos relojes 100MHz y 100MH@180°.
Para el diseño del circuito controlador de memoria, se utilizó un reloj de
50MHz@90°, con el fin de controlar a DRAM con una frecuencia más baja y facilitar la
convergencia en la temporización. Por esta razón todos los circuitos del codifica-
104
dor/decodificador utilizan un reloj de 50MHz@90°, con el fin de mantener una alineación
entre las máquinas de estado. Sin embargo los circuitos controladores del ADC y DAC no
se corrieron los 90°, provocando un problema de temporización cuando estos circuitos interactuaban con el circuito controlador de reproducción. Estos problemas no se identificaron en la simulación funcional, ya que esta simulación es ideal (sin retardos). A
continuación se presenta un diagrama temporal del problema:
Reloj de
Referencia
50MHz
Reloj 2X
Reloj
2X180°
Reloj 90°
MAQUINA
DE ESTADO
A
ESTADO
PRESENTE
REGISTRO
Estado
Estado
Asignación
Estado
Asignación
Estado
Asignación
Estado
Asignación
Estado
Asignación
Estado
Asignación
Estado
Asignación
Estado
Asignación
Estado
Asignación
Reloj
5MHz
MAQUINA
DE ESTADO
B
ESTADO
PRESENTE
REGISTRO
Estado 0
Asignación 0
Asignación 1
5ns
5ns
Problema de
Temporización
Figura D.3 Diagrama temporal, problema de alineación de relojes
Como se observa, la máquina A utiliza un reloj de 50MHz@90° y la máquina B utiliza un reloj 5MHz. Cuando un registro de la máquina B cambiaba y generaba un cambio de
estado en la máquina A y viceversa, se ocasionaba el problema de temporización ya que el
105
cambio en el registro se debía propagar en 5 ns, lo cual no era posible por razones de niveles lógicos y enrutamiento.
Para solucionar este problema se recurrió a cambiar el reloj de 50MHz@90° por uno
de 50MHz@270°, este desplazamiento aportaba 10ns extras para eliminar el problema y
obtener un circuito libre de errores temporales. A continuación se muestra el diagrama temporal con la solución:
Reloj de
Referencia
50MHz
Reloj 2X
Reloj
2X180°
Reloj 270°
MAQUINA
DE ESTADO
A
ESTADO
PRESENTE
REGISTRO
Estado
Estado
Asignación
Estado
Asignación
Estado
Asignación
Estado
Asignación
Estado
Asignación
Estado
Asignación
Estado
Asignación
Estado
Asignación
Estado
Asignación
Reloj
5MHz
MAQUINA
DE ESTADO
B
ESTADO
PRESENTE
REGISTRO
Estado 0
Asignación 0
Asignación 1
15ns
15ns
Temporización
adecuada
Figura D.4 Diagrama temporal, solución al problema de alineación de relojes
Se observa, que el desplazamiento del reloj, permite que el cambio en el registro se
logre propagar ya que ahora posee 15ns de tiempo y se de el cambio de estado en forma
adecuada.
APÉNDICE E: Guía del procedimiento de diseño e implementación de circuitos digitales utilizando herramientas EDA de código abierto.
106
Descargar