¿Por qué la memoria RAM del bloque Xilinx en un Spartan-3E no siempre retorna datos en un solo ciclo de reloj?

2

Estoy creando un diseño usando Verilog en un Xilinx Spartan-3E (XC3S500E) que usa múltiples RAM de bloque de doble puerto, todas creadas a través de primitivos Verilog como RAMB16_S18_S18 . Estoy usando un puerto para leer y escribir (usando habilitación de escritura) y el segundo para solo lectura (estableciendo WEB en 0). Ambos puertos comparten el mismo reloj. El bloque de memoria RAM se establece en ancho de 18 bits, pero ignoro los datos de paridad (es decir, no uso su valor de salida y siempre escribo ceros en bits de paridad)

Estoy usando Xilinx ISE 13.4 y sintetizando / implementando usando el flujo de trabajo de la GUI con la configuración predeterminada. (las configuraciones no predeterminadas, como la optimización de temporización agresiva y / o la síntesis física no tuvieron una diferencia con respecto a este problema)

Tengo restricciones de tiempo para mi único reloj de la red, y es consistente con la señal de reloj real que se está introduciendo (la restricción es para 50MHz, hay un reloj de 50MHz en la placa de desarrollo que estoy usando y el el informe de temporización indica que la frecuencia máxima para mi diseño es de 64,7 MHz. El reloj funciona a través de un mutliplexor de reloj que se utiliza como reloj habilitado, antes de pasar a la totalidad de mi lógica.

En mi código, tengo una máquina de estados que tiene tres estados (transición en el flanco ascendente del mismo reloj de 50MHz que usa el bloque de memoria RAM):

  1. Escriba la dirección en un registro conectado a las entradas de dirección de los puertos A y B.
  2. Lea los datos, realice algunas operaciones lógicas en él y escríbalos en un reg[15:0] que esté conectado a DIA (datos en A) en la RAM del bloque (sin cambiar la dirección). Active el permiso de escritura para el puerto A.
  3. Lea algunos pines IO en registros no relacionados. Desactivar la habilitación de escritura del bloque RAM.

Esto siempre es exitoso en una simulación de comportamiento en ISim, y (aunque tuvo menos pruebas que el simulador) tiene un éxito constante en el puerto A. El puerto B tiene una lógica idéntica (simplemente corte de bits para la dirección, y la misma configuración para SSR, SRVAL, INIT) pero no logra leer durante este ciclo de un reloj. Simplemente agregando un estado adicional entre 1 y 2 (lo que da un tiempo de configuración de más de un ciclo de reloj completo para la dirección) el diseño funciona, aunque como aprendiz de desarrollo de FPGA me gustaría saber por qué y cómo evitarlo.

De acuerdo con hoja de datos de Xilinx DS312 y los diagramas de tiempo, esta debería ser una forma aceptable de utilizando el bloque de memoria RAM. En la misma hoja de datos se dan los tiempos de configuración y de espera, pero las herramientas ISE ya deberían conocerlas y aplicarlas durante el análisis de tiempo, si no me equivoco. Además, he vuelto a leer la sección RAM del bloque de UG331 (Spartan-3 Generation User Guide) varias veces y no he podido encontrar ninguna incoherencia entre las instrucciones y mi uso de la RAM del bloque.

La lista de informes de tiempo de las rutas más lentas misteriosamente no enumera ninguna ruta que vaya al puerto RAM ofensivo.

Si alguien pudiera hacer una recomendación, se agradecería, ya que he pasado bastante tiempo en la depuración de este problema y temo que pueda estar cometiendo el error de algunos principiantes. Si necesita información adicional, avíseme para poder proporcionarla.

    
pregunta Andrey Akhmetov

1 respuesta

1

Los datos recién escritos en el flanco ascendente están disponibles directamente después de este borde solo en el mismo puerto. En realidad, la entrada de datos se reenvía internamente a la salida de datos del mismo puerto RAM. También se llama modo WRITE_FIRST .

Pero, nunca se reenvía a la salida del otro puerto RAM, independientemente del WRITE_MODE especificado. Estará disponible para lectura (por supuesto, en otro flanco ascendente) después de que se haya completado la escritura interna en la memoria. En su ejemplo, es solo el siguiente flanco ascendente del reloj, porque el tiempo de escritura interno siempre es menor (más rápido) que el período de reloj mínimo permitido.

Este comportamiento se describe en XAPP 463 usando el bloque RAM en Spartan-3 Generation FPGAs en la sección Conflictos y resolución de RAM de doble puerto. El ejemplo dado allí utiliza diferentes relojes, pero también se aplica cuando se utiliza el mismo reloj para ambos puertos.

Este comportamiento sigue siendo el mismo en los FPGA actuales de Xilinx y Altera.

El reenvío al otro puerto RAM debe ser realizado por el suyo con la lógica circundante.

    
respondido por el Martin Zabel

Lea otras preguntas en las etiquetas