FPGA VGA Buffer. ¿Cómo leer y escribir?

8

Tengo una placa Altera DE2 e intento dibujar sprites. Tengo problemas para implementar un búfer de pantalla.

Tengo una entidad de visualización que a una velocidad de 25 MHZ genera píxeles para la visualización vga.

Esperaba implementar un búfer en SDRAM. La idea original era cargar píxeles el siguiente píxel a una velocidad de 25 MHZ desde la SDRAM. Esto funciona, pero no puedo escribir píxeles en la SDRAM a este ritmo ni puedo borrar la pantalla lo suficientemente rápido para cada nuevo fotograma. Me toma 2 relojes escribir datos y mi placa funciona a 50 MHZ, así que tengo el tiempo suficiente para hacer una lectura completa.

Asumiría que estoy haciendo algo terriblemente mal. ¿Cómo se implementa normalmente un lienzo de dibujo en VHDL?

Lo más cercano que pude encontrar es usar un esquema de color 2-3-3 (RGB) para recuperar cada píxel y escribir en el lienzo durante el tiempo VGA "porche" (supresión). Esto significa que en cada uno de los relojes de 25 mhz solo puedo actualizar el 15% de la pantalla y de alguna manera necesito que mi circuito sepa cuál es el 15% que se está actualizando.

No puedo entender cómo usar el doble buffer porque no puedo entender cómo escribir datos en la memoria mientras leo. ¿Hay alguna manera de evitar golpes de bits en el protocolo? ¿Cómo lo hace este chico?

ingrese la descripción de la imagen aquí

Mikhail
fuente
doble amortiguación ?
davidcary
@davidcary, con algunos detalles sobre cómo abordar el doble almacenamiento en búfer, ha respondido la pregunta. Me doy cuenta de que lleva tiempo y no puedo arrojar piedras, ya que a menudo da un comentario rápido como un comentario para ayudar al usuario con su problema hasta que alguien pueda escribir una respuesta de alta calidad.
Kortuk
3
Cuando dices "¿Hay alguna manera de evitar golpes de bits en el protocolo?", Supongo que eso significa que no has escrito el controlador SDRAM tú mismo. Recomiendo hacerlo, es un buen ejercicio, y comprenderá más sobre cómo funciona SDRAM y cómo explotar sus tiempos.
mng

Respuestas:

3

Un par de enfoques que pueden ser útiles para algunos estilos de visualización es dividir el panel de visualización en mosaicos, y

  1. restringir cada mosaico para usar un pequeño conjunto de colores, lo que permite el uso de menos de 8 bits por píxel, o
  2. use un byte o dos de cada mosaico para seleccionar una ubicación desde la cual leer los datos de mapa de bits.
El primer enfoque podría reducir la velocidad a la que los datos tenían que leerse desde la memoria de visualización. Por ejemplo, si uno usa mosaicos que eran 16x16 y cada uno podría tener cuatro colores elegidos de un conjunto de 256, entonces, sin usar RAM adicional en el FPGA, uno podría reducir el número de lecturas de memoria por 16 píxeles a ocho (cuatro valores de color, más cuatro bytes para el mapa de bits). Si se agregan 160 bytes de memoria intermedia / RAM (*) al FPGA, se podría reducir el número de lecturas de memoria por 16 píxeles a cuatro, utilizando 160 lecturas adicionales cada 16 líneas de escaneo para leer el siguiente conjunto de colores de mosaico. Si uno quisiera 16 colores por mosaico, el segundo enfoque requeriría 640 bytes adicionales de RAM a menos que se impongan algunas restricciones en el número de paletas diferentes que podrían existir en una línea.

El segundo enfoque probablemente aumentaría en lugar de reducir el ancho de banda de memoria total requerido para producir una pantalla, pero reduciría la cantidad de memoria que tendría que actualizarse para cambiar la pantalla: uno podría cambiar un byte o dos para actualizar un 8x8 o Área de 16x16 de la pantalla. Dependiendo de lo que intente mostrar, puede ser útil usar este estilo de enfoque para usar un dispositivo de memoria para sostener las formas de mosaico y otro para mantener la selección de mosaico. Uno podría, por ejemplo, usar una RAM rápida de 32Kx8 para contener un par de mapas de mosaico de 80x60 con dos bytes por mosaico. Si el FPGA no tuviera almacenamiento en búfer, tendría que leer un byte cada cuatro píxeles; incluso con una RAM estática de 40 ns, eso dejaría mucho tiempo para que la CPU actualice la pantalla (una pantalla completa solo tendría 9600 bytes).

Por cierto, si uno no quisiera agregar una RAM de 32Kx8 pero pudiera agregar 320 bytes de almacenamiento en búfer / RAM (**) al FPGA, uno podría usar un enfoque de mapa de mosaico pero hacer que la CPU o DMA alimente 160 bytes al mostrar cada 8 líneas de escaneo. Eso cargaría un poco al controlador incluso cuando nada en la pantalla cambiara, pero podría simplificar los circuitos.

(*) El búfer podría implementarse como RAM o como una secuencia de 32 registros de desplazamiento de 40 bits de longitud más una pequeña lógica de control.

(**) El búfer podría implementarse como dos RAM de 160 bytes, o como dos grupos de dieciséis registros de desplazamiento de 80 bits.

Super gato
fuente
5

Los sprites no se hacen normalmente con un frame buffer (como entiendo la palabra). En su lugar, compara las coordenadas x e y con los valores xmin, ymin y xmax, ymax del sprite. Si la posición de escaneo actual cae dentro del sprite, envíe el color relevante desde la memoria del sprite.

Si está intentando mostrar un búfer de cuadros, anímese. Este fue mi primer gran proyecto FPGA. SDRAM no debería ser un problema a 100MHz (lo hice por primera vez hace una década, y el silicio es mucho más rápido ahora), así que multiplique su reloj de 50MHz. Escribir su propio controlador será educativo :)

Eso le da mucho ancho de banda para jugar, luego puede duplicar el búfer, no hay problema. VGA de 60Hz necesita un promedio de 18Mpixels / sec. Si tiene un dispositivo de 16 bits de ancho, tiene 200 MBytes / s de ancho de banda máximo. Incluso si solo logra ser 50% eficiente (lo que debería ser factible), eso es 100Mpixels / sec @ 16 bits por pixel o 50Mpixels / sec @ 32bits por pixel.

Por ejemplo, puede ser que su RAM necesite 60ns para configurar una lectura, pero puede reventar 8 palabras en 80 ns después de eso, eso es 8 bytes en ~ 140ns. SI puede hacer que su RAM realice ráfagas más largas, eso ayudaría a amortizar el costo de configurar la lectura.

Según su comentario de que se trata de una RAM de byte, eso es un poco más de 50 MB / s, solo 16 megapíxeles / seg @ 24 bits por píxel :( Simplemente no tiene suficiente ancho de banda para hacer una visualización de color verdadero, incluso en VGA. podría hacer 8 bits por píxel con bastante facilidad, pero eso es solo 2 o 3 bits por color, lo que puede estar bien para su aplicación, no lo sé, o podría hacer una tabla de búsqueda de 256 colores como en los viejos tiempos, después leyendo desde el búfer de trama, luego usa el valor para buscar en un reloj RAM interno para obtener los 24 bits (o 18 bits, que encajarían bien en una BRAM) de color para emitir al monitor.

El doble buffer todavía funciona:

Muestre un cuadro de la dirección 0 (solo lea todos los píxeles, pausando las lecturas durante los intervalos de supresión).

Escribe tu próximo cuadro en otra ubicación. Para este doble almacenamiento en búfer, su controlador DRAM tendrá que priorizar entre las demandas competitivas de los canales de lectura y escritura. Sugerencia, priorice las lecturas ya que son críticas de tiempo :)

Martin Thompson
fuente
¿Es generalmente mejor priorizar las lecturas, o es mejor leer los datos en un FIFO, dar prioridad a las escrituras cuando hay una cierta cantidad de datos en el FIFO y dar prioridad a las lecturas cuando el nivel de FIFO es demasiado bajo? Descubrí que al menos cuando se manejan pantallas LCD que tienen una señal de reloj, es útil permitir que el tiempo de lectura sea bastante 'suelto' siempre que todos los datos se transfieran a tiempo.
supercat
Gracias por tu publicación, podría echar un vistazo al almacenamiento en búfer. Pero creo que me toma 2 relojes (1/50 MHZ) para leer datos y también tengo un dispositivo de 8 bits de ancho.
Mikhail
@supercat: sí, esa es una solución más avanzada que podría ser necesaria si se presiona el ancho de banda.
Martin Thompson
1
@Misha: Se tarda un tiempo en configurar una lectura de datos, pero puede hacer estallar grandes cantidades a la vez.
Martin Thompson