Verilog变量可以局部范围给一个总是阻塞吗?

时间:2014-09-15 22:03:34

标签: scope verilog blocking nonblocking

我有时觉得对"局部变量"使用阻塞分配很有用。里面的时钟总是块。这可以帮助减少重复的代码。

为避免在另一个始终块中意外使用相同的变量(对于模拟可能是非确定性的),我想给它本地范围。有一种很好的综合方式吗?

类似的东西:

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似乎没问题,但Synplify似乎并不喜欢它。)

3 个答案:

答案 0 :(得分:10)

我不清楚普通Verilog中的语义,但根据SystemVerilog LRM部分6.21:

  

变量声明应位于程序块中的任何语句之前。

因此,以下是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

请注意,我已将变量声明sum_temp移动到进程中,从而限制了范围并消除了对命名sum块的需要。这在Modelsim和Riviera上编译(例如EDA Playground)。

如果您的工具不支持此语法,请提出错误!

答案 1 :(得分:2)

尽管有共同的指导方针,但在时钟总是块内使用阻塞分配是可以的,有时你提到有用。见这里:https://stackoverflow.com/a/4774450/1383356

但是,某些工具可能不支持在开始端块中定义的局部变量。

或者,您可以尝试将always块的部分或全部部分放入任务中:

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任务可以访问全局变量和本地变量。此外,它们还可以包含非阻止分配。

答案 2 :(得分:2)

标准的可合成方式是使用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