Can Verilog variables be given local scope to an always block?

mksuth picture mksuth · Sep 16, 2014 · Viewed 20.8k times · Source

I sometimes find it useful to use blocking assignments for "local variables" inside clocked always blocks. This can help cut down on repeated code.

To avoid accidentally using the same variable in a different always block (which can be non-deterministic for simulation), I'd like to give it local scope. Is there a nice synthesizable way of doing this?

Something like:

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 seems to be okay with this, but Synplify doesn't seem to like it.)

Answer

Chiggs picture Chiggs · Sep 16, 2014

I'm not sure of the semantics in plain Verilog, but according to the SystemVerilog LRM section 6.21:

Variable declarations shall precede any statements within a procedural block.

Therefore the following is legal 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

Note that I have moved the variable declaration sum_temp into the process, thereby limiting the scope and removing the need for the named sum block. This compiles on Modelsim and Riviera (example on EDA Playground).

If your tool doesn't support this syntax, raise a bug!