Cosillas que hice hace muuuchos años en Handel-C

Handel-C, ABEL, SystemC, etc
Responder
Avatar de Usuario
mcleod_ideafix
Site Admin
Mensajes: 80
Registrado: 14 Ago 2018, 01:15

Cosillas que hice hace muuuchos años en Handel-C

Mensaje por mcleod_ideafix » 16 Ago 2018, 01:59

De hecho fue mi primer lenguaje de descripción (o programación en este caso?) para dispositivos con lógica programable. Lo aprendí en un curso en el CSIC en Madrid, en otoño del 2010.

Este es uno de los ejercicios que hicimos durante el curso, trasladado a una placa FPGA mucho más barata que las de Celoxica que usamos allí. Un generador de pantalla VGA con un pequeño sprite (un fantasmita del Pacman) dando botes de un lado a otro. Recuerdo que era muuuy fácil modificar el código y hacer que el sprite fuera el doble o el cuádruple de grande, o en general, hacer que cada uno de sus píxeles se ampliara en un factor de una potencia de 2. Código fuente incluido.

Código: Seleccionar todo

/* Ejemplo de uso de la salida VGA de la tarjeta BASYS en Handel-C
   El programa es una adaptación de uno de los ejercicios propuestos
   en el curso de Procesado de Imagen con FPGA.
   (C)2010 Miguel Angel Rodriguez Jodar.
           Departamento de Arquitectura y Tecnologia de Computadores.
           Universidad de Sevilla. */

#define ClockPin "P54"
#define ClockRate 25

#define VGARedPins   {"P67","P68","P70"}
#define VGAGreenPins {"P50","P51","P52"}
#define VGABluePins  {"P43","P44"}
#define VGASyncHPins {"P39"}
#define VGASyncVPins {"P35"}

set clock=external ClockPin with { rate=ClockRate, standard="LVCMOS33" };

#define TSH 800
#define TSV 520
#define TPWH 95
#define TPWV 2
#define TFPH 16
#define TFPV 10
#define TBPH 48
#define TBPV 29
#define TDISPH 639
#define TDISPV 480

static unsigned 10 contador_x=0;
static unsigned 10 contador_y=0;
static unsigned 1 HS=1;
static unsigned 1 VS=1;
unsigned 1 enable_video;

rom unsigned 24 Sprite [16*16] = {  /* fantasmita del PacMan */
    0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,
    0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,
    0x00FF00,0x00FF00,0x00FF00,0x00FF00,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0x00FF00,0x00FF00,0x00FF00,0x00FF00,
    0x00FF00,0x00FF00,0x00FF00,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0x00FF00,0x00FF00,0x00FF00,
    0x00FF00,0x00FF00,0xFF0000,0x000000,0x000000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0x000000,0x000000,0xFF0000,0xFF0000,0xFF0000,0x00FF00,0x00FF00,
    0x00FF00,0x00FF00,0x000000,0x000000,0x000000,0x000000,0xFF0000,0xFF0000,0x000000,0x000000,0x000000,0x000000,0xFF0000,0xFF0000,0x00FF00,0x00FF00,
    0x00FF00,0x00FF00,0xFFFFFF,0xFFFFFF,0x000000,0x000000,0xFF0000,0xFF0000,0xFFFFFF,0xFFFFFF,0x000000,0x000000,0xFF0000,0xFF0000,0x00FF00,0x00FF00,
    0x00FF00,0xFF0000,0xFFFFFF,0xFFFFFF,0x000000,0x000000,0xFF0000,0xFF0000,0xFFFFFF,0xFFFFFF,0x000000,0x000000,0xFF0000,0xFF0000,0xFF0000,0x00FF00,
    0x00FF00,0xFF0000,0xFF0000,0x000000,0x000000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0x000000,0x000000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0x00FF00,
    0x00FF00,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0x00FF00,
    0x00FF00,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0x00FF00,
    0x00FF00,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0x00FF00,
    0x00FF00,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0xFF0000,0x00FF00,
    0x00FF00,0xFF0000,0xFF0000,0x00FF00,0xFF0000,0xFF0000,0xFF0000,0x00FF00,0x00FF00,0xFF0000,0xFF0000,0xFF0000,0x00FF00,0xFF0000,0xFF0000,0x00FF00,
    0x00FF00,0xFF0000,0x00FF00,0x00FF00,0x00FF00,0xFF0000,0xFF0000,0x00FF00,0x00FF00,0xFF0000,0xFF0000,0x00FF00,0x00FF00,0x00FF00,0xFF0000,0x00FF00,
    0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00,0x00FF00

} with {block = "BlockRAM"};

void RunVGAOutput();
void SetRGB (unsigned 8, unsigned 8, unsigned 8);

#define TAMCUADRO 16
void main()
{
    static unsigned 10 posicion_x=0;
    static unsigned 10 posicion_y=16;
    static unsigned 1 delta_x=0;
    static unsigned 1 delta_y=0;
    unsigned 24 color;
    unsigned 1 dibujar_cuadro_h, dibujar_cuadro_v, dibujar_cuadro;
    
    par  /* 3 máquinas de estado en paralelo */
    {
/************************************************************************************************/
        RunVGAOutput();  /* la primera maquina de estado, produce la temporización VGA 
                             y mantiene los contadores x,y*/

/************************************************************************************************/
        while(1)  /* La segunda maquina de estado dibuja un punto */
        {         /* del color apropiado, según la posición de dicho punto */
            if (enable_video)  /* si estamos en zona de pixeles... */
            {
                par   /* este bloque dura 2 ciclos */
                {
                    color=Sprite[(contador_y-posicion_y)[3:0]@(contador_x-posicion_x)[3:0]];  /* color del sprite que tocaria pintar */
                    dibujar_cuadro_h = (contador_x==posicion_x)? 1 : (contador_x==posicion_x+TAMCUADRO || contador_x==639)? 0 : dibujar_cuadro_h; /* si la posicion X está en la zona en la que debe pintarse el sprite, indicarlo */
                    dibujar_cuadro_v = (contador_y==posicion_y)? 1 : (contador_y==posicion_y+TAMCUADRO || contador_y==479)? 0 : dibujar_cuadro_v; /* si la posicion Y está en la zona en la que debe pintarse el sprite, indicarlo */
                    dibujar_cuadro = dibujar_cuadro_h & dibujar_cuadro_v;  /* Si ambos X e Y están en la zona del sprite, indicarlo */
                    if (dibujar_cuadro && color!=0x00ff00)  /* si toca pintar un pixel del sprite y éste no es de color verde... (=transparente) */
                        SetRGB(color[23:16],color[15:8],color[7:0]);
                    else  /* si no, pintar el fondo de pantalla (una trama mu mona que me he inventado) */
                        SetRGB(contador_x[7:0]^posicion_y[7:0],contador_y[7:0]^posicion_x[7:0],contador_x[7]@contador_y[7]@0b000000);
                }
            }
            else  /* si no estamos en zona de píxeles, apaga la generación de color RGB */
                SetRGB(0,0,0);
        }
        
/************************************************************************************************/
        while(1)  /* la tercera máquina de estados actualiza la posición del sprite, una vez cada cuadro (60Hz)*/
        {
            while(VS)  /* esperamos a que baje la señal VS (retrazo vertical) */
                delay;
            while (!VS) /* y ahora esperamos a que suba */
                delay;

            par
            {
                posicion_x = (delta_x)? posicion_x -1 : posicion_x +1;
                posicion_y = (delta_y)? posicion_y -1 : posicion_y +1;
            }
            par
            {
                if (posicion_x==639-TAMCUADRO || posicion_x==0)
                    delta_x = ~delta_x;
                else
                    delay;
                if (posicion_y==479-TAMCUADRO || posicion_y==0)
                    delta_y = ~delta_y;
                else
                    delay;
            }
        }
/************************************************************************************************/
    }
}
        
void RunVGAOutput()
{
    static unsigned 10 contador_h=0;
    static unsigned 10 contador_v=0;
    unsigned 1 enable_video_h,enable_video_v;
    interface bus_out () HSync (unsigned 1 out=HS) with {data = VGASyncHPins, standard = "LVCMOS33"};
    interface bus_out () VSync (unsigned 1 out=VS) with {data = VGASyncVPins, standard = "LVCMOS33"};

    while(1)
    {
        par
        {
            if (contador_h==TSH)
                contador_h=0;
            else
                contador_h++;
            
            if (contador_h==0)
            {
                par
                {
                    HS=0;
                    if (contador_v==TSV)
                        contador_v=0;
                    else
                        contador_v++;
                        
                    if (enable_video_v)
                        contador_y++;
                    else
                        delay;
                }
            }
            else if (contador_h==TPWH)
                HS=1;
            else if (contador_h==TPWH+TBPH)
            {
                par
                {
                    enable_video_h=1;
                    contador_x=0;
                }
            }
            else if (contador_h==TPWH+TBPH+TDISPH)
                enable_video_h=0;
            else
                delay;
            
            if (contador_v==0)
                VS=0;
            else if (contador_v==TPWV)
                VS=1;
            else if (contador_v==TPWV+TBPV)
            {
                par
                {
                    enable_video_v=1;
                    contador_y=0;
                }
            }
            else if (contador_v==TPWV+TBPV+TDISPV)
                enable_video_v=0;
            else
                delay;
            
            enable_video = enable_video_h & enable_video_v;
            
            if (enable_video_h)
                contador_x++;
            else
                delay;
            
        }
    }
}

void SetRGB (unsigned 8 r, unsigned 8 g, unsigned 8 b)
{
    unsigned 3 Red, Green;
    unsigned 2 Blue;
    interface bus_out () VGARed (unsigned 3 out=Red) with {data = VGARedPins, standard = "LVCMOS33"};
    interface bus_out () VGAGreen (unsigned 3 out=Green) with {data = VGAGreenPins, standard = "LVCMOS33"};
    interface bus_out () VGABlue (unsigned 2 out=Blue) with {data = VGABluePins, standard = "LVCMOS33"};
 
    par
    {
        Red = r[7:5];
        Green = g[7:5];
        Blue = b[7:6];
    }
}
phpBB [media]



Efecto "Knight Rider" (seguro que sabeis a qué me refiero) usando los leds de la placa Basys (una placa basada en una Spartan 3 pequeña)
phpBB [media]



Contador de 4 dígitos para la placa Basys3, en Handel-C (incluyo el código fuente)

Código: Seleccionar todo

/* Ejemplo de uso del display de 4 dígitos de 7 segmentos de la
   tarjeta BASYS, en Handel-C.
   (C)2010 Miguel Angel Rodriguez Jodar.
           Departamento de Arquitectura y Tecnologia de Computadores.
           Universidad de Sevilla. */

#define ClockPin "P54"
#define ClockRate 100

#define LEDPins {"P2","P3","P4","P5","P7","P8","P14","P15"}
#define Segmentos {"P83","P17","P20","P21","P23","P16","P25"}
#define Anodos {"P26","P32","P33","P34"}

set clock=external ClockPin with { rate=ClockRate, standard="LVCMOS33" };

void SetLEDs(unsigned 8);
void RunDisplay();

static unsigned 4 numerobcd[4]={0,0,0,0};

void main()
{
    unsigned 23 retardo;
    static unsigned 8 valor=1;
    static unsigned 1 direccion=0;

    par
    {
        RunDisplay();
        
        while(1)
        {
            numerobcd[3]++;
            if (numerobcd[3]==10)
            {
                numerobcd[3]=0;
                numerobcd[2]++;
                if (numerobcd[2]==10)
                {
                    numerobcd[2]=0;
                    numerobcd[1]++;
                    if (numerobcd[1]==10)
                    {
                        numerobcd[1]=0;
                        numerobcd[0]++;
                        if (numerobcd[0]==10)
                            numerobcd[0]=0;
                    }
                }
            }
            
            SetLEDs (valor);
            if (direccion==0)
                valor=valor<<1;
            else
                valor=valor>>1;
            if (valor==1 || valor==128)
                direccion=~direccion;
            
            while (retardo)
                retardo--;
            retardo--;
        }
    }
}


void SetLEDs(unsigned 8 v)  /* 2 ciclos de reloj: uno para asignar el parámetro a V y otro para asignarlo a LED */
{
    unsigned 8 LED;
    interface bus_out () IntLED (unsigned 8 out=LED ) with {data = LEDPins, standard = "LVCMOS33"};

    LED=v;
}

void RunDisplay()
{
 	static rom unsigned 7 Digitos[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};  /* conversor BCD a 7 segmentos */
    static rom unsigned 4 Deco2a4[4]={0b0111,0b1011,0b1101,0b1110};  /* sencillo deco de 2 a 4 para los ánodos */
    unsigned 7 CatSegments;
    unsigned 4 AnSegments;
    interface bus_out () DisplayCatodos (unsigned 7 out=CatSegments) with {data = Segmentos, standard = "LVCMOS33"};
    interface bus_out () DisplayAnodos  (unsigned 4 out=AnSegments) with {data = Anodos, standard = "LVCMOS33"};
    unsigned 2 iDigito;   /* contador de 2 bits para recorrer los 4 digitos */
    unsigned 16 retardo;  /* contador de 16 bits (65536 ciclos de reloj) para implementar un retardo 
                             que dé tiempo a que se vea el digito */

    while(1)  /* esta maquina de estados debe arrancarse en paralelo con el resto de cosas */
    {
        par
        {
            AnSegments = Deco2a4[iDigito];  /* activamos un ánodo de los 4 */
            CatSegments = Digitos[numerobcd[iDigito]];  /* mostramoss el dígito */
            iDigito++; /* siguiente display */
            retardo--; /* preparamos el retardo igual a 0xFFFF (¿sería menos costoso poner retardo=0xffff? */
        }
        while (retardo)  /* bucle de retardo. Gasta "retardo" ciclos de reloj */
            retardo--;
    }
}
phpBB [media]



Primera versión de una "ULA" de Spectrum, o sea, un circuito que genera video (señal VGA en este caso) con la misma disposición de pantalla que el Spectrum.
En este caso en particular, un proceso en paralelo va rellenando lentamente la memoria de video con un patrón. En el video comparo el comportamiento de este diseño con un emulador de Spectrum ejecutando un programa que rellena la memoria de video de la misma forma.
Incluyo el código fuente en primicia total.

Código: Seleccionar todo

/* Generación de imágenes en color con un framebuffer reducido, de 6912 bytes
   He escogido este esquema porque permite imágenes a color con un framebuffer
   lo suficientemente pequeño como para que quepa en la memoria BlockRAM de una
   Spartan3-100, como la que lleva la tarjeta BASYS.
   El formato es un remedo del formato de imagen que genera la ULA del
   Sinclair ZX Spectrum.

   Ver demo en: http://www.youtube.com/watch?v=ronoUVZ3LRo 

   (C)1982 Sinclair Research Ltd / Amstrad plc.
   (C)2010 Miguel Angel Rodriguez Jodar.
           Departamento de Arquitectura y Tecnologia de Computadores.
           Universidad de Sevilla. */

#define ClockPin "P54"
#define ClockRate 25

#define VGAColorPins {"P67","P68","P70","P50","P51","P52","P43","P44"}
#define VGASyncHPins {"P39"}
#define VGASyncVPins {"P35"}

set clock=external ClockPin with { rate=ClockRate, standard="LVCMOS33" };

#define TSH 800
#define TSV 520
#define TPWH 95
#define TPWV 2
#define TFPH 16
#define TFPV 10
#define TBPH 48
#define TBPV 29
#define TDISPH 639
#define TDISPV 480

static unsigned 10 contador_x=0;
static unsigned 10 contador_y=0;
static unsigned 1 HS=1;
static unsigned 1 VS=1;
unsigned 1 enable_video;

unsigned 8 Borde;
mpram
{
    wom unsigned 8 CPU[6912];
    rom unsigned 8 ULA[6912];
} Framebuffer with {block="BlockRAM"};

void RunVGAOutput();
void ZXVideoULA();

void main()
{
    unsigned 13 i;
    unsigned 15 retardo;
    
    par
    {
        ZXVideoULA();
    
        /* máquina de estados que rellena el framebuffer lentamente, para que
        se vea el formato usado, usando los valores 0,1,2,...,254,255,0,1,2,3... */
        seq
        {
            Borde=7;
            for (i=6144;i!=6912;i++)
                Framebuffer.CPU[i]=56;
            for (i=0;i!=6912;i++)
            {
                Framebuffer.CPU[i]=i[7:0];
                while(retardo)
                    retardo--;
                retardo--;
            }
        }
    }
}


macro expr ULA_x=(contador_x-64)>>1;
macro expr ULA_y=(contador_y-48)>>1;
/* 
En alta resolución podemos ponerlo así:
010 BB SSS FFF CCCCC
Coordenadas: X,Y
X/8 = CCCCC
X%8 = bit dentro del byte apuntado por CCCCC
Y = BBFFFSSS
*/

macro expr GetAddrBitmap(x,y)=(y[7:6]@y[2:0]@y[5:3]@x[7:3]);
macro expr GetAddrAttr(x,y)=(0b110@y[7:3]@x[7:3]);

void ZXVideoULA()
{
    unsigned 8 Color;
    interface bus_out () VGAColor (unsigned 8 out=Color) with {data = VGAColorPins, standard = "LVCMOS33"};
    static rom unsigned 8 Paleta[16]={0x00,0b00000010,0b10000000,0b10000010,0b00010000,0b00010010,0b10010000,0b10010010,
                                      0x00,0b00000011,0b11000000,0b11000011,0b00011000,0b00011011,0b11011000,0b11011011};
    unsigned 1 estoy_en_paper_h,estoy_en_paper_v,estoy_en_paper;
    unsigned 8 bitmap,bitmap2,atributo;
    unsigned 13 dirbitmap,dirattr;
    unsigned 4 contbitsbitmap;
    static unsigned 5 contflash=0;
    unsigned 1 fflash;
                                      
    par
    {
        RunVGAOutput();
        
        while(1)
        {
            while(VS)
                delay;
            while(!VS)
                delay;
            contflash++;
            if (contflash==19)
            {
                fflash=~fflash;
                contflash=0;
            }
        }
        
        while(1)
        {
            if (enable_video)
            {
                par
                {
                    estoy_en_paper_h = (contador_x==64)? 1 : (contador_x==576)? 0 : estoy_en_paper_h;
                    estoy_en_paper_v = (contador_y==48)? 1 : (contador_y==432)? 0 : estoy_en_paper_v;
                    estoy_en_paper = estoy_en_paper_h & estoy_en_paper_v;
                    if (!estoy_en_paper)
                    {
                        par
                        {
                            Color=Paleta[0b0@Borde[2:0]];
                            contbitsbitmap=0;
                            if (estoy_en_paper_v && contador_x==61)
                            {
                                par
                                {
                                    dirbitmap = GetAddrBitmap(0,ULA_y);
                                    dirattr = GetAddrAttr(0,ULA_y);
                                }
                            }
                            else if (estoy_en_paper_v && contador_x==62)
                                bitmap = Framebuffer.ULA[dirbitmap];
                            else if (estoy_en_paper_v && contador_x==63)
                                atributo = Framebuffer.ULA[dirattr];
                            else
                                delay;
                        }
                    }
                    else
                    {
                        par
                        {
                            switch (contbitsbitmap)
                            {
                                case 13:
                                    par
                                    {
                                        dirbitmap++;
                                        dirattr++;
                                    }
                                    break;
                                case 14:
                                    bitmap2 = Framebuffer.ULA[dirbitmap];
                                    break;
                                case 15:
                                    par
                                    {
                                        bitmap = bitmap2;
                                        atributo = Framebuffer.ULA[dirattr];
                                    }
                                    break;
                                default:
                                    delay;
                            }
                            
                            contbitsbitmap++;
                            if (contbitsbitmap[0])
                                bitmap = bitmap<<1;
                            else
                                delay;
                            Color=Paleta[ (bitmap[7])? atributo[6]@((atributo[7]&fflash)? atributo[5:3] : atributo[2:0]) : atributo[6]@((atributo[7]&fflash)? atributo[2:0] : atributo[5:3]) ];
                        }
                    }
                }
            }
            else
                Color=0x00;
        }
    }
}

                    
void RunVGAOutput()
{
    static unsigned 10 contador_h=0;
    static unsigned 10 contador_v=0;
    unsigned 1 enable_video_h,enable_video_v;
    interface bus_out () HSync (unsigned 1 out=HS) with {data = VGASyncHPins, standard = "LVCMOS33"};
    interface bus_out () VSync (unsigned 1 out=VS) with {data = VGASyncVPins, standard = "LVCMOS33"};

    while(1)
    {
        par
        {
            if (contador_h==TSH)
                contador_h=0;
            else
                contador_h++;
            
            if (contador_h==0)
            {
                par
                {
                    HS=0;
                    if (contador_v==TSV)
                        contador_v=0;
                    else
                        contador_v++;
                        
                    if (enable_video_v)
                        contador_y++;
                    else
                        delay;
                }
            }
            else if (contador_h==TPWH)
                HS=1;
            else if (contador_h==TPWH+TBPH)
            {
                par
                {
                    enable_video_h=1;
                    contador_x=0;
                }
            }
            else if (contador_h==TPWH+TBPH+TDISPH)
                enable_video_h=0;
            else
                delay;
            
            if (contador_v==0)
                VS=0;
            else if (contador_v==TPWV)
                VS=1;
            else if (contador_v==TPWV+TBPV)
            {
                par
                {
                    enable_video_v=1;
                    contador_y=0;
                }
            }
            else if (contador_v==TPWV+TBPV+TDISPV)
                enable_video_v=0;
            else
                delay;
            
            enable_video = enable_video_h & enable_video_v;
            
            if (enable_video_h)
                contador_x++;
            else
                delay;
            
        }
    }
}
phpBB [media]


Para meterle una imagen predefinida, cambiar en el código anterior esto:

Código: Seleccionar todo

mpram
{
    wom unsigned 8 CPU[6912];
    rom unsigned 8 ULA[6912];
} Framebuffer with {block="BlockRAM"};
Por esto:

Código: Seleccionar todo

static rom unsigned 8 Framebuffer[6912]=
{
    #include "contenido_rom.hch"
    /* Se incluye una aplicación en C (file2data.c) que permite 
    coger un fichero conteniendo una imagen de memoria de la VRAM del
    Spectrum (o una pantalla de carga) y convertirla a un
    formato adecuado para incluirla en este punto del programa.
    Se incluyen unos cuantos de estos ficheros, con extensión SCR */
} with {block="BlockRAM"};
La aplicación en C es un sencillo programa, cuyo código fuente es éste:

Código: Seleccionar todo

#include <stdio.h>

#define SCREENFILE "phantis.scr"  // o cualquier otro...

void main (void)
{
	FILE *fi, *fo;
	unsigned char buffer[6912];
	int i;

	fi=fopen(SCREENFILE,"rb");
	fread (buffer, 1, 6912, fi);
	fclose(fi);
	
	fo=fopen("contenido_rom.hch","wt");
	for (i=0;i<6912;i++)
	{
		fprintf (fo,"0x%02.2X",buffer[i]);
		if (i!=6911)
			fprintf (fo,", ");
		if (i%16==15)
			fprintf (fo,"\n");
	}
	fclose(fo);
}
Y la pinta que tiene es ésta (usando algunos screen$ que pillé por ahí)
basys_cannonbubble.jpg
basys_cannonbubble.jpg (135.49 KiB) Visto 7580 veces
basys_neloquqo.jpg
basys_neloquqo.jpg (65.25 KiB) Visto 7580 veces
basys_jinj.jpg
basys_jinj.jpg (124.35 KiB) Visto 7580 veces

Avatar de Usuario
mcleod_ideafix
Site Admin
Mensajes: 80
Registrado: 14 Ago 2018, 01:15

Re: Cosillas que hice hace muuuchos años en Handel-C

Mensaje por mcleod_ideafix » 16 Ago 2018, 02:01

Si consigo algún que otro ciclo de reloj libre en mi tiempo, veré si es posible adaptar el entorno de desarrollo para que Handel-C pueda generar código (aunque no sea eficiente) para la Spartan 6. Si eso fuera posible, podría usarse con ZXUNO y ZXDOS :)

Hark0
Veroboard
Mensajes: 7
Registrado: 17 Ago 2018, 10:34

Re: Cosillas que hice hace muuuchos años en Handel-C

Mensaje por Hark0 » 23 Ago 2018, 17:20

Hmmm para no caer en lo mismo que hace una vida (creer que los cargadores CM de pokes de la MH... eran el juego completo.. XD), pregunto:

El source de "generar una señal VGA + sprite que se menea"... es SOLO eso????

Y añado en mi ignorancia... puedo sintetizarlo para la placa UnAmiga y/o ZX-Uno?

Ahora es cuando sacas la vara y me corres a galletas por toda el aula... :-P

Avatar de Usuario
mcleod_ideafix
Site Admin
Mensajes: 80
Registrado: 14 Ago 2018, 01:15

Re: Cosillas que hice hace muuuchos años en Handel-C

Mensaje por mcleod_ideafix » 24 Ago 2018, 03:18

Hark0 escribió:
23 Ago 2018, 17:20
El source de "generar una señal VGA + sprite que se menea"... es SOLO eso????
Si no me he dejado nada (que creo que no), sí, es eso. EDITO: confirmo que ese fichero es todo lo que se necesita. Fíjate que incluso los numeros de los pines de la FPGA están incluidos ahí, así que no hace falta siquiera un fichero UCF.
Hark0 escribió:
23 Ago 2018, 17:20
Y añado en mi ignorancia... puedo sintetizarlo para la placa UnAmiga y/o ZX-Uno?
Esto se sintetizó para una FPGA bastante más pequeña que la del ZXUNO, y por supuesto que el UnAmiga, así que por capacidad, sí, se puede hacer.

Lo malo es que el entorno de Handel-C es de lo más propietario que hay. Sólo soporta placas de Celoxica, el fabricante que en su momento tenía esto. El compilador es capaz de generar código para Spartan 3, así que diciéndole que compilara para una placa "genérica" con una Spartan 3, conseguí hacer funcionar todos estos ejemplos (la placa es de las más baratas que hay con Spartan 3, una BASYS2 de Digilent).

Mi intención, minutos después de escribir este post, era coger e instalar de nuevo el entorno y ver si podía exportar lo compilado a un fichero VHDL "normal" o Verilog (algo así como si en el gcc usaras el -S para decirle que genere el código ensamblador de tu programa) de forma que dicho fichero lo incorporara a un proyecto estándar del ISE, peeeeeero... el keygen (ejem ejem) que tengo me genera licencias que caducaron hace unos meses, así que no tengo forma de volver a instalar el software.

Y es una verdadera pena, porque es que no conozco ningún otro compilador/traductor de Handel-C. Algunos dirán que está superado por OpenCL o por el compilador de C de Vivado pero yo siempre he visto a Handel-C como un lenguaje muy potente y muy bueno para hacer de puente entre un ingeniero software, acostumbrado a trabajar con C, y un ingeniero hardware, acostumbrado a circuitería.

Por otra parte, también te puedo decir que el equivalente Verilog de ese diseño que hace que el sprite pegue botes por la pantalla no es tampoco muy largo, y ese sí que puedo escribirlo y usarlo en cualquier FPGA. Me lo apunto como pequeño ejercicio que pondré en el foro :)

Hark0
Veroboard
Mensajes: 7
Registrado: 17 Ago 2018, 10:34

Re: Cosillas que hice hace muuuchos años en Handel-C

Mensaje por Hark0 » 30 Ago 2018, 20:39

Ufff gran put*da lo del registro de la aplicación. Lo dicho en otro hilo... termino mis "deberes" y me estudio todo esto... que me está encantando.

;-)

Responder

Volver a “Otros lenguajes HDL”