Forum: FPGA, VHDL & Co. Sekundenzähler auf zwei 7-Segment-Anzeigen


von Simon (sr0907)


Lesenswert?

Guten Tag,

ich möchte einen Sekundenzähler mit Ausgabe auf zwei 7-Segment-Anzeigen 
implementieren.

Hier mein VHDL-Code:
1
library ieee;
2
3
use ieee.std_logic_1164.all;
4
5
use ieee.numeric_std.all;
6
7
8
entity SekundenZaehler7Segment is
9
10
    port(
11
12
        clk : in std_logic;
13
14
        reset : in std_logic;
15
16
        segments_1 : out std_logic_vector(6 downto 0);
17
18
        segments_10 : out std_logic_vector(6 downto 0)
19
20
    );
21
22
end SekundenZaehler7Segment;
23
24
25
architecture rtl of SekundenZaehler7Segment is
26
27
28
signal clk_en : std_logic;
29
30
    signal counter_1 : std_logic_vector(3 downto 0);
31
32
    signal counter_10 : std_logic_vector(3 downto 0);
33
34
    signal overflow_1 : std_logic;
35
36
    signal overflow_10 : std_logic;
37
38
    signal segments_1_temp : std_logic_vector(6 downto 0);
39
40
    signal segments_10_temp : std_logic_vector(6 downto 0);
41
42
43
    component ClockEnableGenerator is
44
45
        generic (
46
47
            DIVIDE_BY : integer
48
49
        );
50
51
        port(
52
53
            clk_in : in std_logic;
54
55
            clk_en_out : out std_logic;
56
57
            reset : in std_logic
58
59
        );
60
61
    end component;
62
63
64
    component GenericBCDCounter is
65
66
        generic (
67
68
            COUNT_MAX : integer
69
70
        );
71
72
        port(
73
74
            clk : in std_logic;
75
76
            enable : in std_logic;
77
78
            reset : in std_logic;
79
80
            count : out std_logic_vector(3 downto 0);
81
82
            overflow : out std_logic
83
84
        );
85
86
    end component;
87
88
89
    component BCDDecoder is
90
91
        port(
92
93
            digit : in std_logic_vector(3 downto 0);
94
95
            segments : out std_logic_vector(6 downto 0)
96
97
        );
98
99
    end component;
100
101
102
begin
103
104
105
Decoder1: BCDDecoder
106
107
        port map (
108
109
            digit => counter_1,
110
111
            segments => segments_1_temp
112
113
        );
114
115
116
    Decoder10: BCDDecoder
117
118
        port map (
119
120
            digit => counter_10,
121
122
            segments => segments_10_temp
123
124
        );
125
126
127
    Counter1: GenericBCDCounter
128
129
        generic map (
130
131
            COUNT_MAX => 9
132
133
        )
134
135
        port map (
136
137
            clk => clk,
138
139
            enable => clk_en,
140
141
            reset => reset,
142
143
            count => counter_1,
144
145
            overflow => overflow_1
146
147
        );
148
149
150
    Counter10: GenericBCDCounter
151
152
        generic map (
153
154
            COUNT_MAX => 5
155
156
        )
157
158
        port map (
159
160
            clk => clk,
161
162
            enable => overflow_1,
163
164
            reset => reset,
165
166
            count => counter_10,
167
168
            overflow => overflow_10
169
170
        );
171
172
173
    
174
175
    ClockGen: ClockEnableGenerator
176
177
        generic map (
178
179
            DIVIDE_BY => 13
180
181
        )
182
183
        port map (
184
185
            clk_in => clk,
186
187
            clk_en_out => clk_en,
188
189
            reset => reset
190
191
        );
192
193
194
    segments_1 <= segments_1_temp;
195
196
    segments_10 <= segments_10_temp;
197
198
end architecture rtl;

Leider tritt beim Clocked Test folgendes Problem auf. Kann mir jemand 
helfen und sieht mit einem etwas erfahrenderen Blick, wo das Problem 
liegen könnte?
1
CLOCKED TEST SEQUENCE
2
3
RESET to 0 -> 1111110 1111110 OK.
4
5
1 -> 1111110 0110000 OK.
6
7
2 -> 1111110 1101101 OK.
8
9
3 -> 1111110 1111001 OK.
10
11
4 -> 1111110 0110011 OK.
12
13
5 -> 1111110 1011011 OK.
14
15
6 -> 1111110 1011111 OK.
16
17
7 -> 1111110 1110000 OK.
18
19
RESET to 0 -> 1111110 1111110 OK.
20
21
RESET to 0 -> 1111110 1111110 OK.
22
23
1 -> 1111110 0110000 OK.
24
25
2 -> 1111110 1101101 OK.
26
27
3 -> 1111110 1111001 OK.
28
29
4 -> 1111110 0110011 OK.
30
31
5 -> 1111110 1011011 OK.
32
33
6 -> 1111110 1011111 OK.
34
35
7 -> 1111110 1110000 OK.
36
37
8 -> 1111110 1111111 OK.
38
39
9 -> 1111110 1111011 OK.
40
41
 ASYNC!
42
43
 ASYNC!
44
45
 ASYNC!
46
47
 ASYNC!
48
49
 ASYNC!
50
51
 ASYNC!
52
53
 ASYNC!
54
55
 ASYNC!
56
57
 ASYNC!
58
59
 ASYNC!
60
61
10 -> 0110000 1111110 OK.
62
63
11 -> 0110000 0110000 OK.
64
65
12 -> 0110000 1101101 OK.
66
67
13 -> 0110000 1111001 OK.
68
69
14 -> 0110000 0110011 OK.
70
71
15 -> 0110000 1011011 OK.
72
73
16 -> 0110000 1011111 OK.
74
75
17 -> 0110000 1110000 OK.
76
77
18 -> 0110000 1111111 OK.
78
79
19 -> 0110000 1111011 OK.
80
81
 ASYNC!
82
83
 ASYNC!
84
85
 ASYNC!
86
87
 ASYNC!
88
89
 ASYNC!
90
91
 ASYNC!
92
93
 ASYNC!
94
95
 ASYNC!
96
97
 ASYNC!
98
99
 ASYNC!
100
101
20 -> 1101101 1111110 OK.
102
103
104
21 -> 1101101 0110000 OK.
105
106
22 -> 1101101 1101101 OK.
107
108
23 -> 1101101 1111001 OK.
109
110
24 -> 1101101 0110011 OK.
111
112
25 -> 1101101 1011011 OK.
113
114
26 -> 1101101 1011111 OK.
115
116
27 -> 1101101 1110000 OK.
117
118
28 -> 1101101 1111111 OK.
119
120
29 -> 1101101 1111011 OK.
121
122
 ASYNC!
123
124
 ASYNC!
125
126
 ASYNC!
127
128
 ASYNC!
129
130
 ASYNC!
131
132
 ASYNC!
133
134
 ASYNC!
135
136
 ASYNC!
137
138
 ASYNC!
139
140
 ASYNC!
141
142
30 -> 1111001 1111110 OK.
143
144
31 -> 1111001 0110000 OK.
145
146
32 -> 1111001 1101101 OK.
147
148
33 -> 1111001 1111001 OK.
149
150
34 -> 1111001 0110011 OK.
151
152
35 -> 1111001 1011011 OK.
153
154
36 -> 1111001 1011111 OK.
155
156
37 -> 1111001 1110000 OK.
157
158
38 -> 1111001 1111111 OK.
159
160
39 -> 1111001 1111011 OK.
161
162
 ASYNC!
163
164
 ASYNC!
165
166
 ASYNC!
167
168
 ASYNC!
169
170
 ASYNC!
171
172
 ASYNC!
173
174
 ASYNC!
175
176
 ASYNC!
177
178
 ASYNC!
179
180
 ASYNC!
181
182
40 -> 0110011 1111110 OK.
183
184
41 -> 0110011 0110000 OK.
185
186
42 -> 0110011 1101101 OK.
187
188
43 -> 0110011 1111001 OK.
189
190
44 -> 0110011 0110011 OK.
191
192
45 -> 0110011 1011011 OK.
193
194
46 -> 0110011 1011111 OK.
195
196
47 -> 0110011 1110000 OK.
197
198
48 -> 0110011 1111111 OK.
199
200
49 -> 0110011 1111011 OK.
201
202
 ASYNC!
203
204
 ASYNC!
205
206
 ASYNC!
207
208
 ASYNC!
209
210
 ASYNC!
211
212
 ASYNC!
213
214
 ASYNC!
215
216
 ASYNC!
217
218
 ASYNC!
219
220
 ASYNC!
221
222
50 -> 1011011 1111110 OK.
223
224
51 -> 1011011 0110000 OK.
225
226
52 -> 1011011 1101101 OK.
227
228
53 -> 1011011 1111001 OK.
229
230
54 -> 1011011 0110011 OK.
231
232
55 -> 1011011 1011011 OK.
233
234
56 -> 1011011 1011111 OK.
235
236
57 -> 1011011 1110000 OK.
237
238
58 -> 1011011 1111111 OK.
239
240
59 -> 1011011 1111011 OK.
241
242
 ASYNC!
243
244
 ASYNC!
245
246
 ASYNC!
247
248
 ASYNC!
249
250
 ASYNC!
251
252
 ASYNC!
253
254
 ASYNC!
255
256
 ASYNC!
257
258
 ASYNC!
259
260
 ASYNC!
261
262
0 -> 1111110 1111110 OK.
263
264
1 -> 1111110 0110000 OK.
265
266
2 -> 1111110 1101101 OK.
267
268
3 -> 1111110 1111001 OK.
269
270
4 -> 1111110 0110011 OK.
271
272
5 -> 1111110 1011011 OK.
273
274
6 -> 1111110 1011111 OK.
275
276
7 -> 1111110 1110000 OK.
277
278
8 -> 1111110 1111111 OK.
279
280
9 -> 1111110 1111011 OK.
281
282
 ASYNC!
283
284
 ASYNC!
285
286
 ASYNC!
287
288
 ASYNC!
289
290
 ASYNC!
291
292
 ASYNC!
293
294
 ASYNC!
295
296
 ASYNC!
297
298
 ASYNC!
299
300
 ASYNC!
301
302
10 -> 0110000 1111110 OK.
303
304
11 -> 0110000 0110000 OK.
305
306
12 -> 0110000 1101101 OK.
307
308
13 -> 0110000 1111001 OK.
309
310
14 -> 0110000 0110011 OK.
311
312
15 -> 0110000 1011011 OK.
313
314
16 -> 0110000 1011111 OK.
315
316
17 -> 0110000 1110000 OK.
317
318
18 -> 0110000 1111111 OK.
319
320
19 -> 0110000 1111011 OK.
321
322
 ASYNC!
323
324
 ASYNC!
325
326
 ASYNC!
327
328
 ASYNC!
329
330
 ASYNC!
331
332
 ASYNC!
333
334
 ASYNC!
335
336
 ASYNC!
337
338
 ASYNC!
339
340
 ASYNC!
341
342
20 -> 1101101 1111110 OK.
343
344
21 -> 1101101 0110000 OK.
345
346
22 -> 1101101 1101101 OK.
347
348
23 -> 1101101 1111001 OK.
349
350
24 -> 1101101 0110011 OK.
351
352
25 -> 1101101 1011011 OK.
353
354
26 -> 1101101 1011111 OK.
355
356
27 -> 1101101 1110000 OK.
357
358
28 -> 1101101 1111111 OK.
359
360
29 -> 1101101 1111011 OK.
361
362
 ASYNC!
363
364
 ASYNC!
365
366
 ASYNC!
367
368
 ASYNC!
369
370
 ASYNC!
371
372
 ASYNC!
373
374
 ASYNC!
375
376
 ASYNC!
377
378
 ASYNC!
379
380
 ASYNC!
381
382
30 -> 1111001 1111110 OK.
383
384
VALIDATION FAILED!

: Bearbeitet durch Moderator
von Peter X. (dcf)


Lesenswert?

Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

von DSGV-Violator (Gast)


Lesenswert?

Jörg P. schrieb:
> Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Ist hier eigentlich egal, weil der gezeigte Code komplett irrelevant 
ist. Das ist nur ne typisch top entity Verdrahtung- Es fehlt der 
eigentlich funktionalle Code (in den subcomponenten) und die testbench.

Insofern ist der TO - Beitrag komplett für den Arsch und kann nicht 
beantwortet werden.

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


Angehängte Dateien:

Lesenswert?

DSGV-Violator schrieb:
> weil der gezeigte Code komplett irrelevant ist.
Es ist ein "verakademisierter" Code, wo jede noch so winzige 
Subkomponente eine eigene Entity bekommt. Das macht den Code 
undurchsichtig und schlecht überschaubar.

Simon schrieb:
> beim Clocked Test
Was ist das?

Hast du nicht einfach eine simple Testbench für dieses einfache Design?

Meine Uhren sehen zB aus wie dort im 
Beitrag "Re: kruder Fehler bei FPGA-Programmierung (ISE WEBpack-Schematic)"

Oder wie dort: 
http://www.lothar-miller.de/s9y/archives/88-VHDL-vs.-Verilog-am-Beispiel-einer-Stoppuhr.html


BTW: Bedienungsanleitung über der Texteingabevox lesen. VHDL Tags 
verwenden oder Sourcecode anhängen.

: Bearbeitet durch Moderator
von Simon (sr0907)


Lesenswert?

Tut mir Leid, bin noch neu in der Thematik und dachte man würde sich mit 
den gängigen Componenten zurechtfinden. Aber ist gar nicht als Vorwurf 
zu verstehen, da fehlt mir einfach die Erfahrung das einzuschätzen. Ich 
habe heut ezum Glück selbst den Fehler behoben, sodass dieser Beitrag 
geschlossen werden kann.

Viele Dank

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


Lesenswert?

Simon schrieb:
> Ich habe heut ezum Glück selbst den Fehler behoben
Nur falls mal wer was Ähnliches hat: welcher Fehler wars denn?

von DSGV-Violator (Gast)


Angehängte Dateien:

Lesenswert?

Hab mal den code per emacs aufgehübscht (siehe Anhang).
Da die  Simulatormeldungen am zehnerwechsel kommen, könnte ein Problem 
am nicht ganz schlüssigen beschalteten enable-Eingang von Counter10 
liegen.

Aber ohne den Rest der Sourcen und den compile-logs alles Gerate.

von DSGV-Violator (Gast)


Lesenswert?

Simon schrieb:
> Tut mir Leid, bin noch neu in der Thematik und dachte man würde sich mit
> den gängigen Componenten zurechtfinden.

So was wie Standard-Komponenten aka "gängig" gibt es nicht.
VHDL ist zwar standardisiert kennt aber keine (komplexe) Funktionen aus 
stdlib, stdio wie C (ausser Typkonvertierungen). Und digitaler Kleinkram 
wie Counter/siebensegment-Decoder gibt es höchstens in 
Schaltkreisfamilien als Quasi-Industriestandard wie die 74TTL reihe. 
Deren Gebrauch unterscheidet sich aber von dem von 
FPGA-VHDL-Komponenten.

https://de.wikipedia.org/wiki/Liste_von_integrierten_Schaltkreisen_der_74xx-Familie
https://www.rhydolabz.com/documents/74LS48.pdf
https://www.onsemi.com/pdf/datasheet/mc74hc160a-d.pdf

von T.U.Darmstadt (Gast)


Lesenswert?

DSGV-Violator schrieb:
> So was wie Standard-Komponenten aka "gängig" gibt es nicht.

Er meint wohl eine funktionelle Standardkomponente, wie Zähler, Teiler, 
Vergleicher. Einen 7-Segment-Anzeigen-Treibe könnte man als eine solche 
bezeichnen, oder?

von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

So, hier die Komponenten. Und siehe da, es zählt von 0 ... 59 und fällt 
dann wieder auf 0 zurück.

von Viola (sky_w)


Lesenswert?

Simon schrieb:
> Ich habe heut ezum Glück selbst den Fehler behoben

Kann jemand sagen, was der Fehler war? Leider habe ich nämlich das 
gleiche Problem, obwohl mir der Code logisch erscheint und ich es 
genauso gemacht habt.

Zu Gustl B.
> So, hier die Komponenten. Und siehe da, es zählt von 0 ... 59 und fällt
dann wieder auf 0 zurück.
Die Komponenten habe ich auch, aber nicht die richtigen Anschlüsse. 
Konkret: Welches Signal muss an den enable Eingang des 10er Counter? 
Eigentlich overflow_1, aber dann wird es irgendwie unsynchron, weil der 
Takt reduziert sein soll.

von Kay-Uwe R. (dfias)


Lesenswert?

Viola schrieb:
> Die Komponenten habe ich auch, aber nicht die richtigen Anschlüsse.
> Konkret: Welches Signal muss an den enable Eingang des 10er Counter?
> Eigentlich overflow_1, aber dann wird es irgendwie unsynchron, weil der
> Takt reduziert sein soll.
Wenn alle kleineren Stellen auf ´9´ stehen, wird im nächsten Schritt die 
betroffene Stelle inkrementiert:
10er-Stelle bei ´...x9´
100er-Stelle bei ´...x99´
usw.

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


Lesenswert?

Viola schrieb:
> Leider habe ich nämlich das gleiche Problem
Beschreib doch mal dein Problem mit deinem Code und deiner Simulation 
und schreib was du erwartet hättest und was stattdessen passiert.

> Eigentlich overflow_1, aber dann wird es irgendwie unsynchron, weil der
> Takt reduziert sein soll.
Ein Design, das durchgehend nur 1  und denselben Takt hat, kann niemals 
"unsynchron" werden. Und ein Anfängerdeisgn mit mehr als 1 Takt ist mit 
höchster Wahrscheinlichkeit fehlerhaft.

> weil der Takt reduziert sein soll.
Es wird nicht der Takt reduziert, sondern nur die Häufigkeit des 
Takt-Enable-Signals.

von Viola (sky_w)


Lesenswert?

Hallo, erstmal vielen Dank für die ganzen Antworten! Tatsächlich habe 
ich das Problem mittlerweile selbst gelöst.

Die Lösung ist

signal clk_overflow : std_logic;

clk_overflow <= overflow_1 and clk_en;

Dabei habe ich ein Signal zu erstellt, dass den overflow und den intern 
reduzierten "Takt" mit einem logischen and verknüpft. Diese Signal habe 
ich dann an den enable-Eingang des 10er Zählers angeschlossen.


GenericBCDCounter_10 : GenericBCDCounter

generic map (

COUNT_MAX => 5

)

port map (

clk      => clk,

reset    => reset,

enable   => clk_overflow,

count    => count_10,

overflow => open

);

Damit ist das ursprünglich von Simon gestellte Problem gelöst, da der 
Takt reduziert und der Übertrag zum richtigen Zeitpunkt geschieht. Auch 
der Test entspricht der Erwartung.

von Rick D. (rickdangerus)


Lesenswert?

Viola schrieb:
> clk_overflow <= overflow_1 and clk_en;
Das sieht aus, als wenn es  irgendwann schief gehen könnte (Timing & 
Glitches).

Wenn man Takte 'enabeln' will, macht man das so:
1
process:
2
begin
3
4
  if rising_edge( clk) then
5
    if clk_en = '1' then
6
      -- nur
7
      -- hier
8
      -- kommt
9
      -- die
10
      -- getaktete
11
      -- Logik
12
      -- rein
13
    end if;
14
  end if;
15
16
end;

Oder ein Flip-Flop (=Register) für Schreibfaule:
1
  clk_overflow <= overflow_1 when rising_edge( clk) and clk_en = '1';

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


Lesenswert?

Viola schrieb:
> enable   => clk_overflow,
Mein Tipp: nenne einen Enable niemals Clock.

> den intern reduzierten "Takt"
Dann musst du auch den "Takt" nicht in Hochkommas schreiben, weil das 
nämlich gar kein Takt ist.

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.