Guten Tag,
ich habe ein IIR-Filter programmiert und versuche jetzt Multiplikationen
zusammenzufassen, um die Anzahl benötigter Multiplizierer zu reduzieren.
Der Code einer Stufe sieht folgendermaßen aus:
Der CLK beträgt 80MHz und liefert mit jedem Takt einen neuen
Eingangswert bzw. einen neuen Ausgangswert.
Gibt es eine Möglichkeit, die die Multiplikationen A1 * Y(28 downto 11)
und A2 * Y(28 downto 11) so zusammenfasst, dass anstelle von zwei
Multiplizierer nur einer verwendet wird. Habe mit Hilfe eines Prozesses
versucht YA1 auf die steigende Flanke des CLKs zu berechnen und YA2 auf
die fallende Flanke. Jedoch war dieser Versuch nicht von Erfolg gekrönt.
Ein weiterer Punkt ist, dass ich in dieser Stufe 4 Multiplikationen
durchführe, jedoch laut Xilinx 5 Multiplizierer benötigt werden. Meine
Feststellung dazu ist, dass die Multiplikation XB1 <= B1 * XB0(28 downto
11) zwei Multiplizierer benötigt, jedoch ist mir der Grund dafür nicht
ersichtlich.
Grüße
Tom
Tom schrieb:> Habe mit Hilfe eines Prozesses versucht YA1 auf die steigende Flanke> des CLKs zu berechnen und YA2 auf die fallende Flanke. Jedoch war dieser> Versuch nicht von Erfolg gekrönt.
Ja, überleg mal, warum. Du wirst fürs Leben lernen...
Als Tipp: wie ist so ein Multiplizierer aufgebaut? Woher kommen die
Faktoren am Eingang und wohin geht das Ergebnis? Wie wird das
umgeschaltet?
Denn es geht um das Umschalten (aka. Multiplexen): du willst 1
Komponente mehrfach verwenden...
> Der CLK beträgt 80MHz und liefert mit jedem Takt einen neuen> Eingangswert bzw. einen neuen Ausgangswert.> Gibt es eine Möglichkeit, die die Multiplikationen A1 * Y(28 downto 11)> und A2 * Y(28 downto 11) so zusammenfasst, dass anstelle von zwei> Multiplizierer nur einer verwendet wird.
Du musst mit der doppelten Frequenz (das ist auch deine
Zwei-Flankengeschichte) durch einen Multiplexer zwischen den vier
Faktoren und den beiden Ergebnissen umschalten. Im Fall von YA1 und YA2
wäre sogar nur 1 Faktor zu multiplexen...
Tom schrieb:> Ein weiterer Punkt ist, dass ich in dieser Stufe 4 Multiplikationen> durchführe, jedoch laut Xilinx 5 Multiplizierer benötigt werden.
Sieh doch einfach mal den RTL-Schaltplan an. Evtl. kannst du dann
erkennen, was da passiert. Ich vermute sowas wie Register-Doubling (nur
hier eben Multiplier-Doubling)...
BTW: bitte VHDL-Code in die Tags [ vhdl] und [ /vhdl] ohne Leerzeichen
einschließen.
Tom schrieb:> YA1 <= A1 * Y(28 downto 11);> YA2 <= A2 * Y(28 downto 11);> SUMB2A2 <= XB2 - YA2;> SUMB2A2V_2 <= XB1 + SUMB2A2V;> SUMB2A2V_3 <= SUMB2A2V_2 - YA1;
Geht es um das hier?
Du solltest das mathematisch etwas umformulieren, dann fällt eine
Multiplikation später an und es entsteht weiter vorne ein Addierer.
Danke für den Hinweis mit dem RTL Schaltplan. Der „Überschüssige“
Multiplizierer resultiert aus der doppelten Negation im Prozess Delay
und kann somit nicht eingespart werden. Für die Signale YA1 und YA2 ist
es mir mit Hilfe der case-Anweisung gelungen einen Multiplizierer
einzusparen.
Jedoch bekomme ich jetzt immer folgende Warnung:
Found 1-bit latch for signal <YA1<28>>. Latches may be generated from
incomplete case or if statements. We do not recommend the use of latches
in FPGA/CPLD designs, as they may lead to timing problems
So wie ich das verstehe, stimmt irgendwas mit der case-Anweisung nicht?
Tom schrieb:> process(CLK160MHz,YA)
Die Sensitivliste ist unvollständig. Es fehlen A1 und A2.
> begin> case CLK160MHz is> when '0' => A <= A1 ;> when others => A <= A2;> end case;>> case CLK160MHz is> when '0' => YA1 <= YA ;> when others => YA2 <= YA;> end case;> end process;
Ein Takt ist ein Takt und keine Quelle für kombinatorisches
Umschalten...
> when '0' => YA1 <= YA ;> when others => YA2 <= YA;
Daher kommt die Latch-Warnung:
Was soll YA2 sein, wenn CLK160MHz mal '0' ist?
Und was Ya1, wenn der "Takt" '1' ist?
Wie hast du die 160MHz erzeugt?
Lothar Miller schrieb:> Tom schrieb:>> process(CLK160MHz,YA)> Die Sensitivliste ist unvollständig. Es fehlen A1 und A2.>>> begin>> case CLK160MHz is>> when '0' => A <= A1 ;>> when others => A <= A2;>> end case;>>>> case CLK160MHz is>> when '0' => YA1 <= YA ;>> when others => YA2 <= YA;>> end case;>> end process;> Ein Takt ist ein Takt und keine Quelle für kombinatorisches> Umschalten...
Ich finde die Klasse, darauf wäre ich nicht gekommen.
>Wie soll den die Umformulierung aussehen?
Du verwendest beide Terme in derselben Gleichung, nur über
Zwischensignale. Die kannst du anders zusammenfassen.
Also ich habe jetzt eine Lösung, die statt 5 Multiplizierer noch 3
verwendet. Jedoch funktioniert das Filter mit den 160 MHz nicht. Wird
der Takt auf 320 MHz erhöht, läuft es ohne Probleme und ich erziele
dieselben Ergenisse, wie mit 5 Multiplizierer.
Tom schrieb:> Jedoch funktioniert das Filter mit den 160 MHz nicht.
Wie stellst du das fest?
Was sagt die Simulation?
Hast du ein Constraint auf den Takt gesetzt?
Das Filter arbeitet bei einer Mittenfrequenz von 20 MHz und meine
Abtastfrequenz liegt bei 80 MHz. Also lasse ich in der Simulation meine
Eingangswerte so variieren, dass sie einem Sinussignal mit 20 MHz
entsprechen. Funktioniert mein Programm, so muss mein Ausgangssignal
ungefiltert vorliegen und mit der Simulation mit 5 Multiplizierer
übereinstimmen. Dies tut sie aber nur, wenn ich die Frequenz auf 320 MHz
einstelle.
Ich musste mich bisher noch gar nicht mit timing constraints
beschäftigen, deswegen weiß ich nicht was du mit "Constraint auf den
Takt setzen" meinst!
Wenn du bisher "nur" simulierst und da was nicht passt, dann kannst du
ja recht komfortabel den Fehler suchen.
Tom schrieb:> Dies tut sie aber nur, wenn ich die Frequenz auf 320 MHz einstelle.
In der Simulation? Machst du eine Timingsimulation?
> Ich musste mich bisher noch gar nicht mit timing constraints beschäftigen,
Das wird kommen, wenn du aufs FPGA gehst...
> weiß ich nicht was du mit "Constraint auf den Takt setzen" meinst!
Damit teilst du der Toolchain mit, wie schnell du das FPGA takten wirst.
Und 320MHz sind schon sportlich...