Forum: FPGA, VHDL & Co. Rampe mit zwei Grenzwerten


von Alex (Gast)


Lesenswert?

Hallo,

ich bin auf der Suche nach einer schnellen und effizienten Lösung zur 
Realisierung einer Rampenfunktion von Grenzwert G1 bis Grenzwert G2.

Ich habe 24bit als Eingang und 12bit als Ausgang.
Wäre eigentlich ein klassischer Fall für eine LUT, aber die Grenzwerte 
sind variabel und die LUT frisst mit 24x12bit auch recht viel Platz.
Also bleibt nur die Variante die Rampenfunktion abhängig der Granzwerte 
zu berechnen.

Eigentlich könnte man ja prinzipiell so vorgehen:
1
G-Differenz = G2 - G1;
2
if G-Differenz < 4095 then -- Anstieg größer 1
3
   Schrittweite = 4095/G-Differenz;
4
elsif G-Differenz > 4095 then -- Anstieg kleiner 1
5
   Schrittweite = G-Differenz/4095;
6
else -- Anstieg gleich 1
7
   Schrittweite = 1;
8
end if;
9
10
-- Wert über G1 bestimmen
11
Eingang_scal <= Eingang - G1;
12
-- skalierter Eingang mit Anstieg multiplizieren
13
Ausgang <= Eingang_scal * Schrittweite;

Nun habe ich natürlich die in VHDL eher unschönen Rechenarten 
Multiplikation und Division dabei.
Man könnte alles ungenauer machen und alles auf 2er Potenzen festnageln 
und dann nur noch shiften, aber gerade bei größeren Abständen der 
Grenzwerte (im worst case Rampe vom minimalen zum maximalen Eingang) 
dürfte es sehr ungenau werden.

Gibt es vielleicht eine Lösung, die nur mit shiften und Addition 
auskommt?
Könnte mir vorstellen, dass solche Rampenfunktionen häufiger Anwendung 
finden (Schrittmotoren?).

Vielen Dank!
Alex

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Alex schrieb:
> einer Rampenfunktion von Grenzwert G1 bis Grenzwert G2.
Die jeweils wie breit sind? 12 Bit, oder?

> Ich habe 24bit als Eingang und 12bit als Ausgang.
Und mit dem 24-Bit-Wert soll ein Wert zwischen dem unteren und dem 
oberen Grenzwert linear interpoliert werden?

> Nun habe ich natürlich die in VHDL eher unschönen Rechenarten
> Multiplikation und Division dabei.
Eigentlich nur die Division ist unschön.

Wenn sich die Grenzwerte nicht allzuoft ändern, dann kannst du doch 
problemlos dividieren...
1
elsif G-Differenz > 4095 then -- Anstieg kleiner 1
2
   Schrittweite = G-Differenz/4095;
Ich vermute sehr, dass diese Division durch 4095 falsch ist. Vermutlich 
müsste da bei genauer Betrachtung 4096 stehen. Das wird bei AD-Wandlern 
auch gern falsch gemacht.
Aber halb so schlimm: damit bekommst du nur 1/4 Promille Fehler...  ;-)

von SeriousSam (Gast)


Lesenswert?

Such mal nach Bresenham's Algorithmus. Ist aus der Computergrafik zum 
Zeichnen von Linien auf diskretem Raster. Ich könnte mir vorstellen, 
dass du da etwas anpassen kannst.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

SeriousSam schrieb:
> Such mal nach Bresenham's Algorithmus.
Kam mir auch in den Sinn, aber das funktioniert nur, wenn eine Rampe 
erzeugt werden soll. Wenn also irgendwas schrittweise hochläuft. Hier 
gehts aber eher um den Ersatz einer Lookup-Tabelle mit einer 
Geradengleichung...

von SeriousSam (Gast)


Lesenswert?

Wenn ichs mir nochmal durchlese macht das Sinn, ja. Ein Bereich zw. zwei 
24bit Werten soll auf 12 bit abgebildet werden. Ich würde sagen die 
Steigung ist immer 4096/Diff. (=>Fehler im Eingangspost) Wenn die volle 
LUT nicht in Frage kommt gibt es ja immer noch verschiedene 
Näherungsvarianten. (Stückweise linear, (lineare/quadratische/...) 
Interpolation, ...) Je nach Anforderungen an Genauigkeit und Latenz 
lässt sich sicher was finden.

von J. S. (engineer) Benutzerseite


Lesenswert?

SeriousSam schrieb:
> ist immer 4096/Diff. (=>Fehler im Eingangspost)
das hätte ich nun aber auch gesagt

Du musst aber auch den Steigungsvektor genau berechnen und da braucht es 
mehr, als die 12 bit, wegen der Eingangsgenauigkeit und der 
Runddungsproblematik. Du solltest mit > 4096*4096/Differenz rechnen, um 
zum Inkrement zu gelangen und anschließend den akkumulierten Wert der 
sich ergibt, auf 4095 herunterbrechen. Wenn Du es ganz genau machen 
willst, brauchst Du einen 36 Bit Akku und je nach möglichem 
Eingangsbeeich auch einen 36 Bit Vekttor fürs Inkrement.

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
Noch kein Account? Hier anmelden.