Forum: FPGA, VHDL & Co. Inverse Look-Up-Table in VHDL


von Klabauter (Gast)


Lesenswert?

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
type Rom16x8 is array (0 to 31) of integer range 0 to 1909; 
2
3
constant Gamma_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?

von Bego (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Duke Scarring (Gast)


Lesenswert?

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:
1
    function pwm_table( value: natural range 0 to 63) return natural is
2
        variable result: natural range 0 to max_pwm_table_value; 
3
    begin
4
        result := (value * value) / 4;
5
        return result;
6
    end function pwm_table;

Duke

von Klabauter (Gast)


Lesenswert?

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.

von Robert K. (Firma: Medizintechnik) (robident)


Lesenswert?

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.

von Bongo (Gast)


Lesenswert?

Heron / Newton oder schriftliches Wurzelziehen.

http://www.arndt-bruenner.de/mathe/scripts/wurzelziehen.htm

von Markus F. (mfro)


Lesenswert?

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:
1
   gen_loop:
2
    FOR i IN 0 TO gamma_rom'HIGH - 1 GENERATE
3
        p_map : PROCESS
4
        BEGIN
5
            WAIT UNTIL rising_edge(clk);
6
7
            IF map_value >= gamma_rom(i) and map_value < gamma_rom(i + 1) THEN
8
                result <= std_logic_vector(to_unsigned(i, 32));
9
            ELSE
10
                result <= (OTHERS => 'Z');
11
            END IF;
12
        END PROCESS p_map;
13
    END GENERATE gen_loop;

von Robert K. (Firma: Medizintechnik) (robident)


Lesenswert?

Inwiefern wäre das "platzsparender"?

von Jürgen S. (engineer) Benutzerseite


Lesenswert?

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.

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.