Forum: FPGA, VHDL & Co. Umwandlung std_logic_vector to integer alternative


von Chris M. (bloodyboy)


Lesenswert?

hallo zusammen,

ich muss gerade ein Menü für ein Display erstellen in dem ich auch eine 
Adresse eingeben kann.

Es ist eine 32 stellige hex Adresse bei der ich jede Stelle beliebig 
ändern können muss.

nun liegt mein Problem bei der Veränderung der einzelnen Stellen.
Bisher hab ich es so gelöst und funktionert auch:

1
variable adress_h : integer range 0 to 15;                --enthält den wert der zu bearbeitende stelle
2
variable adresse : STD_LOGIC_vector (127 downto 0);       --enthält die gesamte adresse
3
variable courser : integer range 0 to 124 := 0;           --legt fest welche stelle bearbeitet wird
4
5
if oben = '1' and oben_h = '0' then 
6
      adress_h := to_integer (unsigned (adresse(courser +4 downto courser)));                              --z.B. "1001"
7
      adress_h := adress_h +1;                                                                             --adress_h := 9+1
8
      adresse(courser +3 downto courser) := std_logic_vector (to_unsigned(adress_h,4));                    --"1010"
9
      oben_h <= '1';
10
end if;  
11
    
12
if unten = '1' and unten_h = '0' then 
13
      adress_h := to_integer (unsigned (adresse(courser +4 downto courser)));
14
      adress_h := adress_h -1;
15
      adresse(courser +3 downto courser) := std_logic_vector (to_unsigned(adress_h,4));
16
      unten_h <= '1';
17
end if;

nur hab ich nun das Problem, das mein FPGA zu klein wurde und die 
Umwandlung zurück zum std_logic_vector andscheinend ziemlich viel platz 
braucht. (bin mir aber nicht ganz sicher)
Ein anderer FPGA steht mir nicht zur Verfügung.

Deshalb meine Frage: Gibts Alternativen zu der Umwandlung die weniger 
Platz braucht oder kann man die Änderung der Stelle sogar einfacher 
lösen?

Ach ja. Hab erst vor einem Monat angefangen mich mit FPGAs und VHDL zu 
beschäftigen also nich wundern wenn ich nich gleich verstehe was ihr 
meint.

Danke.

Gruß
Chris

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


Lesenswert?

Chris Mayer schrieb:
> nur hab ich nun das Problem, das mein FPGA zu klein wurde und die
> Umwandlung zurück zum std_logic_vector andscheinend ziemlich viel platz
> braucht.
Weil ein Integer genau das selbe wie ein Vektor ist, wird überhaupt 
kein Platz für die "Umwandlung" benötigt. Es ist ja lediglich eine 
andere Darstellung für den Menschen, nicht für /das FPGA/...

Dein Problem liegt also woanders...
Das hier sieht schon mal verdächtig aus:
 variable ... variable ... variable
Wozu die vielen Variablen?

> nur hab ich nun das Problem, das mein FPGA zu klein wurde und die
> Umwandlung zurück zum std_logic_vector andscheinend ziemlich viel platz
> braucht. (bin mir aber nicht ganz sicher)
Häng mal den gesamten Code als *.vhdl Datei hier an. Aus dem 
Code-Fragment oben ist nicht erkennbar, wie da Ressourcen vergeudet 
werden. Aber ich vermute einfach, du hast eine Schleife im Design...

> courser
Meinst du den allseits bekannten "Cursor" oder doch den Vogel?
http://de.wikipedia.org/wiki/Cursor
http://en.wikipedia.org/wiki/Courser

von Chris M. (bloodyboy)


Angehängte Dateien:

Lesenswert?

Danke erstmal für die schnelle Antwort.

Der Code umfasst noch wesentlich mehr und ist warscheinlich nicht 
optimal geschrieben aber mit meinen momentanen Kenntnissen kann ichs 
nicht besser :)

der Code ist im anhang.

Lothar Miller schrieb:
> Weil ein Integer genau das selbe wie ein Vektor ist, wird überhaupt
> kein Platz für die "Umwandlung" benötigt. Es ist ja lediglich eine
> andere Darstellung für den Menschen, nicht für /das FPGA/...
aber wenn ich die eine zeile auskommentiere gehts wieder ohne Probleme.

> Dein Problem liegt also woanders...
> Das hier sieht schon mal verdächtig aus:
>  variable ... variable ... variable
> Wozu die vielen Variablen?
mit signalen hatte ich das problem das auf dem display nicht der 
aktuellste wert angezeigt wurde


>> courser
> Meinst du den allseits bekannten "Cursor" oder doch den Vogel?
> http://de.wikipedia.org/wiki/Cursor
> http://en.wikipedia.org/wiki/Courser

oh :D ich meinte natürlich den Cursor

von Chris M. (bloodyboy)


Angehängte Dateien:

Lesenswert?

hier noch der Aufbau von dem Menü.

Dürfte zum Verständis sehr interessant sein.

von thomas d. (Gast)


Lesenswert?

signal position : integer range 0 to 200000 := 1;    --legt den 
anzuzeigenden text fest
signal LCD : STD_LOGIC_vector (639 downto 0);      --beinhaltet das 
gesamte LCD


hier würde ich zu pufferung greifen..




warum ist
signal lpc_adresse_8_bit : STD_LOGIC_vector (31 downto 0);
signal lpc_adresse_16_bit : STD_LOGIC_vector (63 downto 0);
signal lpc_adresse_24_bit : STD_LOGIC_vector (127 downto 0);
signal lpc_adresse_32_bit : STD_LOGIC_vector (255 downto 0);
8 bit bei dir 32bit breit
16bit 64

usw...

mfg

von Chris M. (bloodyboy)


Lesenswert?

> signal position : integer range 0 to 200000 := 1;    --legt den
> anzuzeigenden text fest
> signal LCD : STD_LOGIC_vector (639 downto 0);      --beinhaltet das
> gesamte LCD
>
>
> hier würde ich zu pufferung greifen..

 kannst du mir das bitte genauer erklären? bin ein vollkommener neuling

> warum ist
> signal lpc_adresse_8_bit : STD_LOGIC_vector (31 downto 0);
> signal lpc_adresse_16_bit : STD_LOGIC_vector (63 downto 0);
> signal lpc_adresse_24_bit : STD_LOGIC_vector (127 downto 0);
> signal lpc_adresse_32_bit : STD_LOGIC_vector (255 downto 0);
> 8 bit bei dir 32bit breit
> 16bit 64
>
> usw...

es sind hex adressen.. die bezeichnung is eigentlich falsch

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


Lesenswert?

Gut, schon mal keine Schleife... ;-)

> das mein FPGA zu klein wurde
Wundert mich nicht, denn die Texte hier wären besser in einem BlockRAM 
aufgehoben:
1
when 1 =>  LCD (639 downto 480) <= (pfeilrechts & space & P & O & S & T & minus & C & O & D & E & minus & T & R & A & C & E & R & space & pfeilrechts);
2
      LCD (479 downto 320) <= (space & space & T & R & I & G & G & E & R & space & E & N & G & I & N & E & space & space & space & space);
3
      LCD (319 downto 160) <= (space & space & B & U & S & minus & D & E & C & O & D & E & R & space & space & space & space & space & space & space);
4
      LCD (159 downto 0) <= empty;
5
      EN <= '1';    
6
when 2 =>  ...
7
when 10004 | 10104 | 10204 | 10304 => ...
8
when 100100 | 101100 | 102100 | 103100 | 100110 | 101110 | 102110 | 103110 | 100120 | 101120 | 102120 | 103120 | 100130 | 101130 | 102130 | 103130 => ...
Und dann müsste nur bei einem Wechsel der Displayseite die passende 
Seite Zeichen für Zeichen und Takt für Takt aus dem RAM geladen werden. 
Denn zur Versorgung eines Displays muss nicht der komplette Inhalt in 1 
Taktzyklus berechnet und geändert werden können. So schnell kann das 
Display es nicht darstellen und erst recht du nicht schauen.

Oder man könnte auch einfach die Displayseite direkt aus dem (DP)RAM ins 
Display laden (so würde ich das machen). Und die Ermittlung der Adressen 
von der Darstellung entkoppeln: du hast jetzt die entsprechenden 
Adressen fest in dein Menü eingebaut, einfacher wäre es, die Adressen 
abhängig von der Cursorpostition und der + oder - Taste zu berechnen, 
und davon entkoppelt ins DP-RAM umzuwandeln, von wo aus sie dann von 
einer ganz anderen "Funktion" im Display dargestellt werden.
Du musst also die Funktionen "Eingabe", "Datenhaltung+Änderung" und 
"Display" voneinander entkoppeln. Sonst ist das Design nicht mehr 
beherrschbar...


Sehr hilfreich wäre besonders auch eine weniger dezimale Nummerierung 
der Seiten. Da muss der Synthesizer viel rechnen und optimieren (wenn er 
es denn kann):
1
-- hier
2
if position /= 100000 and position /= 101000 and position /= 102000 and position /= 103000
3
and position /= 100100 and position /= 101100 and position /= 102100 and position /= 103100
4
and position /= 100110 and position /= 101110 and position /= 102110 and position /= 103110 
5
and position /= 100120 and position /= 101120 and position /= 102120 and position /= 103120
6
and position /= 100130 and position /= 101130 and position /= 102130 and position /= 103130 then  
7
8
-- und da auch:
9
10
when 100100 | 101100 | 102100 | 103100 | 100110 | 101110 | 102110 | 103110 | 100120 | 101120 | 102120 | 103120 | 100130 | 101130 | 102130 | 103130 =>
Wenn du die Nummerierung binär angegangen wärst, dann müsste er nur ein 
paar Bits ausmaskieren und fertig. So muss er erst mal 
Gemeinsamkeiten dieser Dezimalzahlen finden und dann einen möglichst 
kompakten Term ausrechnen. Wehe, wenn du da nur 1 Seite dazuschreibst: 
dann kann was viel Einfacheres oder auch was viel Komplizierteres 
herauskommen. Das merkst du dann sofort am Timing...

BTW: welches FPGA hast du denn?

von Chris M. (bloodyboy)


Lesenswert?

vielen dank erstmal das du dir das alles anschaust.

ich arbeite mit dem MachXO2 Breakout Board von Lattice.
Es ist der LCMXO2-7000HE-4TG144C FPGA drauf.

könntest du das mit dem BlockRam vielleicht erklären wie ich das 
umsetzte?

und bei den dezimalzahlen werd ich mir was überlegen.

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


Lesenswert?

Chris Mayer schrieb:
> könntest du das mit dem BlockRam vielleicht erklären wie ich das
> umsetzte?
Lies dir mal die TN1201 durch
http://www.latticesemi.com/documents/TN1201.pdf

Den ersten Schritt hast du ja schon gemacht:
1
        if char_low = 0 then
2
          EN <= '0';
3
          char_low <= 632;
4
          char_high <= 639;
5
        else
6
          char_low <= char_low -8;
7
          char_high <= char_high -8;
8
        end if;  
9
        
10
      end if;
11
12
      char <= LCD (char_high downto char_low);
Hier werden die Displaydaten aus einem Puffer namens LCD Zeichen für 
Zeichen auf die Anzeige ausgegeben. Und jetzt sorgst du dafür dass 
dieser Puffer in ein EBR kommt. Und über den zweiten Port des Dual Port 
EBR kannst du die anzuzeigenden Werte hineinschreiben. Es reicht aus, 
wenn du das 5-10 Mal pro Sekunde machst. Schneller kann kein Mensch 
schauen. Und schneller wird das Display nicht aktualisiert...

von Chris M. (bloodyboy)


Lesenswert?

ich habe jetzt mir das ganze jetzt mal angeschaut aber was mich noch 
wundert ist wenn ich nur alles was mit der Adresseingabe zutun hat 
auskommentiere bin ich nur noch bei 37% wobei ich mit bei 180% bin.

kann des daran liegen, dass ich auf der letzten display seite fast ne 
reine variable hab?

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


Lesenswert?

Chris Mayer schrieb:
> kann des daran liegen, dass ich auf der letzten display seite fast ne
> reine variable hab?
Es wird damit zu tun haben, dass du dann keine konstanten Werte mehr 
hast, sondern durch den schreibenden Zugriff noch Multiplexer brauchst, 
um auf das Display zu kommen.

> wenn ich nur alles was mit der Adresseingabe zutun hat auskommentiere
Zeig doch mal...

von Chris M. (bloodyboy)


Lesenswert?

> Zeig doch mal...

hab grad nochma geschaut es reicht schon wenn ich das auskommentier:
1
when 100100 | 101100 | 102100 | 103100 | 100110 | 101110 | 102110 | 103110 | 100120 | 101120 | 102120 | 103120 | 100130 | 101130 | 102130 | 103130 =>
2
      LCD (639 downto 480) <= empty;
3
      LCD (479 downto 320) <= (space & space & adresse_ascii(255 downto 128) & space & space);
4
      LCD (319 downto 160) <= empty;
5
      LCD (159 downto 0) <= (space & space & adresse_ascii(127 downto 0) & space & space);
6
      EN <= '1';

oder des:
1
    if oben = '1' and oben_h = '0' then 
2
      adress_h := to_integer (unsigned (adresse(courser downto courser -4)));
3
      adress_h := adress_h +1;
4
      adresse(courser downto courser -4) := std_logic_vector (to_unsigned(adress_h,32));
5
      oben_h <= '1';
6
    end if;  
7
    
8
    if unten = '1' and unten_h = '0' then 
9
      adress_h := to_integer (unsigned (adresse(courser downto courser -4)));
10
      adress_h := adress_h -1;
11
      adresse(courser downto courser -4) := std_logic_vector (to_unsigned(adress_h,32));
12
      unten_h <= '1';
13
    end if;

dadurch bin ich auch auf den schluss gekommen das es an der umwandlung 
liegen könnte

von Chris M. (bloodyboy)


Lesenswert?

es reicht auch wenn ich nur die beiden zeilen auskommentiere:
1
    if oben = '1' and oben_h = '0' then 
2
      adress_h := to_integer (unsigned (adresse(courser downto courser -4)));
3
      adress_h := adress_h +1;
4
      --adresse(courser downto courser -4) := std_logic_vector (to_unsigned(adress_h,32));
5
      oben_h <= '1';
6
    end if;  
7
    
8
    if unten = '1' and unten_h = '0' then 
9
      adress_h := to_integer (unsigned (adresse(courser downto courser -4)));
10
      adress_h := adress_h -1;
11
      --adresse(courser downto courser -4) := std_logic_vector (to_unsigned(adress_h,32));
12
      unten_h <= '1';
13
    end if;

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.