Este es un Warning común, y que es difícil de resolver porque una primer lectura del mensaje no da mucha idea donde puede estar el problema. Sin embardo re-leyéndolo con cuidado, y con la ayuda de un buen diccionario de ingles :) .... , se puede tener una idea del problema.
Lo debería dejar como 'tarea para la casa ... ' , pero como me imagino q ya tienen demasiadas tareas lo resolveremos.....
"Port port_name hidden by declaration in architecture" => hay un puerto (port) de E/S, pues todos los ports son o de E o de S, no señal interna ! ..., que esta 'ocultado'/'escondido' por una declaración en la arquitectura. Es decir hay una declaración en la arquitectura que oculta el puerto de E/S... Q' instrucción de declaración puede haber en una arquitectura ??????? -> una declaración de señal interna (signal declaration). .... pero para q' oculte un port específico de E/S, deber ser q' accidentalmente hemos declarado una señal interna con el mismo nombre q' el port de E/S.... De este modo no se podrá acceder al puerto de E/S desde la arquitectura..... y por eso el compilador chilla con el grito.. .Warning.....
Muy fácil???????????????? entonces el próximo lo deducen Uds :)
bye,
Acá podrás encontrar todo lo que no encuentras en libros, no se aprende en clases, y nadie sabe donde lo puede buscar. El enfoque práctico de situaciones, problemas o solo curiosidades para los que hacemos desarrollos con VHDL/Verilog-FPGAs/CPLDs.
miércoles, 3 de noviembre de 2010
jueves, 28 de octubre de 2010
Añadir puntos de pruebas (probes) en FPGA Editor
Esta es una técnica aconsejada para usuario avanzados, recomendada cuando el tiempo de P&R del diseño es muy largo (>2 horas).
Añadir puntos de pruebas puede ser algo de mucha ayuda cuando se necesita debug un diseño complejo. Dado que un FPGA es un dispositivo programable usualmente hay elementos disponibles que pueden ser usados luego de haber Place & Route el diseño. El caso típico es por ejemplo que se desee saber el valor lógico de una señal interna de un diseño, para ello se puede routear esa señal interna a algún I/O pin disponible y de fácil acceso para poder usar la punta del Oscilloscopio o Analizador Logico. Tambien puede ser útil para routear una senal interna a un LED del board que está conectado a un I/O pad específico. La herramienta FPGA Editor, parte del ISE, ofrece la posibilidad de seleccionar (probe) cualquier red interna y automáticamente rutear la(s) señales deseadas al I/O pin que se necesita.
Los pasos a seguir son los siguientes:
- Una vez Place & Route el diseño, doble-click en el proceso “View/Edit Routed Design (FPGA Editor).
- Una vez abierta la ventana de la herramienta FPGA Editor, de la columna de botones sobre la derecha de la pantalla, presione el botón ‘probes’.
- En la ventana ‘Probes’ presione el botón ‘Add’ (primer botón sobre la derecha).
- Una nueva ventana aparecerá llamada ‘Define Probe’. Esta ventana tiene dos partes principales:
- La parte superior, ‘Select Net’, se refiere a las redes (nets) disponibles pare rutear. Recuerde que una vez que el diseño ha sido P&R algunas señales cambian el nombre, como asi también aparecen nombres como N3, N5, etc. En esta parte de la ventana se debe seleccionar la red deseada.
- La parte inferior, ‘Select Pin Numbers’, se refiere a los I/O pines disponibles para rutear la red seleccionada en la parte a). Hay dos métodos para seleccionar el I/O pin (del menú ‘Method’), uno es automatico, la herramienta selecciona el pin (normalmente el que de menos retardo de ruteo); y el otro método es manual. En el Manual en la columna inferior izquierda, ‘Available Pins’, se selecciona el I/O pin y una vez seleccionado se lo ‘transfiere’ a la columna derecha, ‘Selected Pins’, presionando el botón ‘>’.
- El proceso descripto en el punto 4. se puede repetir tantas veces como se necesite.
- Una vez finalizado se presiona OK. En la ventana ‘Probes’ deberán ahora aparecer las redes seleccionadas, sus respectivos I/O pins y una estimación del retardo para alcanzar la salida desde el punto de conexión de la señal seleccionada.
- Es conveniente usar la opción ‘Save Probes’ para guardas los puntos de pruebas y sus pines asociados. En un futuro uso se puede usar la opción ‘Open Probes’ para abrir los puntos de pruebas anteriormente guardados.
- ‘Close’ cierra la ventana ‘Probes’, retornando a la ventana del FPGA Editor.
- Ahora es necesario grabar los cambios realizados al original diseño. File-> Save o File-> Save As para cambiar el nombre. Por ejemplo rs_232_con_probes.ncd. De este modo se puede distinguir el .ncd original del .ncd con puntos de pruebas.
- El último paso es generar el respectivo archivo de configuración del FPGA, y descargarlo en el FPGA. Si ha usado un nombre diferente para el .ncd grabado (punto 9), se debe tener cuidado de generar correctamente el archivo de configuración.
Espero q les sea de utilidad.....
sábado, 16 de octubre de 2010
Source Synchronous Clocking
Source-synchronous clock se refiere a una técnica usada en buses de alta velocidad para enviar/recibir datos entre dos dispositivos. Existe otro método llamado system synchronous que veremos en un próximo blog.
En el caso de un sistema source-synchronous, el dispositivo transmisor (source) envía el reloj junto con el (los) dato(s). De este modo el timing de los datos, unidireccionales, estan referenciados a este especifico clock (a veces llamado strobe) generado por el dispositivo origen (source).
En la figura de arriba el FPGA es el dispositivo de destino, sin embargo, en otra situación el FPGA puede ser el dispositivo transmisor.
Este tipo de clocking es común en interfaces de alta/muy-alta velocidad como el Intel Front Side Bus, HyperTransport, SPI-4.2 y la mas común DDR.
Ventaja: dado que el reloj y los datos son generados por un mismo dispositivo, variaciones en los retardos de propagación generados por variaciones de PVT (Process Voltage Temperature) serán los mismos para el reloj y los datos. Completamente diferente a lo que suele ocurrir cuando un tercer dispositivo genera el reloj del sistema.
Desventaja: la principal es la creación de un dominio de reloj en el dispositivo receptor separado del reloj principal del mismo. Como consecuencia es necesario un bloque de sincronización en el receptor para transferir el dato recibido, sincronizado con el reloj del transmisor, al dominio del reloj receptor (pues generalmente la lógica del receptor trabaja a una frecuencia no relacionada para nada con la frecuencia del reloj del source synchronous). Para muy altas velocidad problemas de cross-talk y skew pueden aparecer.
Si bien este sistema añade mas lógica, comparado con un sistema de reloj general, permite trabajar con altas velocidades transmisión. Por ejemplo 622 Mbit/s para SPI-4.2.
Relación dato-reloj
Hay dos opciones de relación reloj-dato definidas de antemano por el protocolo del bus source synchronous con que se esté trabajando.
Por ejemplo, cuando se lee una memoria DDR el dato está sincronizado (edge-aligned) con el flanco del reloj. Así, los datos a la salida de la memoria se ven como en la siguiente figura:
Por lo que para realizar una captura correcta del dato, en el receptor normalmente se hace pasar el reloj por un elemento de control de reloj, tipo DCM en los FPGAs de Xilinx, para desplazar (shitf) el reloj 90 grados y asi capturar el dato en los DDR flip-flops sin problema.
En otros protocolos, SPI-4.2 por ejemplo, dato y reloj tienen la siguiente relación:
El reloj esta desplazado (normalmente centrado) con respecto al dato, por lo que el receptor puede usar perfectamente el reloj del transmisor para efectuar el registro de los datos. Sin embargo, en algunas interfaces con este tipo de relación reloj-dato, se usa un PLL o DCM para desplazar (phase offset) la entrada de reloj de modo de hacer un ajuste 'fino' del flanco de reloj para la mejor captura del dato.
Independientemente de la relación reloj-dato con que se trabajo SIEMPRE se deben usar los flip-flops localizados en los bloques E/S, ya sea para transmitir o para recibir. Por ejemplo para el caso de Xilinx se debe usar un contraint como el siguiente:
INST *abus_ddr_* IOB=TRUE;# Fuerza el uso de IOB
#flip-flops en las señales *abus_ddr_*
Para no aburrirlo y que no se haga muy largo este post, seguiré con System-Synchronous en el próximo.... (cdo? ... no se :) :) )
En el caso de un sistema source-synchronous, el dispositivo transmisor (source) envía el reloj junto con el (los) dato(s). De este modo el timing de los datos, unidireccionales, estan referenciados a este especifico clock (a veces llamado strobe) generado por el dispositivo origen (source).
En la figura de arriba el FPGA es el dispositivo de destino, sin embargo, en otra situación el FPGA puede ser el dispositivo transmisor.
Este tipo de clocking es común en interfaces de alta/muy-alta velocidad como el Intel Front Side Bus, HyperTransport, SPI-4.2 y la mas común DDR.
Ventaja: dado que el reloj y los datos son generados por un mismo dispositivo, variaciones en los retardos de propagación generados por variaciones de PVT (Process Voltage Temperature) serán los mismos para el reloj y los datos. Completamente diferente a lo que suele ocurrir cuando un tercer dispositivo genera el reloj del sistema.
Desventaja: la principal es la creación de un dominio de reloj en el dispositivo receptor separado del reloj principal del mismo. Como consecuencia es necesario un bloque de sincronización en el receptor para transferir el dato recibido, sincronizado con el reloj del transmisor, al dominio del reloj receptor (pues generalmente la lógica del receptor trabaja a una frecuencia no relacionada para nada con la frecuencia del reloj del source synchronous). Para muy altas velocidad problemas de cross-talk y skew pueden aparecer.
Si bien este sistema añade mas lógica, comparado con un sistema de reloj general, permite trabajar con altas velocidades transmisión. Por ejemplo 622 Mbit/s para SPI-4.2.
Relación dato-reloj
Hay dos opciones de relación reloj-dato definidas de antemano por el protocolo del bus source synchronous con que se esté trabajando.
Por ejemplo, cuando se lee una memoria DDR el dato está sincronizado (edge-aligned) con el flanco del reloj. Así, los datos a la salida de la memoria se ven como en la siguiente figura:
Por lo que para realizar una captura correcta del dato, en el receptor normalmente se hace pasar el reloj por un elemento de control de reloj, tipo DCM en los FPGAs de Xilinx, para desplazar (shitf) el reloj 90 grados y asi capturar el dato en los DDR flip-flops sin problema.
En otros protocolos, SPI-4.2 por ejemplo, dato y reloj tienen la siguiente relación:
El reloj esta desplazado (normalmente centrado) con respecto al dato, por lo que el receptor puede usar perfectamente el reloj del transmisor para efectuar el registro de los datos. Sin embargo, en algunas interfaces con este tipo de relación reloj-dato, se usa un PLL o DCM para desplazar (phase offset) la entrada de reloj de modo de hacer un ajuste 'fino' del flanco de reloj para la mejor captura del dato.
Independientemente de la relación reloj-dato con que se trabajo SIEMPRE se deben usar los flip-flops localizados en los bloques E/S, ya sea para transmitir o para recibir. Por ejemplo para el caso de Xilinx se debe usar un contraint como el siguiente:
INST *abus_ddr_* IOB=TRUE;# Fuerza el uso de IOB
#flip-flops en las señales *abus_ddr_*
Para no aburrirlo y que no se haga muy largo este post, seguiré con System-Synchronous en el próximo.... (cdo? ... no se :) :) )
jueves, 7 de octubre de 2010
Entendiendo (parte de) la Información dada por Timing Analyzer
Supongamos que se tiene un diseño que necesitamos que corra a una frecuencia de unos 100MHz (10 ns periodo). Un ejemplo de constraint para el reloj es el siguiente:
NET "sys_clk_100" TNM_NET = sys_clk_100;
TIMESPEC TS_sys_clk_100 = PERIOD "sys_clk_100" 10 ns HIGH 50%;
Fijando un periodo de 10 ns para la señal de reloj sys_clk_100.
Ahora bien, una vez que se ejecuta en el ISE el proceso "Analyze Post-Place & Route Static Timing", un montón de información con respecto al timing del diseño se detalla en la respectiva ventana de la herramienta. Entender parte de esa información, la que creo que la parte mas importante, es lo que deseo explicar a continuación:
Timing Analyzer (TA) califica la información en función de los diferentes contraints que se hayan especificado en el diseño. Por ahora estudiaremos la que nos interesa y es la referida al constraint que detallamos arriba. Asi, Taming Analizar detalla la siguiente información referida a ese constraint:
------------------------------------------------------------
Timing constraint:
TS_sys_clk_100=PERIOD TIMEGRP "sys_clk_100" 10 ns HIGH 50%;
TS_sys_clk_100=PERIOD TIMEGRP "sys_clk_100" 10 ns HIGH 50%;
1459 items analyzed, 0 timing errors detected. (0 setup errors, 0 hold errors)
Minimum period is 4.207 ns.
------------------------------------------------------------
Detallando que han sido analizados 1459 diferentes caminos relativos a ese reloj, con 0 errores de timing, pudiendo usarse un reloj de periodo mínimo de 4.124 ns (máxima frecuencia).
Debajo de esa información TA empieza a detallar los caminos referidos a ese reloj, listando el de mayor retardo primero. Se detalla a continuación como se interpreta la información que presenta TA, en este caso para un camino específico.
------------------------------------------------------------------
Slack: 5.793ns(requirement-(data path - clock path skew + uncertainty))
Slack: 5.793ns(requirement-(data path - clock path skew + uncertainty))
Source: baud_gen/count_x16_13 (FF)
Destination: baud_gen/count_x16_4 (FF)
Requirement: 10.000ns
Data Path Delay: 4.207ns (Levels of Logic = 3)
Clock Path Skew: 0.000ns
Source Clock: sys_clk_100_IBUFG rising at 0.000ns
Destination Clock: sys_clk_100_IBUFG rising at 10.000ns
Clock Uncertainty: 0.000ns
-----------------------------------------------------------------
La información más importante se refiere a si el camino ha cumplido con el requerimiento de tiempo. Esta información aparece en la primer línea y es definida como Slack. Si el Slack es positivo, significa que la ruta detallada cumple el requerimiento de tiempo por el número especificado como Slack. Si el Slack es negativo, entonces esa ruta viola el tiempo requerido por el número specificado en el Slack. Al lado del número de Slack se detalla la ecuación usada para calcular el Slack (mas abajo se explican los valores de la misma).
La próxima línea en el reporte es Source. Este es el punto de comienzo del camino analizado, normalmente un componente, en este caso es un flip-flop (FF), pero puede ser otro componente como RAM, PAD, LATCH, etc.
Sigue la línea de Destination, que es el punto final del camino analizado, y corresponde en este caso a un flip-flop (FF).
La siguiente línea se refiere a Requierement. Este es un número calculado con el constraint del periodo del reloj y el tiempo de los flancos del reloj. El reloj de destino y el fuente en este caso son los mismos, por lo que el Requirement es igual el periodo del reloj fijado en el constraint respectivo. Si el reloj de destino o el reloj fuente usaran el flanco de bajada del reloj, el valor de Requierement hubiera sido 5 ns, o sea la mitad del período fijado por el constraint.
EL Data Path Delay es el retardo del camino del dato desde la fuente hasta el destino. Normalmente este valor es la suma del retardo de ruteo más el retardo de la lógica. El retardo de la lógica se mide en niveles de lógica que normalmente es implementada en LUTs, y en este caso se tienen 3 niveles de lógica. Este retardo NO incluye clock-to-out del flip-flop o setup time.
Clock Skew es la diferencia entre el tiempo que la señal de reloj llega al flip-flop fuente y el tiempo en que llega al flip-flop destino. En este caso no hay diferencia, por lo que el valor es 0 ns.
Source Clock o Destination Clock reporta el nombre del reloj en la fuente o destino. También incluye si el flanco de reloj es positivo o negativo y el tiempo en que ocurre el flanco.
Clock Uncertainty se refiere a un parámetro de tiempo que se fija como constraint basado en el jitter del reloj y al error de phase que pueda tener el reloj (en breve escribiré al respecto). En este caso no se ha definido ningún valor en el constraint (restricción) por lo que es igual a 0 ns.
Slack = requirement-(data path - clock path skew + uncertainty)
Slack = 10 - (4.207 + 0 + 0) = 5.793 ns
A continuación del análisis de tiempo detallado arriba, TA presenta un análisis de los distintos componentes en el camino analizado. Debajo se puede ver el detalle, que luego se analiza.
Data Path: baud_gen/count_x16_13 to baud_gen/count_x16_4
Delay type Delay(ns) Logical Resource(s)
---------------------------- -------------------
Tcko 0.374 baud_gen/count_x16_13
net (fanout=2) 0.417 baud_gen/count_x16<13>
Tilo 0.288 baud_gen/count_x16_cmp_eq000062
net (fanout=1) 0.920 baud_gen/count_x16_cmp_eq000062
Tilo 0.313 baud_gen/count_x16_cmp_eq000076
net (fanout=18) 1.582 baud_gen/count_x16_cmp_eq0000
Tilo 0.313 baud_gen/Mcount_count_x16_eqn_41
net (fanout=1) 0.000 baud_gen/Mcount_count_x16_eqn_4
Tdyck 0.000 baud_gen/count_x16_4
---------------------------- ---------------------------
Total 4.207ns (1.288ns logic, 2.919ns route)
(30.6% logic, 69.4% route)
-------------------------------------------------------------
Data Path especifica el origen (baud_gen/count_x16_13) y el destino (baud_gen/count_x16_4)del camino analizado.
La primer columna es la Location (ubicación) del componente en el FPGA, por defecto esta off , por eso no se puede ver en listado de arriba, pero se puede activar activando Preference al hacer click con el botón derecho en un lugar en blanco de TA. La próxima columna es el Delay Type, si es una ruta, el fanout de la misma es mostrado. Los nombres detallados en esta columna corresponden con los detallados en la respectiva hoja de datos. Dentro de Timing Analyzer doble-click sobre cualquiera de estos nombres y se abrirá una figura que gráfica el retardo.
La columna del Delay detalla los respectivos retardos para cada Delay Type.
La próxima columna son los nombres del Logical Resource. Los nombres detallados en esta columna son nombres generados durante el proceso de Map y se asocian a estos componentes.
Al final del reporte se detalla la suma total del retardo para el camino analizado, 4.207 ns en este caso, seguido por un análisis de cuanto de ese total corresponde a retardo lógico y cuanto a retardo de ruteo. En este caso hay un 70% de retardo de ruteo y un 30% de retardo lógico, valores bastantes lógicos J y que deberían ser estandars en diseños con FPGAs.
Wow! q manera de escribir,.... espero q le sea útil a alguien.... :)
Hasta pronto !
sábado, 28 de agosto de 2010
Warning: NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
Este es un mensaje que dependiendo en que tiempo de la simulación ocurra puede ser grave o no.
Veamos...
Primero, normalmente este mensaje significa que la función to_integer recibe un 'metavalue' del vector que le pasa el número (vector) binario a convertir a entero. 'metavalue' significa otro valor que no es '1' ni '0', por ejemplo puede ser 'X', 'U'.
La función to_integer comúnmente se usa en contadores o para leer o escribir en memoria. Por ejemplo la lectura de un data de una memoria se puede describir del siguiente modo:
data_from_mem <= data_mem(to_integer(unsigned(address));
Este mensaje de Warning es común durante la primer parte de la simulación, llamada inicialización. Durante este tiempo los valores 'X' tardan un cierto tiempo (dependiendo del caso, pero aproximadamente entre 10-15 ns) en propagarse y obtener un valor lógico '0' o '1' estable. Por lo que durante este tiempo le están llegando los 'X' a la función to_integer, que no sabe que hacer con ellos y lo avisa con el Warning.
Cuidado ! ... Sin embargo, si este Warning aparece después del periodo de inicialización, es decir todas las señales de3 sistema ya tienen un valor logico '0' o '1' estable, lo mas probable es que sea realmente un bug en el diseño . . . -> a encontrar el problema.... :)
Finalmente, si te molesta el Warning.... se puede desactivarlo y de este modo hacer que no aparezca el mensaje del problema encontrado durante la conversión de la función to_integer. Para ello el famoso archivo modelsim.ini tiene una variable llamada NumerisStdNoWarnings. Seteando esta variable en '1' hace que los Warning relacionados con funciones y procedimientos del paquete numeric_std sean obviados.
Por ejemplo la siguientes líneas puedes encontrarlas en el modelsim.ini:
; Turn off warnings from the IEEE numeric_std and numeric_bit packages.
; NumericStdNoWarnings = 1
El ';' significa un comentario. Entonces, como se puede ver, por defecto la variable para evitar los Warnings, NumeriStdWarnings, no está activada ('1'). Para deshabilitar los Warnings solo deberías borrar el ';' que antecede a la variable.
Otra vez Cuidado! . . . porque puede ser que desactives el mensaje de Warning, te olvides y en otro diseño que a lo mejor realmente tienes problemas puede que queden ocultos por haber desactivado los Warnings. Para estos casos otra opción es tener un modelsim.ini por proyecto, pero ese ya es otro tema...
Si quieres jugar con el archivo modelsim.ini lo puedes encontrar en los siguientes directorios:
Entorno ISE:
..\Modeltech_XE_Starter
Entorno Libero:
..\Libero_vx.x\Model
Entorno Diammond:
?? (alguien lo tiene? pasemelo pls...)
Entorno Quartus:
??
Hasta la próxima...
Veamos...
Primero, normalmente este mensaje significa que la función to_integer recibe un 'metavalue' del vector que le pasa el número (vector) binario a convertir a entero. 'metavalue' significa otro valor que no es '1' ni '0', por ejemplo puede ser 'X', 'U'.
La función to_integer comúnmente se usa en contadores o para leer o escribir en memoria. Por ejemplo la lectura de un data de una memoria se puede describir del siguiente modo:
data_from_mem <= data_mem(to_integer(unsigned(address));
Este mensaje de Warning es común durante la primer parte de la simulación, llamada inicialización. Durante este tiempo los valores 'X' tardan un cierto tiempo (dependiendo del caso, pero aproximadamente entre 10-15 ns) en propagarse y obtener un valor lógico '0' o '1' estable. Por lo que durante este tiempo le están llegando los 'X' a la función to_integer, que no sabe que hacer con ellos y lo avisa con el Warning.
Cuidado ! ... Sin embargo, si este Warning aparece después del periodo de inicialización, es decir todas las señales de3 sistema ya tienen un valor logico '0' o '1' estable, lo mas probable es que sea realmente un bug en el diseño . . . -> a encontrar el problema.... :)
Finalmente, si te molesta el Warning.... se puede desactivarlo y de este modo hacer que no aparezca el mensaje del problema encontrado durante la conversión de la función to_integer. Para ello el famoso archivo modelsim.ini tiene una variable llamada NumerisStdNoWarnings. Seteando esta variable en '1' hace que los Warning relacionados con funciones y procedimientos del paquete numeric_std sean obviados.
Por ejemplo la siguientes líneas puedes encontrarlas en el modelsim.ini:
; Turn off warnings from the IEEE numeric_std and numeric_bit packages.
; NumericStdNoWarnings = 1
El ';' significa un comentario. Entonces, como se puede ver, por defecto la variable para evitar los Warnings, NumeriStdWarnings, no está activada ('1'). Para deshabilitar los Warnings solo deberías borrar el ';' que antecede a la variable.
Otra vez Cuidado! . . . porque puede ser que desactives el mensaje de Warning, te olvides y en otro diseño que a lo mejor realmente tienes problemas puede que queden ocultos por haber desactivado los Warnings. Para estos casos otra opción es tener un modelsim.ini por proyecto, pero ese ya es otro tema...
Si quieres jugar con el archivo modelsim.ini lo puedes encontrar en los siguientes directorios:
Entorno ISE:
..\Modeltech_XE_Starter
Entorno Libero:
..\Libero_vx.x\Model
Entorno Diammond:
?? (alguien lo tiene? pasemelo pls...)
Entorno Quartus:
??
Hasta la próxima...
domingo, 15 de agosto de 2010
Imprimiendo mensajes con Assert/Report
A partir de VHDL'93 report se puede usar como una instrucción sola (sin assert) para imprimir objetos del tipo string. Así por ejemplo se puede reportar el comienzo de un test del siguiente modo:
1report "--- Comienzo del Test ---";
Esto es similar, pero no equivalente, a escribir:
1 assert FALSE
2report "--- Comienzo del Test ---";
En primer lugar report es una instrucción secuencial. Por lo que debería ser usada dentro de un proceso. Por defecto el nivel de severidad de report es NOTE. Por otro lado, assert puede ser una instrucción concurrente o secuencial. En el caso de ser usada como concurrente es equivalente a ser usada en un proceso con una instrucción wait al final del mismo (no lista sensitiva). Este proceso se ejecutará solo una vez durante el comienzo de la simulación y esperará indefinidamente en el wait. El nivel de severidad por defecto para assert es ERROR.
Los strings que se imprimen usando report se pueden leer en la ventana de transcript del simulador. Por ejemplo para ModelSim es la ventana que ocupa la parte inferior del simulador.
Ahora bien, tal como lo especifica el IEEE estandard 1076-1993, LRM §8.3, report solo puede imprimir objetos tipo STRING. Por lo que es muy util y bonito a la hora de imprimir mensajes, pero bastante 'inútil' para otro tipo de objetos. Por ejemplo para imprimir un std_logic_vector.
Recordemos que un 'string' de std_logic_vector (algunas veces llamado bit string) NO es lo mismo que un objeto tipo string. Por ejemplo:
1 signal slv: std_logic_vector(7 downto 0) := "01010101";
2 signal str: std_logic_vector(7 downto 0) := "01010101";
Para estos dos objetos el compilador sabe que son diferentes tipos, pues fueron declarados diferentes, aun cuando ambos valores parecen similares. Cada uno de estos arreglos tienen diferente tipos de elementos. Tipo string es un arreglo de character, mientras std_logic_vector as un arrreglo de std_logic. Tal como se detalla en sus declaraciones:
1 type std_logic_vector is array (natural range < >) of std_logic;
2 type string is array (positive range < >) of character;
Ya que report solo puede imprimir strings, para imprimir otro tipo de objeto es necesaria la conversión a string. El atributo pre-definido IMAGE (LRM §14.1) convierte cualquier tipo o sub-tipo escalar a string. Así:
1 report integer'image(cuenta);
Imprime el valor del entero cuenta. Mientras que:
1 report std_logic'image(flag);
imprimirá el valor de flag del tipo std_logic.
A veces se desea imprimir no solo el valor del objeto, sino tambien el nombre del mismo. Para ello se usa el operador concatenación & (ampersand):
1 process
2 begin
3 if (cuenta = max_cuenta) then -- max_cuenta = 16
4 report "El valor del contador es: " & integer'image(cuenta);
5 end if;
6 wait;
7 end process;
En el simulador se vería el siguiente mensaje:
1 # ** Note: El valor del contador es: 16
2 # Time: 20 ns Iteration: 3 Instance: /tb_test
Tal como se ha explicado anteriormente 'image solo convierte tipo o sub-tipos escalares a tipo string. De modo que si por ejemplo se desea imprimir un objeto tipo std_logic_vector, o un array no es posible hacerlo usando el atributo 'image. En estos casos es necesario escribir una función que convierta por ejemplo de std_logic_vector a string. En realidad haciendo una búsqueda en google se pueden encontrar estas funciones de conversión. Por ejemplo usando una función conversión a string de std_logic_vector llamada slv2string, la instrucción report quedaría escrita de la siguiente forma:
1 report "El vector direccion de memoria es: " & slv2string(address);
Bueno, bueno.......
Esto es todo por hoy.... en realidad escribí mucho y no es lo mejor... :) , más aún siendo Domingo.... :( :)
1
Esto es similar, pero no equivalente, a escribir:
1 assert FALSE
2
En primer lugar report es una instrucción secuencial. Por lo que debería ser usada dentro de un proceso. Por defecto el nivel de severidad de report es NOTE. Por otro lado, assert puede ser una instrucción concurrente o secuencial. En el caso de ser usada como concurrente es equivalente a ser usada en un proceso con una instrucción wait al final del mismo (no lista sensitiva). Este proceso se ejecutará solo una vez durante el comienzo de la simulación y esperará indefinidamente en el wait. El nivel de severidad por defecto para assert es ERROR.
Los strings que se imprimen usando report se pueden leer en la ventana de transcript del simulador. Por ejemplo para ModelSim es la ventana que ocupa la parte inferior del simulador.
Ahora bien, tal como lo especifica el IEEE estandard 1076-1993, LRM §8.3, report solo puede imprimir objetos tipo STRING. Por lo que es muy util y bonito a la hora de imprimir mensajes, pero bastante 'inútil' para otro tipo de objetos. Por ejemplo para imprimir un std_logic_vector.
Recordemos que un 'string' de std_logic_vector (algunas veces llamado bit string) NO es lo mismo que un objeto tipo string. Por ejemplo:
1 signal slv: std_logic_vector(7 downto 0) := "01010101";
2 signal str: std_logic_vector(7 downto 0) := "01010101";
Para estos dos objetos el compilador sabe que son diferentes tipos, pues fueron declarados diferentes, aun cuando ambos valores parecen similares. Cada uno de estos arreglos tienen diferente tipos de elementos. Tipo string es un arreglo de character, mientras std_logic_vector as un arrreglo de std_logic. Tal como se detalla en sus declaraciones:
1 type std_logic_vector is array (natural range < >) of std_logic;
2 type string is array (positive range < >) of character;
Ya que report solo puede imprimir strings, para imprimir otro tipo de objeto es necesaria la conversión a string. El atributo pre-definido IMAGE (LRM §14.1) convierte cualquier tipo o sub-tipo escalar a string. Así:
1 report integer'image(cuenta);
Imprime el valor del entero cuenta. Mientras que:
1 report std_logic'image(flag);
imprimirá el valor de flag del tipo std_logic.
A veces se desea imprimir no solo el valor del objeto, sino tambien el nombre del mismo. Para ello se usa el operador concatenación & (ampersand):
1 process
2 begin
3 if (cuenta = max_cuenta) then -- max_cuenta = 16
4 report "El valor del contador es: " & integer'image(cuenta);
5 end if;
6 wait;
7 end process;
En el simulador se vería el siguiente mensaje:
1 # ** Note: El valor del contador es: 16
2 # Time: 20 ns Iteration: 3 Instance: /tb_test
Tal como se ha explicado anteriormente 'image solo convierte tipo o sub-tipos escalares a tipo string. De modo que si por ejemplo se desea imprimir un objeto tipo std_logic_vector, o un array no es posible hacerlo usando el atributo 'image. En estos casos es necesario escribir una función que convierta por ejemplo de std_logic_vector a string. En realidad haciendo una búsqueda en google se pueden encontrar estas funciones de conversión. Por ejemplo usando una función conversión a string de std_logic_vector llamada slv2string, la instrucción report quedaría escrita de la siguiente forma:
1 report "El vector direccion de memoria es: " & slv2string(address);
Bueno, bueno.......
Esto es todo por hoy.... en realidad escribí mucho y no es lo mejor... :) , más aún siendo Domingo.... :( :)
viernes, 6 de agosto de 2010
Hay solución para el 'feo' text editor del ISE... menos mal :) ..!
A quién le gusta el editor de VHDL/Verilog que viene con el ISE? ? ? Por suerte lo puedes cambiar y usar el editor de tu preferencia. En este link encontrarás como hacerlo, eso sí, fíjate bien cual línea de comando debes usar dependiendo del editor...
http://www.xilinx.com/support/answers/13713.htm
http://www.xilinx.com/support/answers/13713.htm
Suscribirse a:
Entradas (Atom)


