lunes, 9 de febrero de 2015

Partición de Diseño Basada en Dominio de Reloj

Introducción

Cuando el sistema a diseñar tiene varios módulos y a su vez cada uno de estos módulos tiene su propio reloj, y los módulos interactuan entre sí, es conveniente realizar lo que se llama partición del diseño basado en dominio de reloj, y seguir un par de simples reglas con respecto al modo de realizar la partición como así también con respecto al nombre de las señales de E/S, y de las señales de comunicación entre módulos.

Partición del Diseño

Supongamos tenemos un sistema como el que se muestra en la siguiente figura:


En este caso el sistema se ha dividido en tres módulos, A, B y C. Esta división está basada en función de los distintos relojes que tiene el sistema y en la funcionalidad de cada módulo; por ello cada módulo en este partición tiene su propio reloj. Así, cada módulo tiene lo que comúnmente se llama su propio dominio de reloj (clock domain). 
Esta partición de un sistema basada en dominio de reloj es muy importante por diversos motivos, principalmente facilita el trabajo de la herramienta de síntesis, mejora las tareas de las herramientas de cálculo de frecuencia máxima (Static Timing Analysis), ahorra tiempo en la herramienta de place and route. Otra ventaja de este tipo de partición, es que  ahorra mucho tiempo de procesamiento de CPU en sistemas complejos.

Sincronizadores

Al hacer la particion basada en dominio de reloj, y si los distintos módulos deben interactuar entre sí es necesario realizar algún tipo de sincronización entre las señales de comunicación entre módulos, ya que cada señal tiene su propio reloj. Esta sincronización puede ser realizada mediante sincronizadores o mediante FIFOs (no es el objetivo de este blog explicar los diferentes métodos de sincronización). Así por ejemplo, si se desea comunicarse una señal del módulo A con el módulo B, es necesario un sincronizador que sincronice la señal proveniente del módulo A basada en el reloj aclk, con el reloj bclk del módulo B. Del mismo modo para comunicarse o transferir datos desde el módulo B al módulo A, es necesario un sincronizador para pasar del dominio bclk al dominio aclk
De este modo todos los módulos principales tiene solo un solo reloj, mientras que los módulos sincronizadores, tienen múltiples relojes. 

Nombre de Señales

Con este tipo de partición es fácil seguir una convención para el nombre de las señales. Así, todas las señales que solo son controladas por un solo reloj, son definidas con nombres referenciando a ese dominio de reloj. Por ejemplo las señales del módulo A que solo son controlada por el reloj de A, aclk, se pueden nombrar comenzando con la letra a (referenciando al módulo A), así se puede nombrar la señal adata, aadrr, aen, etc., como también bdata, baddr, ben, etc, para las señales controladas por el dominio de reloj del modulo B (bclk). 
Por otro lado las señales que cruzan los dominios de reloj (a travez de los sincronizadores) deberían ser nombradas de forma que sea fácil de deducir el origen y el destino de la señal. Por ejemplo, si la señal ack debe cruzar del dominio bclk al dominio aclk se podría denominar b2a_ack
Usando este tipo de nomenclatura fácilmente se puede identificar cuales son las señales que cruzan diferentes dominios de reloj. Una de las grandes ventajas de esto es que se puede escribir la respectiva restricción (constraint) de false path para facilitar el trabajo de la herramienta de análisis de tiempo estático (Static Timing Analysis). 

Otras Ventajas de Partición por Dominio de Reloj

Ademas de las ventajas mencionadas anteriormente, este tipo de partición facilita el trabajo de floorplanning de la herramienta de síntesis, y como consecuencia se puede llegar más fácilmente a una reducción de área, mejoramiento del rendimiento, e incluso reducir la potencia de consumo del sistema. 
También, al tener los módulos separados por dominio de reloj, las herramientas de síntesis actuales permiten que cada módulo sea optimizado individualmente (ya sea por área, velocidad o potencia). 

Es todo por hoy.....

Espero sea de utilidad.....

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