VGA scandoubler portado con éxito al core del ZX Spectrum

Responder
Avatar de Usuario
mcleod_ideafix
Mensajes: 831
Registrado: 27 Sep 2015, 00:14
Ubicación: Jerez de la Frontera
Contactar:

VGA scandoubler portado con éxito al core del ZX Spectrum

Mensaje por mcleod_ideafix » 15 Nov 2015, 20:19

El test19_multi_vga trae algunas cosas nuevas, no sólamente el scandoubler. No son "features" que se puedan desactivar o activar, sino mejoras internas que espero que solucionen los problemas de síntesis que hemos tenido hasta ahora, y que nos habían obligado a volver a usar la versión 12.4 del ISE.

La clave del asunto está en algo que dijo Quest: "si desactivo la contención, funciona". Esto me ha llevado a encontrar una puñetera línea en la definición de la ULA "ula_radas.v" en la que en un sitio concreto, hago uso de una señal QUE NO ES UN RELOJ como si fuera un reloj. En concreto, la señal hc[0] que en el esquema original es el resultado de dividir la señal de reloj de video (clk7) entre 2, dando los famosos 3.5MHz

Pues bien: en la Spartan 3, esta línea daba warnings porque la Spartan 3 no permite (lo permite, pero degradando el sistema) que un reloj pueda formar parte de un circuito combinacional. En la Spartan 6 esto se permite, si tenemos cuidado de hacerlo bien. Hay otras cosas que también se permiten en la Spartan 6 y no en la 3, como por ejemplo los latches, pero eso lo dejo para otro momento.

En ula_radas.v se generaba el reloj de la CPU, con las "paradas" producidas por la contención, de esta forma:

Código: Seleccionar todo

assign cpuclk = (~(MayContend_n | CauseContention_n | CancelContention)) | hc[0];
Es decir, que si la expresión (~(MayContend_n | CauseContention_n | CancelContention)) valía 1, entonces el reloj se quedaba pillado con el valor 1, pero si la expresión valía 0, entonces el valor de hc[0] pasaba a la salida siendo el reloj de la CPU.

Esto no genera warnings en la Spartan 6 porque se puede sintetizar usando un recurso nuevo que hay en ésta: les presento al maravilloso MULTIPLEXOR DE SEÑALES DE RELOJ: la primitiva BUFGMUX. Esta primtiiva tiene 4 pines: I0, I1 son las entradas al multiplexor. S es la entrada de selección, y O es la salida. I0 e I1 pueden ser relojes, y O es una salida que también será un reloj. S es una entrada que viene de la lógica del diseño (no es un reloj).

Esta primitiva de la Spartan 6 es un multiplexor situado en las rutas globales de reloj, y permite que un diseño pueda conmutar entre un reloj u otro sin más que aplicar un 0 o un 1 en S, como haría cualquier otro multiplexor. Para nuestras intenciones, esto significa que puedo poner la expresión anterior como señal de selección S, poner en la entrada I0 un reloj de 3.5MHz, y en I1, poner sencillamente un 1 lógico.

La otra cosa que había que hacer aquí era librarse de hc[0] como señal de 3.5MHz . He podido ver con mis propios ojos como las señales de reloj generadas de esta forma son inestables y tienen mucho "jitter". En cambio, las generadas por el PLL van clavadas al picosegundo.

Así, la nueva ULA no genera la señal de reloj de la CPU, sino que genera una señal de contención llamada CPUContention. Esta señal se propaga hasta el TLD donde se envía al módulo de generación de relojes: ahí es donde tiene sentido generar la señal de reloj de la CPU, y se hace como podeis ver (cuatro_relojes.v) usando un BUFGMUX que usa como entrada la misma señal de reloj que se usa también para generar los 3.5MHz

Faltaba una cosita por solucionar: el tema de las block RAM de 9K que dan problemas en la Spartan 6. En la versión 14.7 hay una opción de síntesis que me permite decir si quiero que se infieran RAM's de 9K o no. Añadiendo esta opción de síntesis evito que se infieran (en su lugar se infieren RAM's de 18K o de 8K, así que no pasa nada en la práctica).

Con todo esto, el test19_multi_vga me sintetiza perfectamente en la 14.7, y el bitfile generado es estable, hasta donde he podido probarlo. El que teneis ahí está calibrado para un monitor que soporte 50Hz de refresco vertical.

Si no veis imagen y vuestro monitor os saca un cartelito de "entrada fuera de rango" o similar, id a "cuatro_relojes.v" y buscad estas líneas:

Código: Seleccionar todo

    .DIVCLK_DIVIDE          (1),
    .CLKFBOUT_MULT          (9),
    .CLKFBOUT_PHASE         (0.000),
    .CLKOUT0_DIVIDE         (16),
    .CLKOUT0_PHASE          (0.000),
    .CLKOUT0_DUTY_CYCLE     (0.500),
    .CLKOUT1_DIVIDE         (32),
    .CLKOUT1_PHASE          (0.000),
    .CLKOUT1_DUTY_CYCLE     (0.500),
    .CLKOUT2_DIVIDE         (64),
    .CLKOUT2_PHASE          (0.000),
    .CLKOUT2_DUTY_CYCLE     (0.500),
    .CLKOUT3_DIVIDE         (128),
    .CLKOUT3_PHASE          (0.000),
    .CLKOUT3_DUTY_CYCLE     (0.500),
    .CLKIN_PERIOD           (20.0),
    .REF_JITTER             (0.010))
Cada reloj se calcula como 50Mhz multiplicado por CLKFBOUT_MULT, y dividido entre CLKOUTx_DIVIDE, donde x es 0,1,2, o 3 (los 4 relojes).
Los valores actuales dan una frecuencia maestra Fm de 28.125MHz, lo que significa una frecuencia de refresco vertical de:

Código: Seleccionar todo

Fv = 28125000 / (4 * 448 * 312) = 50,303 Hz
Esto para el Spectrum 48K. Para el Spectrum 128K ( .zxunocfg -t128 ) los cálculos son:

Código: Seleccionar todo

Fv = 28125000 / (4 * 456 * 311) = 49,48 Hz
Veis que la frecuencia vertical con timings de 128K es un poco menor, lo que significa que un monitor VGA que acepte 50Hz por los pelos, igual no da señal cuando se conmute a 128K.

Si teneis un monitor rebelde, podeis probar otra frecuencia base más alta para así aumentar la Fv del modo 48K y 128K. Para ello hay que calcular nuevos valores para CLKFBOUT_MULT y CLKOUT0_DIVIDE, con las siguientes restricciones:
- CLKFBOUT_MULT debe valer como mínimo 8 ya que la frecuencia de trabajo mínima del PLL es de 400Mhz (50 MHz x 8). Tampoco podemos pasarnos con este valor, ya que la frecuencia máxima de trabajo del PLL es de 1080 MHz.
- CLKOUT0_DIVIDE debe valer como máximo 16, ya que los sucesivos CLKOUT1_DIVIDE, CLKOUT2_DIVIDE y CLKOUT3_DIVIDE, etc, son el valor de CLKOUT0_DIVIDE multiplicado por 2, 4, y 8. El máximo valor para CLKOUTx_DIVIDE es 128

EJEMPLO:
Pongamos que habeis averiguado que vuestro monitor necesita como mínimo, 56Hz de refresco vertical. Cogiendo la fórmula para el caso peor, que es el 128K, tenemos que la frecuencia maestra la calcularíamos así:

Código: Seleccionar todo

Fm = Fv * (4 * 456 * 311)
Sustituyendo valores, nos queda:

Código: Seleccionar todo

Fm = 56 * (4 * 456 * 311) = 31766784 Hz = 31.767 MHz
Así que hay que buscar un valor para CLKFBOUT_MULT y CLKOUT0_DIVIDE que cumplan con las restricciones anteriores, y que den una Fm lo más cercano posible a 31.767 Mhz, acercándose por arriba (por exceso). Para ello, usad este programa en C cambiando la frecuencia deseada por la que querais usar (el enlace abre un editor/compilador de C online):
http://goo.gl/zGyVbv

Aplicándolo a nuestro ejemplo, la salida del programa es:

Código: Seleccionar todo

CLOCK =  57.1429  M= 8  D= 7
CLOCK =  50.0000  M= 8  D= 8
CLOCK =  44.4444  M= 8  D= 9
CLOCK =  40.0000  M= 8  D=10
CLOCK =  36.3636  M= 8  D=11
CLOCK =  33.3333  M= 8  D=12
CLOCK =  30.7692  M= 8  D=13
CLOCK =  32.1429  M= 9  D=14 
M es el valor de CLKFBOUT_MULT y D el de CLKOUT0_DIVIDE.

Así que nos quedaríamos con la última línea, que es el valor más cercano al pedido, y además está por encima de él. Tenemos por tanto un valor de 9 para CLKFBOUT_MULT y 14 para CLKOUT0_DIVIDE. Los valores de CLKOUT1_DIVIDE, CLKOUT2_DIVIDE y CLKOUT3_DIVIDE serían respectivamente: 28, 56 y 112 (cada una de ellas el doble que la anterior).

Editamos los nuevos valores en el fichero "cuatro_relojes.v", guardamos, y sintetizamos el proyecto completo.

Las nuevas frecuencias de refresco vertical para los modos de 48K y 128K serían:

Código: Seleccionar todo

Fv48 = 32142900 / (4 * 448 * 312) = 57,49 Hz
Fv128 = 32142900 / (4 * 456 * 311) = 56,66 Hz
El sistema en este caso será un 32142900 / 28125000 = 14,28% más rápido.

El monitor VGA ideal para este proeycto es aquel que sea capaz de mostrar la señal de video correctamente tanto en 48K como en 128K con los settings por defecto para la generación de relojes (9 y 16). Todos estos cálculos no serán necesarios en el TEST 20 (coming soon), ya que se podrá elegir entre unas cuantas frecuencias de refresco cuando se active el modo VGA, pero si quereis probar desde YA con vuestros monitores, hay que hacerlo de momento como se ha explicado.
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA

Avatar de Usuario
Quest
Mensajes: 900
Registrado: 27 Sep 2015, 00:20

Re: VGA scandoubler portado con éxito al core del ZX Spectrum

Mensaje por Quest » 15 Nov 2015, 20:46

EXCELENTES noticias. :okidoki;

Era un tema que me preocupaba, y no veas lo aliviado que respiro ahora. La estabilidad en este core lo está haciendo ya insuperable.

Además me viene de perlas esta info para el tema de conmutar relojes que andaba buscando para inplementarlo en un par de cores que me daban guerra con los glitches si lo hacía a través de una señal externa a los relojes y un flag.

Ahora sólo falta apañar el tema de la repetición del teclado (que me trae de cabeza cuando intento teclear cualquier programa BASIC) y esto está "niquelao" :D

Voy a bajarme ahora mismo el core para sintetizarlo con 14.7 y probar. Ya tengo ganas :D
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA

Avatar de Usuario
mcleod_ideafix
Mensajes: 831
Registrado: 27 Sep 2015, 00:14
Ubicación: Jerez de la Frontera
Contactar:

Re: VGA scandoubler portado con éxito al core del ZX Spectrum

Mensaje por mcleod_ideafix » 15 Nov 2015, 21:06

Quest escribió:Ahora sólo falta apañar el tema de la repetición del teclado (que me trae de cabeza cuando intento teclear cualquier programa BASIC) y esto está "niquelao" :D
Debería también funcionar ahora. Mira a ver...
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA

Avatar de Usuario
Quest
Mensajes: 900
Registrado: 27 Sep 2015, 00:20

Re: VGA scandoubler portado con éxito al core del ZX Spectrum

Mensaje por Quest » 15 Nov 2015, 21:39

Probado.

Solo puedo decir una cosa: :maestro: :plasplas: :plasplas: :plasplas: :okidoki; :okidoki; :chocala!: :chocala!:

Es PERFECTO. Resintetizado en 14.7. Ni un solo glitch. Probadas todas las demos y juegos clasifcados "prueba de fuego", probadas todas las combinaciones de teclado que producían repetición (incluida por supuesto la infame "SHIFT + ."), y no me ha fallado ni una sola vez.

Probadas todas las combinaciones de timings 48/128, contención / no contención... perfecto.

Ahora mismo creo que podemos decir que tenemos la reimplementación hardware de un spectrum más precisa que se ha hecho. Otras implementaciones no son capaces siquiera de tener unos timings donde las demos más conocidas de la scene se vean bien o no se queden colgadas.

Cuando se termine con lo de los modos turbo y el switch en tiempo real de RGB/VGA/50/60Hz, por mi quedaría ya como core muy apto para salir "a producción".

Sin perjuicio de futuros añadidos para el soporte para expansión, de ESP8826, spectranet, EDGE, HDMI, etc, etc.

Lo dicho. Grande. :boingg:
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA

Avatar de Usuario
Haplo
Mensajes: 368
Registrado: 05 Oct 2015, 13:51
Ubicación: Ciudad Real

Re: VGA scandoubler portado con éxito al core del ZX Spectrum

Mensaje por Haplo » 15 Nov 2015, 22:31

ole, oleee, gran trabajo McLeod! Resolver un bug como éste entiendo que es crucial para todo el sistema tal y como ha comprobado Quest. No sabéis la alegría que me dan estas cosas chavales. Sois unos cracks. :okidoki;

Avatar de Usuario
Hark0
Mensajes: 683
Registrado: 27 Sep 2015, 00:31
Ubicación: Cornellà de Llobregat - BCN
Contactar:

Re: VGA scandoubler portado con éxito al core del ZX Spectrum

Mensaje por Hark0 » 16 Nov 2015, 07:06

Recogiendo la baba que se me cae... ;)

Enhorabuena por ese pedazo de avance. :plasplas:
http://www.zxuno.com
ZX-Uno · Clon de ordenador ZX Spectrum basado en FPGA.

Avatar de Usuario
yombo
Mensajes: 487
Registrado: 05 Oct 2015, 14:10

Re: VGA scandoubler portado con éxito al core del ZX Spectrum

Mensaje por yombo » 17 Nov 2015, 01:21

Felicidades, seguid así.

enkonsierto
Mensajes: 80
Registrado: 25 Oct 2015, 07:49

Re: VGA scandoubler portado con éxito al core del ZX Spectrum

Mensaje por enkonsierto » 17 Nov 2015, 10:16

Felicidades por acercaros cada vez más al core perfecto.

Responder