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.)
Despite the common guideline, using blocking assignments inside clocked always blocks is ok, and sometime as you mentioned useful. See here: https://stackoverflow.com/a/4774450/1383356
Some tools however, may not support local variables defined inside a begin-end block.
Alternatively, you can try putting some or all of the the body of the always block in a task:
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 tasks can have access to global variables as well as local ones. Also, they can include non-blocking assignments.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With