Forum: FPGA, VHDL & Co. Verilog - Zähler zählt nicht richtig


von Silvia A. (silvia)


Lesenswert?

Ich versuche mich nun in Verilog. Ich habe einen Zähler geschrieben, der 
bis 9 Zählen und dann wieder bei 0 anfangen soll. In der Simulation 
klappt er wunderbar, aber auf dem Dev Board (Spartan 3 von Digilent) 
zählt er einfach bis zum Überlauf (4 Bit = 15 )und fängt dann neu an. 
Lass ich ihn bis 7 Zählen, klappt er hingegen wunderbar. Es gibt eine 
Period Constraint, die auch eingehalten wird.
1
`timescale 1ns / 1ps
2
module test1(clk,button1,button2,button3,button4, ziffer, ziffer_on,dot);
3
    input clk;
4
    input button1;
5
    input button2;
6
    input button3;
7
    input button4;
8
    output [6:0] ziffer;
9
   output [0:3] ziffer_on;
10
   output dot;
11
12
  reg signed [3:0] cnt1 = 0;
13
  reg signed [3:0] cnt2 = 0;
14
  reg signed [3:0] cnt3 = 0;
15
  reg signed [3:0] cnt4 = 0;
16
  reg run;
17
  reg signed [23:0] t_cnt = 0;
18
  reg t_en;
19
  
20
  wire start_i;
21
  wire stop_i;
22
  wire reset_i;
23
  
24
  assign dot = 1'b1;
25
26
27
debounce db1(clk,button1,start_i);
28
debounce db2(clk,button2,stop_i);
29
debounce db3(clk,button3,reset_i);
30
display d1(clk, cnt4, cnt3,cnt2, cnt1, ziffer, ziffer_on);
31
32
33
34
35
// run = 1  wenn der Zähler läuft
36
always @ (posedge clk)
37
if (start_i == 1) 
38
  run <=  1'b1;
39
else if (stop_i == 1) 
40
  run <= 1'b0;
41
  
42
  
43
  
44
// alle x Takte einen weiterzählen  
45
always @ (posedge clk) 
46
begin
47
48
   t_cnt <= t_cnt + 1;
49
50
if (t_cnt == 0) t_en <= 1;
51
else t_en <= 0;
52
53
end
54
55
56
always @ (posedge clk) 
57
58
begin
59
60
  if (run && t_en) 
61
     begin
62
63
// 4. Ziffer  
64
    if (cnt1 == 9) 
65
      cnt1 <= 0; 
66
    else
67
      cnt1 <= cnt1 + 1  ;
68
69
    end 
70
end
71
72
    
73
  
74
endmodule

von CL (Gast)


Lesenswert?

Warum sind deine counter signed?

Falls die signed arithmetic richtig funktioniert, dann ist nur eine 7 
maximal moeglich.
Dein design hat auch irgendwie keinen reset.

Zuweisungen sollten auch immer die richtige Groesse haben, wenn man der 
Synthese Raum gibt um Mist zu bauen, dann wird sie irgendwann Mist 
bauen.

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


Lesenswert?

CL schrieb:
> Dein design hat auch irgendwie keinen reset.
Wozu ein Reset?
Die Werte werden doch initialisiert:   reg signed [3:0] cnt1 = 0;

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
> Die Werte werden doch initialisiert:   reg signed [3:0] cnt1 = 0;

Aber ob das in der Simulation so richtig rüberkommt? In Verilog 
entspricht diese Art der Initialisierung exakt diesem Code:
1
reg signed [3:0] cnt1;
2
3
initial begin
4
    cnt1 = 0;
5
end
Sollte jetzt noch die Testbench ein Taktereignis zum Zeitpunkt 0 
erzeugen, dann gibt es eine race condition zwischen der 
Initialisierung und dem Block, der cnt1 inkrementiert. Es müssen 
zugegebenermaßen einige Nebenbedingungen erfüllt sein, damit das 
schiefgeht.

@Silvia
Da Du ohnehin schon Verilog 200x verwendest (signed...), könntest Du 
auch gleich auf zeitgemäße "ANSI"-Portdeklarationen umstellen.

Warum Du allerdings signed verwendest wird mir auch nicht so ganz klar.

Gruß
Marcus

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


Lesenswert?

Marcus Harnisch schrieb:
> Sollte jetzt noch die Testbench ein Taktereignis zum Zeitpunkt 0
> erzeugen
Darf die (externe) Simulation in Verilog interne Signale des Prüflings 
ändern? (fragt ein VHDLer, dem das suspekt vorkommt...)

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
> Darf die (externe) Simulation in Verilog interne Signale des Prüflings
> ändern? (fragt ein VHDLer, dem das suspekt vorkommt...)

Wie meinen?

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


Lesenswert?

Marcus Harnisch schrieb:
> Wie meinen?
In VHDL sind nur Ports nach aussen sicht- und manipulierbar. Auf interne 
Signale wie cnt1 kann von der Testbench aus nicht zugegriffen werden. 
Von daher kann ich mir nicht vorstellen, dass zum selben Zeitpunkt die 
TB das cnt1 Register manipulieren kann...

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
> In VHDL sind nur Ports nach aussen sicht- und manipulierbar. Auf interne
> Signale wie cnt1 kann von der Testbench aus nicht zugegriffen werden.
> Von daher kann ich mir nicht vorstellen, dass zum selben Zeitpunkt die
> TB das cnt1 Register manipulieren kann...

Das ginge natürlich auch -- es handelt sich ja schließlich um Verilog 
:-)
Alle Objekte sind per hierarchischem Pfad erreichbar. Geht in VHDL2008 
doch auch, oder? 
http://www.doulos.com/knowhow/vhdl_designers_guide/vhdl_2008/vhdl_200x_ease/#hierarchicalnames

Das ist aber nicht, was ich meinte. Die Simulation mit einer steigenden 
Flanke beginnt, dann wird sowohl der Zähler gezählt, als auch das 
Register initialisiert. Die die Initialisierung mit einem blocking 
assignment erfolgt, wissen wir dank der race condition zwischen den 
beiden Blöcken nicht, ob beim Auswerten das Ausdrucks
1
cnt1 <= cnt1 + 1  ;
cnt1 bereits den Wert 0 hat, oder noch x ist.

Gruß
Marcus

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


Lesenswert?

Marcus Harnisch schrieb:
> Geht in VHDL2008 doch auch, oder?
Da wurden (als Tribut an die Software-Programmierer) auch globale 
Variablen eingeführt. Seis drum, wers braucht... :-/

Marcus Harnisch schrieb:
> wissen wir dank der race condition zwischen den beiden Blöcken nicht
Ist da was nicht sauber durchdefiniert?
Denn ich würde zwingend erwarten, dass der (implizite) 
Initialisierungsaufruf quasi zum Zeitpunkt -0ps ausgeführt wird. Auf 
jeden Fall noch vor irgendwas, das ich explizit hingeschrieben habe...

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
> Ist da was nicht sauber durchdefiniert?

Hallo? Jemand zu Hause? Wir reden von V-E-R-I-L-O-G :-)

> Denn ich würde zwingend erwarten, dass der (implizite)
> Initialisierungsaufruf quasi zum Zeitpunkt -0ps ausgeführt wird. Auf
> jeden Fall noch vor irgendwas, das ich explizit hingeschrieben habe...

Nein, deswegen habe ich ja den äquivalenten initial-Block erwähnt. In 
SystemVerilog hat man das allerdings, auf Kosten vollständiger 
Kompatibilität, richtig gemacht.

Bei der Simulation der meisten Designs sollte das allerdings kein 
Problem darstellen. In der Synthese sowieso nicht.

--
Marcus

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


Lesenswert?

Marcus Harnisch schrieb:
> Hallo? Jemand zu Hause? Wir reden von V-E-R-I-L-O-G :-)
Ist das nicht sauber durchdefiniert?  ;-)
> Hallo? Jemand zu Hause? Wir reden von V-E-R-I-L-O-G :-)
Ach klar: organisch gewachsen... :-)

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.