Actualmente estoy tratando de implementar un IP-Core en un sistema FPGA-HPS Cyclone V 5CSEBA6U23I7 usando Altera Quartus II y TimeQuest Analyzer.
El código Verilog pegado a continuación produce un problema de temporización, a saber, la asignación fifo_wdata_289[255:0] <= {fifo_out,fifo_wdata_289[255:16]};
, que escribe la salida de un FIFO en otra matriz de registros FIFO.
Los FIFO en uso son asíncronos, pero las señales utilizadas están en el mismo dominio de reloj.
Esto se coloca en el chip con un sesgo de reloj de -2.255 ns , que es un poco menos que un período completo ( reloj de 288 MHz => 3.47 ns ), y hace que TimeQuest se queje de que se están violando las restricciones.
La recomendación de TimeQuest es Reducir los niveles de lógica combinacional para el camino(Emitir ruta combinada larga ) con niveles adicionales de lógica combinacional = 1.
El reloj de 288 MHz se genera a través de PLL y estoy usando archivos de restricción de tiempo (sdc) con los comandos derivar_pll_relojes y derivar_reloj_incertidumbre.
Mi pregunta ahora es cómo resolver este problema, ya que solo tengo una capa de lógica combinacional (Demuxer y enrutamiento, como lo sugiere la asignación) y, por lo tanto, no tengo idea de cómo reducir eso. ¿Hay alguna otra manera de asegurarme de que se cumpla el requisito de tiempo, o hay una mejor manera de programar esta máquina de estado?
Gracias por tu ayuda.
case(stateProc)
2'b00:
begin
if(~fifo_empty&~fifo_full_289)
begin
fifo_wdata_289[255:0] <= {fifo_out,fifo_wdata_289[255:16]};
fifo_wdata_289[287:256] <= {2'b11,fifo_wdata_289[287:258]};
if(imgSize >= maxImgSize - 32'd2)//image done, transmit data and fire irq
begin
fifo_wdata_289[288] <= 1;
stateProc <= 2'b01;
imgSize <= 32'd0;
end
else if(fifo_wdata_289[258])//process transfer without irq //258 high means that 256 has been written in this cycle and 258 in the previous cycle
begin
fifo_wdata_289[288] <= 0;
stateProc <= 2'b01;
imgSize <= imgSize + 32'd2;
end
else//accumulate more data
begin
fifo_wdata_289[288] <= 0;
stateProc <= 2'b00;
imgSize <= imgSize + 32'd2;
end
end
else
begin
fifo_wdata_289 <= fifo_wdata_289;
imgSize <= imgSize;
stateProc <= 2'b00;
end
end
2'b01:
begin
fifo_wdata_289 <= fifo_wdata_289;
imgSize <= imgSize;
stateProc <= 2'b11;
end
2'b11:
begin
fifo_wdata_289 <= 0;
imgSize <= imgSize;
stateProc <= 2'b00;
end
endcase
EDITAR:
Las rutas fallidas de TimeQuest se ven principalmente así:
Slack:
-3.178
Desde el nodo:
soc_system:u0|CamConnector:camconnector_0|FIFO_289:FIFO_inst_289|dcfifo:dcfifo_component|dcfifo_6up1:auto_generated|wrptr_g[0]
Hasta el nodo:
soc_system:u0|CamConnector:camconnector_0 |fifo_wdata_289[267]
EDIT2:
actualmente estoy usando celdas MLAB como almacenamiento FIFO, que están clasificados para 290 MHz.
Ambos FIFO son asincrónicos y tienen una configuración de sincronización de 3.
Las recomendaciones de cierre de tiempo de TimeQuest informan los dos problemas siguientes:
ya que solo tengo una capa de lógica combinacional (Demuxer y enrutamiento, como lo sugiere la asignación)
No, no tienes eso. También está la compensación en stateProc==2'b11. Pero supongo que las LUT de Cyclone son lo suficientemente grandes como para abarcar una puerta AND adicional al mismo tiempo.
Pero le sugiero que también publique la ruta fallida según lo informado por la herramienta. Porque algo no cuadra aquí. La ruta para fifo_wdata_289[288] es más compleja y usted dice que pasa el tiempo. No me sorprendería si las señales de control mux: fifo_empty, fifo_full_289, stateProc, etc. también están en la ruta de temporización fallida junto con el árbol de transmisión, ya que controla muchos FF desde una señal.
Si no, solo puedes correr a una velocidad más baja. No sirve de nada jugar con el reloj ya que el circuito usa sus propias señales ( fifo_wdata_289 [255:0] <= {fifo_out, fifo_wdata_289[255:16] };) Por lo tanto, si sesga o invierte el reloj, fifo_wdata_289[255: 16] saldrá más tarde y, por lo tanto, volverá a fallar en el tiempo. Puede tener suerte y el fifo_out llega tarde y provoca el error de tiempo, pero vuelva a mirar el informe de tiempo de la ruta fallida.
De todos modos, sesgar un reloj es algo que se puede hacer en un ASIC, pero no lo intentaría en un FPGA. No creo que tenga el control fino para sesgar un reloj ~ 300ps contra otro. Pero no tengo ciclones, así que tal vez....
Actualización:
justo lo que esperaba: la ruta comienza en wrptr_g ... Supongo que es el puntero de escritura que probablemente se compara con el puntero de lectura que hace que las banderas fifo_full/empty controlen el mux.
La mejor manera de deshacerse del problema de tiempo es hacer una versión registrada de las banderas de lleno/vacío. Eso puede significar que tiene que rediseñar parte del resto del circuito.
Si el FIFO es síncrono, hay un truco para generar banderas síncronas de lleno/vacío. Verifica si el nivel es UNO y en una lectura pero no en una escritura síncrona establece el indicador 'vacío'. Vea aquí un código de ejemplo gratuito de FIFO que tiene esa característica. Desafortunadamente, eso no funciona con FIFO asíncronos.
Si ambos FIFO están siendo alimentados con la misma fase de reloj, entonces se están violando los tiempos de configuración y espera para el segundo FIFO, como si llegara demasiado pronto. Su programa está insinuando que necesita ralentizar algo, a saber, su reloj.
Puede agregar un inversor para bloquear el segundo FIFO en el flanco descendente mucho después de que los datos se hayan asentado. Una mejor opción si su software puede hacer esto es mover la línea del reloj antes de que llegue al segundo FIFO. Software como Specctra puede hacer los cálculos para esto.
A falta de algo mejor, una resistencia de bajo valor en serie con el reloj hasta el segundo FIFO creará un retraso natural. Averigüe la capacitancia del pin del reloj y calcule lo que se necesita para un retraso de algunos nS. Creo que 100 ohmios como máximo, pero más de 10 ohmios.
Krustenkaese
Krustenkaese
Krustenkaese