Forum: FPGA, VHDL & Co. Variable Wert aus Array zuweisen


von Michael B. (mbauswhv)


Lesenswert?

Hallo zusammen


ich bin gerade dabei mit einem FPGA-Bord eine LED-Matrix anzusteuern.
Die 8 Zeilen werden durch 3 Ausgänge angesprochen. Ich möchte gerne die 
Zeilenauswahl durch ein Array realisieren. Das initalisieren des Arrays 
habe ich hin bekommen aber leider bekomme ich die zuweiung der Ausgänge 
nicht hin.

architecture Behavioral of Steuer is

type BIT_3 is array (0 to 2) of std_logic ;
type FELD_3mal8 is array (0 to 7) of BIT_3;
signal ZEILEN: FELD_3mal8 := ("000","100" 
,"010","110","001","101","011","111" );
signal cnt : unsigned (4 downto 0) := (others=>'0');


begin



 process (Takt) begin
    if rising_edge (Takt) then
       if(cnt<8) then cnt <=cnt+1;
       else       cnt <=  (others => '0')
       end if;
    end if;
  end process;

A<= ZEILEN (cnt,0);
B<= ZEILEN (cnt,1);
C<= ZEILEN (cnt,2);


end architecture Behavioral;



Wie bekomme ich das hin , dass ich A den Wert Zeilen [i][0], B  den Wert
Zeilen [i][1] und C den Wert Zeilen [i][2] zuweisen kann.

Ich danke schonmal für die Hilfe

MfG Michael

von Pat A. (patamat)


Lesenswert?

Hallo Michael,

so müsste es funktionieren:

A<= ZEILEN(to_integer(cnt))(0);
B<= ZEILEN(to_integer(cnt))(1);
C<= ZEILEN(to_integer(cnt))(2);

Aber es wäre einfacher, A, B und C zu einem Vektor zusammenzufassen, den 
Counter von 0 bis 7 laufen zu lassen und dann sofort ohne Umwege über 
das Array auf den Std-Logic-Vector zu casten:

...
CBA : out std_logic_vector(2 downto 0);
...
signal cnt : unsigned (2 downto 0) := (others=>'0');
...

CBA <= std_logic_vector(cnt);

...

Aber das war ja nicht die Frage ;-)

mfg, PataMat

von Christoph Z. (christophz)


Lesenswert?

Michael Berger schrieb:
> signal cnt : unsigned (4 downto 0) := (others=>'0');

Pat a Mat schrieb:
> A<= ZEILEN(to_integer(cnt))(0);

Ich denke, das sollte so gehen. Find das aber für diesen Zweck etwas 
umständlich. Du kannst deinen Zähler ja auch gleich direkt mit einem 
Bereichsbegrenzten Integer definieren:
1
signal cnt : integer range ZEILEN'range ;  *
2
[...]
3
A<= ZEILEN (cnt,0);

* Falls du mal auf "downto" Ordnung umstellen willst aber die 
Zählervariable doch aufsteigend definieren möchtest:
1
signal cnt : integer range ZEILEN'low to ZEILEN'high ;

von Michael B. (mbauswhv)


Lesenswert?

Danke für die Hilfe

ich werde es nachher gleich mal ausprobieren und das ergebniss Posten.

Das mit dem Vector ABC habe ich mir auch schon überlegt, aber das 
problem ist, dass die Zeilen nicht binär hochgezählt werden, die haben 
in den Registern in der LED-Matrix eine "komische" Reihenfolge, deswegen 
musste ich das mit dem Array machen .


Wenn ich das mit der range mache , setzt er sich dann wieder automatisch 
auf 0 zurück wenn er das Ende der Range ereicht hat, oder muss ich das 
manuel machen .


Danke

MfG Michael

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


Lesenswert?

Michael Berger schrieb:
> aber leider bekomme ich die zuweiung der Ausgänge nicht hin.
Welche Fehlermeldung bekommst du denn?

> signal cnt : unsigned (4 downto 0) := (others=>'0');
>  A <= ZEILEN (cnt,0);
Auf Arrayelemente kann nur mit Integern zugegriffen werden. Also musst 
du aus deinem unsigned Vektor noch einen Integer machen:
http://www.lothar-miller.de/s9y/categories/16-Numeric_Std

von Christoph Z. (christophz)


Lesenswert?

Michael Berger schrieb:
> Wenn ich das mit der range mache , setzt er sich dann wieder automatisch
> auf 0 zurück wenn er das Ende der Range ereicht hat, oder muss ich das
> manuel machen .

Gute Frage, weiss ich leider nicht, müsste ich mal ausprobieren.
Habe mir angewöhnt sowas immer explizit hinzuschreiben, dann ist es dem 
leser klar, die Tools machen auch sicher was sie sollen (und ich komme 
mit meiner Vergesslichkeit nicht in Konflikt :-)).

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


Lesenswert?

Michael Berger schrieb:
> Wenn ich das mit der range mache , setzt er sich dann wieder automatisch
> auf 0 zurück
Nein. Die 'range Angabe ist nur für 2 Dinge gut:
1. Bereichsüberwachung im Simulator
2. Bereichseinschränkung für den Synthesizer.
Dann müssen nicht hinterher 28 Bits eines Integers wegoptimiert werden, 
wenn z.B. der 'range nur 0..9 ist...

: Bearbeitet durch Moderator
von Michael B. (mbauswhv)


Lesenswert?

ich habe es jetzt nochmal ausprobiert ,allerdings ohne die Range , das 
proviere ich , wenn ich das andere zum laufen bekommen haben

1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_arith.all;
4
use ieee.std_logic_unsigned.all;
5
use ieee.numeric_std.all;
6
7
8
entity Steuer is
9
    Port ( Takt : in  STD_LOGIC;
10
           ZEILE : out  STD_LOGIC_VECTOR (2 downto 0);
11
        Spalte : out  STD_LOGIC_VECTOR (5 downto 0);
12
        
13
        A : out  STD_LOGIC;
14
           B : out  STD_LOGIC;
15
           C : out  STD_LOGIC);
16
end Steuer;
17
18
architecture Behavioral of Steuer is
19
20
type BIT_3 is array (0 to 2) of std_logic ;
21
type FELD_3mal8 is array (0 to 7) of BIT_3;
22
signal ZEILEN: FELD_3mal8 := ("000","100" ,"010","110","001","101","011","111" );
23
signal ZEILE_COUNT : STD_LOGIC_VECTOR (2 downto 0) := ("000");
24
signal Spalte_COUNT : STD_LOGIC_VECTOR (5 downto 0) := ("000000");
25
26
begin
27
28
29
30
 process (Takt) begin
31
    if rising_edge (Takt) then
32
       if(Spalte_COUNT<="100000") then 
33
      Spalte_COUNT <=Spalte_COUNT+1; 
34
       else  Spalte_COUNT <=  ("000000"); ZEILE_COUNT<=ZEILE_COUNT+1;
35
     
36
     if (ZEILE_COUNT<="111" ) then 
37
      ZEILE_COUNT <="000";
38
     end if;
39
       end if;
40
    end if;
41
  end process;
42
 
43
--k <= to_integer(unsigned(ZEILEN_COUNT));
44
--k := to_integer(unsigned(ZEILEN_COUNT));
45
46
A<= ZEILEN(to_integer(ZEILE_COUNT))(0); --(73)
47
B<= ZEILEN(to_integer(ZEILE_COUNT))(1);  --(74)
48
C<= ZEILEN(to_integer(ZEILE_COUNT))(2);  --(75)
49
50
ZEILE <=ZEILE_COUNT;
51
Spalte<= Spalte_COUNT;
52
53
54
end architecture Behavioral;




ERROR:HDLCompiler:432 - 
"C:\Users\Admin\Desktop\BA-VHDL\Steuerung\Steuer.vhd" Line 73: Formal 
<arg> has no actual or default value.


ERROR:HDLCompiler:541 - 
"C:\Users\Admin\Desktop\BA-VHDL\Steuerung\Steuer.vhd" Line 73: Type 
integer is not an array type and cannot be indexed.



Das sind meine  Fehler die ich angeeit bekomme, die gleichen Fehler 
habe ich in den Zeilen  (74) (75).

Habe ich vielleicht vergessen eine library einzubinden

: Bearbeitet durch Moderator
von Duke Scarring (Gast)


Lesenswert?

Michael Berger schrieb:
> library ieee;
> use ieee.std_logic_1164.all;
> use ieee.std_logic_arith.all;
> use ieee.std_logic_unsigned.all;
> use ieee.numeric_std.all;

Die folgenden Bibliotheken reichen völlig:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;



Michael Berger schrieb:
> Habe ich vielleicht vergessen eine library einzubinden
Nein, aber die Typkonvertierung passt so nicht.
Dazu wird immer wieder gern folgendes zu lesen empfohlen:
http://www.lothar-miller.de/s9y/categories/16-Numeric_Std

von Michael B. (mbauswhv)


Lesenswert?

Danke erstmal an alle  für die Tips.
Ich denke ich muss da erstmal noch ein bischen lesen und verstehen.

ich melde mich wenn ich das Problem gelöst habe .

Danke nochmal

MfG Michael

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


Lesenswert?

Michael Berger schrieb:
> Habe ich vielleicht vergessen eine library einzubinden
Du hast zuallererst die [ vhdl ] und [ /vhdl ] Tags (ohne die 
Leerzeichen in der Klammer) am Anfang und Ende deines VHDL-Codes 
vergessen. Ich habe die mal nachgetragen...

> A<= ZEILEN(to_integer(ZEILE_COUNT))(0);
Was ist ZEILE_COUNT?
Wie bekommt man daraus einen Integer?


BTW: ich mache Zähler immer mit eingeschränkten Integern und konvertiere 
die dann zur Ausgabe, denn dann liest sich eine Zuweiseung und ein 
Vergleich gleich ganz anders:
1
-- mit Vektoren
2
  if counter = "110001001110001" then
3
     counter <= "000010000110110"
4
-- oder mit Integern
5
  if counter = 25201 then
6
     counter <= 1078;

: Bearbeitet durch Moderator
von Michael B. (mbauswhv)


Lesenswert?

Hallo zusammen .

Weihnachten ist vorbei und ich hatte wieder Zeit zu arbeiten.
Dank eurer Hilfe habe ich mein Problem gelöst .
Ich habe es mit der Range ausprobiert  und wenn das Ende der Range 
erreicht ist wird automatisch zum Anfang der Range zurückgesetzt.
Das spart natürlich die Abfrage ob das Ende erreicht ist .

1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_arith.all;
4
use ieee.std_logic_unsigned.all;
5
use ieee.numeric_std.all;
6
7
8
entity Steuer is
9
    Port ( TAKT : in  STD_LOGIC;
10
           ZEILE : out  STD_LOGIC_VECTOR (2 downto 0);
11
        Spalte : out  std_logic_Vector (5 downto 0);
12
        OE :out std_logic;
13
        LAT: out std_logic;
14
        A : out  std_logic;
15
           B : out  STD_LOGIC;
16
           C : out  STD_LOGIC);
17
end Steuer;
18
19
architecture Behavioral of Steuer is
20
21
type BIT_3 is array (0 to 2) of std_logic ;
22
type FELD_3mal8 is array (0 to 7) of BIT_3;
23
signal ZEILEN: FELD_3mal8 := ("000","100" ,"010","110","001","101","011","111" );
24
signal ZEILE_COUNT : std_LOGIC_vector  (2 downto 0) := ("000");
25
signal Spalte_COUNT :STD_LOGIC_VECTOR (5 downto 0) := ("000000");
26
27
28
29
signal CNT : integer  range 0 to 7 := 0;
30
31
32
begin
33
34
35
36
 process (TAKT) begin
37
 
38
39
 
40
    if rising_edge (TAKT) then   
41
       if (Spalte_COUNT>"011111") then 
42
       Spalte_COUNT <=  "000000"; 
43
         --ZEILE_COUNT<=ZEILE_COUNT+1;
44
         
45
         CNT<= CNT+1;
46
         
47
         
48
          OE <= '1';
49
          LAT <= '1';
50
         
51
       else
52
         
53
          Spalte_COUNT <=Spalte_COUNT+1;
54
          OE <= '0';
55
          LAT <= '0';
56
     
57
58
     
59
     end if;
60
       end if;
61
    
62
  end process;
63
 
64
65
66
A<= ZEILEN(CNT)(0);  
67
B<= ZEILEN(CNT)(1);  
68
C<= ZEILEN(CNT)(2);  
69
70
ZEILE <=ZEILE_COUNT;
71
Spalte<= Spalte_COUNT;
72
73
74
end architecture Behavioral;


Ich habe es jetzt auf ein DIGILENT NEXYS2 Bord programmiert. Es tut was 
ich ihm gesagt habe .
Mich wundert nur , dass ich folgende Fehlermeldung bekomme:

Signal <ZEILEN> is used but never assigned. Tied to default value.



Ich bedanke mich für die schnelle und gute Hilfe

MfG Michael

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


Lesenswert?

1
use ieee.std_logic_arith.all;
2
use ieee.std_logic_unsigned.all;
3
use ieee.numeric_std.all;
Viel hilft viel, oder wie?
Hast du den Post im Beitrag "Re: Variable Wert aus Array zuweisen"
[ ] nicht gesehen?
[ ] nicht verstanden?
Wenn du damit irgendwann seltsame unerklärliche Effekte wegen doppelter 
Typdefinitionen bekommst, dann such hier im Forum mal nach 
"std_logic_arith obsolete"...

Und es taucht immer wieder auf:
Beitrag "Re: Syntaxfehler bei Simulation, kein Syntaxfehler bei Synthese"

Michael Berger schrieb:
> Signal <ZEILEN> is used but never assigned. Tied to default value.
Der Synthesizer hat erkannt, dass diese Beschreibung hauptsächlich 
NICHTS macht, und hat den Ausgängen A,B,C einfach direkt die Werte 
"000", "100" und "010" zugewiesen. Und der Rest von ZEILEN wird eh' 
niemals verwendet...

von Michael B. (mbauswhv)


Lesenswert?

Hallo  Lothar

gelesen, verstanden und noch einmal nachgelesen und dann vergessen. Habe 
ich gerade geändert .


Lothar Miller schrieb:
> Der Synthesizer hat erkannt, dass diese Beschreibung hauptsächlich
> NICHTS macht, und hat den Ausgängen A,B,C einfach direkt die Werte
> "000", "100" und "010" zugewiesen. Und der Rest von ZEILEN wird eh'
> niemals verwendet...

Es werden alle 8 Kombinationen verwendet . Ist es schlimm, dass er 
"NICHTS" macht ,oder muss ich da noch was ändern.


Werden die seldsamen Effekte nur auftreten wenn ich std_logic_arith 
benutzte (habe ich gerade rausgenommen ), oder habe ich da noch andere 
Fehler drin .

Was sagst du denn im Allgemein zu dem Programm. Das ist ein erstes 
großes Projekt mit VHDL . Ist der Stil OK oder kann man da noch etwas 
verbessern   Ich bin für jeden Tip dankbar.

MfG Michael

von Duke Scarring (Gast)


Lesenswert?

Michael Berger schrieb:
> Ist der Stil OK oder kann man da noch etwas
> verbessern
Da kann man noch einiges verbesser. Wie sieht denn Deine Definition von 
Spalte_COUNT jetzt aus, nachdem Du die unsägliche arith rasugenommen 
hast?

Duke

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


Lesenswert?

Michael Berger schrieb:
>> Und der Rest von ZEILEN wird eh' niemals verwendet...
> Es werden alle 8 Kombinationen verwendet .
Nicht im geposteten Code...

> Werden die seldsamen Effekte nur auftreten wenn ich std_logic_arith
> benutzte
Nein. Ob ein Signal unbenutzt ist oder nicht, das hängt nicht von der 
verwendeten Arithmetik-Bibliothek ab.

> oder habe ich da noch andere Fehler drin .
Von welchem Code reden wir?

> Was sagst du denn im Allgemein zu dem Programm.
Es ist KEIN Programm! Denn VHDL ist keine Programmiersprache, sondern 
eine Beschreibungssprache. Denn sonst müsste VHDL ja eher VHPL heissen.

> Ist der Stil OK oder kann man da noch etwas verbessern
Das ist, wie wenn du jemand durchs Schlüsselloch spicken lässt und 
frägst: gefällt dir mein Haus? Kurz: aus dem Schnipsel kann man nichts 
sagen, ausser dass die Verwendung von Groß- und Kleinschreibung 
inkonsistent ist...

: Bearbeitet durch Moderator
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.