Hallo,
ich brauche wieder Hilfe ...:(
Ich habe folgendes Problem. Ich möchte 2 werte miteinander
Multiplizieren. Beide Werte sind 12 bit breit. Ich möchte Sie am DA
wandler ausgeben. Der DA wandler ist 12 bit breit. Ich hab über den CORE
generator auch multiplikation gefunden. Aber so ganz hab ich das nicht
verstanden.
12 bit mal 12 bit müsste ja 24 bit ergeben. Muss ich dann die 24 bit auf
12 bit normieren um Sie am DA wandler auszugeben? Muss ich das Ergebnis
durch 12 Teilen oder wie?
Mein Multiplizierer sieht folgender maßen aus:
1
PortMap(
2
3
clk=>CLK_20MHZ,
4
ce=>'1',
5
sclr=>'1',
6
bypass=>'1',
7
a=>EINGANG_AD_WANDLER,
8
b=>"000000000001",
9
s=>AUSGANG_DA_WANDLER);
Im obigen Beipsiel will ich einen Wert vom AD wandler mit einem
KOnstantem Wert Multiplizieren und am DA Wandler ausgeben, aber da bin
ich mir unsicher wegen dem 12 bit mal 12 bit ....
Kann mir da jemand helfen? Muss ich da Ergebniss wieder Teilen? Und wie
sind die Signale sclr und ce zu verstehen?
Gruß
Das maximale Ergebnis ist 24bit. Aber nicht jedes Ergebnis ist
zwangsweise so breit (z.B. wenn der Wert 1 ist...).
Du nimmst einfach die untersten 12Bit des Ergebnisses für den DA Wandler
und musst sicherstellen, dass das Ergebnis nicht größer wird.
Du kannst in VHDL eine Multiplikation auch einfach so schreiben:
ergebnis = a*b;
Der Synthesizer macht dann den Rest.
> Du nimmst einfach die untersten 12Bit des Ergebnisses für den DA Wandler> und musst sicherstellen, dass das Ergebnis nicht größer wird.
Widerspruch: es sind die oberen 12 Bit zu nehmen. Man lässt einfach
die nicht signifikanten unteren weg. Allerdings ist das nicht eine
Division durch 12, sondern quasi ein Schieben um 12 Bit.
Das Blöde an deinen Werten ist, dass der Wert
> b => "000000000001",
extrem ungünstig gewählt ist. Mit ein wenig Nachdenken wird dir das klar
werden: besser wäre "111111111111".
Hallo,
danke für die Antworten. Ist es jetzt besser den von ISE Coregenerator
Multiplizierer zu nehmen oder es aus selbst zu programieren?
Es ist so gedacht um es bessere zu beschreiben. Ich kriege ein Impuls
welches ca. 10 usek breit ist. Wenn der Impuls gekommen ist wird die
Amplitude dieses Impulses mit Werten einer Efunktion die sich in
Flashspeicher befindet multipliziert. Mein AD wandler hat ein bereich
zwischen -1 V bis + 1 V. Der Impuls ist eignetlich ein Lichtblitz der
über eine Photdiode als strom und dann über eine Strom spannungswandler
in den AD Wandler eingespeißt wird. Soweit klappt alles bis auf diese
Tatsache mit dem multplizieren was mich halt etwas verwirrt wie ich
jetzt das skalieren bzw. multiplizieren soll.... und wie ich das mit dem
24bit Ergebinis dann am DA Wanlder ausgeben soll....
Gruß
Igor schrieb:
> Es ist so gedacht um es bessere zu beschreiben.
Portierbarer (und zudem leichter lesbar) ist auf jden Fall die
generische Multiplikation über a*b. Das kann jedes FPGA.
> was mich halt etwas verwirrt wie ich> jetzt das skalieren bzw. multiplizieren soll....
Da kommt es nur auf Skalierungswerte und Vektorbreiten an. Das kannst du
auf einem Blatt Papier herrechnen, zu diesem Zeitpunkt ist die
tatsächliche Implementierung (ob als Core oder generisch) des
Multiplizierers vollkommen egal.
Hallo,
danke für die Antwort. BIn grad dabei den Multiplizierer zu Simulieren
um mir mit den Werten etwas besser zu verstehen. Nun kommt aber beim
Ergebnis nichts, reicht es wenn ich lediglich den Takt anlege?
Hier mal die Bench, was mach ich Falsch ? Wieso kommt kein Ergebnis?
Welchen Vorteil hat dann der multiplizierer über den CORE generator dann
?
Eine Frage hätte ich noch. Angenommen Signal A = 12 bit , B = 12 bit ,
Eregbnis = 24 bit. Multipliziere A und B und schreibe ein Prozess der
darauf schaut wie groß das Ergebniss ist und erstelle
Fallunterscheidungen. Z.b
1
ifErgebnis>"111111111111"then-- größer 12 bit
2
DA_WANDLER<=Ergebnis(12downto1);
3
elsifErgebnis>"1111111111111"then-- größer 13 bit
4
DA_Wandler<=Ergebnis(13downto2);
5
6
usw.
ich weiß das der Code oben nicht ganz korrekt ist, mir geht es jetzt nur
ums prinzip.
Gruß
Für das was Du machen willst ist es vom Prinzip her falsch. Du Brauchst
z.B. DAC <= Ergebnis (24 downto 13)
Die least significant bits gehen dann halt in der Genauigkeit deines DAC
unter.
> und erstelle Fallunterscheidungen. Z.b
Du versuchst also das Ergebnis für den AD-Wandler zu skalieren? Wozu?
Auf diese Art unterdrückst du deine 12 signifikanten Bits, das ist
irgendwie kontraproduktiv. Ein Multiplikationsergebnis von
"111111111111111111111111" ergbit dann den selben DA-Wert
wie z.B. das hier: "000000000000111111111111"
oder das hier: "000000011111111111111111"
BTW1:
Was du willst (aber eigentlich nicht brauchst) heißt "Finde das MSB",
also "Finde die erste 1 im Vektor". Diese Aufgabe habe ich auf meiner HP
schon mal untersucht:
http://www.lothar-miller.de/s9y/archives/55-Finde-das-MSB.html
BTW2:
> if Ergebnis > "111111111111" then -- größer 12 bit> DA_WANDLER <= Ergebnis (12 downto 1);> elsif Ergebnis > "1111111111111" then -- größer 13 bit> DA_Wandler <= Ergebnis (13 downto 2);> ...
Hier ist die Reihenfolge falsch, denn auch wenn Ergebnis =
"111111.....111" ist, wird immer der erste Fall zuschlagen...
BTW3:
Mit Vektoren rechnet man nicht. Sieh dir mal die anderen
Darstellungsmöglichkeiten für Zahlen an. Sehr schön eignet sich ein
Integer zum Rechnen :-o
Ok,
also von std_logic auf unsigned dann auf integer und dann die
fallunterscheidung?
>Du versuchst also das Ergebnis für den AD-Wandler zu skalieren? Wozu?
Nein, ich versuche das Ergebnis für den DA Wandler zu skaliern, der Wert
von AD Wandler multipliziert mit den Werten der Efunktion und dann die
MSB auf DA Wandler ....?
Igor schrieb:
> ... dann die MSB auf DA Wandler ....?
Rechnen wir einfach mal unsigned:
Du hast einen 12 Bit Eingangswert 0..4095,
und eine e-Funktion, die (hoffentlich) auf 0..4095 skaliert ist.
Und du hast einen 12 Bit-Wandler, d.h. 4095 ist der größte Wert, den du
damit darstellen kannst.
Nehmen wir jetzt einfach mal den Maximalwert:
4095 * 4095 = 16769025 = 11111111 11100000 00000001
Also würdest du hier 111111111110 = 4094 ausgeben.
Und jetzt nehmen wir irgendwas anders:
32 * 2047 = 65504 = 00000000 11111111 11100000
Was willst du denn hier ausgeben?
Etwa einfach die führenden Nullen wegskalieren?
Also als 12-Bit-Wert dann 111111111110 = 4094 ausgeben?
Das Ergebnis wäre also bei 4095 4095 und 32 2047 das selbe?
Da kann irgendwas nicht stimmen.... :-o
EDIT:
Da hat mir das Autoformat mit den Sternchen dazwischengefunkt :-/
Meine Abschglussfrage war:
Das Ergebnis wäre also bei 4095 mal 4095 und 32 mal 2047 das
selbe?
>Du hast einen 12 Bit Eingangswert 0..4095,>und eine e-Funktion, die (hoffentlich) auf 0..4095 skaliert ist
Ja sind sie alle.
>Das Ergebnis wäre also bei 4095 mal 4095 und 32 mal 2047 das>selbe?
Ja stimmt, jetzt bin ich erst recht verwirrt.
Ums noch verständlicher zu machen, ich will die Ausgabe der Efunktion
abhängig von der Amplitude des Eingangssignals machen. Also ist der
Impuls nur z.b 500mV groß soll auch die Efunktion mit den 500
multipliziert werden. ist die Amplitude 1000mv groß soll die Efunktion
mit 1000 multipliziert werden. Somit soll für eine kleine Amplitude auch
eine in der AMplitude kleinere Efuntion rauskommen. Wenn ich das
Eingangssignal in der AMplitude erhöhe soll auch die Efuntion höher
erscheinen......
Man ich krieg die krise... :(
also rein mathematisch müsstest du zum skalieren dann durch 4096 teilen
oder halt um 12 bit verschieben, was bedeutet das du nur die obersten 12
bits verwenden könntest. die kleinen werte würden ja in den
nachkommastellen verschwinden und wären dann für dich eigentlich nicht
mehr nutzbar.
so wie sich das jedoch bei dir anhört kannst du auf diese art und weise
nicht skalieren, falls es überhaupt möglich ist. da du den gesamten
wertebereich ausnutzt.
Puhhhhhhhhh..... mein Kopf raucht.
Dann frag ich mal anders. Was müsste ich den tuen wenn ich das
Ausgangssignal abhängig von Eingangsignal in der Amplitude machen will.
Große Amplitude am Eingang soll auch große Amplitude am Ausgang, kleine
Amplitude am Eingang soll auch kleine Amplitude am Ausgang bedeuten?
Und wenn ich ich es nach der Multiplikation durch 4096 teile ? Quasi das
Ergebniss auf 4096 skaliere??
>mit 1 multiplizieren ?
Welchen Sinn soll das ergeben ? Dann ist das Ergebnis ja immer konstant
egal wie hoch mein Eingangssignal ist....
>Lassen wie es ist???
Wieso ? Es muss doch wohl gehen ein Eingangssignal * Wert = Ergebnis ...
Eingangssignal klein => Ergebnis klein, Eingangssignal groß => Ergebnis
groß
Gruß
Igor, ich habe irgendwie so das Gefühl Du bist Dir selbst noch nicht so
im klaren was Du eigentlich willst.
Schreib doch mal auf:
Eingangssignal = 1
Wert = 1
DAC = 1
Eingangssignall = 2
Wert = 1
DAC = 1?
Eingangssignal = 4096
Wert = 1
DAC = 2?`
Eingangssignal = 4096
Wert = 4096
DAC = 3?
Jetz Du: 1?, 2? und 3? ??
> Und wenn ich ich es nach der Multiplikation durch 4096 teile ?
Das heißt also die letzten 12 Bits einfach abschneiden. Richtig so.
> Quasi das Ergebniss auf 4096 skaliere??
Das ist jetzt wieder die falsche Denkweise. Du solltest dich mal
tiefgehend mit Festkommaarithmetik beschäftigen: stell dir vor, der
Wert x"000" wäre 0 und der Wert x"FFF" wäre 0,9999. In diesem
Zahlenbereich kann bei einer Multiplikation niemals ein Wert >1
herauskommen. Die Berechnung in der Hardware ist aber genau die selbe
wie für Werte zwischen 0...4095 (=x"000" ... x"FFF"). Daran siehst du,
dass dieses Festhalten an irgendwelchen Zahlenwerten wie z.B. 4096
unsinnig ist.
Sieh dir mal den Beitrag "Re: Festkomma Berechnungen" an
und das davor und das dahinter...
Fazit: das Umrechnen in Dezimalwerte ist nur eine Denkhilfe für uns
Menschen.
>Große Amplitude am Eingang soll auch große Amplitude am Ausgang, kleine>Amplitude am Eingang soll auch kleine Amplitude am Ausgang bedeuten?
kleine Amplitude = kleine Amplitude
große Amplitude = große Amplitude
1 Vpp = 1 Vpp
10 Vpp = 10 Vpp
Wenn man deine Forderungen also wörtlich nimmt dann reicht
Eingangssignal == Ausgangsignal
und das bedeutet man könnte unnötigerweise mit zb. 1 multiplizieren oder
gleich so lassen wie es ist.
Gruß Hagen
Hallo,
also zuerst vielen vielen Dank für die Antworten. Ich versuche es jetzt
nochmal zu erklären.
Ich habe eine LED. Diese blitzt eine Photodiode an. Der Strom der aus
Photodiode kommt wird in Spannung umgewandelt und geht auf ein AD
Wandler auf.
1. Wenn LED nicht leuchtet => Strom an Photodiode 0 (Abgesehn von
Dunkelstrom) somit am AD Wandler spannung 0. ( Einwände ? )
Mein AD Wandler hat ein Bereich von -1 V bis +1 V.
2. Schaltung ist so ausgelegt das wenn LED nicht leuchtet, Strom an
Photodiode 0 => Spannung am AD Wandler -1V. ( Addiere ein Offset)
Zusammengefasst heisst es wenn LED nicht leuchtet kommt am AD Wandler
Spannung -1 V (Was ja den Minimum entspricht). Wenn LED max. Leuchtet
kommt an AD Wandler +1V (Was den Maximum entspricht). ( Einwände?)
Jetzt kommen wir zu verarbeitung:
Ich habe wie schon erwähnt Kurven (Efunktion) mit 12 bit auflösung und
8400 Werte breit im Flashspeicher abgelegt. So wenn meine LED blitzt
(Impuls) soll jeder 8400 Wert der Efunktion mit dem Wert der Amplitude
multipliziert werden. Somit soll wenn ich nur LED nur schwach anblitzt
auch eine in der Amplitude kleiner Efunktion rauskommen. Wenn meine LED
stark Leuchtet/Blitzt soll auch die Efunktion mit der maximalen
AMplitude rauskommen.
Vielleich jetzt verständlicher.
Der AD Wandler arbeitet -1V = "0000000000000"
+1V = "1111111111111"
Somit denk ich das ich die Multiplikaton einfach durch 4096 teile oder ?
also, so wie ich das verstehe brauchst du keine multiplikation. nimm
doch den digitalisierten spannungswert als indizie für den
speicherbereich und liest dementsprechend den wert der efunktion aus und
fertig. oder muss der wert der efunktion zwangsläufig verändert werden?
Nephilim schrieb:
> also, so wie ich das verstehe brauchst du keine multiplikation.
Ich sehe das auch so. Die eigentliche Aufgabe lautet vermutlich:
die logarithimsche Kennlinie der Photodiode soll linearisiert werden.
Wenn das so ist, dann wäre der Ansatz über eine Tabelle mit 4096 Werten
denkbar. Oder auch eine Tabelle mit Stützpunkten und linearer
Interpolation dazwischen.
Hallo,
>also, so wie ich das verstehe brauchst du keine multiplikation.
nein leider nicht. Mein Speicher ist voll mit verschiedenen Kurven. Ich
blitze alle Milisekunde die Photodiode an . Somit bekomme ich quasi eine
Kurvenschar die ich aus den FLASH für jeden Lichtimpuls hole.
Mit der Multiplikation ist es schon richtig gedacht von mir. Wenn die
Intensität von den Impulsen klein ist soll dementsprechend die komplette
Kurvenschar in der Amplitude kleiner erscheinen. Wenn ich mit größerer
Intensität blitze soll die Kurvenschar auch größer in der Amplitude
erscheinen.
Somit frag ich jetzt noch ein mal :), ist dann der Gedanke richtig mit
das Ergebnis durch 4095 teilen?
P.s Ich hab mit dem Multiplikatior gespielt, nur das in der Siumulation
sich nichts tut. Oben ist das BENCH File... kann mir jemand sagen wieso?
Gruß
> Ich wäre echt dankbar,wenn mir jetzt noch jemand helfen würde :(
Dazu wäre es nötig, dein Problem zu verstehen. Ich kapiere das immer
noch nicht: irgendwo liegen irgendwelche Kurvenscharen herum, die mit
irgendwas multipliziert werden sollen und dann über einen DA-Wandler
ausgegeben werden?
Probiers mal mit einer Skizze, denn ein Bild sagt mehr als 1000 Worte...
Vor allem, wieso müssen die "Blitze" (?) mit unterschiedlichen Kurven
multipliziert werden? Worin unterscheiden sich die Blitze außer in der
Amplitude noch voneinander?