2014-09-15 33 views
8

Czasami przydaje się użycie blokujących przypisań dla "zmiennych lokalnych" w taktowanych zawsze blokach. Pomoże to ograniczyć liczbę powtarzających się kodów.Czy zmienne Verilog mogą mieć zakres lokalny na zawsze blok?

Aby uniknąć przypadkowego użycia tej samej zmiennej w innym bloku zawsze (który może być niedeterministyczny w przypadku symulacji), chciałbym nadać mu zasięg lokalny. Czy istnieje ładny syntezowalny sposób robienia tego?

Coś jak:

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 wydaje się być w porządku z tym, ale Synplify nie wydaje się to podoba)

+0

Twój kod zawiera wiele błędów kompilacji z dwoma używanymi przeze mnie symulatorami (VCS i Incisive). – toolic

+0

Edytowane, aby naprawić błędy kompilacji. – mksuth

+0

Jakieś opinie od niedziałających wyborców? – mksuth

Odpowiedz

10

nie wiem, semantyki w zwykły Verilogu, ale według części SystemVerilog LRM 6,21:

Deklaracje zmiennych poprzedzają wszelkie oświadczenia w ramach bloku proceduralnego.

Dlatego Oto składnia prawny w 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 

pamiętać, że zostały przeniesione deklaracji zmiennej sum_temp do procesu, a tym samym ograniczenie zakresu i eliminuje konieczność nazwanego sum bloku. Kompiluje się na Modelsim i Riviera (przykład na EDA Playground).

Jeśli twoje narzędzie nie obsługuje tej składni, podnieś błąd!

+1

To nie kompiluje się w zwykłym Verilogu, jednak po prostu dodanie etykiety do instrukcji "begin" bloku zawsze działa, np. 'begin: sum'. @Chiggs, Jeśli chcesz dokonać tej edycji, to myślę, że jest to najlepsza odpowiedź. – mksuth

2

Pomimo wspólnych wytycznych, przy użyciu zadania blokujące wewnątrz taktowany zawsze bloki jest ok, a kiedyś, jak wspomniałeś, przydatne. Zobacz tutaj: https://stackoverflow.com/a/4774450/1383356

Niektóre narzędzia mogą jednak nie obsługiwać zmiennych lokalnych zdefiniowanych w bloku początkowym.

Alternatywnie, można spróbować umieścić niektóre lub wszystkie z ciałem Zawsze zablokować w zadaniu:

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 zadania mogą mieć dostęp do zmiennych globalnych, jak i lokalnych nich. Mogą też zawierać zadania nieblokujące.

2

Standardowe sythesizable sposobem jest użycie stałego przydziału z 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

Działa to w tym prostym (i wymyślonym) przykładzie, ale w bardziej złożonych przypadkach może to zaszkodzić czytelności (przypisania kończą się daleko od miejsca, w którym zmienne są używane). Są też przypadki, kiedy możesz chcieć użyć różnych pośrednich wartości "zmiennej lokalnej". – mksuth

+0

@mksuth Nie zaszkodzę czytelności. 'zadania kończą się z dala od miejsca, w którym używane są zmienne." Co masz na myśli mówiąc daleko? Jest to zadanie placer i routera, o które nie musisz się martwić. Jeśli chcesz użyć "różnych wartości pośrednich" użyj innego "reg" dla niego w bloku zawsze. – tod

+0

@tod, mam na myśli tylko ludzką czytelność kodu.Jeśli blok 'always' zajęłby setki linii kodu, użycie' drutu' dla "zmiennej pośredniej" może spowodować, że przypisanie będzie daleko (w kodzie) od miejsca, w którym 'przewód' jest rzeczywiście używany wewnątrz blok 'always'. Moim zdaniem kod jest bardziej czytelny, gdy przypisanie zmiennej i użycie zmiennej są zgrupowane w kodzie. – mksuth