Forum: FPGA, VHDL & Co. Brauche dringend Hilfe mit 4Gewinnt


von Denis (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich brauche bitte eure Hilfe mit einem 4 Gewinnt, welches ich in VHDL 
für einen XILINX Spartan auf einem Evaluation Board entwickle.
Das ganze wird mit einer externen Platine worauf sich eine DuoLED 7x6 
Matrix befindet, inklusive Taster für die Spalten(inp(0) - inp(6)) und 
einem Reset Taster(inp(7))

Das ganze funktioniert bei mir in meiner Testbench(angehängt) 
einwandfrei, sobald ich es allerdings synthetisiere, verhält sich das 
Board komplett anders, es wird z.b. stets nur die 1. Spalte mit 
"Steinen" aufgefüllt, obwohl ein anderer Taster gedrückt wird. Lediglich 
der Reset Taster funktioniert so wie er soll.
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
6
entity ledmatrix is
7
  PORT
8
  (
9
  
10
    clk    : IN  std_logic; -- 50 MHz Quartz
11
      ledout   : OUT  std_logic_vector (0 to 23) := "000000000000000000000000"; 
12
    inp    : IN std_logic_vector (0 to 7); -- 0-6 = Spaltentaster, 7 = Reset  
13
    segments : out  std_logic_vector (0 to 7) := "00000000" 
14
    
15
  );
16
17
end ledmatrix;
18
19
20
architecture Behavioral of ledmatrix is
21
22
--Matrixmultiplex
23
type matrixB is array (1 to 8, 1 to 7) of integer range 0 to 3;
24
signal matP      : matrixB := (others => (others => 0)); --0 = None, 1=Rot, 2=Grün, 3=Gelb
25
signal f_multiplex: std_logic := '0'; -- 800Hz
26
-------------------
27
28
--Logik
29
signal win        : integer range 0 to 2 := 0;
30
-------------------
31
32
--Taster entprellen
33
signal inp_entp    :  std_logic_vector (0 to 7) := "00000000";
34
type intB is array(0 to 7) of integer range 0 to 50000;
35
signal inp_entp_cnt  :   intB := (others => 0);
36
signal inp_trigger  : std_logic := '0';
37
-------------------
38
39
begin
40
41
42
43
44
--------------Taster entprellen----------------------
45
process (clk)
46
begin 
47
48
  if rising_edge(clk) then
49
  -----------
50
  for i in 0 to 7 loop
51
  
52
    if (inp(i) = inp_entp(i)) then
53
      inp_entp_cnt(i) <= 0;
54
    else 
55
      inp_entp_cnt(i) <= inp_entp_cnt(i) + 1;
56
    end if;
57
  -----------
58
    if (inp_entp_cnt(i) = 50000) then
59
      inp_entp(i) <= inp(i);
60
    end if;
61
    
62
  end loop;
63
  end if;
64
end process;
65
66
inp_trigger <= inp_entp(0) or inp_entp(1) or inp_entp(2) or inp_entp(3) or inp_entp(4) or inp_entp(5) or inp_entp(6) or inp_entp(7); 
67
--------------------------------------------------------
68
69
--Schalterauswertung--
70
process
71
variable xls         : integer range 0 to 7 := 0;
72
variable yls         : integer range 0 to 6 := 0;
73
74
variable checkC      : integer range 0 to 4 := 0;
75
variable checkF      : integer range 0 to 2 := 0;
76
77
variable currentPlayer : std_logic := '0';
78
79
type intA is array(0 to 7) of integer range 0 to 8;
80
variable CountS      : intA := (others => 0);
81
82
variable isWin        : std_logic := '0';
83
begin
84
85
wait until rising_edge(inp_trigger);
86
  
87
  --Reset
88
  if inp_entp(7) = '1' then
89
  
90
  currentPlayer := '0'; 
91
  win <= 0;
92
  xls := 0;
93
  
94
  --Matrix zurücksetzen
95
  for x in 1 to 7 loop 
96
  
97
  CountS(x) := 0;
98
  
99
    for y in 1 to 6 loop
100
    matP(x, y) <= 0;
101
    end loop;
102
103
  end loop;
104
  
105
  ---Kein Reset
106
  elsif win = 0 then
107
  
108
  xls := 1;
109
  
110
  if inp_entp(0) = '1' then
111
  xls := 1;
112
  elsif inp_entp(1) = '1' then
113
  xls := 2;
114
  elsif inp_entp(2) = '1' then
115
  xls := 3;
116
  elsif inp_entp(3) = '1' then
117
  xls := 4;
118
  elsif inp_entp(4) = '1' then
119
  xls := 5;
120
  elsif inp_entp(5) = '1' then
121
  xls := 6;
122
  elsif inp_entp(6) = '1' then
123
  xls := 7;  
124
  end if;
125
  
126
  CountS(xls) := CountS(xls) + 1;
127
  
128
--Gewinnauswertung Start
129
130
    yls := CountS(xls);
131
132
    if currentPlayer = '0' then
133
    checkF := 1;
134
    else
135
    checkF := 2;
136
    end if;
137
138
    --Rechts
139
    checkC := 1;
140
    if xls < 5 then
141
    
142
    for j in 1 to 3 loop
143
      if (matP(xls+j, yls) = checkF) then
144
      checkC := checkC + 1;
145
      end if;
146
    end loop;
147
    if checkC >= 4 then
148
    win <= checkF;  
149
    end if;
150
    
151
    end if;
152
    
153
    
154
    --Links
155
    checkC := 1;
156
    if (win = 0) then
157
    if xls > 3 then
158
    
159
    for j in 1 to 3 loop
160
      if (matP(xls-j, yls) = checkF) then
161
      checkC := checkC + 1;
162
      end if;
163
    end loop;
164
    if checkC >= 4 then
165
    win <= checkF;    
166
    end if;
167
    
168
    end if;
169
    end if;
170
    
171
    
172
    --Unten
173
    checkC := 1;
174
    if (win = 0) then
175
    if yls > 3 then
176
    
177
    for j in 1 to 3 loop
178
      if (matP(xls, yls-j) = checkF) then
179
      checkC := checkC + 1;
180
      end if;
181
    end loop;
182
    if checkC >= 4 then
183
    win <= checkF;
184
    end if;
185
    
186
    end if;
187
    end if;  
188
189
    
190
    
191
    --Links Unten
192
    checkC := 1;
193
    if (win = 0) then
194
    if (yls > 3) and (xls > 3) then
195
    
196
    for j in 1 to 3 loop
197
      if (matP(xls-j, yls-j) = checkF) then
198
      checkC := checkC + 1;
199
      end if;
200
    end loop;
201
    if checkC >= 4 then
202
    win <= checkF;
203
    end if;
204
    
205
    end if;
206
    end if;    
207
    
208
    
209
    --Rechts Unten
210
    checkC := 1;
211
    if (win = 0) then
212
    if (yls > 3) and (xls < 5) then
213
    
214
    for j in 1 to 3 loop
215
      if (matP(xls+j, yls-j) = checkF) then
216
      checkC := checkC + 1;
217
      end if;
218
    end loop;
219
    if checkC >= 4 then
220
    win <= checkF;
221
    end if;
222
    
223
    end if;
224
    end if;
225
    
226
    
227
    --Rechts Oben
228
    checkC := 1;
229
    if (win = 0) then
230
    if (yls < 4) and (xls < 5) then
231
    
232
    for j in 1 to 3 loop
233
      if (matP(xls+j, yls+j) = checkF) then
234
      checkC := checkC + 1;
235
      end if;
236
    end loop;
237
    if checkC >= 4 then
238
    win <= checkF;
239
    end if;
240
    
241
    end if;
242
    end if;    
243
    
244
    
245
    --Links Oben
246
    checkC := 1;
247
    if (win = 0) then
248
    if (yls < 4) and (xls > 3) then
249
    
250
    for j in 1 to 3 loop
251
      if (matP(xls-j, yls+j) = checkF) then
252
      checkC := checkC + 1;
253
      end if;
254
    end loop;
255
    if checkC >= 4 then
256
    win <= checkF;  
257
    end if;
258
    
259
    end if;
260
    end if;  
261
262
263
--Gewinnauswertung Ende    
264
265
  
266
  --Spielstein erzeugen
267
  
268
  
269
  if currentPlayer = '0' then
270
  matP(xls, CountS(xls)) <= 1;
271
  else
272
  matP(xls, CountS(xls)) <= 2;
273
  end if;  
274
    
275
  currentPlayer := not currentPlayer;
276
  
277
  end if;
278
  
279
280
281
282
end process;
283
-------------------------------------------------------------------------------------------------------
284
285
---Gewinnanzeige provisorisch
286
process (f_multiplex)
287
begin
288
  if rising_edge(f_multiplex) then
289
  
290
    case win is
291
    when 0 => 
292
    segments <= "00000000";
293
    when 1 =>
294
    --R
295
    segments <= "01110111";
296
    when 2 =>
297
    --G
298
    segments <= "01111101";
299
    end case;
300
    
301
  end if;
302
end process;
303
304
305
306
307
  --clk -> f_multiplex
308
process (clk)
309
    constant  max_cnt    : integer := 62500; --ergibt ca 114 Hz Bildaufbau pro Led
310
    variable  cnt      : integer range 0 to max_cnt + 1;
311
begin
312
  if rising_edge(clk) then
313
    cnt := cnt + 1;
314
    if cnt = max_cnt +1 then
315
    cnt := 0;
316
    f_multiplex <= not f_multiplex;
317
    end if;
318
  end if;
319
end process;
320
   
321
  
322
  
323
  --////////Matrix Ausgabe Anfang//////////
324
  
325
  
326
  process
327
  variable x    : integer range 0 to 7 := 1;
328
  constant spaltenAnz   : integer range 0 to 10 := 7; 
329
  begin
330
  
331
    wait until rising_edge(f_multiplex);
332
  
333
    --unbenutzte pins
334
    for i in 13 to 17 loop
335
    ledout(i) <= '0';
336
    end loop;
337
  
338
  
339
    -- 1 Spalte auf High/Kathode durchschalten
340
    ledout(x-1) <= '1';
341
    
342
    -- die letzte Spalte wieder auf 0
343
      if (x>1) then
344
      ledout(x-2) <= '0';
345
      else
346
      ledout(spaltenAnz-1) <= '0';
347
      end if;
348
    
349
    
350
    --Code für die zu leuchtenden LEDs in der aktuellen Spalte:
351
    --ledout[0-6] = Kathoden // werden gemultiplext  // Header A - PIN[2-8]
352
    --ledout[7-12] = Anoden Rot // Header A - PIN[9-14]
353
    --ledout[18-23] = Anoden Grün // Header B - PIN[2-7]
354
    
355
      
356
      
357
      for i in 0 to 5 loop
358
      
359
        case (matP(x, i+1)) is 
360
          when 1 => 
361
          ledout(7+i) <= '1';
362
          ledout(18+i) <= '0';
363
          
364
          when 2 => 
365
          ledout(18+i) <= '1';
366
          ledout(7+i) <= '0';
367
          
368
          when 3 => 
369
          ledout(7+i) <= '1'; 
370
          ledout(18+i) <= '1';  
371
          
372
          when others => 
373
          ledout(7+i) <= '0'; 
374
          ledout(18+i) <= '0';
375
        end case;      
376
        
377
      end loop;
378
        
379
380
    
381
      
382
    
383
      if (x = spaltenAnz) then 
384
      x := 1;
385
      else
386
      x := x + 1;
387
      end if;
388
      
389
  
390
  
391
  end process;
392
393
   
394
   
395
   
396
   --////////Matrix Ausgabe Ende//////////
397
   
398
  
399
400
401
end Behavioral;


Danke schon einmal für euer Bemühen!

von Solide Vollnarkose (Gast)


Lesenswert?

Ja glaubst du ernsthaft, solch langen Kot liest sich einer durch?

von Jürgen G. (Firma: Elektronikentwickler Aachen) (fjgensicke)


Lesenswert?

wait until rising_edge(inp_trigger);

läuft nur im Simulator!

von Patrick (Gast)


Lesenswert?

@ Solide Vollnarkose: Zumindest hast du schon mal drüber gescrollt und 
deinen unangebrachten Senf dazu abgegeben. Das ist doch schon mal ein 
Anfang.

Gruß Patrick

von Denis (Gast)


Lesenswert?

Solide Vollnarkose schrieb:
> Ja glaubst du ernsthaft, solch langen Kot liest sich einer durch?

Wenn du nicht helfen willst spar dir in Zukunft die Antwort bitte, ich 
kann das Problem halt nicht wirklich eingrenzen.

Den Teil mit wait until habe ich auch mit if rising_edge(x) probiert mit 
dem selben Ergebnis. Laut Forum soll aber beides funktionieren und die 
wait methode sogar besser sein.

von Duke Scarring (Gast)


Lesenswert?

Jürgen Gensicke schrieb:
> wait until rising_edge(inp_trigger);
>
> läuft nur im Simulator!
Kann man so nicht sagen.

Auf jeden Fall sollte der Originalposter nur einen Takt (clk) 
verwenden. Und auch nur der gehört in das rising_edge rein.
Abgesehen davon werden seine Tasten prellen.

Das Problem läßt sich z.B. so lösen:
http://www.lothar-miller.de/s9y/archives/18-Flinke-Flankenerkennung.html

Duke

von Duke Scarring (Gast)


Lesenswert?

P.S.: Hier ist die Tastenentprellung noch besser erklärt:
http://www.lothar-miller.de/s9y/categories/5-Entprellung

von PittyJ (Gast)


Lesenswert?

Ich nehme immer die Signale anstatt der Variablen.

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


Lesenswert?

Jürgen Gensicke schrieb:
> wait until rising_edge(inp_trigger);
> läuft nur im Simulator!
Diese Aussage war bis zum Ende des letzten Jahrtausends noch korrekt.
http://www.lothar-miller.de/s9y/archives/16-Takt-im-Prozess.html
Aber heute geht sogar noch viel mehr:
http://www.lothar-miller.de/s9y/archives/47-wait-im-Prozess.html

Denis schrieb:
1
 inp_trigger <= inp_entp(0) or inp_entp(1) or inp_entp(2) or inp_entp(3) or inp_entp(4) or inp_entp(5) or inp_entp(6) or inp_entp(7);
2
 wait until rising_edge(inp_trigger);
3
4
     f_multiplex <= not f_multiplex;
5
 wait until rising_edge(f_multiplex);
So werden im FPGA keine Takte erzeugt!
Deine Fehler wurden von anderen auch schon gemacht. Sieh dich einfach 
mal hier im Forum um. Auf jeden Fall wirst du ersntzunehmende Probleme 
durch die vielen Taktdomänen bekommen. Überleg das mal, was ich da 
geschrieben habe:
http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html
Taster sind asynchrone externe Eingänge...


Zum Thema "extensive und unnötige Verwendung von Variablen" mehr im 
Beitrag "Variable vs Signal"

von Bronco (Gast)


Lesenswert?

Denis schrieb:
> Das ganze funktioniert bei mir in meiner Testbench(angehängt)
> einwandfrei, sobald ich es allerdings synthetisiere, verhält sich das
> Board komplett anders,

Das liegt mit an Sicherheit grenzender Wahrscheinlichkeit am Takt.
Benutze nach Möglichkeit nur einen einzigen Takt für alle Prozesse, 
sonst kommst Du in Teufel's Küche (wo wir alle schon öfters waren).
1
inp_trigger <= inp_entp(0) or inp_entp(1) or inp_entp(2) or inp_entp(3) or inp_entp(4) or inp_entp(5) or inp_entp(6) or inp_entp(7); 
2
3
process
4
begin
5
  wait until rising_edge(clk);
6
  if (inp_trigger = '1') and (inp_trigger_vorher = '0') then
7
    ...
8
  end if;
9
  inp_trigger_vorher <= inp_trigger;
10
end process;

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


Lesenswert?

Was wird daraus generiert:
1
inp_trigger <= inp_entp(0) or inp_entp(1) or inp_entp(2) or inp_entp(3) or inp_entp(4) or inp_entp(5) or inp_entp(6) or inp_entp(7); 
2
--------------------------------------------------------
3
4
--Schalterauswertung--
5
process begin
6
7
wait until rising_edge(inp_trigger);
8
  
9
  --Reset
10
  if inp_entp(0) = '1' then
11
  xls := 1;
12
  elsif inp_entp(1) = '1' then
13
  xls := 2;
14
  elsif inp_entp(2) = '1' then
15
  xls := 3;
16
  elsif inp_entp(3) = '1' then
17
  xls := 4;
18
  elsif inp_entp(4) = '1' then
19
  xls := 5;
20
  elsif inp_entp(5) = '1' then
21
  xls := 6;
22
  elsif inp_entp(6) = '1' then
23
  xls := 7;  
24
  end if;
25
  
26
  CountS(xls) := CountS(xls) + 1;
27
28
    checkC := 1;
29
    if xls < 5 then
30
    
31
    for j in 1 to 3 loop
32
      if (matP(xls+j, yls) = checkF) then  -- Wegen des Taktes ändert sich xls.
33
        checkC := checkC + 1;              -- gleichzeitig wird es ausgewertet und ein Zählerflipflop hochgezählt!
Eines jedes der checkC oder CountS Flipflops wird hier in etwa wie folgt 
beschaltet:
1
                          .-----.
2
Taster -----o---[Logik]---|D   Q|----
3
            |             |     |
4
            '-------------|>    |
5
                          '-----'
Meine Frage: was wird das Flipflop zuerst sehen?
Richtig: sehr wahrscheinlich den Takt, meistens...

VHDL sieht zwar aus wie eine prozedurale Programmiersprache, verhält 
sich aber komplett anders. In der Simulation wird alles nacheinander 
abgearbeitet, ind der Hardware ist alles parallel und gleichzeitig da.

Denis schrieb:
> Das ganze funktioniert bei mir in meiner Testbench einwandfrei
1
library IEEE; 
2
use IEEE.STD_LOGIC_1164.ALL; 
3
 
4
entity BlinkLED is 
5
    Port (led : buffer  STD_LOGIC := '0'); 
6
end BlinkLED; 
7
 
8
architecture Behavioral of BlinkLED is 
9
begin 
10
   led <= not led after 500 ms;    -- LED alle 500 ms toggeln 
11
end Behavioral;
Das hier funktioniert in einer Testbench auch einwandfrei... ;-)

von Solide Vollnarkose (Gast)


Lesenswert?

Denis schrieb:
> Wenn du nicht helfen willst spar dir in Zukunft die Antwort bitte, ich
> kann das Problem halt nicht wirklich eingrenzen.

In diesem Fall bitte ich um Entschuldigung...

von Denis (Gast)


Lesenswert?

Es funktioniert jetzt!
Habe dank Lothar die Probleme erkannt und jetzt läuft alles synchron nur 
mit clk. Die Spiellogik hab ich jetzt nach der einleuchtenden Skizze mit 
einer kleinen Statemaschine umgesetzt.

Vielen Dank nochmal!

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


Lesenswert?

Denis schrieb:
> Es funktioniert jetzt!
Schön.
Wenn kein Copyright drauf ist könntest du den Code hier posten. Dann 
hätte man einen Vorher-Nachher Vergleich.

> Vielen Dank nochmal!
De nada.

von Denis (Gast)


Lesenswert?

Klar, hier:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
6
entity ledmatrix is
7
  GENERIC ( 
8
              delay  : natural := 63
9
         );
10
  PORT
11
  (
12
  
13
    clk    : IN  std_logic; -- 50 MHz Quartz
14
      ledout   : OUT  std_logic_vector (0 to 23) := "000000000000000000000000"; 
15
    inp    : IN std_logic_vector (0 to 7); -- 0-6 = Spaltentaster, 7 = Reset  
16
    segments : out  std_logic_vector (7 downto 0) := "00000000" 
17
    
18
  );
19
20
end ledmatrix;
21
22
23
architecture Behavioral of ledmatrix is
24
25
--Matrixmultiplex
26
type matrixB is array (1 to 7, 1 to 6) of integer range 0 to 3;
27
signal matP      : matrixB := (others => (others => 0)); --0 = None, 1=Rot, 2=Grün, 3=Gelb
28
signal f_multiplex: std_logic := '0'; -- 800Hz
29
signal f_mult_f: std_logic := '0';
30
------------------- 
31
32
--Logik
33
signal win        : integer range 0 to 2 := 0;
34
signal xls         : integer range 1 to 7 := 1;
35
signal yls         : integer range 1 to 6 := 1;
36
signal state       : integer range 0 to 11 := 0;
37
38
39
signal checkF      : integer range 0 to 2 := 1;
40
41
signal currentPlayer : std_logic := '0';
42
43
type intA is array(0 to 7) of integer range 0 to 8;
44
signal CountS      : intA := (others => 0);
45
-------------------
46
47
--Taster entprellen
48
signal inp_entp    :  std_logic_vector (0 to 7) := "00000000";
49
-------------------
50
51
begin
52
53
54
EntprellenNeu:
55
process
56
type intB is array(0 to 7) of integer range 0 to 150000;
57
variable inpcnt : intB := (others => 0);
58
variable inp_active : std_logic_vector(0 to 7) := (others => '0');
59
begin
60
  wait until rising_edge(clk);
61
  
62
  for i in 0 to 7 loop
63
  inp_entp(i) <= '0';
64
  
65
  if inp(i) = '0' then
66
  inp_active(i) := '1';
67
  end if;
68
  
69
  if inp_active(i) = '1' then
70
    if inpcnt(i) = 150000 then
71
    inpcnt(i) := 0;
72
      if inp(i) = '1' then
73
      inp_entp(i) <= '1';  --Steigende flanke
74
      inp_active(i) := '0';
75
      end if;
76
    else
77
    
78
    inpcnt(i) := inpcnt(i) + 1;
79
    end if;
80
  end if;
81
82
  end loop;
83
84
85
end process;
86
87
88
89
--Schalterauswertung--
90
Schalterauswertung: 
91
process
92
variable checkC      : integer range 0 to 6 := 0;
93
variable checkV      : integer range 0 to 6 := 0;
94
variable checkH      : integer range 0 to 6 := 0;
95
variable checkDR      : integer range 0 to 6 := 0;
96
variable checkDL      : integer range 0 to 6 := 0;
97
begin
98
99
   wait until rising_edge(clk);
100
  
101
  
102
  case state is
103
  when 0 =>
104
    
105
      --Reset
106
      if inp_entp(7) = '1' then
107
      
108
      currentPlayer <= '0'; 
109
      win <= 0;
110
      xls <= 1;
111
      
112
      --Matrix zurücksetzen
113
      for x in 1 to 7 loop 
114
      
115
      CountS(x) <= 0;
116
      
117
        for y in 1 to 6 loop
118
        matP(x, y) <= 0;
119
        end loop;
120
        
121
      end loop;
122
    
123
    ---Kein Reset
124
    elsif (win = 0) then
125
      
126
      if inp_entp(0) = '1' then
127
      xls <= 1;
128
      state <= state + 1;
129
      elsif inp_entp(1) = '1' then
130
      xls <= 2;
131
      state <= state + 1;
132
      elsif inp_entp(2) = '1' then
133
      xls <= 3;
134
      state <= state + 1;
135
      elsif inp_entp(3) = '1' then
136
      xls <= 4;
137
      state <= state + 1;
138
      elsif inp_entp(4) = '1' then
139
      xls <= 5;
140
      state <= state + 1;
141
      elsif inp_entp(5) = '1' then
142
      xls <= 6;
143
      state <= state + 1;
144
      elsif inp_entp(6) = '1' then
145
      xls <= 7;  
146
      state <= state + 1;
147
      end if;  
148
    
149
    
150
    end if;
151
    
152
  
153
  when 1 =>
154
  --Auswertung Stufe 1
155
    
156
    CountS(xls) <= CountS(xls) + 1;
157
    
158
      if currentPlayer = '0' then
159
      checkF <= 1;
160
      else
161
      checkF <= 2;
162
      end if;
163
      
164
    state <= state + 1;
165
166
  when 2 =>
167
168
169
  yls <= CountS(xls);
170
  checkH := 1;
171
  checkV := 1;
172
  checkDL := 1;
173
  checkDR := 1;
174
175
  state <= state + 1;
176
  
177
  when 3 =>
178
179
  
180
    --Rechts
181
182
    
183
    for j in 1 to 3 loop
184
      if (matP(xls+j, yls) = checkF) then
185
      checkH := checkH + 1;
186
      end if;
187
    end loop;
188
189
    
190
  state <= state + 1;
191
192
  when 4 =>    
193
    
194
    --Links
195
    if (win = 0) then
196
    
197
    for j in 1 to 3 loop
198
      if (matP(xls-j, yls) = checkF) then
199
      checkH := checkH + 1;
200
      end if;
201
    end loop;
202
    end if;
203
    
204
  state <= state + 1;
205
  
206
207
  when 5 =>
208
    
209
    --Unten
210
    if (win = 0) then
211
    
212
    for j in 1 to 3 loop
213
      if (matP(xls, yls-j) = checkF) then
214
      checkV := checkV + 1;
215
      end if;
216
    end loop;
217
218
    end if;
219
220
  state <= state + 1;  
221
222
223
  when 6 =>
224
    
225
    --Links Unten
226
    if (win = 0) then
227
    
228
    for j in 1 to 3 loop
229
      if (matP(xls-j, yls-j) = checkF) then
230
      checkDR := checkDR + 1;
231
      end if;
232
    end loop;
233
    
234
    end if;
235
  
236
    state <= state + 1;
237
  
238
  when 7 =>
239
240
    --Rechts Unten
241
242
243
    if (win = 0) then
244
    
245
    for j in 1 to 3 loop
246
      if (matP(xls+j, yls-j) = checkF) then
247
      checkDL := checkDL + 1;
248
      end if;
249
    end loop;
250
    end if;
251
    
252
  state <= state + 1;
253
254
  when 8 =>
255
    
256
    --Rechts Oben
257
258
    if (win = 0) then
259
    
260
    for j in 1 to 3 loop
261
      if (matP(xls+j, yls+j) = checkF) then
262
      checkDR := checkDR + 1;
263
      end if;
264
    end loop;
265
    end if;
266
    
267
  state <= state + 1;
268
  
269
  when 9 =>
270
    
271
    --Links Oben
272
    if (win = 0) then
273
    for j in 1 to 3 loop
274
      if (matP(xls-j, yls+j) = checkF) then
275
      checkDL := checkDL + 1;
276
      end if;
277
    end loop;
278
    
279
    end if;  
280
  
281
  state <= state + 1;
282
  
283
  when 10 =>
284
  
285
  if (checkH >= 4) or (checkV >= 4) or (checkDR >= 4) or (checkDL >= 4) then
286
  win <= checkF;  
287
  end if;
288
289
  state <= state + 1;
290
  
291
  when 11 =>
292
  
293
  --Spielstein erzeugen
294
  
295
  if currentPlayer = '0' then
296
  matP(xls, CountS(xls)) <= 1;
297
  else
298
  matP(xls, CountS(xls)) <= 2;
299
  end if;  
300
    
301
  currentPlayer <= not currentPlayer;  
302
  
303
  state <= 0;
304
  
305
  end case;
306
  
307
308
end process;
309
310
311
312
-------------------------------------------------------------------------------------------------------
313
314
---Gewinnanzeige provisorisch
315
Gewinnanzeige: 
316
process
317
begin
318
  wait until rising_edge(clk);
319
  
320
    case win is
321
    when 0 => 
322
    segments <= "00000000";
323
    when 1 =>
324
    --R
325
    segments <= "00000110";
326
    when 2 =>
327
    --G
328
    segments <= "01011011";
329
    end case;
330
331
end process;
332
333
334
335
336
--clk -> f_multiplex
337
Multiplexfreq: 
338
process (clk)
339
    constant  max_cnt    : integer := 62500; --ergibt ca 114 Hz Bildaufbau pro Led
340
    variable  cnt      : integer range 0 to max_cnt + 1;
341
begin
342
   if rising_edge(clk) then
343
    cnt := cnt + 1;
344
    if cnt = max_cnt +1 then
345
    cnt := 0;
346
    f_multiplex  <= not f_multiplex;
347
    end if;
348
  end if;
349
end process;
350
   
351
  
352
  
353
  --////////Matrix Ausgabe Anfang//////////
354
  
355
FlankeFMult: 
356
process
357
    variable sr : std_logic_vector (3 downto 0) := "0000";
358
  begin
359
    wait until rising_edge(clk);
360
    -- Flanken erkennen
361
    f_mult_f <= not sr(3) and sr(2);
362
    
363
    -- Eingang in Schieberegister einlesen
364
    sr := sr(2 downto 0) & f_multiplex;
365
end process;
366
  
367
  
368
  
369
Matrixausgabe: process
370
  variable x    : integer range 0 to 7 := 1;
371
  constant spaltenAnz   : integer range 0 to 10 := 7;  
372
begin
373
    
374
  wait until rising_edge(clk);
375
  if (f_mult_f = '1') then
376
  
377
  
378
  --unbenutzte pins
379
  for i in 13 to 17 loop
380
  ledout(i) <= '0';
381
  end loop;
382
  
383
  
384
  -- 1 Spalte auf High/Kathode durchschalten
385
  ledout(x-1) <= '1';
386
    
387
  -- die letzte Spalte wieder auf 0
388
  if (x>1) then
389
  ledout(x-2) <= '0';
390
  else
391
  ledout(spaltenAnz-1) <= '0';
392
  end if;
393
    
394
    
395
  --Code für die zu leuchtenden LEDs in der aktuellen Spalte:
396
  --ledout[0-6] = Kathoden // werden gemultiplext  // Header A - PIN[2-8]
397
  --ledout[7-12] = Anoden Rot // Header A - PIN[9-14]
398
  --ledout[18-23] = Anoden Grün // Header B - PIN[2-7]
399
    
400
      
401
      
402
  for i in 0 to 5 loop
403
      
404
    case (matP(x, i+1)) is 
405
    when 1 => 
406
    ledout(7+i) <= '1';
407
    ledout(18+i) <= '0';
408
          
409
    when 2 => 
410
    ledout(18+i) <= '1';
411
    ledout(7+i) <= '0';
412
          
413
    when 3 => 
414
    ledout(7+i) <= '1'; 
415
    ledout(18+i) <= '1';  
416
          
417
    when others => 
418
    ledout(7+i) <= '0'; 
419
    ledout(18+i) <= '0';
420
    end case;      
421
        
422
  end loop;
423
          
424
    
425
    if (x = spaltenAnz) then 
426
    x := 1;
427
    else
428
    x := x + 1;
429
    end if;
430
   
431
  end if;
432
  
433
434
  
435
end process;
436
437
    
438
   --////////Matrix Ausgabe Ende//////////
439
   
440
  
441
end Behavioral;

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


Lesenswert?

Und die vielen Variablen? Na gut, so lernt man das heute...


Aber hier sind zwei grundlegender Fehler drin: ein Denkfehler und ein 
Strukturfehler. Der weniger schlimme Denkfehler:
1
    constant  max_cnt : integer := 62500; -- ergibt ca 114 Hz Bildaufbau pro Led
2
    variable  cnt : integer range 0 to max_cnt + 1;   -- wohl nur drin wegen der Simulation?
3
                                                      -- in der Praxis wird dieser maximale Zählerstand /nie/ erreicht!

Aber das ist der Knackpunkt: Du zählst einen Schritt zuviel! Nämlich 
nicht 62500 Zyklen, sondern 62501, weil die Null auch ein Schritt ist: 
0,1,2,...62499,62500. Klar macht das hier jetzt nur 1/10 Promille aus, 
aber wehe du bist mit dem Zählerendwert mal im einstelligen Bereich. Ein 
Zähler für drei Schritte darf nicht bis 3 zählen. Er darf nur 0,1 und 2 
erreichen...

Richtigerweise muss da also vorerst stehen:
1
    variable  cnt : integer range 0 to max_cnt-1;   
2
3
   if rising_edge(clk) then                -- besser die Abfrage so machen:
4
    if cnt = max_cnt-1 then                -- auf Endwert abfragen. Wenn erreicht: 
5
       cnt := 0;                           -- zurücksetzen         
6
       f_multiplex  <= not f_multiplex;
7
    else                                   -- sonst: 
8
       cnt := cnt + 1;                     -- zählen
9
    end if;
10
  end if;

Und dann kommt der schlimmere, strukturelle Fehler:
Denis schrieb:
> jetzt läuft alles synchron nur mit clk.
Naja, nicht so ganz...
Noch immer werden so keine Takte erzeugt:
1
  
2
      f_multiplex  <= not f_multiplex;
3
4
    :
5
    :
6
7
   if rising_edge(f_multiplex) then  -- hier darf nur einer stehen: der CLK
Mag sein, dass es jetzt gerade mal geht, aber sauber ist das nicht...

Richtig wäre ein Clock-Enable:
1
    variable  cnt : integer range 0 to max_cnt-1;   
2
3
   if rising_edge(clk) then                
4
    multiplex_enable <= '0';
5
    if cnt = max_cnt-1 then                
6
       cnt := 0;                           
7
       multiplex_enable <= '1';  -- nur für 1 Taktzyklus lang aktiv!
8
    else                                   
9
       cnt := cnt + 1;                     
10
    end if;
11
  end if;
12
   
13
  :
14
  :
15
16
  if rising_edge(clk) then -- es kann nur einen geben: den CLK
17
     if (multiplex_enable='1') then
18
        :


BTW:
Diese Konstante hier würdest du leichter den Synthesizer ausrechnen 
lassen:
1
    constant  max_cnt : integer := 62500; -- ergibt ca 114 Hz Bildaufbau pro Led
So etwa:
1
    constant  fosc : integer := 50000000;
2
  :
3
  :
4
    constant  max_cnt : integer := fosc/(7*114); -- ergibt bei 7 Spalten ca. 114 Hz Bildaufbau pro Led

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.