2014-09-15 10 views
8

Manchmal finde ich es nützlich Blockierungszuweisungen für "lokale Variablen" in getakteten immer Blöcken zu verwenden. Dies kann helfen, wiederholten Code zu reduzieren.Können Verilog-Variablen lokalen Bereich zu einem immer blockieren?

Um zu vermeiden, dass Sie versehentlich dieselbe Variable in einem anderen always-Block verwenden (der für die Simulation nicht deterministisch sein kann), möchte ich einen lokalen Bereich angeben. Gibt es eine schöne synthetisierbare Art, dies zu tun?

Etwas wie:

module sum3(
    input   clk, 
    input  [7:0] in1, 
    input  [7:0] in2, 
    input  [7:0] in3, 
    output reg [7:0] result, 
    output reg [7:0] result_p1); 

    begin :sum 
    reg [7:0] sum_temp; // local variable 
    always @(posedge clk) begin 
     sum_temp = in1 + in2 + in3; 
     result <= sum_temp; 
     result_p1 <= sum_temp + 1; 
    end 
    end 

endmodule 

(. ModelSim scheint dies in Ordnung zu sein, aber Synplify scheint nicht zu mögen)

+0

Ihr Code hat mehrere Kompilierungsfehler mit den 2 Simulatoren, die ich verwendet habe (VCS und Incisive). – toolic

+0

Bearbeitet, um die Kompilierungsfehler zu beheben. – mksuth

+0

Irgendwelche Rückmeldungen vom Downvoter? – mksuth

Antwort

10

Ich bin nicht sicher, ob der Semantik im Klar Verilog, sondern nach dem SystemVerilog LRM Abschnitt 6.21:

Variablendeklarationen müssen allen Anweisungen innerhalb eines prozeduralen Blocks vorausgehen.

Deshalb finden Sie rechtliche Syntax in SystemVerilog:

module sum3(
    input   clk, 
    input  [7:0] in1, 
    input  [7:0] in2, 
    input  [7:0] in3, 
    output reg [7:0] result, 
    output reg [7:0] result_p1); 

    always @(posedge clk) begin : sum 
    reg [7:0] sum_temp; // local variable (scope limited to process) 
    sum_temp = in1 + in2 + in3; 
    result <= sum_temp; 
    result_p1 <= sum_temp + 1; 
    end 

endmodule 

Bitte beachte, dass ich die Variablendeklaration sum_temp in den Prozess bewegt habe, um dadurch den Umfang zu begrenzen und die Notwendigkeit für den benannte sum Block zu entfernen. Dies kompiliert auf Modelsim und Riviera (Beispiel auf EDA Playground).

Wenn Ihr Tool diese Syntax nicht unterstützt, melden Sie einen Fehler!

+1

Dies kompiliert nicht in einfachem Verilog, jedoch fügt das einfache Hinzufügen einer Markierung zu der Anweisung 'begin' des Immerblocks den Trick, z. 'Beginnen: Summe'. @ Chiggs, Wenn du das bearbeiten willst, dann denke ich, das ist die beste Antwort. – mksuth

2

Trotz der gemeinsamen Leitlinie, nach innen blockiert Zuweisungen getaktet immer Blöcke ist in Ordnung, und irgendwann, wie Sie erwähnt nützlich. Siehe hier: https://stackoverflow.com/a/4774450/1383356

Einige Tools unterstützen jedoch möglicherweise keine lokalen Variablen, die in einem Anfangs-/Endblock definiert sind.

Alternativ können Sie versuchen, einige oder alle der Körper der immer blockieren in einer Aufgabe setzen:

task SUM_TASK(); 
    reg [7:0] sum_temp; // local variable 
    sum_temp = in1 + in2 + in3; 
    result <= sum_temp; 
    result_p1 <= sum_temp + 1; 
endtask 

always @(posedge clk) begin 
    SUM_TASK(); 
end 

Verilog Aufgaben können den Zugriff auf globale Variablen sowie auf lokaler Ebene haben. Sie können auch nicht blockierende Zuweisungen enthalten.

2

Der Standard sythesizable Weg ist mit einer eine kontinuierliche Zuordnung verwenden wire:

module sum3(
    input  clk, 
    input [7:0] in1, 
    input [7:0] in2, 
    input [7:0] in3, 
    output reg [7:0] result, 
    output reg [7:0] result_p1); 

    wire [7:0] sum_temp = in1 + in2 + in3; 
    always @(posedge clk) begin 
     result <= sum_temp; 
     result_p1 <= sum_temp + 1; 
    end 
endmodule 
+0

Dies funktioniert für dieses einfache (und konstruierte) Beispiel, aber in komplexeren Fällen kann dies die Lesbarkeit beeinträchtigen (Zuweisungen enden weit entfernt von dem Ort, an dem die Variablen verwendet werden). Es gibt auch Fälle, in denen Sie verschiedene Zwischenwerte der "lokalen Variablen" verwenden möchten. – mksuth

+0

@mksuth Ich werde Lesbarkeit nicht schaden. "Zuweisungen enden weit entfernt von dem Ort, an dem die Variablen verwendet werden": Was meinst du weit weg? Es ist die Aufgabe von Placer und Router, um die Sie sich keine Sorgen machen müssen. Wenn Sie "verschiedene Zwischenwerte" verwenden möchten, verwenden Sie ein anderes "reg" für das Element im always block. – tod

+0

@tod, ich beziehe mich nur auf die menschliche Lesbarkeit des Codes.Wenn der "always" -Block hunderte von Codezeilen belegt, dann könnte die Verwendung einer "wire" für eine "intermediate variable" dazu führen, dass die Zuweisung weit entfernt ist (im Code), von wo aus die 'wire' tatsächlich verwendet wird 'Immer' Block. Der Code ist meiner Meinung nach besser lesbar, wenn die Zuweisung der Variablen und die Verwendung der Variablen im Code zusammengefasst sind. – mksuth

Verwandte Themen