Forum: FPGA, VHDL & Co. Verstehe Verhalten eines Zählers im FPGA nicht


von A.G. (Gast)


Lesenswert?

Hallo,

mein Zähler, ein 8bit großes Register namens "write_counter" verhält 
sich total seltsam, ich kann das einfach nicht nachvollziehen.
1
reg [7:0] write_counter;
2
3
4
always@ (posedge clk)
5
begin
6
7
8
  if(SW[0])
9
  begin
10
  
11
  case(write_counter)
12
      
13
      0:  begin
14
            sdram_res <= 1'b1;
15
            write_counter <= write_counter + 8'd1;
16
          end
17
          
18
     100: begin
19
            sdram_res <= 1'b0;
20
            sdram_length <= 8'd1;
21
            write_counter <= write_counter + 8'd1;
22
          end
23
          
24
     105: begin
25
            sdram_res <= 1'b1;
26
            write_counter <= write_counter + 8'd1;
27
          end
28
          
29
     120: begin
30
            sdram_wr <= 1'b1;
31
            write_counter <= write_counter + 8'd1;
32
          end
33
          
34
     128: begin
35
            write_counter <= write_counter + 8'd1;
36
          end
37
          
38
     129: begin
39
            if(sdram_done)
40
            begin
41
            sdram_wr <= 1'b0;
42
              write_counter <= 8'd110;
43
              sdram_address <= sdram_address + 23'd1;
44
            end
45
          end
46
          
47
     default:  
48
            write_counter <= write_counter + 8'd1;
49
  endcase
50
  
51
  end
52
  
53
54
end

von A.G. (Gast)


Angehängte Dateien:

Lesenswert?

Ups, bin aus Versehen schon auf "Absenden" gekommen.
Anbei noch ein SignalTap-Trace, den ich erstellt habe.

Das Problem ist, dass der Counter plötzlich von 111 auf 116 springt, 
obwohl noch einige Schritte dazwischen kämen.


Der Code von oben ist alt, wollte eigentlich den posten:
1
// Controls the SDRAM and writes data from fat32 module
2
always@ (posedge sdram_clk)
3
begin
4
5
  case(write_counter)
6
      
7
      0:  begin
8
            topsdram_res <= 1'b1;
9
            sdram_wr <= 1'b0;
10
            topsdram_address <= 31'd0;
11
            topsdram_length <= 8'd1;
12
            write_counter <= 8'd1;
13
          end
14
          
15
     100:  begin
16
            topsdram_res <= 1'b0;
17
            write_counter <= write_counter + 1'b1;
18
           end
19
          
20
     110:  begin
21
            topsdram_res <= 1'b1;
22
            step <= 1'b1;
23
            write_counter <= write_counter + 1'b1;
24
           end
25
          
26
     111:  begin
27
            step <= 1'b1;
28
            if(o_val)
29
            begin
30
              sdram_datain[15:8] <= data;
31
              write_counter <= write_counter + 1'b1;
32
            end
33
           end
34
          
35
     112:  begin
36
            step <= 1'b1;
37
            if(!o_val)
38
              write_counter <= write_counter + 1'b1;
39
           end
40
          
41
     114:  begin
42
            if(o_val)
43
            begin
44
              sdram_datain[7:0] <= data;
45
              //topsdram_res <= 1'b1;
46
              sdram_wr <= 1'b1;
47
              step <= 1'b0;
48
              write_counter <= write_counter + 1'b1;
49
            end
50
           end
51
          
52
          
53
     115:  begin
54
            step <= 1'b0;
55
            
56
            if(sdram_done)
57
            begin
58
              sdram_wr <= 1'b0;
59
              topsdram_address <= topsdram_address + 31'd2;
60
              write_counter <= 8'd2;
61
            end
62
            
63
            if(!o_val)
64
              write_counter <= write_counter + 1'b1;
65
          end
66
          
67
          
68
     116:  begin
69
            
70
            if(sdram_done)
71
            begin
72
              //if(done)
73
              //  write_counter <= write_counter + 1'b1;
74
              //else
75
              //begin
76
                //topsdram_res <= 1'b0;
77
                sdram_wr <= 1'b0;
78
                topsdram_address <= topsdram_address + 31'd1;
79
                write_counter <= 8'd110;
80
              //end
81
            end
82
            
83
           end
84
          
85
          
86
          
87
     default:  
88
         write_counter <= write_counter + 1'b1;
89
  endcase
90
  
91
end

von bko (Gast)


Lesenswert?

Wo findet man die Zeitskala auf dem "SignalTap-Trace"?
oder wie lang ist "der Counter  111" auf dem Bild?

von Georg A. (georga)


Lesenswert?

Bin jetzt nicht so fit in Verilog (br, schaut das Gestottere greislig 
aus), aber entweder hat der Simulator einen Bug oder du hast nicht den 
vollständigen Code gepostet.

von Lattice User (Gast)


Lesenswert?

Zur Info:
SignalTap == ChipsScope == Reveal  (Altera,Xilinx,Lattice)

Da sind entweder asynchrone Signal im Design oder Timing wurde nicht 
erfüllt.

von A.G. (Gast)


Lesenswert?

bko schrieb:
> Wo findet man die Zeitskala auf dem "SignalTap-Trace"?
> oder wie lang ist "der Counter  111" auf dem Bild?

Entschuldige, ich hatte keine Zeitskala eingefügt und deswegen beim 
Bearbeiten der Grafik einfach abgeschnitten.
Der Counter ist 5 Takte einer 50MHz clock lang im Zustand 8'd111.


Georg A. schrieb:
> Bin jetzt nicht so fit in Verilog (br, schaut das Gestottere greislig
> aus), aber entweder hat der Simulator einen Bug oder du hast nicht den
> vollständigen Code gepostet.

Der vollständige Code wäre zu lang. Aber was den counter betrifft, so 
wird er nur innerhalb dieses Codes verändert.


Lattice User schrieb:
> Zur Info:
> SignalTap == ChipsScope == Reveal  (Altera,Xilinx,Lattice)
> Da sind entweder asynchrone Signal im Design oder Timing wurde nicht
> erfüllt.

Welche Signale meinst denn genau bei diesem Code, sodass dieser Fehler 
auftritt?


Übrigens scheint es nicht nur ein paar Schritte zu überspringen. 
Manchmal, setzt es gar nicht die Signale, wie es im Code steht!
Beispiel: Im Code oben steht beim Schritt 114, dass ein Register high 
werden soll (sdram_wr <= 1'b1;), jedoch scheint es manchmal zufällig das 
einfach zu "vergessen". Es befindet sich zwar mehrere Takte lang im 
State 114, aber sdram_wr wird nicht high!

von bko (Gast)


Lesenswert?

Nun aber ohne mehr Information wird das nichts, denn am gezeigten Code 
liegts eigentlich nicht.
Wo kommen z.B.  >sdram_done< und >o_val< denn her und
sind das syncrone Signale (also syncron zu sdram_clk)?
Und was sagt die Simulation?

von A.G. (Gast)


Lesenswert?

bko schrieb:
> Nun aber ohne mehr Information wird das nichts, denn am gezeigten Code
> liegts eigentlich nicht.
> Wo kommen z.B.  >sdram_done< und >o_val< denn her und
> sind das syncrone Signale (also syncron zu sdram_clk)?
> Und was sagt die Simulation?

Die Signale waren tatsächlich asynchron, Fehler gefunden!
Aber ich hätte nicht gedacht, dass das solche Auswirkungen hat. Das kann 
ich mir eigentlich auch nicht erklären, schließlich sind die Signale 
o_val und sdram_done viel länger high, als ein clock-cycle.
Definitiv keine stablile Logik, das hätte ich selber erkennen sollen.
Ich danke euch für eure Hilfe und Gelduld!

von Johannes E. (cpt_nemo)


Lesenswert?

A.G. schrieb:
> Das kann
> ich mir eigentlich auch nicht erklären, schließlich sind die Signale
> o_val und sdram_done viel länger high, als ein clock-cycle.

Es ist nicht wichtig, wie lange die "high" sind, sondern zu welchem 
Zeitpunkt die Signale ihren Pegel ändern.

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


Lesenswert?

Zum Hintergrund des Problems:
http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html
Ein Zähler ist die einfachste Form einer FSM...

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.