Uso eficiente del espacio en FPGA

2

Antecedentes y aclaraciones:

Nunca he desarrollado / escrito una sola pieza de hardware antes, pero actualmente estoy usando Verilog para desarrollar un gran proyecto para un FPGA como mi proyecto final de graduación.

Tengo algunas preguntas sobre cómo escribir código verilog de manera eficiente. (Supongamos que, cuando digo "eficiente", me refiero a "la forma en que utiliza menos área y pines de la placa").

Dentro de los problemas, sugeriré posibles soluciones, pero si ninguna de ellas es correcta, no dude en anularlas y agregar su solución correcta.

De cierta manera, el problema 1 es el mismo que el problema 3, así que siéntete libre de responder solo a uno de ellos. He escrito ambos para proporcionar otro ejemplo del problema, en caso de que uno se sienta más cómodo respondiendo uno que el otro.

En caso de que no sepa cómo responder al problema 2, no se preocupe, ya que no es el problema principal aquí.

Gracias por su ayuda.

Problemas :

1 - Supongamos que tenemos un módulo X que controla si los módulos A, B, ... N están lógicamente encendidos / apagados, es decir, envía señales a ellos para señalar si deben ser habilitados o deshabilitados. Veo dos formas de hacer esto:

Opción 1: Envíe, a cada módulo de destino, un par de cables de habilitación / inhabilitación, desperdiciando espacio con cables. es decir:

module X(o_enable1, o_enable2, o_disable1, o_disable2);

assign i_enable1 = o_enable1;
assign i_disable1 = o_disable1;
module A(i_enable1, i_disable1);

assign i_enable2 = o_enable2;
assign i_disable2 = o_disable2;
module B(i_enable2, i_disable2);

Opción 2: Cree un bus, y cada módulo de destino será responsable de enmascararlo y verificar si se le envió la señal de habilitación / inhabilitación, lo que ahorra espacio en los cables, pero crea un demux para cada módulo. es decir:

// o_enableDisable -> 0 = 'ENABLE, 1 = 'DISABLE
module X(o_enableDisable, o_enableDisable_bus);

assign i_enDis1 = o_enableDisable;
assign i_enDis_bus1 = o_enableDisable;
module A(i_enDis1, i_enDis_bus1);

assign i_enDis2 = o_enableDisable2;
assign i_enDis_bus2 = o_enableDisable2;
module B(i_enDis2, i_enDis_bus2);

// ... Inside A
if ((if i_enDis1 == 'ENABLE)&&(i_enDis_bus1 == ENABLE_FOO1)) // Do something
if ((if i_enDis1 == 'DISABLE)&&(i_enDis_bus1 == DISABLE_FOO1)) // Do something

2 - En el problema anterior, asumimos que íbamos a habilitar / deshabilitar los módulos de manera lógica. En caso de que quisiéramos encenderlos / apagarlos físicamente para ahorrar energía, ¿hay alguna forma de hacerlo o simplemente tenemos una instrucción if dentro del módulo? es decir:

if (enabled) begin
  // Contents of module while on
end else begin
  // Contents of module while off
end

3 - Supongamos que tenemos un módulo decodificador X que envía comandos a los módulos A, B, ..., N. Veo 3 formas de hacer esto:

Opción 1: Comandos como cables simples, perdiendo pines, pero ahorrando el espacio de un demux. es decir:

module X(o_com1, ..., o_com_m, ..., o_com_n);

assign i_com1 = o_com1;
// ...
assign i_com_m = o_com_m;
module A(i_com1, ... , i_com_m);

module B(i_com_m_plus_1, ..., i_com_n);

Opción 2: La entrada logarítmica se descodificará dentro del módulo de destino, desperdiciando espacio con un demux. (Tenga en cuenta que X decodifica una instrucción, decide a qué módulo debe enviar un comando y luego le envía un comando)

module X(o_command_A, o_command_B, ...);

assign i_command_A = o_command_A;
module A(i_command_A);

assign i_command_B = o_command_B;
module B(i_command_B);

// Inside A
case (i_command_A)
  'COMMAND_1: begin /* ... */ end
  // ...
  'COMMAND_n: begin /* ... */end
endcase

Opción 3: Una combinación de ambos.

    
pregunta Daniel Carvalho

2 respuestas

2

Primero, cuando diseñamos FPGA, principalmente pensamos en "recursos" en lugar de "espacio". Los recursos son cosas como recursos de enrutamiento, celdas lógicas, bloques RAM, bloques de adición múltiple, etc. Parece que le preocupa minimizar el uso de recursos de enrutamiento y está dispuesto a usar más celdas lógicas para hacer eso.

Realmente, la mejor manera de responder sus preguntas (y primero, averiguar si la lógica de comercio para el enrutamiento es lo correcto) es sintetizar su diseño de primer borrador y observar el uso de recursos. Si los recursos de enrutamiento están casi totalmente utilizados, entonces comience a buscar formas de reducirlos. Si la lógica está casi totalmente utilizada, comience a buscar formas de hacer el tipo de optimización opuesto.

  

Supongamos que tenemos un módulo X que controla si los módulos A, B, ... N están lógicamente encendidos / apagados, es decir, les envía señales para indicar si deben habilitarse o deshabilitarse.

La forma típica de hacer esto en un FPGA es simplemente dejar que todos los módulos N se ejecuten continuamente. Si solo se usa una de las N en un momento dado, entonces a menudo puede usar un mux para seleccionar cuál de las salidas se usa en la lógica descendente. Si las combinaciones de módulos que se "deshabilitan" son más complejas, a menudo simplemente le dice a la lógica descendente que ignore esas entradas, en lugar de desactivar el módulo que las genera.

Normalmente, no tiene cables separados para enable y disable como propuso en su primera opción. Solo un cable que está (por ejemplo) alto cuando el módulo debería estar habilitado y bajo cuando debería estar deshabilitado.

Aunque, por supuesto, tener líneas separadas enable y disable que solo pulsan intermitentemente también es posible si tiene una buena razón para hacerlo. Por lo general, las entradas SET y RESET de un flip-flop se generarían para generar la señal enable real.

  

En el problema anterior, asumimos que íbamos a habilitar / deshabilitar módulos de forma lógica. En caso de que quisiéramos encenderlos / apagarlos físicamente para ahorrar energía, ¿hay alguna forma de hacerlo o simplemente tenemos una declaración if dentro del módulo?

Los FPGA no suelen tener disposiciones para apagar selectivamente partes de la tela.

Es posible utilizar los pines de habilitación para reducir el consumo de energía (debido a la reducción de la conmutación), pero si la cantidad de lógica que se deshabilita no es una fracción muy grande de su diseño, es probable que no mejore significativamente su presupuesto de energía.

Además, debe demostrar que en cualquier momento dado, al menos alguna fracción conocida de la lógica está deshabilitada, ya que de todos modos tendrá que diseñar sus fuentes de alimentación y el disipador de calor para tener en cuenta las condiciones operativas más desfavorables. / p>

  

Supongamos que tenemos un módulo decodificador X que envía comandos a los módulos A, B, ..., N. Veo 3 formas de hacer esto:

Su opción 1 (una señal separada para cada comando) es un estilo de codificación FPGA muy común. Del mismo modo, los fabricantes de herramientas de síntesis suelen recomendar one-hot para la máquina de estado de codificación. estados.

    
respondido por el The Photon
1

El diseño FPGA no se preocupará realmente por tus módulos, sino que creará un gran conglomerado de puertas y luego intentará encontrar un diseño óptimo.

Las señales de habilitación en FPGA generalmente se usan solo en los registros, que tienen una entrada enable dedicada. Si deshabilita un módulo al reducir su señal de habilitación, está cerca del consumo de energía más bajo posible, ya que las salidas de LUT ya no cambiarán y, por lo tanto, las puertas conectadas a sus salidas no tendrán que cambiar.

Si usa dos cables que van altos para un cambio de estado, necesita un flip-flop que los combine en un solo nivel lógico, y el optimizador sería estúpido si no se moviera tan cerca del componente de su controlador y solo enrutara un línea de habilitación única, por lo que simplemente puede hacer esto explícito. Probablemente lo mismo sucederá con la arquitectura de bus, pero el optimizador tendría que trabajar más duro para ello y podría verse obligado a encontrar la solución óptima debido a algún caso de esquina.

Un error común es cambiar la línea del reloj con la señal de habilitación. Esto es común en el diseño ASIC, ya que conservará una gran cantidad de energía, pero en los FPGA, esto no funciona realmente porque la distribución del reloj es una red separada. Los FPGA tampoco tienen una red de distribución de energía programable, por lo que tampoco hay manera de eliminar la energía de un área en el chip. Si fueras a construir un ASIC con esa lógica, agregarías estas cosas. Hay una buena FOSDEM talk sobre esto si está interesado.

Para la multiplexación de comandos, no importa mucho, porque el optimizador hará su trabajo de todos modos. Lo mantendría en el módulo, donde lógicamente pertenece.

    
respondido por el Simon Richter

Lea otras preguntas en las etiquetas