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];
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))
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
Código: Seleccionar todo
Fv = 28125000 / (4 * 456 * 311) = 49,48 Hz
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)
Código: Seleccionar todo
Fm = 56 * (4 * 456 * 311) = 31766784 Hz = 31.767 MHz
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
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 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.