Ich bin durch ein Projekt mit einer LED-Anzeige auf folgendes Problem
gestoßen. Da bei der farbechten Ansteuerung von LEDs eine Gammakorrektur
von nöten ist, hatte ich im ersten Durchlauf ein Look-Up-Tabelle
implementiert, die nach dem Auslesen aus einem Bus und VOR dem
Abspeichern der Daten in einen Bildpuffer die Farbwerte ersetzt.
Die sah dann wie folgt aus:
1
typeRom16x8isarray(0to31)ofintegerrange0to1909;
2
3
constantGamma_Rom:Rom16x8:=(
4
0,1,4,11,
5
21,34,51,72,
6
97,125,158,195,
7
236,282,332,386,
8
445,509,577,650,
9
728,810,898,990,
10
1087,1189,1297,1409,
11
1526,1649,1776,1909
12
);
Dies war vorerst in der Simulation gut zu gebrauchen. Da es später aber
das Probleme gab, dass die Ansammlung der Daten zu groß wurde habe ich
beschlossen die Gammakorrektur nach dem Abspeichern durchzuführen. Durch
einen Vergleich mit einem Zähler wird so die PWM-Zeit festgelegt.
Da dies aber später auch zu Problemen führte, weil es nötig war mehrere
LUTs für einen parallelen Vergleich zu benutzen, wollte ich die
Gammakorrektur nicht bei den Farbwerten durchführen sondern die
Inversion bei dem Zähler durchführen.
Für den Zählerwert 0 soll demnach eine 0 ausgegeben werden. Für den
Zählerwert 1-3 soll eine 1 ausgegeben werden. Für den Zählerwert 4-10
eine 2 usw...
Gibt es eine Möglichkeit, in Hinblick auf eine mögliche Erweiterung auf
256 Tabellenwert, diese inverse LUT resourcensparend zu implementieren?
Du kannst das exakt so formulieren und der Synthese die passende
Zusammenfassung der Adressedekodierung überlassen.
Oder Du schreibt ein stufenförmiges IF/ELSIF-Then Konstrukt, wie o.a.
Solche monotonen Kurven implementiert man aber in VHDL besser mit einer
quadratischen Kurve, da ist dann die Interpolation gleich miterledigt.
Klabauter schrieb:> Gibt es eine Möglichkeit, in Hinblick auf eine mögliche Erweiterung auf> 256 Tabellenwert, diese inverse LUT resourcensparend zu implementieren?
Hast Du Multiplizierer übrig?
Wenn ja, kannst Du es z.B. so machen:
Bego schrieb:> Du kannst das exakt so formulieren und der Synthese die passende> Zusammenfassung der Adressedekodierung überlassen.>> Oder Du schreibt ein stufenförmiges IF/ELSIF-Then Konstrukt, wie o.a.>> Solche monotonen Kurven implementiert man aber in VHDL besser mit einer> quadratischen Kurve, da ist dann die Interpolation gleich miterledigt.
Kann man eine Wurzel in VHDL implementieren? Das wäre ja was. Jedoch
müsste die Wurzelberechnung innerhalb eines Taktes abgeschlossen sein.
Das Mega-If-Then-Else-Konstrukt würde ich gernen umgehen...
Duke Scarring schrieb:> Klabauter schrieb:>> Gibt es eine Möglichkeit, in Hinblick auf eine mögliche Erweiterung auf>> 256 Tabellenwert, diese inverse LUT resourcensparend zu implementieren?> Hast Du Multiplizierer übrig?>> Wenn ja, kannst Du es z.B. so machen: function pwm_table( value: natural
range 0 to 63) return natural is
> variable result: natural range 0 to max_pwm_table_value;> begin> result := (value * value) / 4;> return result;> end function pwm_table;>> Duke
Ja ich hätte multiplizierer übrig. Jedoch versteh ich ganz ehrlich
nicht, wie mir das helfen sollte. Die Umrechnung von Eingangs- zu
Ausgangswert wäre das Potenzieren mit dem Wert 2,2 (üblicher
Gammakorrekturwert, siehe http://de.wikipedia.org/wiki/Gammakorrektur).
Nach der inversen Gammakorrektur müsste ich theoretisch die 2,2te Wurzel
ziehen.
Klabauter schrieb:> die 2,2te Wurzel
... was auf ein entsprechendes Potenzieren hinaus liefe.
>Kann man eine Wurzel in VHDL implementieren?
Ja, in der Regel ist die implementiert.
Man könnte es gfs umrechnen:
Wurzel2,2(X) = Potenz(X/2,2) = Potenz (0,9090..*X / 2)
= Potenz ( (1-0,09090) * X /2)
= Potenz ( (X/2 - 0,0909X /2)
= Potenz (X/2) / Potenz (0,04545 X)
= Wurzel (X) / Potenz (v.o.) <- = Potenz (1/10 v.o.)
Das müsste man rekursiv fomrulieren können.
Klabauter schrieb:> Für den Zählerwert 0 soll demnach eine 0 ausgegeben werden. Für den> Zählerwert 1-3 soll eine 1 ausgegeben werden. Für den Zählerwert 4-10> eine 2 usw...>> Gibt es eine Möglichkeit, in Hinblick auf eine mögliche Erweiterung auf> 256 Tabellenwert, diese inverse LUT resourcensparend zu implementieren?
Ressourcensparend ist was anderes, aber Du könntest dir ein Gatternetz
basteln, das das richtige Ergebnis ausspuckt:
Ich habe festgestellt, dass Xilinx neuerdings kein Federlesen mehr macht
und alles fleißig in ein ROM schaufelt, auch wenn per Dekodierung in
LUTs noch viel komprimierbar gewesen wäre.