antoniovillena escribió:[*]Reducir la máquina de estados para que en lugar de un 15%, el reproductor PZX tenga una ocupación en FPGA sensiblemente inferior.[/list]
Ahí está el problema: que la reducción no sea suficiente. Como esto pasará por una refactorización para extraer la ruta de datos y el controlador, veré cómo queda tras ello y cuántos recursos consume. De momento te puedo contar que de los tres tipos de bloques "mínimos" que se necesitan, uno de ellos, el de pausa, se puede implementar mediante un bloque de pulsos que contenga un solo pulso de la duración especificada en el parámetro de la pausa. Así, la implementación quedaría con dos bloques "complejos": PULS y DATA y dos triviales: STOP y FULLSTOP. De los 4, el de DATA es quizás el más complejo. Patrik me comentó que podía implementarse este bloque con un tren de bloques PULS, pero eso engordaría tremendamente el fichero PZX resultante: cada bit de datos necesitaría al menos 4 bytes para describir los dos pulsos de que consta, lo que significa un aumento de 32 veces el tamaño original de un bloque DATA, con lo que el buffer se vaciaría 32 veces más rápido y tendríamos microcortes mucho más frecuentemente.
-- Actualizado 21 Jun 2015, 17:57 --
Sigueindo con la descripción de este invento, aquí teneis la simulación del reproductor que hice en ISim, para probar que la descripción era correcta antes de pelearme con la síntesis propiamente dicha:
La forma de onda resaltada es la salida del reproductor, que sigue fielmente la descripción textual que hay en la parte de abajo. Patrik Rak, el creador del formato, ha desarrollado una serie de utilidades para ayudar a los escritores de emuladores a implementar este formato, y entre ellas, hay una que convierte una descripción textual de pulsos y datos a un fichero PZX listo para ser reproducido. El texto describe primero 23 pulsos de 2168T estados cada uno. El nivel (alto o bajo) cambia cada vez que se envía un pulso completo (los referidos 2168 estados). Podeis contar en la simulación que hay efectivamente 23 pulsos: un pulso bajo, uno alto, uno bajo, uno alto, etc, hasta el último que es bajo. Esto sería una especie de tono guía muy cortito.
A continuación viene un pulso (alto) de 667 estados, seguido de otro (bajo) de 735 estados. Esto sería un pulso de sincronismo.
A continuación, un bloque de datos, concretamente de 4 bytes. Después de este bloque hay un último pulso que dura 3000 estados (para poner una pequeña pausa entre el final de un bloque y el principio de otro). Este bloque de datos define cómo se han de interpretar los unos y los ceros: un cero es un pulso alto de 855 estados, seguido por otro pulso bajo también de 855 estados. Un bit uno es un pulso alto de 1710 estados seguido de otro pulso bajo de 1710 estados. Estos timings son los de la rutina de carga estándar de la ROM.
A continuación vienen los datos en sí: en binario estos datos son 11111111 00000000 10101010 01010101 . Creo que en el cronograma, muchos de vosotros podreis distinguir las formas de onda de estos cuatro bytes

He puesto los cursores de medida en uno de los pulsos que representa la mitad de un bit '1': lo que dura este pulso, medido en microsegundos es 488.638948 us (en la imagen está en milisegundos por el zoom que he hecho al cronograma). Para saber cuánto es este tiempo medido en ciclos de reloj del reloj de CPU del Spectrum, basta multiplicar por 3.5 dando el resultado que se refleja en la calculadora: 1710.236318 ciclos de reloj: una desviación de menos de 0.24 ciclos de reloj respecto de la duración ideal. ¿No está mal, no?

En el cronograma también se pueden ver otras señales interesantes, como los dos vectores (pequeñas memorias) que mantienen los valores de los pulsos para los bits 0 y 1, el contenido del bus de direcciones y de datos de la SRAM, con el próximo dato a leer listo, y varios contadores.
Fijaros también cómo al pasar a decodificar un bloque de datos, se producen un montón de accesos a memoria: esto ocurre cuando termina el pulso de sincronismo, y se puede ver una especie de emborronamiento en el bus de direcciones y de datos de la SRAM, debido a que sus contenidos están cambiando en esa porción de tiempo muy rapidamente. A partir de ahí también podeis ver cómo las dos pequeñas memorias que guardan los pulsos para el bit 0 y 1 ahora contienen datos válidos, y se comienza la lectura byte a byte de cada dato. Gracias a que el reloj de la máquina de estados es de 28MHz, el tiempo que se pierde en esta operación (unos 2-3 ciclos de reloj de CPU) es apenas apreciable comparado con los tiempos (cientos o miles de ciclos de reloj) que dura cada pulso.
Y así es como se depura un circuito electrónico descrito en Verilog
