Conjunto de Herramientas para Desarrollo de Hardware con FPGA
Desde HDL hasta una FPGA Operativa
Copyright (C) 2007 Fernando G. Tinetti
La idea de este documento es, justamente, documentar el desarrollo de un dispositivo de hardware desde la especificación en un HDL (Hardware Description Language) hasta la evaluación con la medición de las señales de entrada y salida del dispositivo implementado en FPGA con un analizador lógico.
Para la especificación, simulación, implementación y medición se utilizarán:
Está claro que en este documento se tratan herramientas específicas, pero la idea es que esto no quite la generalidad del "ciclo" (aunque aquí será como una "cascada") de desarrollo de hardware desde la especificación hasta la verificación/evaluación del dispositivo mismo sobre una FPGA. Puesto de otra manera, los pasos de
Gran parte de la explicación contenida en esta página puede
encontrarse en varios otros sitios, aunque se han utilizado
relativamente pocos documentos de referencia que son muy buenos. Sin
embargo, se ha hecho un esfuerzo considerable en enfocar la información
y la metodología hacia la idea de "comenzar con HDL y terminar
midiendo un dispositivo". Dado que hay varias herramientas
involucradas, era de esperar que no toda esta información estuviera en
un solo documento o en una sola fuente. Más específicamente, el primer
documento de descripción de QII utilizado es
"Quartus II Introduction Using Verilog Design", disponible en
http://www.altera.com/education/univ/materials/manual/labs/tut_intro_verilog.pdf
es decir que es información "oficial" de Altera. Más en
general, se puede recurrir a las páginas web de Altera donde se
describe la documentación asociada a QII en general y a QII para
diseño:
http://www.altera.com/support/software/sof-quartus.html
http://www.altera.com/support/software/quartus2/design_flow/des-index.html
El manual más completo disponible de QII es "Introduction to
Quartus II", que está disponible en el sitio web de Altera:
http://www.altera.com/literature/manual/intro_to_quartus2.pdf
Sin lugar a dudas existen otras fuentes de información, la
información que se describe y resume aquí incluye partes de los
documentos elaborados por el prof. Zvonko George Vranesic
http://www.eecg.toronto.edu/~zvonko/
específicamente, los apéndices B, C y D que están disponibles en su
página web (aunque no queda claro a cuál de sus libros corresponden
los apéndices)
http://www.eecg.toronto.edu/~zvonko/AppendixB_quartus.pdf
http://www.eecg.toronto.edu/~zvonko/AppendixC_quartus.pdf
http://www.eecg.toronto.edu/~zvonko/AppendixD_quartus.pdf
También hay información disponible de cursos universitrarios sobre
FPGA donde utilizan algún producto de Altera y en todos los casos
utilizan QII como software de desarrollo.
Diseño en Verilog de un Dispositivo Simple: Un Inversor
A) Todo diseño en QII se crea en el contexto de un
proyecto. Para la creación de un proyecto, dentro de QII
A.1) File -> New Project Wizard
A.2) En la pantalla del wizard
Click on Next
A.3) Se abre la siguiente pantalla del wizard con:
Directorio, Nombre del proyecto, Entidad de mayor nivel del
diseño
A.3.1)
Directorio: recomendado crear un directorio
por proyecto, independientemente del que se muestra (que es del
propio QII). Ej: c:\users\user1\nombre_proy
A.3.2) Nombre del
proyecto: recomendado que
sea el mismo que la entidad de mayor nivel del
diseño. Ej: inv (de inversor)
A.3.3) Entidad
de mayor nivel del diseño:
inv (será un inversor)
Click on Next
A.4) Se abre la siguiente pantalla del wizard con la
posibilidad de agregar archivos con diseños ya hechos al proyecto
Si
hay archivos de éstos, agregarlos
Click on Next
A.5) Se abre la pantalla del wizard con la selección
del hardware a usar (FPGA, etc.)
muestra lo que encuentra (que es correcto): familia FLEX10K,
dispositivo disponible EPF10K10... (el mismo de la placa)
Click on Next
A.6) Se abre la pantalla del wizard con EDA
tools
poner las que se usen (ninguna)
Click on Next
A.7) Se abre la pantalla del wizard con el resumen
Click on Finish
En QII (como resultado de todo lo anterior): Aparece en Entity el
nombre de la familia y del dispositivo y en el nivel siguiente el nombre
de la entidad de diseño de mayor nivel
B) A partir de este punto se deben incluir
especificaciones Verilog en el proyecto. En QII
B.1) File -> New...
B.2) Se abre la pantalla del New..., y en
ella
Seleccionar Verilog HDL File
En QII (como resultado de lo anterior): aparece en pantalla un
editor de textos propio de QII con el nombre de archivo
Verilog1.
Para que el nombre del archivo sea el mismo que el de la entidad que se
describe, se hace
File -> Save As...
en la pantalla del Save As.. directamente con el nombre de la entidad de
diseño de mayor nivel que ya se dio: inv, el archivo se llama,
entonces, inv.c (al final de la pantalla aparece que el archivo será
incluido en el proyecto actual).
B.3) En este punto se pone todo lo que sea necesario en
el archivo de texto (especificación Verilog). En este caso:
// FGT May 11th, 2007 module inv (bin, bout); input bin; output bout; assign bout = ~ bin; endmoduleque es simplemente un inversor de la señal de entrada. Guardar el archivo.
C) Una vez que se ha finalizado de incorporar la
especificación HDL de los dispositivos del diseño, se debe
realizar la Síntesis Funcional y Simulación
Funcional. En algunas ocasiones se presenta simplemente como
"Síntesis", pero parece apropiado aclarar desde ahora
que esta serie de pasos corresponde a la simulación funcional
porque:
1) La primera
simulación debería ser
funcional para verificar que el diseño hace lo que se pretende
que haga desde el punto de vista lógico.
2) La simulación funcional
es la más rápida en tiempo de
ejecución. Esto no es significativo para este ejemplo, pero
sí lo es cuando el sistema es relativamente
complejo.
3) La simulación funcional
no usa ninguna información del hardware
a utilizar, en este sentido es
"independiente del hardware" con todo lo bueno y malo que esto
tiene asociado.
Los pasos a seguir para esta fase son básicamente tres:
C.1) Análisis
compilación del
diseño.
C.2) Generación de los patrones de
test.
C.3)
Simulación funcional.
A continuación se muestra cómo se lleva a cabo cada uno
de estos pasos con QII.
C.1) Análisis o compilación del
diseño. En QII
Processing -> Start -> Start Analysis & Synthesis (ctrl-k)
termina sin errores o mostrando los errores que correspondan
(como cualquier compilador).
Click on OK
C.2) Generación de los patrones de test. En QII
File -> New...
En la pantalla del New...
Seleccionar la pestaña Other Files
Seleccionar Vector Waveform File
En QII aparece la pantalla del Waveform Editor. Como en el caso del
archivo Verilog, guardar este archivo con el nombre de la entidad de
diseño de mayor nivel (que es la que se quiere simular con las
señales que se están definiendo en este
punto).
File -> Save As...
pantalla del Save As...
inv (agrega .vwf y lo incluye al proyecto por default)
En este punto hay que incluir varios datos relacionados con las
señales de entrada y con la cantidad de tiempo a simular, aun
cuando la simulación sea funcional. Debe recordarse que todo lo
relacionado con el hardware se considera "de respuesta
instantánea" para la simulación funcional, pero es
necesario definir tiempo para asociar los cambios de las señales
con una evolución temporal del sistema.
Edit -> End Time
Pantalla: poner 100 ns
Para ver todo el período en la pantalla de QII
View -> Fit in Window
Aprovechando para hacer otra sesión, saliendo y
volviendo a entrar a QII.
Salir: File -> Save Project
Cuando se reingresa,
File -> Open Project
Seleccionar el proyecto que se salvó anteriormente (inv)
Todo lo que hace es mostrar que abrió un proyecto. Si se hace
doble click en el nombre, que está a la izq., aparece el archivo
de texto con Verilog.
Probando seguir a partir de lo que se dejó, es decir en la
generación de patrones de test previo a la simulación
funcional...
File -> Open...
Aparece por default Device Design Files, pero cambiar a Waveform/Vector
Files
Allí aparece el único generado en/para este proyecto, es
decir inv.wvf, y al abrirlo tiene todo lo estrictamente relacionado con
señales que se haya incluido en el editor de señales. No
está, por ejemplo, el "simulation end time". Es
más, de alguna manera, el "Simulation end time" se ha
perdido, puede ser considerado propio de la sesión y no del
proyecto.
Se vuelve a poner el Simulation End Time como se indica en C.2 (100 ns)
El Compilation Report reaparece tal como fue generado en su momento, es
decir que sí tiene lo mismo que antes de cerrar el
proyecto.
Retomando la generación de señales para la
simulación... patrones de test
Para agregar señales/patrones de test en el editor de
fromas de onda...
Edit -> Insert -> Insert Node or Bus
Se abre la pantalla de inserción y aquí conviene utilizar
el botón de esta pantalla denominado "Node
Finder..."
Al usar Node Finder... se abre otra pantalla en la que hay que utilizar
el botón "List" para que muestre/despliegue las
señales involucradas en las entidades del proyecto
Elegir, en este caso: bin (con doble click ya la "pasa" a
"Selected Nodes"), lo mismo para bout. Se
debe hacer notar que esta selección genera que la señal
correspondiente aparezca luego en la pantalla del editor de
señales (en este punto no se le da valor a ninguna señal
en ningún instante/intervalo de tiempo).
Al hacer ok en la pantalla anterior aparece bin con estado en 0 y bout
mostrando que no tiene valor conocido.
Evidentemente se debe asignar valor/estado a bin, correr la
simulación funcional y ver si lo que se genera en bout es
correcto.
Para dar valores a bin...
Seleccionar bin (click sobre el nombre de la señal en el editor
de señales en el que se está)
Se activan/están disponibles un conjunto de posibilidades en el
editor de señales en el medio de la pantalla, entre ellas el que
corresponde a "Overwrite Clock", que es el único
botón que incluye un reloj en su dibujo. Al seleccionar
"Overwrite Clock" aparece la pantalla que le corresponde,
donde se establecen:
a) Período: 10 ns, por ejemplo.
b) Duty Cycle (ya está en 50% y en general se puede dejar en este valor).
El Apéndice B (mencionado antes como una de las referencias
utilizada), explica una serie de pasos para dibujar (literalmente) las
señales, pero no parece ser un método sustentable, dado
que es totalmente manual. Cuando las señales son varias
(¿más de dos?) y/o tienen mucha variación en el tiempo de
simulación, dibujar cada uno de estos cambios se torna casi
imposible sin tener errores o sin que sea demasiado extendido en el
tiempo. En este caso, se simplifica la tarea a una señal
periódica, pero habría que investigar la manera de
especificar cambios de señales de manera más sustentable
en términos de tiempo y errores. Una posibilidad a estudiar
sería analizar el archivo de señales y agregar/cambiar
datos/información directamente allí.
Habiendo hecho lo anterior, aparece en pantalla la señal de
entrada de este circuito, bin, con todos los cambios posibles en el
período de tiempo a simular.
Queda, entonces, hacer la simulación funcional.
C.3) Assignments -> Settings...
En la pantalla que se abre, seleccionar Simulator Settings y en la
derecha seleccionar Simulation mode: Functional. Click on ok
Processing -> Generate Functional Simulation Netlist
Esto corre algo así como un compilador que termina
indicando que terminó correctamente.
Para realizar la simulación efectivamente
Processing -> Start Simulation
El simulador corre, genera la salida que corresponde y notifica que
terminó correctamente. En la pantalla aparece la señal
bout con el valor que el simulador generó para cada instante de
tiempo. Recordar que se puede usar View -> Fit in Window
En este punto se termina la simulación funcional, que muestra que
el circuido invierte la señal de entrada y eso significa que
está bien.
Queda pendiente en este punto cómo hacer esta verificación
de manera más sustentable que mirar en pantalla que la
señal de salida tiene la "forma" (en este caso,
invertida respecto de la entrada) que tiene que tener.
Resumiendo las tareas realizadas: especificar en Verilog, controlar que
la especificación sea "correcta" en el sentido de
Verilog (como con un compilador para un lenguage como C) y simular
funcionalmente el diseño. Esto significa que, de hecho, se puede
hacer exactamente lo mismo que hasta este punto con cualquier simulador
de Verilog. En este caso se utiliza QII porque las tareas a realizar a
partir de este punto ya son exclusivas de QII, no se pueden llevar a
cabo con los simuladores de Verilog dado que incluyen información
específica de la FPGA que maneja QII y esto es, de hecho,
copyrigthed como mínimo.
También en este punto termina la información relacionada
casi directamente con el Apéndice B.
D) Simulación de tiempos/Simulación
con los dispositivos físicos/de hardware
Básicamente se usa lo que está en el apéndice C
Processing -> Start Compilation
Utiliza bastante tiempo, aún para este proyecto con un inversor
(varios segundos). A medida que avanza muestra el % de completado en la
barra inferior y algunas pantallas de reporte de resultados. Finalmente,
la aparece la pantalla con el ok
Esto en realidad genera bastante más que un netlist,
básicamente para "capturar" el hardware a utilizar
(aquel que se incluyó en el comienzo del proyecto y que se puede
cambiar con Assignments -> Device...)
Ahora se debe indicar que se debe hacer la simulación con
análisis de tiempo teniendo en cuenta el hardware a
utilizar...
Assignments -> Settings...
Click on Simulator Settings
Simulation Mode: Timing (estaba en Functional por la sucesión de pasos anteriores)
Processing -> Start Simulation
Después de mostrar el avance de la simulación, hace
básicamente lo mismo que el simulador funcional: muestra la
señal de salida y notifica que terminó la
simulación
Ahora el cambio en bout no se muestra de manera simultánea con el
cambio de la entrada. De hecho, hay varias cosas interesantes a ver en
la salida:
a) A pesar de que la señal de entrada
cambiar en el ns 5 (de 0 a 1) el primer cambio de la salida (de 1 a 0)
se da recién en el ns 18.1; esto indicaría que hay un
"delay" inicial de 18.1 - 5 ns de la
señal.
b) Todos los demás cambios de la
señal de salida se dan cada 5 ns, es decir que siguen el paso de
la señal de entrada. Esto podría indicar el tiempo de
transferencia de la información pin a pin que se indica en el
Apéndice C como "speed grade" del
chip...
Solamente para verificar si es un problema del "speed
grade" se cambia la señal de entrada a un período
de 50 ns (y se alarga un poco el "end time simulation"...)
Se debe poner la ventana del editor de señales y cambiar la
señal bin y el end time simulation...
Luego, Processing -> Start Simulation
Ahora el primer cambio de bin (de 0 a 1) se da en el ns 25 y el primer
cambio de bout (de 1 a 0) se da en el ns 38.1, la pregunta es... ¿(18.1 -
5) = (38.1 - 25)? Dado que es igual (13.1 ns), este primer cambio tiene
en cuenta el tiempo de un inversor de la FPGA seleccionada (EPF10k10...)
más el tiempo de "viaje" de la señal desde un
pin de entrada hasta un pin de salida
En este punto se puede terminar una sesión: Salvar todo y
salir... A partir de ahora, lo que queda es cargar/programar
una FPGA y verificar que el diseño funciona y que se corresponde
la simulación de tiempos con el funcionamiento real del
dispositivo. Es más, se puede verificar cuán bien hace la
simulación de tiempos QII. Para esto, se debe
"programar" la FPGA (en terminología de QII) y hacer
todo lo necesario para:
a) Definir los pines
asociándolos (o viéndolos asociados) a las entradas y
salidas del diseño.
b) Grabar la FPGA que
corresponde.
c) proporcionarle la entrada necesaria, por
los pines que se definan.
d) Ver cómo funciona el
dispositivo utilizando un analizador lógico, por
ejemplo.
Dado que la idea a partir de aquí es corroborar el comportamiento real del dispositivo diseñado con el funcionamiento sobre la FPGA, se vuelve a la simulación de tiempos para simular ahora con una señal de entrada igual a la que se puede utilizar como entrada real de la FPGA. Una de las señales que se puede utilizar de manera directa es la propia del oscilador de la placa de desarrollo, que es de 8 MHz y que debería ser "ruteada" o "introducida" como la señal bin del dispositivo diseñado. A nivel de simulación esto no es un problema: solamente se cambia la señal en el editor que corresponde.
E) Retomando para una simulación de tiempos a
partir de lo hecho hasta D), con la idea de simular exactamente con el
reloj de entrada de la propia placa de desarrollo, que es de 8
MHz.
E.1) Abrir el proyecto.
E.2) Processing -> Start Compilation (recordar que
usa varios segundos, quizás un minuto)
E.3) Assignments -> Settings...
Simulator Settings -> Simulation Mode: Timing
E.4) Se pone la señal de entrada como la de la
propia placa de la FPGA: 8 MHz
File -> Open...
Files of Type: Wave/Vector File (elegir el que ya estaba hecho)
Edit -> End Time... (1 us)
En la señal bin, cambiar el ciclo a 125 ns
Salvar el archivo de señales
E.5) Processing -> Start Simulation
E.6) La primera transición de bin se da a los
62.5 ns (de 0 a 1) y la primera de bout (de 1 a 0) a los 75.6 ns, es
decir 13.1 ns después. En todos los casos las transiciones de
bout son 13.1 ns posteriores a las correspondientes de bin
Es decir: todo funciona como está previsto en la
compilación, a 13.1 ns de diferencia
Ahora se puede retomar la idea de utilizar directamente la placa de
desarrollo, y los pasos a seguir serán:
F) Averiguar los pines usados y para
qué
G) Carga en la FPGA/programación de la FPGA
H) Evaluación sobre la FPGA con el analizador
lógico
F) La averiguación de los pines a usar por el
cargador/QII de la FPGA se puede realizar (visualmente) con
(Apéndice C)
Assignments -> Timing Closure Floorplan
View -> Package Top
Haciendo zoom se puede llegar a ver cada pin de la FPGA y su
correspondiente asignación. Cada pin tiene un color y una
forma. Los asignados son círculos verde con una letra D en blanco
y con el puntero sobre ellos se llega a que el pin 84 es para la
señal bin, que se muestra con el texto:
"[Fitter Placed] bin <Input> @ PIN_84[Dedicated Input,.]".
De la misma manera, en un círculo verde sin letra:
"[Fitter Placed] bout <Ouput> @ PIN_18[Row I/O]".
Toda esta información se
usará luego para conectar los pods del analizador lógico y
la propia señal de entrada a la FPGA. El esquema general de la
placa de desarrollo está dado en la documentación, junto
con el conexionado de los pines de la FPGA hacia el exterior por
conectores específicamente puestos para esta tarea. Esta
información se replica aquí de manera condensada (ver la
información de la placa de desarrollo UPx10K10).
Figura 1: Esquema de la Placa de Desarrollo y Conexionado de los Pines.
CON1 (a la izq.) y CON2 (a la der.) tienen los pines conectados de
acuerdo a la tabla dada en la misma figura. De acuerdo con esta
información, se pueden relacionar los datos del QII en cuanto a
mapping de los pines,
[Fitter Placed] bin <Input> @ PIN_84[Dedicated Input,.]
por ejemplo, implica que la señal bin ingresa por el PIN_84 de la
FPGA, que según la tabla de la Fig. 1 anterior está
conectado al pin 12 del conector CON2. De la misma manera,
[Fitter Placed] bout <Ouput> @ PIN_18[Row I/O]
la señal bout del diseño se envía por el PIN_18 de
la FPGA, que según la misma tabla está conectado al pin 7
del conector CON1.
G) Carga en/Programación de la FPGA
(Apéndice D)
Tools -> Programmer
Asegurarse de que en Hardware Setup... esté
"ByteBlasterMV[LPT1]"
En la misma fila: inv.sof (el
proyecto a cargar en formato .sof, que se hace
"automáticamente"), con el dispositivo EPF10K10... y
Program/Configure checked
En la fila siguiente, el otro dispositivo
de la placa: EPC2, pero sin nada a cargar
Click sobre Start, y termina satisfactoriamente.
H) Evaluación sobre la FPGA con el analizador
lógico
La Fig. 2 muestra una foto de la placa conectada al analizador
lógico, donde no llega a visualizarse la interconexión de
la señal del clock de la placa vía el pin 1 del conector
CON1 hacia el pin 12 del conector CON2, donde es tratada como
la señal bin del dispositivo diseñado.
Figura 2: Foto de la Placa de Desarrollo Interconectada al Analizador Lógico.
Es decir que, placa: clock a pin 1 con1
Cables:
pin 1 con 1 a pin 12 con2
pin 1 con1 a pod1-0 entrada
pin 7 con1 a pod1-1 entrada
Los retardos son de 7.5 ns (medidos) en vez de 13.1 ns (simulados)
Sugerencias/reporte de errores/etc.: envíe un e-mail a ftinetti @ gmail . com con subject "Combo con FPGA"