yombo escribió: ↑07 Dic 2021, 12:30
Sé lo que está ocurriendo. Probablemente la utilización de la fpga ya es muy alta. El compilador de Xilinx usa los nombres de variables como hash para tomar decisiones durante el sintetizado. Si la utilización es muy alta, estas decisiones pueden implicar que ya no se cumplan los tiempos de propagación de las señales, por el simple hecho de refactorizar un poco el código para hacerlo más legible.
Tras las últimas optimizaciones que llevé a cabo a partir de los fuentes originales de @distwave, tampoco me parece a mí que ahora mismo se encuentre muy al límite de recursos:
Sin embargo, sí que se puede apreciar lo que comentas acerca del uso de los nombres de variables como
hash. Y a partir de ello, se puede entender lo que sucede, aunque no el por qué... que posiblemente sea debido a un
bug del sintetizador
ISE de
Xilinx:
Esto es parte del reporte de síntesis, que tal como me ha sugerido @mcleod_ideafix, es un buen recurso para entender cómo se ha llevado a cabo la sintetización. Aquí podemos observar que la memoria generada es del tamaño que se le ha indicado durante su declaración:
Código: Seleccionar todo
// Character ROM
reg[7:0] char_rom[0:4095];
initial $readmemh("cga.hex", char_rom, 0, 4095);
Y también podemos ver cómo
addrA está correctamente direccionada a partir del código original:
Código: Seleccionar todo
always @ (posedge clk)
begin
// Only load character bits at this point
if (...) begin
charbits <= char_rom[{~thin_font,rom_addr}]; // El bit alto (thin_font invertido) se aplica o no dependiendo del resto de código. ¿problema del sintetizador de Xilinx?
end
end
donde se encuentra la etiqueta
thin_font que menciona @yombo. Pero una vez que se ha llevado a cabo la limpieza de código innecesario, con el mismo código nos encontramos con la siguiente síntesis de
char_rom:
Es decir, se ha creado una memoria de la
2KB en lugar de
4KB, y la referencia a
thin_font simplemente ha desaparecido del direccionamiento como
bit alto. A partir de aquí, de nada sirve fijar este bit con
1'b1 por ejemplo, o reestructurar el código de múltiples maneras para hacérselo más sencillo al sintetizador, tal como me ha sugerido @mcleod_ideafix vía Telegram en el grupo de
ZXUno. Hasta el momento, las únicas soluciones que me han funcionado son las comentadas inicialmente:
Código: Seleccionar todo
// 1. Declarando char_rom como un solo byte más de tamaño
reg[7:0] char_rom[0:4096];
o:
Código: Seleccionar todo
// 2. Accediendo a la memoria de esta otra forma:
charbits <= char_rom[{~thin_font, 11'd0} | rom_addr];
En ambos casos, obtenemos la generación de una memoria de
4KB correctamente, y con
addrA direccionado de la misma forma adecuada, ya que
thin_font en este caso está fijo a 0, y tras la negación es 1... esta vez sin el uso de etiquetas, pero con un mismo resultado satisfactorio:
Todo esto me lleva a la conclusión de que es de vital importancia revisar los mensajes generados y ver si son coherentes con el resultado que se espera, no deberíamos tener que preocuparnos por estas cosas, pero los
bugs que por lo visto hay en el sintetizador
ISE de
Xilinx nos obligan a ello.