Hallo, irgendwie steh ich auf dem Schlauch. Ich kriege von einem bipolaren AD zwei 12 Bit Werte, welche ich mir als zweierkomplement oder als straight binary (0 bis 4095) ausgeben kann. Diese liegen mir dann als std_logic_vector vor, welche ich dann entsprechend in signed oder unsigned casten kann oder muss ich noch was beachten? zweierkomplement wäre ja signed und straight binary unsigned oder? Mach ich das am besten mit den Werten als Zweierkomplement oder mit dem straight binary? Später muss ich das Ergebnis dividieren, so das der Quotient immer zwischen -1 und 1 liegt. Dafür wollt ich den IP-Core von Lothar Miller verwenden. http://www.lothar-miller.de/s9y/archives/29-Division-in-VHDL.html oder hat da jemand eine andere Idee, weil mein Quotient ja nicht größer als 1 wird?! Danke für eure hilfe :-)
Marc K. schrieb: > Mach ich das am besten mit den Werten als Zweierkomplement Eher ja. Denn sonst hast du nur positive Werte und musst selber noch den Offset abziehen... > Später muss ich das Ergebnis dividieren, so das der Quotient immer > zwischen -1 und 1 liegt. Wie willst du denn diesen Zahlenbereich darstellen? > oder hat da jemand eine andere Idee, weil mein Quotient ja nicht größer > als 1 wird?! Denk dir einfach das Komma vor das MSB. Dann hast du eine Zahl von -1...+0.999, und das ganz ohne Rechnen... :-o
ok vielen dank. Ich werde es mit dem Zweierkomplement machen :-) Lothar Miller schrieb: > Wie willst du denn diesen Zahlenbereich darstellen? Das hab ich mich auch gefragt. Ich weiß noch nicht so recht wie ich das realisieren soll. Lothar Miller schrieb: > Denk dir einfach das Komma vor das MSB. > > Dann hast du eine Zahl von -1...+0.999, und das ganz ohne Rechnen... > > :-o Ich muss die Divison aber durchführen, der Divisor ändert sich immer so das halt keine größere Zahl als 1 rauskommt. Mich interessiert eigentlich nur das vorzeichen und paar Nachkommastellen.
Marc K. schrieb: > Ich muss die Divison aber durchführen, Warum? > keine größere Zahl als 1 rauskommt. Nach wie vor die Frage: wie willst du mit Integerzahlen eine Zahl kleiner 1 darstellen? Weiterhin meine Antwort: denk dir einfach ein "Null Komma" vor die 12 Bit. Dann hat das führende Bit (links) die Wertigkeit 1/2, das nächste 1/4, dann 1/8, 1/16, usw. Je weiter du nach rechts kommst, umso weniger ist ein Bit wert. Genau so, wie du es von gewöhnlichen Integerzahlen gewöhnt bist. So wird das bei Signalprozessoren, die mit Festkommazahlen rechnen, auch gern gemacht. Und dafür gibt es massenweise Literatur.
Lothar Miller schrieb: > Marc K. schrieb: > >> Ich muss die Divison aber durchführen, > > Warum? Da sich mein Dividend und Divisor unabhängig ändert. Ich jedoch weiß das nur der bereich (-1 bis 1) rauskommen kann. Sonst ist ein fehler im AD Wert. Ich weiß auch das dies mit Integer nicht möglich ist... ich werd mich erstmal einlesen und vermutlich löst sich das Problem. ich dachte nur vielleicht gehts auch ganz einfach :-) vielen dank für die antwort :-)
Gast
#2817625
Du hast doch für beide einen Skalierungsfaktor drin. Z.B. wird die 1 immer als 32768 dargstellt. Das betrifft dann Zähler und Nenner. Rauskommen "tut" dann bei einer Division (egal ob mit core oder manuell) immer einen Bitfolge, die du nur zu interpretieren brauchst. Also: Bit einsammeln und für jeden shift nach links, den Du zusätzlich machst, musst du hinterher einen "weginterpretieren". Bei einem core kannst Du so teilen, dass vorne die 1 rauskommt und dann sofort den Rest weiterverarbeiten, indem du nochmal teilst. Oder, Du multiplizierst = schiebst den Zähler so weit nach links, dass Du genug Stellen rausbekommst. Beispiel: Zählerwert = Z, Nennerwert = N, mit -N < Z < +N; Digitale Darstellung: ZD = 32768 x Z = -32768*Z < ZD < 32767*Z Wenn Z aus z.B: einem ADC stammt und selber schon 15 Bit hat, hast du eben rund 30Bit+Signum. Dann könntest Du reduzieren. Gehen wir also davon aus, dass wir 31 Bit im Zähler haben und 31 im Nenner. Du rechnest dann einfach ZD & "00000000" / ND und heraus kommt eine Zahl mit 8 Stellen vor dem Komma. Den Rest, den der Core auswirft, kannst Du dann verwerfen. Der teil der Schaltung wird dann auch nicht synthetisiert. Habe das bei Altera exzessiv durchgecheckt.
ok danke. Ich bin gerade noch am umstrukturieren, aber hab ich das jetzt richtig verstanden. Ich erweitere die Zähler und Nenner so Divisor <= "000000000000" & std_logic_vector(Nenner); Dividend <= std_logic_vector(Zaehler) & "000000000000";
Gast
#2821186
Marc K. schrieb: > Divisor <= "000000000000" & std_logic_vector(Nenner); Den Divisor würde ich gar nicht erweitert. Bläht nur den Divider auf, der dann wieder reduziert wird, wenn die Synthese die vielen Nullen sieht.
ich nutzte ein FPGA von Microsemi und ich habe dort bezüglich der division nachgefragt. Diese meinten man kann es einfach mit "/" implementieren. Wie es aussieht funktioniert es auch :-/
Marc K. schrieb: > Diese meinten man kann es einfach mit "/" implementieren. > Wie es aussieht funktioniert es auch :-/ Kann Altera auch. Aber sieh mal nach, wie es mit dem Ressourcenverbrauch aussieht. Was kostet dich eine 32/16 Division, die in 1 Takt fertig ist?
Lothar Miller schrieb: > Marc K. schrieb: >> Diese meinten man kann es einfach mit "/" implementieren. >> Wie es aussieht funktioniert es auch :-/ > Kann Altera auch. > Aber sieh mal nach, wie es mit dem Ressourcenverbrauch aussieht. > Was kostet dich eine 32/16 Division, die in 1 Takt fertig ist? Das sagt die synthese bei folgendem code:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
Compile report:
===============
CORE Used: 151 Total: 38400 (0.39%)
IO (W/ clocks) Used: 19 Total: 147 (12.93%)
Differential IO Used: 0 Total: 65 (0.00%)
GLOBAL (Chip+Quadrant) Used: 1 Total: 18 (5.56%)
PLL Used: 0 Total: 2 (0.00%)
RAM/FIFO Used: 0 Total: 60 (0.00%)
Low Static ICC Used: 0 Total: 1 (0.00%)
FlashROM Used: 0 Total: 1 (0.00%)
User JTAG Used: 0 Total: 1 (0.00%)
Wolltest du das wissen?
Gast
#2824274
Marc K. schrieb: > CORE Used: 151 Total: 38400 (0.39%) Das sind vermutlich die Logic Cells. Interessant wäre noch die Taktfrequenz. Dazu müsste man vorher und hinterher noch ein Register dranpappen. Duke
Marc K. schrieb: > Wolltest du das wissen? Jein... Einen Divider für 6 Bit kann ich in ein BRAM packen... Ich wollte das eigentlich für 32/16 Bits wissen:
1 | |
2 | |
3 | |
4 | |
Und auch: Wie schnell kannst du dieses Design takten?
Lothar Miller schrieb: > Marc K. schrieb: >> Wolltest du das wissen? > Jein... > Einen Divider für 6 Bit kann ich in ein BRAM packen... > > Ich wollte das eigentlich für 32/16 Bits wissen: >
1 | |
2 | |
3 | |
4 | |
5 | |
CORE Used: 1799 Total: 38400 (4.68%)
IO (W/ clocks) Used: 81 Total: 147 (55.10%)
Differential IO Used: 0 Total: 65 (0.00%)
Lothar Miller schrieb: > Marc K. schrieb: >> Wolltest du das wissen? > Jein... > Einen Divider für 6 Bit kann ich in ein BRAM packen... > > Ich wollte das eigentlich für 32/16 Bits wissen: >> : > zahl_32 : IN std_logic_vector(31 downto 0); > zahl_16 : IN std_logic_vector(16 downto 0) > : > CORE Used: 1799 Total: 38400 (4.68%) IO (W/ clocks) Used: 81 Total: 147 (55.10%) Differential IO Used: 0 Total: 65 (0.00%) > Und auch: Wie schnell kannst du dieses Design takten? Wo seh ich das?
Marc K. schrieb: > zahl_32 : IN std_logic_vector(5 downto 0); > zahl_16 : IN std_logic_vector(5 downto 0) > CORE Used: 151 Total: 38400 (0.39%) Marc K. schrieb: > zahl_32 : IN std_logic_vector(31 downto 0); > zahl_16 : IN std_logic_vector(15 downto 0) > CORE Used: 1799 Total: 38400 (4.68%) Da wird tatsächlich ein kombinatorischer Divider gebaut. >> Und auch: Wie schnell kannst du dieses Design takten? > Wo seh ich das? Das ist eine wichtige Zahl, die solltest du mit einem Blick erkennen können. Such mal im Synthese- oder Implementation-Report nach MHz.
>>> Und auch: Wie schnell kannst du dieses Design takten? >> Wo seh ich das? > Das ist eine wichtige Zahl, die solltest du mit einem Blick erkennen > können. Such mal im Synthese- oder Implementation-Report nach MHz. Alles was ich mit MHz im Report gefunden habe.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
Gast
#2825252
Lothar Miller schrieb: > Da wird tatsächlich ein kombinatorischer Divider gebaut. Klaro und wenn man dem genug FF-stages hinten dran packt, kann die Synthese ihn per register retiming auch auf das jeweils benötigte Tempo bringen.
Bei Actel FPGAs würde ich da nicht zuviel erwarten bezüglich Taktfrequenz. Deren Architecktur ist nicht auf solche Rechenschaltungen optimiert. Ich kann es hier ja auch mal fix bauen und nachprüfen, haben die Toolchain auch am Start.
Also Synplify Pro 9.0.2A2 kann diese Division nicht synthetisieren. Er möchte gern nur durch 2^n teilen.
T. M. schrieb: > Also Synplify Pro 9.0.2A2 kann diese Division nicht synthetisieren. Er > möchte gern nur durch 2^n teilen. Ich nutzte Synplify Pro AE F-2012.03MSP1. Da gehts.
Gast
#2825643
M. K. schrieb: > Ich nutzte Synplify Pro AE F-2012.03MSP1. Da gehts. Mit Synplify Pro F-2012.03L geht es auch. Resourcen auf ECP3-35
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
Geschwindigkeit (Speedgrade 9)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Ich habe noch Eingangsregister hinzugefügt, ohne hatte er mit dem Constraint nix am Hut.
Gast
#2825689
Das ganze nochmal für einen MachXO2 (LCMXO2-4000HE Speedgrade 6) Spannend ist der Unterschied zwischen der neuen Lattice Synthese Engine (LSE) und Synplify Pro LSE:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
Synplify Pro:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
Mit dem LSE werden viel weniger Resourcen gebraucht, es ist obendrein noch schneller obwohl der kritische Pfad über fast 3 mal so viele Logikebenen geht.
Gast
#2825820
Du solltest am Eingang UND Ausgang mindestens 2, besser 3 Register haben, damit er a) in die IO-FFs kommt b) bequem zu jeder Resource kommt. Damit ist sicher gestellt, dass das ausgerechnete Tempo wirklich das Maximum ist, dass die Architektur in einer günstigen Umgebung kann. Habe beispielhaft einen Divider mit 160 Stellen gemacht: signed(Zaehler(79 downto 0) & Leerbits(79 downto 0)) / signed (Nenner(79 downto 0)); Er braucht nach 6 min Synthese >33.000 slices im Spartan3 und kommt auf etwas über 1MHz :-) Nach Optimierung durch Trans & MAP (insgesamt 49 min) braucht er 154.000 slices und schafft knapp 3 MHz Da waren die alten DX33-Copros schon schneller :-) Gibt es eigentlich CoProzessor-Chips als fertige ASICs? Sowas liesse sich doch an einen FPGA anschliessen, die könnten dann DIV/LOG/SQR berechnen.
Gast
#2825897
> Gibt es eigentlich CoProzessor-Chips als fertige ASICs?
Nimm nen Fließkomma DSP z.B. C6000 mit PCIe Interface und verbinde den
mit nem V6 oder V7. Oder über Serdes.
Gast
#2825908
> Gibt es eigentlich CoProzessor-Chips als fertige ASICs? Klar nennt sich FPU 80387 für x86 und MC68882. http://en.wikipedia.org/wiki/X87 http://de.wikipedia.org/wiki/Motorola_68881
Gast
#2825990
Uwe schrieb: >> Gibt es eigentlich CoProzessor-Chips als fertige ASICs? > > Klar nennt sich FPU 80387 für x86 und MC68882. War schon klar, dass SO ein link kommt :-) Uwe schrieb: > Nimm nen Fließkomma DSP z.B. C6000 > SERDES Ist wieder mit Flaschenhals. Ein ASIC könnte mit jedem Takt ein Datum berechnen.
Gast
#2826009
Spartanist schrieb: > Ist wieder mit Flaschenhals. Ein ASIC könnte mit jedem Takt ein Datum > berechnen. Das kannst du mit einem Kern im FPGA auch, und noch dazu vergleichsweise ressourcenschonend. Tradeoff ist dann halt die Latenz. Zwar jeden Tankt ein Datum, aber nicht sofort am Ausgang.
Spartanist schrieb: > Lothar Miller schrieb: >> Da wird tatsächlich ein kombinatorischer Divider gebaut. > Klaro und wenn man dem genug FF-stages hinten dran packt, kann die > Synthese ihn per register retiming auch auf das jeweils benötigte Tempo > bringen. Das ist aber immer langsamer als ein nicht aufgeteilter Pfad und dazu ein Multicycle Constraint, weil ja für jedes FF noch die Setup-Zeit dazukommt...
Gast
#2826221
Lothar Miller schrieb: > Das ist aber immer langsamer als ein nicht aufgeteilter Pfad und dazu > ein Multicycle Constraint, Nun, dieses gilt ja generell: Sobald Speicher hinzutreten, wird der Zeitpfad länger, aber oft benötigt man die pipelinefähige Schaltung, um bei jedem Takt Daten einspeisen zu können.
Es ist aber nicht so, dass eine mit "register retiming" beschleunigte Logik automatisch pipelinefähig wäre...
Gast
#2826288
Doch, natürlich - unser Beispiel schon.. Oben die Kombinatorik hat 0,x Takte und benutzt damit einen Takt. Einen, der langsam genug ist. Eine beschleunigte Architektur braucht dann mehr Takte, nämlich die, die man künstlich angehängt hat und wird Dank balancing schneller. Sie ist dann immer noch pipelinefähig. Du hast natürlich dann Recht, wenn eine nicht gepipelinte Architektur mit FFs nachversorgt wird.
Gast
#2826724
Michael schrieb: > Sie ist dann immer noch pipelinefähig. Da wage ich mal vorsichtig zu widersprechen... Wenn du eine <10MHz Logik durch Zugabe von Registern und anpassen der Constraints auf ~100MHz hochzwiebelst ist das mitnichten pipelined. Pipelined wuerde bedeuten, dass du jeden 100MHz Takt neue Daten in die Stufe reinfuetterst und dass nach ~10 Zyklen dann das jeweilige Ergebnis rausfaellt. Wenn du das ganze pipelined machen willst musst du schon eine adequate FSM schreiben die in jeder pipeline-Stufe eben auch die Daten entsprechend auf die naechste Stufe verteilt. Das ist dann aber Design/Handarbeit
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.