2014-09-15 24 views
8

A volte mi sembra utile utilizzare assegnazioni di blocco per "variabili locali" all'interno di blocchi sempre funzionanti. Questo può aiutare a ridurre il codice ripetuto.Le variabili Verilog possono avere un ambito locale su un blocco sempre?

Per evitare di utilizzare accidentalmente la stessa variabile in un blocco sempre diverso (che può essere non deterministico per la simulazione), mi piacerebbe dargli un ambito locale. C'è un bel modo sintetico per farlo?

Qualcosa di simile:

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 sembra essere a posto con questo, ma Synplify non sembra piacere)

+0

Il codice presenta più errori di compilazione con i 2 simulatori utilizzati (VCS e Incisive). – toolic

+0

Modificato per correggere gli errori di compilazione. – mksuth

+0

Qualche commento da parte dell'elettore in basso? – mksuth

risposta

10

non sono sicuro della semantica in pianura Verilog, ma secondo il SystemVerilog LRM sezione di 6.21:

Le dichiarazioni variabili devono precedere qualsiasi dichiarazione all'interno di un blocco procedurale.

Pertanto la seguente sintassi è legale 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 

nota che mi sono mosso dichiarazione variabile sum_temp nel processo, limitando così la portata ed eliminando la necessità per il nome sum blocco. Questo compila su Modelsim e Riviera (esempio su EDA Playground).

Se il tuo strumento non supporta questa sintassi, genera un bug!

+1

Questo non viene compilato in semplice Verilog, tuttavia, semplicemente aggiungendo un'etichetta all'istruzione 'begin' del blocco always fa il trucco, ad es. 'Inizio: sum'. @Chiggs, se vuoi apportare quella modifica, allora penso che questa sia la migliore risposta. – mksuth

2

Nonostante la linea guida comune, utilizzando le assegnazioni di blocco all'interno di clock sempre blocchi è ok, e qualche volta come hai detto utile. Vedi qui: https://stackoverflow.com/a/4774450/1383356

Alcuni strumenti tuttavia, potrebbero non supportare le variabili locali definite all'interno di un blocco iniziale.

In alternativa, si può provare a mettere un po 'o tutto il corpo del blocco sempre in un compito:

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 

compiti Verilog possono avere accesso alle variabili globali e quelli locali. Inoltre, possono includere compiti non bloccanti.

2

Il modo sythesizable standard è di utilizzare un compito continuo con una 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

Questo funziona per questo semplice esempio (e forzato), ma in casi più complessi ciò può compromettere la leggibilità (gli assegnamenti finiscono lontano da dove vengono utilizzate le variabili). Inoltre, ci sono casi in cui potresti voler utilizzare diversi valori intermedi della "variabile locale". – mksuth

+0

@mksuth Non danneggerò la leggibilità. 'I compiti finiscono lontano da dove vengono usate le variabili ': Cosa intendi per molto tempo? È compito di placer e router di cui non devi preoccuparti. Se vuoi usare 'valori intermedi diversi 'usa un altro' reg' per questo all'interno del blocco sempre. – tod

+0

@tod, mi riferisco solo alla leggibilità umana del codice.Se il blocco 'always' occupava centinaia di righe di codice, quindi usando un' wire' per una "variabile intermedia", si potrebbe ottenere che l'assegnazione fosse lontana (nel codice) da dove il 'wire' è effettivamente usato all'interno del 'sempre' blocco. A mio parere, il codice è più leggibile quando l'assegnazione della variabile e l'uso della variabile sono raggruppati nel codice. – mksuth