Hallo! Ich muss für ein Uni Labor einen 10er log auf den FPGA bringen. Ich arbeite mit Xilinx ISE und einem Spartan 3A Starter Kit! Ich habe mir schon den Cordic Algorithmus angeschaut und auch schon überrissen wie ich im CoreGen ein passendes Modul instanziere. Ich bin jedoch ein wenig Ratlos wenn es um die Constraints der Eingangsvektoren des Cordic Blocks geht: die Eingänge werden im Fixkomma format x.xxxxxxxx(wieviele bit auch immer nach dem Komma) benötigt. Muss ich nun meine 8 Bit Eingangszahl sooft nach rechts shiften das ich sie in dem format hab? dann von 2^n den natürlichen logarithmus in eine tabelle schreiben und nachdem ich von meiner zahl 0<zahl<2 den ln berechnet habe, diesen mit dem passenden ln(2^n) addieren? Oder gibt es eine einfachere Möglichkeit die ich gerade nicht bedenke? Den natürlichen Log muss ich dann am schluss eben noch zum 10er Log umformen. Vielen Dank für eure Hilfe und eure Tipps! LG Alex Hier der Link zur Doku des Moduls: http://www.xilinx.com/support/documentation/ip_documentation/cordic_ds249.pdf
Du musst sie so schieben, dass sie alle passen und dabei wissen, wo du aufgefüllt hast. Das ist quasi ein Faktor, der hinten "mehr" rauskommt. Den muss man wieder "abziehen" - in diesem Fall wohl tatsächlich abziehen, weil ein Shift im Logarithmischen ein Minus ist. Dann einfach den log(10,2) draufmultiplizieren. Oder war es ln(10)/ln(2) - bin nicht mehr so sicher.
also ist das schon die "richtige" Art es zu machen? Hab leider kein einziges richtig ausdokumentiertes Projekt oder Beispiel gefunden, immer nur mit der erklärung dass es mit dem Cordic geht.... Es muss + sein, weil (ich schreibs mal fürs 10er system auf): Log(1500) = log (1.5 *10^3)= log(1.5)+log(10^3)=log(1.5)+3 Ich soll 8bit einlesen und 8 bit ausgeben, ich darf mir selber aussuchen welche Zahlen das sein dürfen (natürliche, ganze, fixkomma). ich will bei als eingang 0-255 machen und als ausgang xx.xxxxxx fixkomma. weil mehr als 2,40...kann dann ehh nicht rauskommen! LG und danke!
Alex schrieb: > Ich soll 8bit einlesen und 8 bit ausgeben, ich darf mir selber aussuchen > welche Zahlen das sein dürfen (natürliche, ganze, fixkomma). ich will > bei als eingang 0-255 machen und als ausgang xx.xxxxxx fixkomma. weil > mehr als 2,40...kann dann ehh nicht rauskommen! Bei 2^8 Eingangswerten würde ich eine Tabelle nehmen, ehe ich mich mit dem Coregen-Format rumplage. Duke
Wie gesagt, ist für eine Uni Übung und die 8bit kommen eher daher das das DevBoard nur 4 DIP Switches und 4 Taster hat...Und Cordic ist vorgegeben! LG
Duke Scarring schrieb: > Bei 2^8 Eingangswerten würde ich eine Tabelle nehmen Und die kann man dann auch leicht den Synthesizer berechnen lassen. Alex schrieb: > als ausgang xx.xxxxxx fixkomma. Damit verschenkst du von deinen 8 Bits aber gut 40% des maximalen Wertebereichs und damit 40% der Genauigkeit. Ich würde am Ausgang 0..255 herauskommen lassen und das bei Bedarf im Verlauf der späteren Rechnung dann per Multiplikation zurechtskalieren. Damit hätte ich in der eigentlichen log10 Berechnung die maximale Genauigkeit und Dynamik. Und sehr wahrscheinlich muss das Ergebnis sowieso irgendwo skaliert oder umgerechnet werden... Hier mal mein Ansatz und im Anhang die Waveform der Testbench (die gibt nur die Werte 0..255 vor):
1 | library IEEE; |
2 | use IEEE.std_logic_1164.all; |
3 | use IEEE.numeric_std.all; |
4 | USE ieee.math_real.log10; |
5 | |
6 | Entity LOG is |
7 | Port ( CLK : in std_logic; |
8 | Din : in std_logic_vector (7 downto 0); |
9 | Dout : out std_logic_vector (7 downto 0) |
10 | );
|
11 | end LOG; |
12 | |
13 | Architecture RTL of LOG is |
14 | |
15 | type Rom256x8 is array (0 to 255) of unsigned (7 downto 0); |
16 | signal LOG_Rom : Rom256x8; |
17 | signal RomAddr : integer range 0 to 255; |
18 | |
19 | begin
|
20 | |
21 | -- Tabelle berechnen beginnend mit log(1)
|
22 | table: for i in 0 to 255 generate |
23 | LOG_Rom(i) <= to_unsigned( integer( log10(real(i)+1.0)/log10(256.0)*255.0 ),8); |
24 | end generate; |
25 | |
26 | -- BROM
|
27 | process begin |
28 | wait until rising_edge(CLK); |
29 | RomAddr <= to_integer(unsigned(Din)); -- getaktete Adresse --> BROM |
30 | end process; |
31 | Dout <= std_logic_vector(LOG_Rom(RomAddr)); |
32 | |
33 | end RTL; |
Alex schrieb: > Und Cordic ist vorgegeben! Also eine schöne, aber realitätferne Übung... ;-)
:
Bearbeitet durch Moderator
Für so wenige Werte ist ein Logarithmus ja eher witzlos. Ließe sich das nicht irgendwie mathematisch zerlegen und zwei kleine Tabellen mit Ergebnissen der Teiler aus der Vorgabezahl nutzen, um Platz zu sparen? wenn ... log (a*b) = log (a) + log(b) -> könnt man doch die Zweierpotenzen aus der Vorgabe rausziehen und später wieder "drafaufaddieren", da der Log (2) trivial ist. Bliebe nur die Umrechnung auf log(10).
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.