Forum: FPGA, VHDL & Co. verilog sequentiell


von verilog_sequentiell (Gast)


Lesenswert?

Hallo,

Wieviel sequentielle Anweisungen darf man innerhalb eines always blocks 
angeben?

Für mein verständnis sollte der untenstehende always block einen 
undefinierten wert ausgeben.
ich erhalte in der simulation den wert 23.
Ist das korrekt, würde das im FPGA ebenso funktionieren und wenn ja 
wieviel sequentielle logik kann man denn in so einen block einbringen?
1
module gate(out, in1, in2);
2
input [7:0] in1;
3
input [7:0] in2;
4
output [7:0] out;
5
reg [7:0] out;
6
7
always @(in1 or in2) begin
8
    out = in1 + in2;
9
    out = out + 1;
10
    out = in1 + out;
11
end
12
endmodule
13
14
15
module main;
16
    reg [7:0] in1;
17
    reg [7:0] in2;
18
    wire  [7:0] out;
19
    
20
    gate dut_gate(out,in1,in2);
21
    
22
  initial 
23
    begin
24
        $monitor("%d",out);
25
      $display("Hello, World");
26
      
27
      #10 in1 = 10; in2 = 2;
28
      
29
      $finish ;
30
    end
31
endmodule

von Vancouver (Gast)


Lesenswert?

verilog_sequentiell schrieb:
> Für mein verständnis sollte der untenstehende always block einen
> undefinierten wert ausgeben.

Und warum erwartest Du das? Du verwendest das Blocking Assignment, das 
Ergebnis 23 ist völlig korrekt.

Eine Beschränkung der Anzahl der Statements in einem always-Kontext ist 
zumindest mir nicht bekannt.

von verilog_sequentiell (Gast)


Lesenswert?

> Eine Beschränkung der Anzahl der Statements in einem always-Kontext ist
> zumindest mir nicht bekannt.

Nun bis das Ergebnis korrekt anliegt vergeht zeit. Was ist wenn ich ein 
hundert mal den Ausdruck "out = out + 1;" reinschreiben würde?
Würde es dann nicht zu timing problemen kommen?
Ich meine im FPGA laufen die dinge parallel ab und nicht wie im 
prozessor seuentiell.

von Vancouver (Gast)


Lesenswert?

Die Designsoftware erzeugt im FPGA eine Schaltungsstruktur, die dasselbe 
Ergebnis liefert wie dein always-Statement. Das bedeutet nicht, dass 
diese Struktur sequenziell rechnet (Achtung Reizthema: FPGA werden nicht 
programmiert). Wenn Du 100mal out+1 hinschreibst, wird bei der 
Logiksynthese ein Addierer erzeugt, der out+100 berechnet. Das ergibt 
sich einfach aus der Logikoptimierung auf Gatterebene.
Natürlich können Deine Anweisungs so komplex werden, dass ein riesiges 
und damit langsames Gatternetzwerk herausskommt, aber das führt nur 
dazu, dass Du den Takt im FPGA entsprechend langsam machen musst. Die 
Anzahl der Statements im Always-Block wird dadurch nicht begrenzt

von Duke Scarring (Gast)


Lesenswert?

verilog_sequentiell schrieb:
> Würde es dann nicht zu timing problemen kommen?
Nö, wenn Du lange genug wartest, ist alles ok.
Die Durchlaufzeit spuckt Dir der Synthesizer mit aus.

Erst wenn ein Takt ins Spiel kommt, will man i.d.R. das das Ergebnis zur 
nächsten Flanke stabil am Eingang der nächsten FF-Stufe anliegt.

Duke

von verilog_sequentiell (Gast)


Lesenswert?

Danke das war sehr verständlich. Mal angenommen ich möchte meinen Takt 
nicht herunter takten wollen und mein design darf an manchen stellen 
auch gern asynchron werden, ist folgendes möglich?
Wie lang nun die ausführung dauert hängt nun doch sicherlich nur noch 
von dem speedgrade und der taktung des fpga und meiner logiktiefe.
1
module gate(out, in1, in2);
2
input [7:0] in1;
3
input [7:0] in2;
4
output [7:0] out;
5
6
reg [7:0] out;
7
8
reg [7:0] out1;
9
reg [7:0] out2;
10
reg [7:0] out3;
11
//..
12
reg [7:0] outn;
13
14
always @(in1 or in2) begin
15
    out1 = in1 + in2;
16
    out1 = out1 + 1;
17
end
18
19
always @(out1) begin
20
    out2 = out1 + out1;
21
end
22
23
always @(out2) begin
24
    out3 = out2 + out2;
25
end
26
27
always @(out3) begin
28
    outn = out3 + out3;
29
end
30
31
// ...
32
33
always @(outn) begin
34
    out = outn + outn;
35
end
36
endmodule
37
38
39
module main;
40
    reg [7:0] in1;
41
    reg [7:0] in2;
42
    wire  [7:0] out;
43
    
44
    gate dut_gate(out,in1,in2);
45
    
46
  initial 
47
    begin
48
        $monitor("%d",out);
49
      $display("Hello, World");
50
      
51
      #10 in1 = 10; in2 = 2;
52
      
53
      $finish ;
54
    end
55
endmodule

von Vancouver (Gast)


Lesenswert?

Das Ergebnis Deiner Berechnung ist (in1+in2+1)*2^n, also zwei Additionen 
und ein Shift. Das geht sehr schnell und die Logiksynthese wird das auch 
so umformen.

Asnychronität im Design ist kaum in den Griff zu bekommen, die 
Ergebnisse sind mitunter nicht vorhersehbar. Bei einer großen Logiktiefe 
verwendest Du besser Pipelineregister, um den kritischen Pfad zu 
reduzieren.
In Deinem Code fehlt übrigens der Takt. Getaktet und gepipelinet sähe 
das so aus (ungetestet, vermutlich falsche Syntax):
1
always @(posedge clk) begin
2
  out1 <= in1+in2+1;
3
  out2 <= out1 + out1;
4
  out3 <= out2 + out2;
5
...
6
  out  <= outn+outn;
7
end

Damit hast Du nach n Takten das erste Ergebnis (out). Aber wie gesagt, 
Pipelining wäre bei diesem Design nicht erforderlich

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.