Entonces, después de recibir algunos consejos de algunas buenas personas aquí, logré armar mi primer (muy modesto) diseño de FPGA. Básicamente son solo unos pocos registros y contadores, y solo se ejecuta a unos pocos MHz, pero pude sintetizarlo e implementarlo sin advertencias, y las señales reales que salen parecen hacer lo que la simulación me hizo pensar que harían. Aprendí algunas cosas en el camino.
Ahora quiero aprender a establecer restricciones de tiempo y ejecutar análisis de tiempo. Así que estoy leyendo el documento de Xilinx UG612 y veo en la parte superior de la página 205:
"Usar solo un borde del reloj"
Mmm. Parece que infringí la ley. Parte de mi diseño es un registro de cambio de carga en paralelo: utilicé el margen del último ciclo del reloj para cargarlo (desde un contador que se marcó en el margen anterior). Un boceto rápido:
Por supuesto, no estoy usando directamente el negedge aquí, pero la señal de carga se deriva de él. Pensé que esto era bueno, pero Xilinx me dice: no hagas eso.
¿Me equivoco? Si es así, ¿por qué? ¿Qué debo hacer en su lugar?
"Usar solo un borde del reloj"
No sé por qué dirían eso. Puede usar flancos de reloj ascendentes y descendentes en el diseño y el analizador de tiempo lo tendrá en cuenta.
Por lo tanto, un reloj de 200MHz le dará 5 ns desde el flanco ascendente hasta el flanco ascendente, pero solo 2,5 ns desde el flanco ascendente hasta el flanco descendente. Hice un pequeño ejemplo usando valores de 16 bits:
always @(posedge clk)
result1 <= counter + hold;
always @(negedge clk)
result2 <= counter + hold;
A continuación se muestra una captura de pantalla del análisis de tiempo de ISE. Es para un reloj de ciclo de trabajo del 50% de 5ns.
El texto trata sobre una ruta fallida desde el bit 3 counter
hasta el bit 15 de result2
. Como puede ver, utiliza el flanco ascendente como fuente y el flanco descendente como destino.
Los elementos lógicos en la FPGA generalmente se diseñan con tiempo de espera cero , específicamente para permitirle diseñar con solo un borde de reloj.
En su ejemplo, esto significa que tanto la señal CTR INC como la señal SR LOAD se ven como afirmadas en el borde 0, y ninguna se ve como afirmada en el borde 15. El valor que se carga en el registro de desplazamiento será el que está en el contador antes del borde 0. El efecto de incrementar el contador no se verá en el registro de desplazamiento hasta la próxima vez que se afirme SR LOAD.
Si hizo que la señal SR siguiera la misma forma de onda que CTR INC, esto seguiría siendo cierto y el comportamiento del circuito sería el mismo.
No está equivocado, solo está haciendo su vida más difícil de lo que debe ser... especialmente en lo que respecta al cierre de tiempo (desarrollar restricciones precisas es más difícil). Puede hacer que este diseño funcione fácilmente solo en el borde ascendente.
Me parece que si desea cargar cuando contador = 0, podría tener alguna lógica combinatoria que: assign load = (counter==15)
(o similar). Esto cambiará su señal de carga hacia atrás 1/2 ciclo de reloj, y se verá en el borde ascendente de edge0 como se afirma. Sin embargo, hay muchas maneras de hacer esto (utilizando todos los FF con reloj de flanco ascendente), y probablemente un poco de google será de gran ayuda.
SRR
danmcb
tom carpintero
danmcb
Paebbels
Tony Estuardo EE75
Paebbels
danmcb
oscuro
Paebbels
BUFG
,BUFH
,BUFR
, ... No puede usar un reloj combinatorio de este tipo para ningún bloque modificador de reloj (CMB) como entrada. A continuación, debe especificar nuevas restricciones en el sistema para notificar al análisis de tiempo estático que esta señal tiene una frecuencia, un ciclo de trabajo y quizás una relación de fase. Normalmente, tales restricciones se infieren automáticamente.Paebbels
Paebbels
danmcb
danmcb