Mira este fragmento de código (voltear la imagen en X)
PROCESS(iCLK)
BEGIN
IF (rising_edge(iCLK)) THEN
-- Mise en mémoire du pixel
ram(640*IdxC + PixX) <= PIXIN;
-- Choix traitement
IF (SWITCH='1') THEN
PIXOUT <= ram(640*((IdxC + 1) mod 2) + PixX);
ELSE
PIXOUT <= ram(640*(2-IdxC) - PixX + 1);
END IF;
END IF;
END PROCESS;
Cuando lo compilo, el proyecto general ocupa alrededor del 15 % de los elementos lógicos y el 13 % del total de bits de memoria (QuartusII en el ciclón III). Si cambio el código a
PROCESS (iCLK)
BEGIN
IF(rising_edge(iCLK)) THEN
-- Mise en mémoire du pixel
ram(640*IdxC + PixX) <= PIXIN;
-- Choix traitement
IF (SWITCH='1') THEN
PIXOUT <= ram(640*((IdxC + 1) mod 2) + PixX);
ELSE
IF (PixX > 1 AND PixX < 640) THEN
PIXOUT <= ram(640*(2-IdxC) - PixX + 1);
ELSE
PIXOUT <= x"111";
END IF;
END IF;
END IF;
END PROCESS;
yo obtengo
Error (276003): Cannot convert all sets of registers into RAM megafunctions when creating nodes. The resulting number of registers remaining in design exceeds the number of registers in the device or the number specified by the assignment max_number_of_registers_from_uninferred_rams. This can cause longer compilation time or result in insufficient memory to complete Analysis and Synthesis
Eso parece que no puedo encajar más el diseño. No creo esto. ¿Hay un error en el compilador o estoy haciendo algo mal?
Tengo la edición web Quartus II
Simplemente poniendo algunos --
comentarios en las líneas como esta y compila de nuevo:
PROCESS (iCLK)
BEGIN
IF (rising_edge(iCLK)) THEN
-- Mise en mémoire du pixel
ram(640*IdxC + PixX) <= PIXIN;
-- Choix traitement
IF (SWITCH='1') THEN
PIXOUT <= ram(640*((IdxC + 1) mod 2) + PixX);
ELSE
-- IF (PixX > 1 AND PixX < 640) THEN
PIXOUT <= ram(640*(2-IdxC) - PixX + 1);
-- ELSE
-- PIXOUT <= x"111";
-- END IF;
END IF;
END IF;
END PROCESS;
Este código funciona con el puerto megafunción RAM 2:
PROCESS (iCLK)
BEGIN
IF rising_edge(iCLK) THEN
-- Ecrire linéairement dans la RAM le pixel de la cam
RAMWRITE <= TO_UNSIGNED(640*IdxC + PixX - 1, 11);
-- Choix traitement
IF (SWITCH='1') THEN
RAMREAD <= TO_UNSIGNED(640*((IdxC + 1) mod 2) + PixX - 1, 11);
PIXOUT <= PIXMEM;
ELSE
RAMREAD <= TO_UNSIGNED(640*(2-IdxC) - PixX, 11);
IF (PixX > 1 AND PixX < 640) THEN
PIXOUT <= PIXMEM;
ELSE
PIXOUT <= x"FFF";
END IF;
END IF;
END IF;
END PROCESS;
No diría que es un error, es más una limitación y, en cierto modo, tiene mucho sentido. Quiere que infiera una ram de puerto dual, el compilador quiere inferir una ram de puerto dual, sin embargo, el proceso en el fragmento de código del problema no describe correctamente la entrada de dirección del puerto de lectura de la ram, porque no todas las rutas están cubiertas, por lo que tendría que inferir un pestillo, mientras que lo que realmente quieres es que no te importe. Entonces, básicamente, le estás poniendo difícil al compilador.
Tenga en cuenta que para inferir la ram, también debe inferir algunas señales y sus valores, uno de los cuales es la entrada de dirección. En el proceso síncrono no se define el valor de esta señal inferida para el caso que termine en PIXOUT <= x"111". Por lo tanto, tendría que inferir un pestillo y la advertencia sería una incómoda "inferir pestillo en la señal de dirección inferida del carnero inferido". Termina siendo demasiado, por lo que probablemente se da por vencido, pero luego la solución alternativa no se ajusta al dispositivo. No estoy diciendo que esta sea la razón exacta por la que se está rindiendo, pero debería quedar claro que el compilador tendría dificultades para llenar los espacios en blanco para el ram inferido, dada la forma en que se codificó este proceso.
Todas las soluciones que funcionan cubren todos los casos para la señal de dirección, inferida o no. Podría probar declarando la señal y luego codificarla de la misma manera para que tenga que inferir un latch, e incluso puede compilar porque ahora al menos tendría una señal explícitamente declarada a la que puede referirse.
Los estilos de codificación para inferir bloques ram para Altera se pueden encontrar en http://www.altera.com/literature/hb/qts/qts_qii51007.pdf#page13
Esta es una de las razones por las que se recomienda encarecidamente que, si desea utilizar bloques de hardware existentes, los cree instancias como tales para evitar ambigüedades o siga los estilos de codificación apropiados para que pueda inferirse fácil y adecuadamente.
También tenga en cuenta que un simulador no tendría que lidiar con esto, porque no tendría que inferir un bloque ram per se y lidiar con el ambiguo no importa vs latch de esta señal fantasma, porque en la simulación no existe.
david tweed
Olivier Monnom
usuario_1818839
david tweed
usuario_1818839
else PIXOUT <= ram(some addr) or x"111";
lo hará...Olivier Monnom