Buscar este blog

domingo, 30 de noviembre de 2014

QUIEN USA DK HANDEL-C

  • Durante el año 2005 el detector el Gran Colisionador de Hadrones (GCH) ubicado en la Organización Europea para la Investigación Nuclear (CERN) desarrollo la tecnología de adquisición y transmisión de datos basado en FPGA para su sistema de detección ATLAS. Diseñado para que detecte y mida el mayor intervalo posible de energías así como sus propiedades. Véase figura donde se muestra las características principales de este sistema. 

  • La plataforma en hardware GETB por la cual procesaría y transmitirá toda la información del detector ATLAS se ve en la figura xx, la cual hace uso de un FPGA Stratix de ALTERA. Un punto relevante de este desarrollo fue el hecho de utilizar la metodología de programación en C utilizando para ello el lenguaje Handel-C al 90%.




Research Seminar, Fermi National Accelerator Laboratory

November 2005








sábado, 29 de noviembre de 2014

La tecnología detrás de DK

  • Introducción.

Handel-C [1] es un lenguaje de programación síncrono donde la noción del tiempo es fundamental. La construcción de circuitos síncronos usa relojes globales que continuamente ofrecen ticks. El lenguaje es similar en abstracción a RTL (Register Transfer Language) y se inclina hacia un estilo de programación del comportamiento en lugar de un lenguaje de descripción de hardware estructural tal como VHDL.
Handel-C capta los programas a un nivel de transformaciones simples en los datos y la circulación de los mismos entre variables (registros). El paralelismo puede ser definido explícitamente. La semántica del lenguaje está basada sobre Occam/CSP [2,3] y la sintaxis se basa en lenguaje C [4].

  • La ruta de datos.


Todas las variables en el programa de usuario son mapeadas a registros en hardware. Estos se construyen a partir de conjuntos de flip-flop. La arquitectura exacta de los flip-flop es específica de cada dispositivo destino. Un flip-flop básico de tipo D es mostrado en la figura 1. Un flipflop se construye para cada bit de una variable de programa. Cada franco ascendente del reloj se copia el valor de entrada D hacia el flip-flop, el estado actual del flip-flop se emite de forma continua a Q. Los relojes globales son usados para activar todos los flip-flops conectados a ese reloj al mismo tiempo como una acción atómica.

Figura 1

Los registros tienen multiplexores de entrada si tienen múltiples fuentes, por ejemplo, si son objeto de una asignación o comunicación en el programa Handel-C. Los circuitos de control en las declaraciones del programa generan las señales de control del multiplexor y la habilitación de las señales de reloj para los registros de destino. Todas las expresiones son implementadas con lógica combinacional. La ruta de los datos generada por esta estrategia coincide exactamente con el flujo de datos del programa original del usuario.

  • La ruta de control.

         En los circuitos de control siguientes la caja con un triángulo en la esquina superior izquierda se utiliza para referirse a una sola instancia de un circuito de control. El enlace de control se realiza mediante una sola entrada y una sola salida para cada circuito de control.

         El circuito de control para una construcción de retardo (delay) es mostrado en la figura 2. Esta construcción no tiene ningún efecto sobre el estado de la computación. Se tarda exactamente 1 ciclo de reloj para completar.

         El circuito de control para la instrucción de asignación R = exp; se muestra en la figura 3. La señal de arranque se forma por la señal de reloj CLK y la señal de habilitación CE para la correcta asignación del registro. Al final del ciclo en el que está prevista la asignación de la expresión de hardware se ha calculado el nuevo valor y este pasara al registro destino. La señal de arranque se retrasa por un solo ciclo de reloj para proporcionar la señal de finalización para este procedimiento de control. Esto se deduce del hecho de que la asignación siempre está programada inmediatamente y siempre se completa en exactamente un ciclo de reloj. Generalmente asignaciones Handel-C son libres por diseño de bucle. Se crea lógica combinacional suficiente para llevar a cabo la asignación en un ciclo de reloj incluso si la expresión es compleja. Un método para la refinación de programas en Handel-C es dividir las tareas complejas de expresiones para evaluarlas a través de múltiples ciclos de reloj.

El circuito de la figura 4 muestra la parte de la ruta de los datos generada por dos instrucciones de asignación R = Exp1; R = Exp2; que tienen como objetivo el mismo registro. Una señal de arranque dirige la expresión del valor apropiado por medio del multiplexor de la entrada del registro destino. El multiplexor es un solo disparo con una habilitación para cada línea de datos. De igual manera sea cual sea el inicio de la señal esta es activada hacia el destino vía compuerta OR.



         El circuito de control para la ejecución secuencial de estados es trivialmente sencillo. Las señales de salida y llegada de los procesos están conectadas entre sí en una conexión en cadena como se muestra en la figura 5. La estrategia de control es básicamente el de una codificación del estado de control “one-hot” modificado. Este esquema particular es muy adecuado para las implementaciones FPGA ya que requieren pocos recursos de cableado y de lógica, en comparación con las representaciones codificadas de estado de control. De hecho, el compilador puede tomar ventaja de la arquitectura específica, tales como registros de desplazamiento para optimizar aún más su aplicación.


En la figura 6 se muestra la construcción de un control utilizado para la ejecución en paralelo de los estados par{S1; S2;… Sn } ; Este circuito pasa el control al mismo tiempo a todas las declaraciones paralelas S1, S2, … Sn para que inicien su ejecución. El constructor par{} termina solo cuando todos los componentes constituyentes han terminado. Así, el circuito de control en paralelo recoge las señales de finalización en un conjunto de flip-flops y produce su propia señal de acabado tan pronto como se genera la última señal de los estados paralelos. Además, esta señal reestablece la sincronización de los flip-flops y que estén listos para la próxima vez que se utilicen en el circuito.
Las composiciones paralelas y secuenciales pueden ser anidadas arbitrariamente.


[1] Handel-C Language Reference Manual.
[2] C.A.R. Hoare, Communicating Sequential Processes, International Series in Computer Science, Prentice-Hall, 1985.
[3] Inmos, The occam2 Programming Manual, Prentice-Hall,1988.
[4] B.W. Kernigham and D.M. Ritchie, The C Programming Language, Prentice-Hall,1988.





viernes, 28 de noviembre de 2014

METODOLOGÍA DE PROGRAMACIÓN FPGA EN C CON DK HANDEL-C

  • En la literatura existen innumerables ejemplos de uso de lenguajes de alto nivel para la descripción de Hardware.

 Se mencionan algunos como los siguientes:

          C-Based System level languages
          Commercial
          SystemC --  The Open SystemC Initiative
          Handel C -- Celoxica Ltd.
          Impulse C  -- Impulse Accelerated Technologies
          Carte C – SRC Computers
          Research
          Streams-C -- Los Alamos National Laboratory
          SA-C -- Colorado State University, University of California, Riverside, Khoral Research, Inc.
          SpecC – University of California, Irvine and SpecC Technology Open Consortium
          Matlab-based
          AccelChip DSP Synthesis -- AccelChip
          System Generator for DSP -- Xilinx
          GUI Data-Flow based
          Corefire -- Annapolis Microsystems
          Java-based
          Commercial
          Forge -- Xilinx
          Research
          JHDL – Brigham Young University


  • En la metodología de DK Handel-C, la siguiente figura muestra en qué posición se encuentra comparado con otros lenguajes tanto de descripción en HW como meramente de SW.


Ventajas de Handel-C

·         Muy fácil de aprender y usar
·         Las instrucciones son basadas en ANSI C
·         Oculta detalles complejos de implementación
·         Muy flexible, no tiene limitaciones en paralelismo y tipos de datos.
·         Tiene operadores extendidos para la manipulación de bits
·         Tiene un modelo de tiempos bien definido
·         Tiene diversidad de dispositivos FPGA abarcados
·         Códigos heredados de lenguaje C previos son portados con facilidad.
·         Cada asignación toma un ciclo de reloj en ser ejecutada.


  • La metodología DK Handel-C se muestra en la siguiente figura:


  • Ejemplo de la metodología:



El ejemplo consistirá en realizar un sumador de 8 bits utilizando para ello un CORE VHDL llamado AddVHDL.vhd cuyo código fuente es: 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity AddVHDL is
    Port ( x : in  STD_LOGIC_VECTOR (7 downto 0);
           y : in  STD_LOGIC_VECTOR (7 downto 0);
           z : out  STD_LOGIC_VECTOR (7 downto 0));
end AddVHDL;

architecture Behavioral of AddVHDL is
begin
                        z <= x + y;       
end Behavioral;


  • Las herramientas necesarias para realizar estos ejemplos son:

Ø  Xilinx Design Tools ISE Suite 14.7
Ø  DK Desing suite  5.0 SP5
Ø  Synplify Pro H-2013.03
Ø  Tarjeta Spartan 3AN (XC3S700AN)


  • El siguiente esquema muestra el proceso de obtención del archivo final suma.bit para el FPGA


Pasos:


I.           Hacer un nuevo proyecto en DK Handel-C llamado suma. El código de main.hcc es el siguiente:

#include "delay.hch"
set clock = external "E12";
unsigned 8 LEDS,n,m;
interface bus_out() salida(LEDS) with {data = {"W21","Y22","V20","V19","U19","U20","T19","R20"}};

interface AddVHDL(unsigned 8 z)
AddVHDL(unsigned 8 x = n, unsigned 8 y = m) with {vhdl_type = "std_logic_vector",busformat="B(I)"};
void main(void)
{  
   par
   {
       while(1)
       {
           LEDS = AddVHDL.z;
       }
      
       while(1)
       {
           par
           {
               n++;
               m++;
           }
           delay_ms(C_MHZ,1000); //1000 ms
       }
   }
}

CONFIGURACIÓN DK


I.             II.        Hacer un proyecto en ISE de Xilinx llamado suma y agregar los archivos AddVHDL.vhd, main_hcc.vhd, agility.vhd, suma.vhd, suma.ufc.



I.                  III.       Cambiar en la línea 197 del archivo main_hcc.vhd I0_AddVHDL_main_32 : AddVHDL por I0_AddVHDL_main_32 : entity work.AddVHDL. Después guardar e implementar todo el proceso.



  • Implementación satisfactoria.









jueves, 27 de noviembre de 2014

INTERFAZ CON TECLADO AT-PS2 CON SPARTAN-3AN


  • Por la red existe una vasta información acerca del teclado at-ps2 y su forma de comunicarse con microcontroladores.


  • En el siguiente link se encuentra un documento donde se explica de manera detallada  todo acerca del teclado at-ps2 y su estándar de comunicación:



  • La conexión con la tarjeta spartan-3AN es la siguiente:


  • teclado.hch


interface bus_clock_in(unsigned 1 clk)  PS2_Clk() with {data = {"W12"}};
interface bus_clock_in(unsigned 1 data) PS2_Data() with {data = {"V11"}};

void decode(char sc);

static char unshifted[67][2] = {
0x0d,9,
0x0e,' ',
0x15,'q',
0x16,'1',
0x1a,'z',
0x1b,'s',
0x1c,'a',
0x1d,'w',
0x1e,'2',
0x21,'c',
0x22,'x',
0x23,'d',
0x24,'e',
0x25,'4',
0x26,'3',
0x29,' ',
0x2a,'v',
0x2b,'f',
0x2c,'t',
0x2d,'r',
0x2e,'5',
0x31,'n',
0x32,'b',
0x33,'h',
0x34,'g',
0x35,'y',
0x36,'6',
0x39,',',
0x3a,'m',
0x3b,'j',
0x3c,'u',
0x3d,'7',
0x3e,'8',
0x41,',',
0x42,'k',
0x43,'i',
0x44,'o',
0x45,'0',
0x46,'9',
0x49,'.',
0x4a,'-',
0x4b,'l',
0x4c,' ',
0x4d,'p',
//0x4e,''',
0x52,' ',
0x54,'`',
0x55,' ',
0x5a,13,
0x5b,'+',
0x5d,' ',
0x61,'<',
0x66,8,
0x69,'1',
0x6b,'4',
0x6c,'7',
0x70,'0',
0x71,'.',
0x72,'2',
0x73,'5',
0x74,'6',
0x75,'8',
0x79,'+',
0x7a,'3',
0x7b,'-',
0x7c,'*',
0x7d,'9',
0,0
};

static char shifted[68][2] = {
0x0d,9,
0x0e,' ',
0x15,'Q',
0x16,'!',
0x1a,'Z',
0x1b,'S',
0x1c,'A',
0x1d,'W',
0x1e,'"',
0x21,'C',
0x22,'X',
0x23,'D',
0x24,'E',
0x25,'$',
0x26,' ',
0x29,' ',
0x2a,'V',
0x2b,'F',
0x2c,'T',
0x2d,'R',
0x2e,'%',
0x31,'N',
0x32,'B',
0x33,'H',
0x34,'G',
0x35,'Y',
0x36,'&',
0x39,'L',
0x3a,'M',
0x3b,'J',
0x3c,'U',
0x3d,'/',
0x3e,'(',
0x41,';',
0x42,'K',
0x43,'I',
0x44,'O',
0x45,'=',
0x46,')',
0x49,':',
0x4a,'_',
0x4b,'L',
0x4c,' ',
0x4d,'P',
0x4e,'?',
0x52,' ',
0x54,'^',
0x55,' ',
0x5a,13,
0x5b,'*',
0x5d,' ',
0x61,'>',
0x66,8,
0x69,'1',
0x6b,'4',
0x6c,'7',
0x70,'0',
0x71,'.',
0x72,'2',
0x73,'5',
0x74,'6',
0x75,'8',
0x79,'+',
0x7a,'3',
0x7b,'-',
0x7c,'*',
0x7d,'9',
0,0
};

void init_teclado(void)
{
   unsigned 1 flag_1,flag_0;
   unsigned 8 bitcount;
   unsigned 8 data;
                        data=0;
                        bitcount=11;
   flag_1=1;
   flag_0=0;

   while(1)
   {
      if(~PS2_Clk.clk && flag_1) //ext_int_edge(H_TO_L);
      {
                                                if(bitcount < 11 && bitcount > 2)
                                                {
                        data = (data >> 1);
                        if( PS2_Data.data == 1)
                                                data = data | 0x80;
                                                }
        --bitcount;
                                                if(bitcount == 0)
                                                {
                        decode((char)data);
                        data = 0;
                        bitcount = 11;
                                                }
                                                flag_1=0;
                                                flag_0=1;
      }
      else if(PS2_Clk.clk && flag_0)
      {
          flag_1=1;
                                                  flag_0=0;
      }
                          else
                             delay;
   }  
}

void decode(char sc)
{
   static unsigned 1 is_up=0,shift=0;
   unsigned 7 i;                              

   //is_up=0;
   //shift = 0;
  
   //-------- El ltimo dato recibido fue el identificador de Up-Key
   if (!is_up)
      {
         switch (sc)
            {
            //-------- Identificador de Up-Key
               case 0xF0 :
                  is_up = 1;
                  break;
               //-------- SHIFT Izquierdo
               case 0x12 :
                  shift = 1;
                  break;
               //-------- SHIFT Derecho
               case 0x59 :
                  shift = 1;
                   lcd_gotoxy(1,1);
                  break;
               //-------- ENTER
               case 0x5A :
                  //printf("\n\r");
                    lcd_gotoxy(1,2);
                    break;
               default:
                  if(!shift)
                     {
                        for(i = 0; i<=67; i++)
                        {
                           if (unshifted[i][0] == sc)
                           {
                              //printf("%c", unshifted[i][1]);
                                lcd_putc(unshifted[i][1]);
                           }
                        }
                     }
                  else
                    {
                        for(i = 0; i<=68; i++)
                        {
                           if (shifted[i][0] == sc)
                           {
                               //printf("%c", shifted[i][1]);
                                 lcd_putc(shifted[i][1]);
                           }
                        }
                     }
                 break;
            }
     }
     else
         {
         //-------- No se permiten 2 0xF0 en una fila
         is_up = 0;
         switch (sc)
            {
               //-------- SHIFT Izquierdo
               case 0x12 :
                  shift = 0;
                  break;
               //-------- SHIFT Derecho
               case 0x59 :
                  shift = 0;
                  break;
            }
         }
}



  • El driver fue elaborado en DK Design Suite en Handel-C :



  • La síntesis fue hecha con SynplifyPro y la implementacion con ISE:


  • La programación del FPGA a través de iMPACT:


  • Resultados: