Verschiedene Möglichkeiten zur Verwendung von DSP-Slices in Spartan 6 FPGA

Ich lese das Spartan 6 DSP-Slice-Benutzerhandbuch und muss das DSP-Slice in einem meiner Projekte verwenden.

Ich bin auf diese Frage gestoßen, die im Grunde 3 Möglichkeiten zur Verwendung der DSP-Slices vorschlägt

  1. Ableitung des DSP-Slice
  2. Verwenden des Core-Generators
  3. Verwenden der RAW-DSP-Instanziierungsvorlage

Die zweite Option ist fast selbsterklärend, aber ich habe irgendwie keine Lust, sie zu verwenden, da sie sich etwas oberflächlich anfühlt. Ich bin daran interessiert, die erste und dritte Option zu verwenden, da diese Optionen am besten anpassbar sind, aber es fällt mir schwer zu verstehen, wo ich anfangen soll.

Das sind die Fragen, die mir auf der Seele brennen:

  • Auf welche verschiedenen Arten können Sie einen DSP-Slice in Ihrem Design ableiten?
  • Wo finde ich die RAW-DSP-Instanziierungsvorlage? Ich habe danach gegoogelt, aber keine genaue Anleitung dazu gefunden.
  • Aufbauend auf meiner zweiten Frage gibt es viele Xilinx-Dokumente, die man lesen kann, um Informationen zu vielen Dingen zu erhalten. Da ich ein Noob bin, bin ich immer verwirrt darüber, was ich lesen soll, und ich habe immer gerne eine Mindmap von dem, was alles da draußen ist, und welche Möglichkeiten ich habe. Gibt es einen Ort, an dem alle xilinx-Dokumente mit ihrer Beschreibung aufgelistet sind, oder auf welche Dokumente ich mich für eine bestimmte Anwendung beziehen kann?
sollte es nicht in der xilinx ide-Vorlage sein? Das ist der übliche Ort, an dem Sie eine auf Silizium bereitgestellte Funktion instanziieren (RAM, PLL usw.).
@JonRB Das wäre Methode 2 mit dem Core-Generator.

Antworten (4)

Das Ableiten von DSP-Slices ist eigentlich ziemlich einfach. Der Spartan 6 hat DSP48A1 DSP-Slices, also werfen Sie einen Blick auf Xilinx UG389. Seite 15 enthält ein Blockdiagramm des DSP-Slice. XST ist ziemlich gut darin, DSP-Slices abzuleiten. Stellen Sie nur sicher, dass alle Pipeline-Register für maximale Leistung vorhanden sind, und stellen Sie sicher, dass alle Ihre Bitbreiten nicht breiter sind als die im Blockdiagramm gezeigten. Hier ist ein einfacher Multiplikator mit AXI-Stream-Schnittstellen, der einen DSP-Slice auf einem Spartan 6 herleitet: https://github.com/alexforencich/verilog-dsp/blob/master/rtl/dsp_mult.v .

Werfen Sie auch einen Blick in das XST-Benutzerhandbuch, ug627, Seiten 98-121. Eine ziemlich ärgerliche Sache, die zu beachten ist: Die Pipeline-Multiplikatoren in diesem Abschnitt werden nicht zu vollständig Pipeline-DSP48-Slices synthetisieren (sie werden wahrscheinlich Slices ableiten, aber Sie werden eine Leistungseinbuße bekommen, da die Register nicht unbedingt an den richtigen Stellen sein werden). Beispielsweise zeigen die Codierungsbeispiele und das Blockdiagramm auf den Seiten 104-108 alle einen Multiplizierer mit einem Pipeline-Register davor und drei danach. Als ich mir das zum ersten Mal ansah, ging ich davon aus, dass XST schlau genug wäre, die Register so zu verschieben, dass sie mit dem tatsächlichen DSP-Slice übereinstimmen (es ist möglich, Register "durch" den Multiplikator zu verschieben, ohne die Operation zu ändern). Es ist nicht. Sie sollten Register hinzufügen (nur mit synchronen Resets! ) genau wie im DSP-Slice-Handbuch gezeigt, damit XST einen DSP-Slice richtig mit den Pipeline-Registern an den richtigen Stellen für maximale Leistung ableiten kann (beachten Sie, dass diese Register intern im DSP-Slice implementiert sind; alle gezeigten Pipeline-Register werden hinzugefügt im DSP-Slice-Benutzerhandbuch führt nur zu einer Latenzstrafe - sie verbrauchen keine Fabric-Flip-Flops). Ich würde empfehlen, das DSP-Slice-Blockdiagramm auszudrucken und als Referenz an die Wand zu heften. Und vergessen Sie auch nicht, sich die Syntheseprotokolle anzusehen, um sicherzustellen, dass die DSP-Slices die Pipeline-Register korrekt einlesen. Das Hinzufügen aller im DSP-Slice-Benutzerhandbuch gezeigten Pipeline-Register führt nur zu einer Latenzstrafe - sie verbrauchen keine Fabric-Flip-Flops). Ich würde empfehlen, das DSP-Slice-Blockdiagramm auszudrucken und als Referenz an die Wand zu heften. Und vergessen Sie auch nicht, sich die Syntheseprotokolle anzusehen, um sicherzustellen, dass die DSP-Slices die Pipeline-Register korrekt einlesen. Das Hinzufügen aller im DSP-Slice-Benutzerhandbuch gezeigten Pipeline-Register führt nur zu einer Latenzstrafe - sie verbrauchen keine Fabric-Flip-Flops). Ich würde empfehlen, das DSP-Slice-Blockdiagramm auszudrucken und als Referenz an die Wand zu heften. Und vergessen Sie auch nicht, sich die Syntheseprotokolle anzusehen, um sicherzustellen, dass die DSP-Slices die Pipeline-Register korrekt einlesen.

Was eine Auflistung der Dokumentation angeht, gibt es keinen guten Ort für alles (FPGAs, IP-Kerne, Software usw.). Werfen Sie einen Blick auf die Produktseite, um nur die Funktionen eines einzelnen FPGAs zu erfahren. Beispiel: http://www.xilinx.com/products/silicon-devices/fpga/spartan-6.html#documentation . Stellen Sie sicher, dass Sie „Benutzerhandbücher“ und nicht „Datenblätter“ auswählen. Das sollte Ihnen eine ziemlich umfassende Liste der Spartan 6-Dokumentation geben.

Nachdem ich mir den Github-Code angesehen habe, ist klar geworden, wie ein DSP-Slice abgeleitet wird, aber jetzt verstehe ich nicht zwischen "Ableiten eines DSP-Slices" und "Verwenden einer RAW-DSP-Instanziierungsvorlage". Sind sie anders?
Ich glaube nicht, dass es einen großen Unterschied gibt, außer vielleicht ist die Vorlage etwas expliziter darüber, was im DSP-Slice enthalten ist und was nicht. Hier ist eine weitere Datei, die Sie sich ansehen sollten: github.com/alexforencich/verilog-dsp/blob/master/rtl/… . Dieser leitet zwei DSP-Slices mit vollen Pipeline-Registern (Multiplikator und Post-Addierer) ab. Es ist jedoch nicht so klar, was genau wohin geht. Wenn Sie den 'Template'-Weg gewählt hätten, wäre es meiner Meinung nach viel offensichtlicher, wie die DSP-Slice-Eingänge angeschlossen sind.

Alex hat schon viel über das Ableiten der DSP-Slices geschrieben. Meine Antwort konzentriert sich nur auf:

Wo finde ich die RAW-DSP-Instanziierungsvorlage? Ich habe danach gegoogelt, aber keine genaue Anleitung dazu gefunden.

Die Vorlage finden Sie im Libraries Guide for HDL Designs von Xilinx. Für Ihr Spartan-6 FPGA ist es UG615 . Die Beschreibung der DSP48A1-Slices finden Sie auf Seite 92 ff. . Die VHDL-Instanziierungsvorlage lautet beispielsweise:

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
);

In Bezug auf die Ausgabe der Xilinx-Dokumente hat Xilinx ein nettes Tool entwickelt, um bei diesem Problem zu helfen: DocNav .

Es ist ein durchsuchbarer Katalog der gesamten Xilinx-Dokumentation, mit filterbaren Kategorien für Dinge, die Sie interessieren/nicht interessieren, und einer einigermaßen guten Suche innerhalb von Dokumenten.

Wenn Sie es verwenden, stellen Sie sicher, dass Sie das richtige erhalten (Vivado vs. ISE-Registerkarten auf der Download-Seite, obwohl das ISE-Installationsprogramm aus irgendeinem Grund immer noch das Vivado-Branding hat) und aktualisieren Sie den Katalog, wenn Sie ihn zum ersten Mal verwenden.

Ich befinde mich in einer ähnlichen Situation, Ironstein. In meiner Anwendung muss ich Spartan-6-FPGAs (die die Verwendung von XST erfordern) und auch Artix-7-FPGAs (die in einigen Fällen Vivado und XST oder Vivado mit anderen Modellen erfordern) unterstützen. Ich bin mit den Speicher- und Taktverwaltungskacheln einfach geworden.

Ich stimme Ihrer Einschätzung zu, dass die Verwendung von IPcores am einfachsten ist, aber aus Sicht des Projektmanagements finde ich es schwierig zu verwalten, da es so viele Dateien gibt, die „einfach so“ am richtigen Ort sein müssen. Ich ziehe es vor, nur IPcores zu verwenden, um verteilte Speicherelemente zu instanziieren.

Ich bin im Allgemeinen etwas vorsichtig mit abgeleiteten Designs, da die geringste Änderung die DSP-Architektur oder einige der Feinheiten bei der Zuweisung von Registern „brechen“ kann, wie Alex.Forencich betonte.

Ich ziehe es vor, die genaue Kontrolle darüber zu haben, was vor sich geht, und so bin ich auf der mühsamen Lernkurve, um den DSP48A1-Block und die zugehörigen Makroblöcke zu verstehen: ADDMACC_MACRO, ADDSUB_MACRO, COUNTER_LOAD_MACRO, MULT_MACRO und MACC_MACRO. Diese Makros sprechen allgemeine Funktionen an, mit denen Sie beginnen können, ohne die gesamte Komplexität des vollständigen DSP48A1-Grundelements der Spartan-6-Familie kennen zu müssen.

Sie finden VHDL/Verilog-Vorlagen für das DSP48A1-Grundelement und diese Makros im UG615-Benutzerhandbuch, wie vorgeschlagen wurde. Diese Vorlagen sind jedoch lang genug, dass ich es vorziehe, die Sprachvorlagenfunktion in XST zu verwenden, um sie direkter in meine Designs zu kopieren/einzufügen. Der Zugriff erfolgt über „Edit > Language Templates… > VHDL || Verilog > Device Macro Instantiation“ (für Makros) oder „Edit > Language Templates… > VHDL || Verilog > Device Macro Primitives“ (für die primitiven Module). Anschließend wählen Sie die FPGA-Familie und den DSP aus und schon sind Sie fertig. Da meine Designs auch die von XST unterstützten Spartan-6 / Artix-7-Familien umfassen, finde ich die Sprachvorlagenfunktion sehr praktisch.

Das ist es, was ich letztendlich getan habe (nachdem ich viele Dinge ausprobiert habe) :)
Ich bin froh, dass meine Antwort nützlich war. Trotzdem möchten Sie vielleicht meine Antwort positiv bewerten, da ich hier relativ neu bin und den „Rep“ gebrauchen könnte. ;-)