Forum: FPGA, VHDL & Co. Probleme mit undefinierten Bits in STD_LOGIC Vektoren


von Klaus K. (yildi)


Angehängte Dateien:

Lesenswert?

Hallo!
Ich habe ein großes Problem, das mich schon seit Tagen an den Rande der 
Verzweiflung bringt. Es geht um ein Spiel, welches in VHDL umgesetzt 
werden sollte und so funktionieren soll:

- Über 4 Schalter (ZIEL) ist vor Spielbeginn ein Testmuster einzustellen
- Nach Betätigung der RESET-taste beginnt das Spiel, d.h. mittels 
Pseudozufallsgenerator werden an 4 Leuchtdioden (MUSTERLED) verschiedene 
Muster ausgegeben.
- Beim visuellen Erkennen des Testmusters (ZIEL) müssen die beiden 
Spieler ihren prellfreien Taster betätigen (BUTTON_1 und BUTTON_2)
- Drückt man zu früh wird ein Fehlersignal ausgegebe und das Spiel 
unterbrochen. ANdernfalls wird ein Timer gestartet, um die verstrichende 
Zeit zwischen der Darstellung des Testmusters und der Betätigung des 
Tasters in Balkenform (ZEITBALKENLED) anzuzeigen.

Soweit die Aufgabenstellung (erstmal mit 4 Bit Mustern). Daraus habe ich 
dann einen Autoamtengraphen entwickelt (im Anhang zu sehen). Danach 
haben wir dann das VHDL Programm geschrieben. Eigentlich funktioniert es 
auch schon, bzw. hat es teilweise mal kurz. Nur eben sehr 
unzuverlässig.. es macht was es will.. ganz unbeschreiblich und 
unberechenbar. Also auf dem richtigen Weg scheinen wir zu sein. Probleme 
treten seltsamerweise immer auf, wenn wir zum Beispiel die 
ZEITBALKENLEDs anmachen, die zur Zeit im Quelltext auskommentiert sind. 
So wie das Programm nun aussieht, läuft es auch, nur müssen, um zum 
Beispiel einen Fehler erkennen zu lassen noch mehr LEDs angemacht 
werden. Nur wenn wir das machen funktioniert kaum noch was. So. Also 
habe ich den Quelltext mal in ModelSim simuliert, jedenfalls die 
allerersten Takte des Spiels. Und schon da ist zu erkennen, dass in der 
wave Ansicht (angehängter Screenshot) Vektoren teilweise rot 
gekennzeichnet werden. Setzen wir Status zum Beispiel: STATUS <= "0110"; 
ist in der Simulation STATUS = 0XX0, wobei X ja ein undefinierter 
Zustand ist. Das gleiche Problem ist auch Beim Vetor ZAEHLER zu sehen. 
AUch wenn ausgerechnet diese beiden Vektoren uns keine merkbaren 
Probleme gemacht haben, denke ich, dass die Ursache unserer Probleme an 
ähnlicher Problematik liegt. Ich hatte testweise die typen der Vektoren 
von STD_LOGIC_VECTOR mal auf BIT_VECTOR geändert. In dem Fall zeigt die 
Simulation dann gar keine Veränderung der Bits an.. sie bleiben alle 
immer auf 0.

Es gilt also herauszufinden, wieso die Bits, die wir eigentlich auf 1 
gesetzt haben undefiniert X sind. Ich habe am Anfang des Programms schon 
sehr viel rumprobiert, aber nichts verändern können. Deshalb frage ich 
nun hier, ob vielleicht einer auf den ersten Blick schon ein 
grundlegenden Denkfehler oder was auch immer entdeckt. Über jede 
erdenkliche Hilfe wäre ich sehr sehr dankbar !! :)

Hier der VHDL-Code:
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
6
entity SPIEL is
7
    port ( TAKT : in STD_LOGIC;
8
           RESET : in STD_LOGIC;
9
        BUTTON_1 : in STD_LOGIC;
10
        BUTTON_2 : in STD_LOGIC;
11
        ZIEL : in STD_LOGIC_VECTOR(4 downto 1);
12
        SIEGERLED : out bit_vector(8 downto 1);
13
        MUSTERLED : out STD_LOGIC_VECTOR(4 downto 1);
14
        ZEITBALKENLED : out STD_LOGIC_VECTOR(16 downto 1);
15
        STATUS : out STD_LOGIC_VECTOR(4 downto 1)
16
          );
17
end SPIEL;
18
19
architecture ASPIEL of SPIEL is
20
  type STATE_TYPE is (VORBEREITUNG, SPIEL, ZAEHLEN, FEHLER, AUSWERTUNG_1, AUSWERTUNG_2, P1, P2, P3);
21
  signal STATE, NEXT_STATE : STATE_TYPE;
22
23
  signal EINGANG : STD_LOGIC;
24
  signal AUSGANG : STD_LOGIC;
25
  signal ZUFALL : STD_LOGIC_VECTOR(4 downto 1) := "0000";
26
  signal ZAEHLER :  STD_LOGIC_VECTOR(10 downto 1) := "0000000000";
27
  signal TIMER : STD_LOGIC_VECTOR(10 downto 1) := "0000000000";
28
29
begin
30
31
  process(TAKT)
32
    begin
33
      if TAKT'event and TAKT='1' then
34
        STATE <= NEXT_STATE;
35
36
       ZAEHLER <= ZAEHLER + 1;
37
       if (ZAEHLER = "1111101000" and STATE = SPIEL) then
38
         ZAEHLER <= "0000000000";
39
         ZUFALL(4) <= ZUFALL(3);
40
         ZUFALL(3) <= ZUFALL(2);
41
         ZUFALL(2) <= ZUFALL(1) xor AUSGANG;
42
         ZUFALL(1) <= EINGANG xor AUSGANG;
43
         AUSGANG <= ZUFALL(4);
44
       end if;
45
46
       if (STATE = VORBEREITUNG) then
47
         ZUFALL <= "0000";
48
        ZAEHLER <= "0000000000";
49
        EINGANG <= '1';
50
        AUSGANG <= '0';
51
        TIMER <= "0000000000";
52
       end if;
53
54
       if (STATE = ZAEHLEN) then
55
         TIMER <= TIMER + 1;
56
       end if;
57
58
      end if;
59
  end process;
60
61
  process(STATE, RESET, BUTTON_1, BUTTON_2, ZUFALL, ZIEL, TIMER)
62
    begin
63
64
    case STATE is
65
66
    ------------------------------------------------------------------
67
68
      when VORBEREITUNG   =>  STATUS <= "1000";
69
70
        SIEGERLED <= "00000000";
71
        MUSTERLED <= "0000";
72
        ZEITBALKENLED <= "0000000000000000";
73
74
        if (RESET = '0') then NEXT_STATE <= P1; end if;
75
        if (RESET = '1') then NEXT_STATE <= VORBEREITUNG; end if;
76
77
    ------------------------------------------------------------------
78
79
      when P1          =>  STATUS <= "1111";
80
81
        if (RESET = '0') then NEXT_STATE <= P1; end if;
82
        if (RESET = '1') then NEXT_STATE <= SPIEL; end if;
83
84
    ------------------------------------------------------------------
85
86
      when SPIEL        =>  STATUS <= "0100";
87
88
        if (RESET = '0') then NEXT_STATE <= P2; end if;
89
        if (RESET = '1') then NEXT_STATE <= SPIEL; end if;
90
91
        MUSTERLED <= ZUFALL;
92
93
        if (ZUFALL = ZIEL) then
94
          NEXT_STATE <= ZAEHLEN;
95
        end if;
96
97
        if (BUTTON_1 = '0') then NEXT_STATE <= AUSWERTUNG_1; end if;
98
        if (BUTTON_2 = '0') then NEXT_STATE <= AUSWERTUNG_2; end if;
99
100
    ------------------------------------------------------------------
101
102
      when ZAEHLEN      =>  STATUS <= "0010";
103
104
        if (TIMER = "1111101000") then
105
          NEXT_STATE <= FEHLER;
106
        end if;
107
108
        if (BUTTON_1 = '0') then NEXT_STATE <= AUSWERTUNG_1; end if;
109
        if (BUTTON_2 = '0') then NEXT_STATE <= AUSWERTUNG_2; end if;
110
111
    ------------------------------------------------------------------
112
113
      when P2          =>  STATUS <= "1111";
114
115
        if (RESET = '0') then  NEXT_STATE <= P2; end if;
116
        if (RESET = '1') then  NEXT_STATE <= VORBEREITUNG; end if;
117
118
    ------------------------------------------------------------------
119
120
      when FEHLER        =>  STATUS <= "0001";
121
122
--          SIEGERLED <= "11111111";
123
--          ZEITBALKENLED <= "1111111111111111";
124
125
        if (RESET = '0') then NEXT_STATE <= P3; end if;
126
        if (RESET = '1') then NEXT_STATE <= FEHLER; end if;
127
128
    ------------------------------------------------------------------
129
130
      when AUSWERTUNG_1    =>  STATUS <= "0001";
131
132
--        if TIMER > 31 then
133
--          ZEITBALKENLED(1) <= '1';
134
--        end if;
135
--        if TIMER > 31+63 then
136
--          ZEITBALKENLED(2) <= '1';
137
--        end if;
138
--        if TIMER > 31+63*2 then
139
--          ZEITBALKENLED(3) <= '1';
140
--        end if;
141
--        if TIMER > 31+63*3 then
142
--          ZEITBALKENLED(4) <= '1';
143
--        end if;
144
--        if TIMER > 31+63*4 then
145
--          ZEITBALKENLED(5) <= '1';
146
--        end if;
147
--        if TIMER > 31+63*5 then
148
--          ZEITBALKENLED(6) <= '1';
149
--        end if;
150
--        if TIMER > 31+63*6 then
151
--          ZEITBALKENLED(7) <= '1';
152
--        end if;
153
--        if TIMER > 31+63*7 then
154
--          ZEITBALKENLED(8) <= '1';
155
--        end if;
156
--        if TIMER > 31+63*8 then
157
--          ZEITBALKENLED(9) <= '1';
158
--        end if;
159
--        if TIMER > 31+63*9 then
160
--          ZEITBALKENLED(10) <= '1';
161
--        end if;
162
--        if TIMER > 31+63*10 then
163
--          ZEITBALKENLED(11) <= '1';
164
--        end if;
165
--        if TIMER > 31+63*11 then
166
--          ZEITBALKENLED(12) <= '1';
167
--        end if;
168
--        if TIMER > 31+63*12 then
169
--          ZEITBALKENLED(13) <= '1';
170
--        end if;
171
--        if TIMER > 31+63*13 then
172
--          ZEITBALKENLED(14) <= '1';
173
--        end if;
174
--        if TIMER > 31+63*14 then
175
--          ZEITBALKENLED(15) <= '1';
176
--        end if;
177
--        if TIMER > 31+63*15 then
178
--          ZEITBALKENLED(16) <= '1';
179
--        end if;
180
181
        if (TIMER = "0000000000") then
182
          SIEGERLED <= "00001111";
183
        else
184
          SIEGERLED <= "11110000";
185
        end if;
186
187
        if (RESET = '0') then NEXT_STATE <= P3; end if;
188
        if (RESET = '1') then NEXT_STATE <= AUSWERTUNG_1; end if;
189
190
    ------------------------------------------------------------------
191
192
      when AUSWERTUNG_2    =>  STATUS <= "0001";
193
194
--        if TIMER > 31 then
195
--          ZEITBALKENLED(1) <= '1';
196
--        end if;
197
--        if TIMER > 31+63 then
198
--          ZEITBALKENLED(2) <= '1';
199
--        end if;
200
--        if TIMER > 31+63*2 then
201
--          ZEITBALKENLED(3) <= '1';
202
--        end if;
203
--        if TIMER > 31+63*3 then
204
--          ZEITBALKENLED(4) <= '1';
205
--        end if;
206
--        if TIMER > 31+63*4 then
207
--          ZEITBALKENLED(5) <= '1';
208
--        end if;
209
--        if TIMER > 31+63*5 then
210
--          ZEITBALKENLED(6) <= '1';
211
--        end if;
212
--        if TIMER > 31+63*6 then
213
--          ZEITBALKENLED(7) <= '1';
214
--        end if;
215
--        if TIMER > 31+63*7 then
216
--          ZEITBALKENLED(8) <= '1';
217
--        end if;
218
--        if TIMER > 31+63*8 then
219
--          ZEITBALKENLED(9) <= '1';
220
--        end if;
221
--        if TIMER > 31+63*9 then
222
--          ZEITBALKENLED(10) <= '1';
223
--        end if;
224
--        if TIMER > 31+63*10 then
225
--          ZEITBALKENLED(11) <= '1';
226
--        end if;
227
--        if TIMER > 31+63*11 then
228
--          ZEITBALKENLED(12) <= '1';
229
--        end if;
230
--        if TIMER > 31+63*12 then
231
--          ZEITBALKENLED(13) <= '1';
232
--        end if;
233
--        if TIMER > 31+63*13 then
234
--          ZEITBALKENLED(14) <= '1';
235
--        end if;
236
--        if TIMER > 31+63*14 then
237
--          ZEITBALKENLED(15) <= '1';
238
--        end if;
239
--        if TIMER > 31+63*15 then
240
--          ZEITBALKENLED(16) <= '1';
241
--        end if;
242
243
        if (TIMER = "0000000000") then
244
          SIEGERLED <= "11110000";
245
        else
246
          SIEGERLED <= "00001111";
247
        end if;
248
249
        if (RESET = '0') then NEXT_STATE <= P3; end if;
250
        if (RESET = '1') then NEXT_STATE <= AUSWERTUNG_2; end if;
251
252
    ------------------------------------------------------------------
253
254
      when P3          =>  STATUS <= "1111";
255
        if (RESET = '0') then NEXT_STATE <= P3; end if;
256
        if (RESET = '1') then NEXT_STATE <= VORBEREITUNG; end if;
257
258
    ------------------------------------------------------------------
259
260
    end case;
261
262
  end process;
263
264
end ASPIEL;

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


Lesenswert?

> Es gilt also herauszufinden, wieso die Bits, die wir eigentlich auf 1
> gesetzt haben undefiniert X sind.
Setzt du STATUS und ZAEHLER in der TB auf '0'?
Das darfst du nicht, weil es ja Ausgäng deines Moduls sind...

von Klaus K. (yildi)


Lesenswert?

Was ist denn TB ?
STATUS setze ich erst in den Zuständen auf einen Wert. Und ZAEHLER ist 
doch aber gar kein Ausgang

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


Angehängte Dateien:

Lesenswert?

Phillip D. schrieb:
> Was ist denn TB ?
Eine TB = Testbench ist ein VHDL-Modell, das dein Spiel ansteuert.
Wie erzeugst du deine Stimulidaten (TAKT, BUTTON...)?

> STATUS setze ich erst in den Zuständen auf einen Wert. Und ZAEHLER ist
> doch aber gar kein Ausgang
Ich habe das mal mit einer simplen Testbench ausprobiert, das scheint 
besser zu gehen (sieh Anhang).


BTW: Nimm den bit_vector wieder aus dem Port raus...

von Klaus K. (yildi)


Lesenswert?

Ah okay, das scheint bei Ihnen ja zu funktionieren. Ich hatte bislang 
eine *.do Datei die ich dann ausführen konnte. Sie hatte den folgenden 
Inhalt.

vsim work.SPIEL
restart
view wave
radix bin

force takt 0 0, 1 500us -r 1000us
force reset 1
force button_1 1
force button_2 1
force ziel "0110"
force siegerled "00000000"
force musterled "0000"
force zeitbalkenled "0000000000000000"
force status "0000"
force eingang 1
force ausgang 0
force zufall "0000"
force zaehler "0000000000"
force timer "000000000000000"

run 5ms

force reset 0
run 5ms
force reset 1
run 5ms
force zaehler "1111101000"
run 20ms

Ich werde es nun aber mal auf die Art versuchen, wie Sie es gemacht 
haben.. Ich meld mich dann wieder ;-)

von Klaus K. (yildi)


Lesenswert?

So nun bekomme ich in meiner Simulation auch eine einwandfreie wave 
Grafik. Alles funktioniert so wie es soll :) Allerdings habe ich im 
eigentlichen Quelltext ja nichts geändert, sondern nur die Simulation 
angepasst. Ich denke nicht, dass es nun in der Realität funktionieren 
wird, das kann ich aber allerdings erst Montag wieder im Labor 
austesten. Sowiet schonmal vielen Dank! Falls doch noch jemand eine Idee 
hat, was falsch sein könnte... das wäre super :)

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.