Hallo an alle VHDL-Freunde
Ich habe folgendes Problem: Ein 20Bit std_logic_vector soll durch einen
anderen std_logic_vector geteilt werden. Kann ich dies einfach durch das
Zeichen ":" erreichen?
z.B.
Ergebnis <= A : B;
Grüsse
Michael
Der Divisonsoperator in VHDL ist / , also
Ergebnis <= A / B;
Allerdings funktioniert dieser glaube ich nur sinnvoll für die
Simulation und nicht für die Synthese.
In der Praxis schreibt man schon mal den ein oder anderen Testbench. Der
Divisionsoperator ist wenn auf Konstanten angewendet auch fuer die
Synthese bestens brauchbar.
Cheers, Roger
Ich möchte gern eine Summe mit Hilfe eines Signals (std_logic_vector)
bilden und diese anschließend durch einen anderen std_logic_vector
dividieren. Muss ich den Divisor als Konstante erzeugen oder reicht ein
Signal?
Du musst ja nicht unbedingt Konstanten verwenden um in VHDL zu
dividieren. Die Division muss man halt nur erst implementieren, es gibt
synthesefähige Algorithmen dazu.
Ich denke nicht, dass diese library eine synthesefähige Division
enthält.
Algorithmen zur Division kann man per google finden. Diese sind meist
sequentiell, für kurze Bitweiten kann das auch in einem Takt machbar
sein, da der kritische Pfad dann nicht zu lang wird.
Welchen Algorithmus du benötigst hängt vor allem von der Bitlänge und
deinen Taktvorgaben ab.
Bei Xilinx und Altera gibt es kostenlose Dividierer-Einheiten:
www.xilinx.com/bvdocs/ipcenter/data_sheet/div_gen_ds530.pdf
www.altera.com/literature/ug/ug_lpm_divide_mf.pdf
Meine Literatur dazu wäre dieses Buch:
http://www.amazon.com/Digital-Processing-Programmable-Communication-Technology/dp/3540211195/ref=si3_rdr_bb_product/103-6643607-4511066
"DSP with FPGAs" ISBN: 3540211195
"from Table of Contents:
Binary Dividers ....
2.5.1 Linear Convergence Division Algorithms ...
2.5.2 Fast Divider Design ...
2.5.3 Array Divider ..."
Dazu hätte ich die Anwendung eines "Reziproken Frequenzzählers" im FPGA
mit mehreren 100 MHz Taktfrequnez, der die Periodendauer mißt und dann
den Kehrwert bildet, also eine ca. 32bit-Division ausführt.
Die oben genannte Xilinx-Applikation werde ich mir mal näher anschauen,
danke für den Link
Ich möchte halt 14 x 12Bit Werte aufaddieren und anschließend durch die
Zahl 14 teilen. Ich weiß wenn man 16 aufaddiert kann man durch einfaches
schieben durch 8 oder 16 teilen. Hierzu möchte ich jetzt nicht 20% des
FPGAs belegen.
@Fpgaingenieur
Kann man Deinen Teiler auch auf einfach reduzieren? Meine Frequenz die
ich verwende beträgt 40MHz wenn das ganze unter 100 Takte benötigt ist
das alles ok. Nur es sollte nicht 20% des FPGAs belegen.
Grüsse
Michael
@Michael
>Ich möchte halt 14 x 12Bit Werte aufaddieren und anschließend durch die>Zahl 14 teilen. Ich weiß wenn man 16 aufaddiert kann man durch einfaches>schieben durch 8 oder 16 teilen. Hierzu möchte ich jetzt nicht 20% des
Was hindert dich daran einfach 16 Werte zu addieren und dan duch 16 zu
teilen? Das belegt nämlich 0 Ressourcen.
MfG
Falk
Ich weiß das mache ich momentan auch so. Aber 16 sind zu viel und 8 zu
wenig. Mein Chef möchte halt über 14 Werte das ganze haben. Mit einem µP
kann ich es ja auch (demnach sollte es doch auch mit einem FPGA möglich
sein.
zwei zusätzliche Messwerte die Null sind addieren, durch 16 dividieren
und dann mit einem Korrekturfaktor 16/14 multiplizieren
Ist aber dasselbe wie gleich mit 1/14 multiplizieren...
@Christoph Kessler
>zwei zusätzliche Messwerte die Null sind addieren, durch 16 dividieren
?? Dann sind es wahrscheinlich KEINE Messwerte sondern eingeschmuggelte
Nullen. -> Gehe nicht über los
>Ist aber dasselbe wie gleich mit 1/14 multiplizieren...
Das wohl eher. Um es aber mal praktisch runterzubrechen.
Multipliziren mit 256/14 = 18,2 also 18 und die unteren 8 Bit weg.
Wenn dir das zu ungenau ist (0,2 von 18 = 1,1% Fehler) dann rechne mal
4096/14 = 292,6 also 293 und lass die unteen 14 Bit weg. Mach nur noch
0,14% Fehler. Wenn das immer noch nicht reicht, . . . ich denke du hast
das Prinzip verstanden.
MfG
Falk
@Christoph Kessler
Ist das von dir genannte Buch generell empfehlenswert für Entwickler
oder sind nur wenige interessante Ansätze drin? Sind die halbwegs auf
dem neuesten Stand oder ist der größere Teil überholt?
Michael, der von mir beschriebene Devider rechnet je nach Frequenz und
Breite in 8-10 clks. Bei Deiner Breite brauchst Du den aber nicht
sondern nimmmst einen standard-Devider von Xilinx. Der dürfte auch so um
6-8clks haben. Bei den Breiten ist keine besondere Rechentechnik nötig.
Du kannst einfach deine 14x12Bit = faktisch 16Bit-Werte in einen
32-Bit-Teiler einspeisen und durch 14 teilen:
a <= summe1412 & "0000000000000000"; b <= teiler & "00";
c = divider (a,b)
@ fpgaengineer
Das ging mir etwas zu schnell. Du bildest die Summe aus 14 Werten.
Anschließend hängst Du an die Summe 16 Bits ran. Dann hängst Du an den
Teiler
2 Nullen ran. Zuletzt teilst Du a durch b oder was soll die
Quellcodezeile c = divider (a,b) bedeuten?
Was bringt das denn für Vorteile die Nullen ranzuhängen?
Ich habe heute morgen mal das Kapitel über Division angeschaut.
Für schnelle Division empfiehlt der Autor ein Multiplikation mit dem
Kehrwert, den er mittels Newtonschem Iterationsverfahren der Funktion
f(x)=1/x-D berechnet. In seinem Beispiel hat er nach 5 Iterationen 36
gültige Bits erreicht, noch schneller gehts dann mit Lookuptable für den
Startwert.
Ich hatte das Buch bei einem Kollegen gesehen und mir bestellt, aber
bisher ist das meiste viel zu hoch für mich. Schneller als FFT mit
irgendwelchen zahlentheoretischen wasweißich, ein Zahlensystem dem die
Null fehlt.
Bei Amazon kann man das Inhaltsverzeichnis betrachten dazu ein paar
Ausschnitte ( wenn einen der/die/das firewall durchläßt).
Michael, das mit den Nullen tue ich deshalb, um eine möglichst hohe
Auflösung des Ergebnisses zu erzeugen. So, wie definiert, hat das
Ergebnis 16 Bit Auflösung. (s.u.) Zugleich passt diese 32/16 Architektur
auf die Standard Devider im Spartan (meine ich jetzt aus Errinnerung).
Den Teiler koennte man auch mit 2 Bits von vorne ausfüllen.
Beispiel: Der Wert 34/1177 ergibt also 1893 was also real 0,0288848875
entspricht und damit nur minimal vom korrekten real wert 0,0288848870
abweicht.