viernes, 30 de enero de 2015

"Warning: NUMERIC_STD, "=": metavalue detected, returning FALSE" en ISim de Xilinx

Introducción

Cuando puedo evito usar ISim entre otras cosas por su pobre soporte, y también por sus encriptados mensajes de Warnings y Errors. En el último proyecto que trabajé no tenía opción, y cuando iba todo bien obtuve este famoso mensaje de advertencia "Warning: NUMERIC_STD, "=": metavalue detected, returning FALSE". Y digo famoso, porque busque en la web y encontré muchas entradas pero en casí ninguna me daba una idea de que pasaba y menos aún como solucionarlo. Bueno, acá les cuento lo que esto significa y por lo menos una manera concreta de encontrar una pista de donde o porque se genera este Warning. 

Qué es "Metavalue Detected" ?

Este mensaje significa que el simulador a encontrado como resultado un valor no numérico, que puede ser por ejemplo "UUUU" o "XXXX", o algún otro valor. 
Comúnmente este resultado se da durante el proceso de inicializacion del sistema bajo test, y dependiendo del tipo de test se puede repetir  este mensaje periódicamente. A modo de ejemplo les muestro en la siguiente figura los mensajes que obtenía en mi simulación. 


Cómo encontrar el problema ?

Tal como se puede ver de la figura mostrada anteriormente no se ve nada 'raro' en la forma de onda de las distintas señales mostradas, por lo que la solución no está a 'simple vista'. 
Un modo de encontrar el origen de este mensaje, por lo menos en este caso en particular, es tratar de ver las distintas señales internas del sistema descripto en VHDL. Para ello se debe ir al panel denominado "Instance and Processes", y hacer click en la flechita que está al lado del test bench, en el caso que muestro en la figura anterior, hacer click en la flecha al lado de top_tb. Aparecerá el nombre de la instancia del componente bajo test en el test bench, en este caso le llamé 'uut'. Vuelvo hacer click en la flechita que está al lado de 'uut', y se detallan ahora los distintos sub-componentes del sistema. La siguiente figura detalla lo explicado. 


El siguiente paso es seleccionar cada sub-componente e ir agregando las distintas señales del mismo a la ventana de formas de ondas (Wave Window). Para ello se selecciona el sub-componente, al hacer simple click sobre el nombre del mismo y luego en el panel 'Objects' aparecen las señales de E/S y las señales internas, Se seleccionan todas las señales, porque no sabemos cual es la que funciona incorrectamente, y se agregan a la Wave Window. En la siguiente figura se detallan los pasos explicados. 


En el caso detallado en la figura de arriba, agrego todas la señales del sub-componente cont_4bits_1 a la Wave Window. Puedo también agregar las señales de los otros componentes, freq_div_1 y bcd_7seg_1, Pero dio la casualidad que al agregar estas señales encontré parte del problema, cómo?... pues, una vez agregadas las señales del sub-componente, ejecuto la simulación nuevamente y inmediatamente visualizo algo que me llamó la atención,.... qué fé? .. pues descubranlo Uds. mismos en la siguiente figura: 


Que ven de raro???? .......

Si, que las dos ultimas señales, count e i_count, no están definidas ('U' = undefined).... Encontramos algo !.... 

Posibles Soluciones

Ahora bien llegado a este punto, los pasos a seguir son dos: 
1) revisar el VHDL/Verilog del sub-componente cont_4bits_1, y verificar sobre todo la inicialización de los vectores count e i_count.  
2) revisar el test bench y verificar el valor dado a la señal que inicializa el sistema, comúnmente llamada reset. En alguno de los dos lados esta el origen del Warning, y la solución al alcance de la mano..... ! ... (en mi caso en particular no tenía bien definido el reset en el test bench.... ) ....

Finalmente una nota para quienes usen ModelSim, van a leer en varios foros que ModelSim tiene una opción para que este tipo de Warnings (basados en 'metavalues') sean ignorados, por supuesto que no comparto esa opinión, por que siempre es bueno saber el origen del Warning, en mi caso en particular si hubiera usado ModelSim y hubiera usado la opción de ignorar esos Warning, nunca hubiese encontrado el problema que encontré con el reset. . . 

Bueno, espero que les sea útil... avisen si es así !

Hasta pronto...

martes, 23 de diciembre de 2014

FeLiCiDaDeS !

Estimados/as... Por este medio quería dejarles mi mas afectuoso saludos de un HERMOSA NAVIDAD y un MUY PROSPERO AÑO NUEVO. Esperando y deseando que el 2015 sea un GraN AÑO para todos Uds. en todo sentido.

El 2014 los he tenido un poco abandonados, pero fue un año bastante complicado, por suerte recien estoy volviendo de un Curso en Costa Rica (saludos a los valientes participantes) que me ha llenado de sugerencias para el blog, así es q esperen novedades pronto....

Muchas Felicidades y los Mejores Augurios !!

 Cristian

miércoles, 22 de octubre de 2014

Diseño Jerárquico - Components / Port Map / Generic Map

Introducción

VHDL es extremadamente potente cuando un gran sistema se divide en sub-sistemas individuales, pequeños, y luego se va creando el sistema mediante la conexión de los componentes individuales. algunos les llaman sub-sistema, sub-componentes, otros sub-modulos, etc. también se le llama diseño top-down a este modo de dividir en partes pequeñas un sistema complejo. 

Para poder construir un componente complejo a partir de diversos sub-componentes, VHDL tiene un par de instrucciones que facilitan este proceso: declaración de componente, e instanciacion de componente. 

Declaración de Componentes 

Para usar un componente ya definido (entity/architecture), que va pasar a ser un sub-componente, en un nuevo componente es necesario primer declarar el componente a usar, y luego instanciarlo. Una declaración de componente simplemente específica la interface de E/S del componente mediante el uso de los puertos de E/S (I/O ports),  y los generics.   

-- declaracion de component
component register
  generic(bus);
  port (
    clk: in  std_logic;
    rst: in  std_logic;
    d_b: in  std_logic_vector(bus-1 downto 0);
    reg: out std_logic_vector(bus-1 downto 0)
       );
end component;


Nota: cuando la cantidad de declaración de componentes sea un número considerable, es aconsejable declarar los componentes en un paquete. De este modo el código en sí queda mas ordenado, limpio, y fácil de seguir. De todos modos a partir de VHDL-2008 no hace falta la declaración de componentes si la sintaxis de la instanciación de componentes es similar a la que se detalla en el ejemplo debajo. 


Instanciación de Componentes

Específica como las E/S del componente declarado (usando la declaración de componente explicada previamente), son conectadas en el diseño en que se utiliza el componente.


-- a)instanciacion de componente con asociacion posicional

U1: register port map (sys_clk, sys_rst, data_bus, reg_data);


-- b) instanciacion de componente con asociacion por nombre

U1: register port map (

                 clk => sys_clk,
                 rst => sys_rst,
                 d_b => data_bus,
                 reg => reg_data

                   );

-- c) instanciación en VHDL-2008 (sin declaración de componente)
U1: entity work.register port map (
                 clk => sys_clk,
                 rst => sys_rst, 
                 d_b => data_bus,
                 reg => reg_data
                   );


En la instanciación por posición, la lista de conexiones se hace en el mismo orden en que los puertos fueron declarados en la entidad del componente instanciado. 
Se aconseja el uso de asociación por nombre, ya que es menos propensa a errores. En esta caso también se aconseja separar las asociaciones por funcionalidad mas que por si son entradas o salidas. 


Ejemplo Sencillo 




library ieee;
use iee.std_logic_1164.all;

entity GATING is
  port (A, CK, MR, DIN: in  std_logic;

        RDY, CTRLA    : out std_logic);

end GATING;

architecture STRUCT of GATING is

component AND2
  port(  X, Y: in  std_logic;
         Z   : out std_logic);
end component;
component DFF
  port (D, CLOCK: in  std_logic;
        Q, QBAR : out std_logic);
end component;
component NOR2
    port ( DA, DB: in  std_logic;
           DZ    : out std_logic);
end component;
signal S1, S2: std_logic;

begin
D1: DFF  port map (A, CK, S1, S2);
A1: AND2 port map (x => S2, y=>DIN, Z => CTRLA);
N1: NOR2 port map (S1, MR, RDY);
end STRUCT;


Salidas no Usadas

En caso en que una salida del componente instanciado no se use cuando se instancia el componente, se debe explícitamente usar la palabra clave open para especificar que esa salida se deja abierta, no se utiliza, por lo que si es posible el sintetizado puede optimizar la lógica correspondiente. 

Entradas no Usadas

En caso en que una entrada del componente instanciado no se use cuando se instancia el componente, se debe explícitamente fijar un valor lógica a dicha entrada. Para ello se puede asociar la entrada no utilizada con '1' o '0'. 


Generic Map


El generic es un valor constante usado para describir en forma parametrizada una entidad. Ahora bien, diferentes instanciaciones de una misma entidad pueden tener diferentes valores de generic, para ello se usa el generic map.
Del mismo modo que antes, en caso de haber mas de un generic se puede usar asociación por posición o asociación por nombre. 
Ejemplo: 

entity registro_dff
  generic(reg_width: positive);
  port(
    rst,clk: in  std_logic;
    d, q   : out std_logic_vector(reg_width-1 downto 0);
     );
end entity registro_dff;
. . .
architecture ejemplo of registro_dff is
....
....
end ejemplo; 

-- instanciacion de registro_dff en otra entity
....  architecture test of registro_bus is
constant width_8 : positive:= 8;
constant width_16: positive:= 16;
signal d8, q8  : std_logic_vector(7 downto 0);
signal d16, q16: std_logic_vector(15 downto 0);
. . .

begin
  ff8: registro_dff generic map(width_8)
           port map (rst, clk, d8, q8);
  ff16: registro_dff generic map(width_16)
            port map (rst, clk, d16, q16);
. . .

end test;


martes, 14 de octubre de 2014

Reduciendo el tiempo de compilación en Quartus II

Por defecto Quartus recompila todos los módulos .vhd/.v del proyecto que se está llevando a cabo, aún cuando lo único que se haya modificado haya sido un punto y coma en uno solo de los módulos .vhd o .v. 
Existe una opción que permite recompilar solo los módulos modificados, ahorrando así mucho tiempo de compilación. 
Los pasos a seguir para configurar Quartus para minimizar el tiempo de compilación son: 

Assignments menu -> Settings 

Compilation Process Settings -> Incremental Compilation , click para seleccionar Rapid Recompile opción ON.

Otra opción que permite reducir tiempo de compilación es configurar Quartus para que use todos los núcleos del procesador de la computadora que se esté usando. 

Compilation Process Settings -> Parallel Compilation -> Use All Available Processors

Una ultima opción, es decirle a Quartus que use Smart Compilation. Al usar Smart Compilation se saltean alguno de los pasos del Compiler, tales como Analysis y Synthesis (cuando estos no son necesarios para recompilar el diseño).  

Compilation Process Settings -> Smart Compilation, click para opción ON.


Nota: estas son soluciones muy simples para diseños simples . Para diseños complejos hay otras opciones y factores a tener en cuenta que los detallaré en otro blog. 


viernes, 3 de octubre de 2014

Descanso del Blog y ..... VHDL Guía de Referencia...

Fines del '13 y comienzos del '14 fueron bastantes ocupados para mi ... cursos varios (VHDL Básico/ VHDL Avanzado / NIOS), lugares diversos (Los Reyunos / Parana / Trieste / Buenos Aires) todo esto me mantuvo alejado de este Blog.... 
PERO, PERO, la frutilla del postre es un pequeño libro de referencia que terminé (finalmente) de escribir- "VHDL Sintax. Guía de Referencia Rápida". 
Es una guía bastante práctica que describe las instrucciones de VHDL más frecuentemente usadas para la descripción de un sistema digital que será implementado en un FPGA. Por cada instrucción se presenta en forma detallada la sintaxis, la síntesis resultante, consejos para el mejor uso de la instrucción y algún cuidado o precaución a tener en cuenta cuando se la use. 
Les dejo acá unas fotos para su deleite :) ... 




Por supuesto que está a la venta para quien quiera tenerlo en sus manos. 
Por favor contactarme por email para costo, envío, etc, etc... 


viernes, 11 de abril de 2014

Correcto uso de Reset en FPGAs y su Codificación en VHDL


Introducción


En esta nota técnica se describirán con bastante detalle los distintos tipos de reset que se pueden usar en un sistema digital, sus ventajas y desventajas, y cual de ellos es el más aconsejable a usar para tener un sistema más confiable.

A pesar de que el reset de un sistema es un tema crítico, pocas veces se le da la importancia que tiene y es usualmente uno de los aspectos ignorados en un diseño con FPGA. Un circuito de reset que no se comporte correctamente resulta directamente en un mal funcionamiento aleatorio del sistema. Y como ya sabemos, los problemas aleatorios, no repetitivos, de un sistema son los más difíciles de depurar.

Un diseño puede tener reset sincrónico o asincrónico. Normalmente la señal de reset es generada externamente al FPGA, por lo que es una señal asincrónica. Básicamente la señal de reset es una entrada al sistema que posibilita la correcta inicialización del mismo. Como así también, pueda forzar al sistema a ese estado inicial cuando haga falta (por ejemplo, cuando el sistema se ‘cuelga’, o se va de su normal funcionamiento). Esta señal asincrónica puede sincronizarse a través de un circuito sincronizador, para de este modo crear una señal de reset sin glitches y por lo menos de un ciclo de reloj de ancho. Sin embargo, como se detallará en los próximos puntos el reset totalmente sincrónico puede ocasionar alguna fallas aleatorias, por lo que se propone otro circuito a fin de hacer el sistema más confiable.


.........................................................................................................................................................

Comencé a escribir este blog, investigué bastante, y me encontré conque no hay algún lugar donde se pueda encontrar lo que yo considero importante de este tema. Por eso armé algo basado en mi experiencia, más una que otra información, y me quedó un blog kilométrico, que no creo conveniente publicar algo tan largo como un blog; por lo que sí te interesa este tema podes bajar el pdf desde este -link-

Espero te sea útil. 

Hasta pronto, y gracias por visitar mi blog. . . 

Cristian 

miércoles, 21 de agosto de 2013

Como 'ver' los 'delta delay' en ModelSim

Introducción 

Para algunas personas el concepto de delta delay en HDLs es uno de los mas difíciles de 'digerir' (entender). No es el objetivo de este articulo escribir acerca del concepto de 'delta delay' y sus derivados .... (hay demasiada literatura al respecto), lo que SI quiero hacerles llegar es que ModelSim tiene herramientas disponibles de modo que de manera sencilla se puede 'ver' el delta delay en forma gráfica o tabular. 

Como 'ver' los delta delays en ModelSim

Explicaré los pocos pasos necesarios a seguir para saber y ver cuantos delta times suceden hasta que una señal obtiene un valor estable. 
Primero, les detallo el simple código VHDL a usar para la demostración.

 1 library ieee;
 2 use eee.std_logic_1164.all;
 3
 4 entity aoi is
 5 port(A, B, C, D: in std_logic;
 6      E         : out std_logic);
 7 end aoi;
 8
 9 architecture beha4 of aoi is
10 signal O1, O2, O3:std_logic;
11
12 begin
13 b4: process(A, B, C, D, O1, O2, O3)
14  begin
15   E  <= not O3;
16   O1 <= A and B;  
17   O2 <= C and D;  
18   O3 <= O1 or O2;
19 end process b4;
20 end dflow1;

A continuación el simple test bench usado. 

 1 library ieee;
 2 use eee.std_logic_1164.all;
 3
 4 entity aoi_tb is
 5 end aoi_tb;
 6
 7 architecture test of aoi_tb is
 8 signal O1, O2, O3   : std_logic;
 9 signal a, b, c, d, e: std_logic;
10 component  aoi is
11   port(A, B, C, D: in std_logic; E: out std_logic);
12 end component;
13
14 begin
15    a <= '0', '1' after 6 ns;
16    b <= '0', '1' after 5 ns, '0' after 8 ns;
17    c <= '0', '1' after 7 ns;
18    d <= '0';
19
20 uut: aoi  port map(
21   E => e, a => a ,b => b ,c => c, d => d
22   );
23 end test;
24

Bien, entonces una vez que ejecutas el test bench en el entorno ModelSim se abre la ventana 'Wave', que muestra la forma de ondas de las senales del modulo que se esta simulando. Un punto a considerar es que normalmente por defecto se muestran solo por puertos de Entrada y Salida del modulo, por lo que hará falta agregar las señales internas necesarias a la ventana 'Wave' para poder ver los delta delay respectivos. 
Despues de ejecutar el test bench del ejemplo descrito la ventana Wave que se obtiene es la siguiente



Entonces, supongamos que queremos saber los delta delay asociados al evento en la senal 'B' al tiempo 8 ns. Los pasos a seguir son los siguientes: 
1- Colocar (sumar) un cursor en el tiempo de simulacion 8 ns. 
2- Hace click en el boton "Expanded Time Delta Mode"



3- Hace click en el boton "Expand Time At Active Cursor"



4- Click en "Zoom In At Active Cursor"




5- LiStO !

La siguiente figure resume los pasos detallados arriba  y muestra el resultado obtenido. 


< br/> Otro modo de Ver los Delta Delay

ModelSim ofrece tambien una especie de tabla, llamada en realidad 'List', donde detalla las senales, sus eventos y los respectivos delta delays. Para acceder a la misma hacer 'View->List'. De ese modo se obtiene una table similar a la siguiente.




Finalmente

Si alguna vez tuviste problemas para entender los delta delay, y como realmente 'funcionan', esta herramienta te ayuda mucho a poder dilucidad ese dilema... 

Hasta la próxima.....