Diferentes formas de usar segmentos DSP en Spartan 6 FPGA

Estoy leyendo la guía del usuario de Spartan 6 DSP slice y necesito usar el DSP slice en un proyecto mío.

Me topé con esta pregunta, que básicamente sugiere 3 formas de usar los cortes DSP

  1. Inferir el segmento DSP
  2. Usando el generador de núcleo
  3. Uso de la plantilla de creación de instancias RAW DSP

La segunda opción casi se explica por sí misma, pero de alguna manera no tengo ganas de usarla, ya que se siente algo superficial. Estoy interesado en usar la primera y la tercera opción, ya que esas opciones son las más personalizables, pero me cuesta entender por dónde empezar.

Estas son las preguntas que tengo en mente:

  • ¿Cuáles son las diferentes formas en que puede inferir un corte DSP en su diseño?
  • ¿Dónde encuentro la plantilla de creación de instancias RAW DSP? Lo he estado buscando en Google, pero no encontré una guía definitiva.
  • Sobre la base de mi segunda pregunta, hay muchos documentos de xilinx que uno puede leer para obtener información sobre muchas cosas. Como soy un novato, siempre me confundo acerca de qué leer, y siempre me gusta tener un mapa mental de todo lo que hay por ahí, y qué opciones tengo. ¿Hay algún lugar donde se enumeren todos los documentos de xilinx con su descripción, o qué documentos puedo consultar para una aplicación en particular?
¿No debería estar en la plantilla ide de xilinx? Ese es el lugar habitual en el que instancia una función proporcionada en el silicio (ram, pll, etc.)
@JonRB Ese sería el método 2, usando el generador Core.

Respuestas (4)

Inferir segmentos de DSP es bastante sencillo. El Spartan 6 tiene cortes DSP DSP48A1, así que eche un vistazo a Xilinx UG389. La página 15 tiene un diagrama de bloques del segmento DSP. XST es bastante bueno para inferir segmentos DSP. Solo asegúrese de incluir todos los registros de tubería para obtener el máximo rendimiento, y asegúrese de que todos los anchos de bits no sean más anchos que los que se muestran en el diagrama de bloques. Aquí hay un multiplicador simple con interfaces de flujo AXI que infiere un segmento DSP en un Spartan 6: https://github.com/alexforencich/verilog-dsp/blob/master/rtl/dsp_mult.v .

Consulte también la guía del usuario de XST, ug627, páginas 98-121. Una cosa bastante molesta a tener en cuenta: los multiplicadores canalizados en esa sección no se sintetizarán en segmentos DSP48 completamente canalizados (probablemente inferirán segmentos, pero obtendrá una penalización de rendimiento ya que los registros no estarán necesariamente en las ubicaciones correctas). Por ejemplo, los ejemplos de codificación y el diagrama de bloques de las páginas 104 a 108 muestran un multiplicador con un registro de tubería antes y tres después. Cuando miré eso por primera vez, supuse que XST sería lo suficientemente inteligente como para mover los registros para que coincidieran con el segmento DSP real (es posible mover registros "a través" del multiplicador sin cambiar la operación). no lo es Debe agregar registros (¡con solo reinicios sincrónicos! ) exactamente como se muestra en el manual del segmento DSP para que XST infiera un segmento DSP correctamente con los registros de tubería en los lugares correctos para un rendimiento máximo (tenga en cuenta que estos registros se implementan internamente en el segmento DSP; agregando todos los registros de tubería que se muestran en la guía del usuario de segmento de DSP solo resultará en una penalización de latencia, no consumirán flip-flops de tela). Recomendaría imprimir el diagrama de bloques de corte de DSP y pegarlo en la pared como referencia. Y tampoco te olvides de mirar los registros de síntesis para asegurarte de que los segmentos DSP estén ingresando los registros de canalización correctamente. agregar todos los registros de tubería que se muestran en la guía del usuario del segmento DSP solo resultará en una penalización de latencia; no consumirán flip-flops de estructura). Recomendaría imprimir el diagrama de bloques de corte de DSP y pegarlo en la pared como referencia. Y tampoco te olvides de mirar los registros de síntesis para asegurarte de que los segmentos DSP estén ingresando los registros de canalización correctamente. agregar todos los registros de tubería que se muestran en la guía del usuario del segmento DSP solo resultará en una penalización de latencia; no consumirán flip-flops de estructura). Recomendaría imprimir el diagrama de bloques de corte de DSP y pegarlo en la pared como referencia. Y tampoco te olvides de mirar los registros de síntesis para asegurarte de que los segmentos DSP estén ingresando los registros de canalización correctamente.

En cuanto a una lista de documentación, no hay un buen lugar para todo (FPGA, núcleos IP, software, etc.). Para ver las características de un solo FPGA, eche un vistazo a la página del producto. Por ejemplo, http://www.xilinx.com/products/silicon-devices/fpga/spartan-6.html#documentation . Asegúrese de seleccionar 'guías de usuario', no 'hojas de datos'. Eso debería darle una lista bastante completa de la documentación de Spartan 6.

Después de mirar el código de github, quedó bastante claro cómo inferir un segmento DSP, pero ahora no entiendo entre "inferir un segmento DSP" y "usar la plantilla de creación de instancias RAW DSP". ¿Son diferentes?
No creo que haya una gran diferencia, excepto que tal vez la plantilla sea un poco más explícita sobre lo que está en el segmento DSP y lo que no. Aquí hay otro archivo para mirar: github.com/alexforencich/verilog-dsp/blob/master/rtl/… . Este infiere dos segmentos de DSP con registros de canalización completos (multiplicador y sumador posterior). Sin embargo, no está tan claro exactamente qué va a dónde. Si siguió la ruta de la 'plantilla', entonces creo que sería mucho más obvio cómo se conectan las entradas de segmento DSP.

Alex ya ha escrito mucho sobre cómo inferir los cortes de DSP. Mi respuesta se centra solo en:

¿Dónde encuentro la plantilla de creación de instancias RAW DSP? Lo he estado buscando en Google, pero no encontré una guía definitiva.

La plantilla se puede encontrar en la Guía de bibliotecas para diseños HDL de Xilinx. Para su Spartan-6 FPGA es UG615 . La descripción de los cortes DSP48A1 se encuentra en la página 92 ​​y siguientes. . La plantilla de creación de instancias de VHDL es, por ejemplo:

Library UNISIM;
use UNISIM.vcomponents.all;

-- DSP48A1: 48-bit Multi-Functional Arithmetic Block
-- Spartan-6
-- Xilinx HDL Libraries Guide, version 14.7

DSP48A1_inst : DSP48A1
generic map (
    A0REG => 0, -- First stage A input pipeline register (0/1)
    A1REG => 1, -- Second stage A input pipeline register (0/1)
    B0REG => 0, -- First stage B input pipeline register (0/1)
    B1REG => 1, -- Second stage B input pipeline register (0/1)
    CARRYINREG => 1, -- CARRYIN input pipeline register (0/1)
    CARRYINSEL => "OPMODE5", -- Specify carry-in source, "CARRYIN" or "OPMODE5"
    CARRYOUTREG => 1, -- CARRYOUT output pipeline register (0/1)
    CREG => 1, -- C input pipeline register (0/1)
    DREG => 1, -- D pre-adder input pipeline register (0/1)
    MREG => 1, -- M pipeline register (0/1)
    OPMODEREG => 1, -- Enable=1/disable=0 OPMODE input pipeline registers
    PREG => 1, -- P output pipeline register (0/1)
    RSTTYPE => "SYNC" -- Specify reset type, "SYNC" or "ASYNC"
)
port map (
    -- Cascade Ports: 18-bit (each) output: Ports to cascade from one DSP48 to another
    BCOUT => BCOUT, -- 18-bit output: B port cascade output
    PCOUT => PCOUT, -- 48-bit output: P cascade output (if used, connect to PCIN of another DSP48A1)

    -- Data Ports: 1-bit (each) output: Data input and output ports
    CARRYOUT => CARRYOUT, -- 1-bit output: carry output (if used, connect to CARRYIN pin of another
                          -- DSP48A1)
    CARRYOUTF => CARRYOUTF, -- 1-bit output: fabric carry output
    M => M, -- 36-bit output: fabric multiplier data output
    P => P, -- 48-bit output: data output

    -- Cascade Ports: 48-bit (each) input: Ports to cascade from one DSP48 to another
    PCIN => PCIN, -- 48-bit input: P cascade input (if used, connect to PCOUT of another DSP48A1)

    -- Control Input Ports: 1-bit (each) input: Clocking and operation mode
    CLK => CLK, -- 1-bit input: clock input
    OPMODE => OPMODE, -- 8-bit input: operation mode input

    -- Data Ports: 18-bit (each) input: Data input and output ports
    A => A, -- 18-bit input: A data input
    B => B, -- 18-bit input: B data input (connected to fabric or BCOUT of adjacent DSP48A1)
    C => C, -- 48-bit input: C data input
    CARRYIN => CARRYIN, -- 1-bit input: carry input signal (if used, connect to CARRYOUT pin of another
                        -- DSP48A1)
    D => D, -- 18-bit input: B pre-adder data input

    -- Reset/Clock Enable Input Ports: 1-bit (each) input: Reset and enable input ports
    CEA => CEA, -- 1-bit input: active high clock enable input for A registers
    CEB => CEB, -- 1-bit input: active high clock enable input for B registers
    CEC => CEC, -- 1-bit input: active high clock enable input for C registers
    CECARRYIN => CECARRYIN, -- 1-bit input: active high clock enable input for CARRYIN registers
    CED => CED, -- 1-bit input: active high clock enable input for D registers
    CEM => CEM, -- 1-bit input: active high clock enable input for multiplier registers
    CEOPMODE => CEOPMODE, -- 1-bit input: active high clock enable input for OPMODE registers
    CEP => CEP, -- 1-bit input: active high clock enable input for P registers
    RSTA => RSTA, -- 1-bit input: reset input for A pipeline registers
    RSTB => RSTB, -- 1-bit input: reset input for B pipeline registers
    RSTC => RSTC, -- 1-bit input: reset input for C pipeline registers
    RSTCARRYIN => RSTCARRYIN, -- 1-bit input: reset input for CARRYIN pipeline registers
    RSTD => RSTD, -- 1-bit input: reset input for D pipeline registers
    RSTM => RSTM, -- 1-bit input: reset input for M pipeline registers
    RSTOPMODE => RSTOPMODE, -- 1-bit input: reset input for OPMODE pipeline registers
    RSTP => RSTP -- 1-bit input: reset input for P pipeline registers
);

Con respecto al problema de los documentos de Xilinx, Xilinx creó una buena herramienta para ayudar con ese problema: DocNav .

Es un catálogo navegable de toda la documentación de Xilinx, con categorías filtrables para las cosas que le interesan o no, y una búsqueda razonablemente buena dentro de los documentos.

Si lo usa, asegúrese de obtener el correcto (pestañas Vivado vs ISE en la página de descarga, aunque el instalador ISE todavía tiene la marca Vivado por alguna razón) y actualice el catálogo cuando lo use por primera vez.

Me encuentro en una situación similar, Ironstein. En mi aplicación necesito admitir Spartan-6 FPGA (que requiere el uso de XST) y también Artix-7 FPGA (que requiere Vivado en algunos casos, y XST o Vivado con otros modelos). Me he vuelto fácil con los mosaicos de administración de memoria y reloj.

Estoy de acuerdo con su evaluación de que usar IPcores es más fácil, pero luego, desde el punto de vista de la gestión de proyectos, creo que puede ser complicado de administrar, ya que hay tantos archivos que deben estar en la ubicación correcta 'solo así'. Prefiero usar solo IPcores para instanciar elementos de memoria distribuida.

Soy un poco cauteloso con los diseños inferidos en general, ya que el más mínimo cambio puede 'romper' la arquitectura DSP, o algunas de las sutilezas de cómo se asignan los registros, como señaló Alex.Forencich.

Prefiero tener un control explícito de lo que está sucediendo con precisión, por lo que estoy en la ardua curva de aprendizaje para comprender el bloque DSP48A1 y los macrobloques relacionados: ADDMACC_MACRO, ADDSUB_MACRO, COUNTER_LOAD_MACRO, MULT_MACRO y MACC_MACRO. Estas macros abordan funciones comunes que pueden ayudarlo a comenzar sin tener que conocer toda la complejidad de la primitiva DSP48A1 completa de la familia Spartan-6.

Puede encontrar plantillas VHDL/Verilog para la primitiva DSP48A1 y estas macros en la guía del usuario de UG615 como se ha sugerido. Sin embargo, estas plantillas son lo suficientemente largas por lo que prefiero utilizar la función Plantillas de idioma en XST para copiarlas y pegarlas más directamente en mis diseños. Se accede a eso a través de "Editar > Plantillas de idioma… > VHDL || Verilog > Instanciación de macro de dispositivo" (para macros) o "Editar > Plantillas de idioma… > VHDL || Verilog > Primitivas de macro de dispositivo" (para los módulos primitivos). Luego selecciona la familia FPGA y DSP, y ya está todo listo. Dado que mis diseños también abarcan las familias Spartan-6/Artix-7 que son compatibles con XST, considero que la función Plantillas de idioma es muy útil.

Esto es lo que finalmente terminé haciendo (después de probar muchas cosas) :)
Me alegro de que mi respuesta haya sido útil. Dicho esto, es posible que desee votar mi respuesta ya que soy relativamente nuevo aquí y podría usar el 'representante'. ;-)