Sekundenzähler auf zwei 7-Segment-Anzeigen

OP #7367792
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!
Gast #7367836
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.

Moderator (Firma: Titel) Persönliche Seite #7367900
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.

Angehängte Dateien:
OP #7368267
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

Gast #7368976
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.

Angehängte Dateien:
Gast #7369360
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

#7615930
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.

#7616484
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.

Moderator (Firma: Titel) Persönliche Seite #7616752
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.

#7618443
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.

#7618778
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';

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren