我有时觉得对"局部变量"使用阻塞分配很有用。里面的时钟总是块。这可以帮助减少重复的代码。
为避免在另一个始终块中意外使用相同的变量(对于模拟可能是非确定性的),我想给它本地范围。有一种很好的综合方式吗?
类似的东西:
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似乎并不喜欢它。)
答案 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