Tengo un proyecto que consume 34 de las macrocélulas de un Xilinx Coolrunner II. Noté que tenía un error y lo rastreé hasta esto:
assign rlever = RL[0] ? 3'b000 :
RL[1] ? 3'b001 :
RL[2] ? 3'b010 :
RL[3] ? 3'b011 :
RL[4] ? 3'b100 :
RL[5] ? 3'b101 :
RL[6] ? 3'b110 :
3'b111;
assign llever = LL[0] ? 3'b000 :
LL[1] ? 3'b001 :
LL[2] ? 3'b010 :
LL[3] ? 3'b011 :
LL[4] ? 3'b100 :
LL[5] ? 3'b101 :
3'b110 ;
El error es eso rlever
y llever
son de un bit de ancho, y necesito que tengan tres bits de ancho. Tonto de mí. Cambié el código para ser:
wire [2:0] rlever ...
wire [2:0] llever ...
entonces había suficientes pedazos. Sin embargo, cuando reconstruí el proyecto, este cambio me costó más de 30 macrocélulas y cientos de términos de productos. ¿Alguien puede explicar lo que he hecho mal?
(La buena noticia es que ahora simula correctamente ... :-P)
EDITAR -
Supongo que estoy frustrado porque, cuando creo que empiezo a entender a Verilog y al CPLD, sucede algo que muestra que claramente no entiendo.
assign outp[0] = inp[0] | inp[2] | inp[4] | inp[6];
assign outp[1] = inp[1] | inp[2] | inp[5] | inp[6];
assign outp[2] = inp[3] | inp[4] | inp[5] | inp[6];
La lógica para implementar esas tres líneas ocurre dos veces. Eso significa que cada una de las 6 líneas de Verilog consume aproximadamente 6 macrocélulas y 32 términos de producto cada una .
EDITAR 2: según la sugerencia de @ ThePhoton sobre el cambio de optimización, aquí hay información de las páginas de resumen producidas por ISE:
Synthesizing Unit <mux1>.
Related source file is "mux1.v".
Found 3-bit 1-of-9 priority encoder for signal <code>.
Unit <mux1> synthesized.
(snip!)
# Priority Encoders : 2
3-bit 1-of-9 priority encoder : 2
Claramente, el código fue reconocido como algo especial. Sin embargo, el diseño aún consume enormes recursos.
EDITAR 3 -
Hice un nuevo esquema que incluye solo el mux que @thePhoton recomendó. La síntesis produjo un uso insignificante de recursos. También sinteticé el módulo recomendado por @Michael Karas. Esto también produjo un uso insignificante. Entonces prevalece cierta cordura.
Claramente, mi uso de los valores de la palanca está causando consternación. Más por venir.
Edición final
El diseño ya no es una locura. Sin embargo, no estoy seguro de lo que sucedió. Hice muchos cambios para implementar nuevos algoritmos. Un factor que contribuyó fue una 'ROM' de 111 elementos de 15 bits. Esto consumió un número modesto de macrocélulas pero muchode términos del producto: casi todos los disponibles en el xc2c64a. Busqué esto pero no lo había notado. Creo que mi error estaba oculto por la optimización. Las 'palancas' de las que estoy hablando se utilizan para seleccionar valores de la ROM. Supuse que cuando implementé el codificador de prioridad de 1 bit (roto), ISE optimizó parte de la ROM. Eso sería un buen truco, pero es la única explicación que se me ocurre. Esta optimización redujo notablemente el uso de los recursos y me indujo a esperar cierta línea de base. Cuando arreglé el codificador de prioridad (según este hilo), vi la sobrecarga del codificador de prioridad y la ROM que previamente se había optimizado y atribuí esto al primero exclusivamente.
Después de todo esto, era bueno en macrocélulas pero había agotado los términos de mi producto. La mitad de la ROM era un lujo, en realidad, ya que solo eran las 2 comp de la primera mitad. Eliminé los valores negativos, reemplazándolos en otro lugar con un cálculo simple. Esto me permitió intercambiar macrocélulas por términos de producto.
Por ahora, esta cosa encaja en el xc2c64a; He usado el 81% y el 84% de mis macrocélulas y términos de producto respectivamente. Por supuesto, ahora tengo que probarlo para asegurarme de que hace lo que quiero ...
Gracias a ThePhoton y Michael Karas por la ayuda. Además del apoyo moral que prestaron para ayudarme a resolver esto, aprendí del documento de Xilinx publicado por ThePhoton, e implementé el codificador de prioridad sugerido por Michael.
fuente
|
lugar de||
.Respuestas:
El código que muestra es esencialmente un codificador de prioridad. Es decir, tiene una entrada de muchas señales, y su salida indica cuál de esas señales está configurada, dando prioridad a la señal configurada más a la izquierda si se configura más de una.
Sin embargo, veo definiciones contradictorias del comportamiento estándar para este circuito en los dos lugares que verifiqué.
Según Wikipedia , el codificador de prioridad estándar numera sus entradas desde 1. Es decir, si se establece el bit de entrada menos significativo, genera 1, no 0. El codificador de prioridad de Wikipedia genera 0 cuando ninguno de los bits de entrada está configurado.
Sin embargo, la Guía del usuario XST de Xilinx (pág. 80) define un codificador de prioridad más cercano a lo que codificó. Las entradas están numeradas desde 0, por lo que cuando se establece lsb de la entrada, se obtiene una salida 0. Sin embargo, la definición de Xilinx no proporciona especificaciones para la salida cuando todos los bits de entrada son claros (su código generará 3'7).
La guía del usuario de Xilinx, por supuesto, determinará qué espera el software de síntesis de Xilinx. El punto principal es que
(*priority_extract ="force"*)
se requiere una directiva especial para que XST reconozca esta estructura y genere resultados de síntesis óptimos.Aquí está la forma recomendada de Xilinx para un codificador de prioridad 8 a 3:
Si puede reorganizar su lógica circundante para permitirle usar el estilo de codificación recomendado por Xilinx, esa es probablemente la mejor manera de obtener un mejor resultado.
Creo que puede obtener esto instanciando el módulo codificador Xilinx con
No he reunido todos los bits
RL[6:0]
para obtener un octavo bit de entrada que activará la salida 3'b111 cuando todos los bits RL estén bajos.Para la
llever
lógica, probablemente pueda reducir el uso de recursos haciendo un módulo codificador modificado, siguiendo la plantilla Xilinx, pero requiriendo solo 7 bits de entrada (sus 6 bitsLL
más un bit adicional que sube cuando los otros 6 están bajos).El uso de esta plantilla supone que la versión de ISE que tiene está usando el motor de síntesis XST. Parece que cambian las herramientas de síntesis en cada revolución importante de ISE, así que verifique que el documento que vinculé en realidad corresponde a su versión de ISE. De lo contrario, verifique el estilo recomendado en su documentación para ver qué espera su herramienta.
fuente
(* priority_extract="force" *)
y, probablemente, también incluir explícitamente el resultado de no importar aunque cubra todas las entradas posibles. (Sin ella, XST probablemente esté tratando de generar una tabla de búsqueda completa, por eso hay tantos términos de productos) Intente agregar primero la opción no importa. Si no funciona, intente usar la placa de cocción Xilinx exactamente.La respuesta de ThePhoton es excelente. Me gustaría agregar información adicional aquí para su consideración. Esto se debe al hecho de que, a pesar de que tenemos dispositivos FPGA y CPLD de última generación que utilizan HDL y herramientas de síntesis, puede ser informativo observar de cerca las cosas diseñadas hace años. Quédate conmigo mientras paso por esto para mi recomendación al final.
Hay partes lógicas discretas que realizan la función de codificación de prioridad. La lógica implementada por estas partes ha existido durante mucho tiempo cuando era esencial reducir la cantidad de transistores al mínimo. Puede buscar en la web partes lógicas con números de parte genéricos como 74HC148 o MC14532B para encontrar hojas de datos que incluyen diagramas lógicos equivalentes para estas partes. El siguiente diagrama es un ejemplo tomado de la hoja de datos de TI para la parte 74HC148 .
Esta lógica implementa la siguiente tabla de verdad (tomada de la misma hoja de datos):
Tenga en cuenta que la familia de la parte anterior utiliza señales de entrada activas bajas. Otra hoja de datos para la parte ON Semiconductor MC14532B muestra una tabla de verdad para la función del codificador que utiliza señales activas de entrada alta similares a su ejemplo de Verilog.
La misma hoja de datos muestra las ecuaciones lógicas para el MC14532B de la siguiente manera:
Puede considerar codificar ecuaciones similares directamente en su código Verilog para ver cómo se compara con su ejemplo actual. Es muy probable que resulte en un resultado mucho más favorable.
fuente