mikrocontroller.net

Forum: FPGA, VHDL & Co. Hardware Multiplikation


Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:


Port Map (
        
        clk              =>  CLK_20MHZ  ,    
        ce               =>  '1',
        sclr             =>  '1',
        bypass           =>  '1',  
        a                => EINGANG_AD_WANDLER,
        b                =>  "000000000001",
        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ß

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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".

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Igor (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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 
?

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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


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);

usw. 



ich weiß das der Code oben nicht ganz korrekt ist, mir geht es jetzt nur 
ums prinzip.



Gruß

Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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-...

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

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ....?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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... :(

Autor: Nephilim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lassen wie es ist???

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mit 1 multiplizieren ?

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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? ??

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ?

Autor: Nephilim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: Igor (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich wäre echt dankbar,wenn mir jetzt noch jemand helfen würde :(


gruß

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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...

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vor allem, wieso müssen die "Blitze" (?) mit unterschiedlichen Kurven 
multipliziert werden? Worin unterscheiden sich die Blitze außer in der 
Amplitude noch voneinander?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.