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.
Was macht es denn für einen Sinn wenn ich diesen Operator nicht in der Praxis einsetzen kann?
VHDL Simulationen kommen in der Praxis schon vor. Damit testet man, ob das, was ins FPGA (oder CPLD) kommt, so funkioniert wie gewünscht.
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.
Und wie kommt man an diese Algorithmen. Ich Dachte ich verwende einfach die Bibliothek "math".
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
Ich hätte einen Divider, der 38Bit durch 38Bit teilen kann. Abgestimmt auf die Spartan-kompatiblen 18Bit-multipliere.
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.
Mein Chef möchte das alle Feiertage auf einen Tag zusammengelegt werden. Dann nimm doch einen Prozessor.
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.
Ich brauche nur 1 Nachkommastelle wenn überhaupt. Ich werde Deine Lösung noch mal durchdenken. Grüsse Michael
Haste das nun hingekriegt? Habe nun selber mal die Newtonsche Itereation verwendet. Sehr zu empfehlen. Nur schwer validierbar.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.