Subject: Section 10.3 always_comb and function sensitivity
From: Adam Krolnik (krolnik@lsil.com)
Date: Thu Mar 28 2002 - 08:43:17 PST
Good morning;
The current spec compares always_comb and @* and notes this
difference:
"always_comb is sensitive to changes within the contents of a
function whereas @* is only sensitive to the changes to the
arguments of the function."
For example, the result of a block using 'always_comb' vs 'always @*'
will potentially be different when the code calls this simple function:
function [3:0] bad_code;
input [3:0] offset;
bad_code = offset + base; // Add the user offset to the global base.
endfunction
The argument for having this proposal is that it is a good usage
model to have functions that use information from within the
current module but are not identified in the signature of the
function. For example, a module has three computational units
within that utilize common information to all but also has
separate information for each.
module three_barrel(
input global_inputs;
input barrel1, barrel2, barrel3;
output global_outputs;
output barrel1_out, barrel2_out, barrel3_out;
reg ...;
always_comb
begin
<compute some global elements to all 3 barrels.>
...
end
reg barrel1_...;
reg barrel2_...;
reg barrel3_...;
always_comb
begin
<computation for barrel1 using barrel1
variables and global variables>;
...
// This is not a great idea - I copied the above large
// code and changed the names from barrel1 to barrel2.
// I wish there would be a better way?!
<same computation for barrel2 using barrel2
variable and global variable.>
...
// Arrrgh - same thing for barrel3... What to do?>
...
end
endmodule
Okay, how about taking the above code and making a function.
function barrel1_outs barrel_computation;
input barrel1_<signals>;
begin
<move code from above down here - don't change a thing :)>
end
Now rewrite the above block as follows.
always_comb
begin
barrel1_out = barrel_computation(barrel1_<signal set>);
...
barrel2_out = barrel_computation(barrel2_<signal set>);
...
barrel3_out = barrel_computation(barrel3_<signal set>);
...
end
Hey, that made my work much easier. Except that there are more
signals that the function depends on that I've noted in the
signature.
I would argue that this is a poor way for these reasons:
1. You will confuse a reviewer of the code to see that there
are variables not mentioned in the function interface.
2. Someone else using the code may not know that a variable
is used by the function and accidently make unintended changes.
There are other potential problems with this proposed feature:
1. What do you do with static variables in a function. Does
a change in these cause all blocks that use the function
to recompute their values?
2. What about functions that call functions, etc. This could
have a far reaching effect.
3. You prevent potential use of a function or require a copy
and rewrite if another use is required but with a few different
global variables.
I would propose an alternative approach to the use of the function.
This approach would use the nested modules. This would be a better
approach for these reasons:
1. Nested modules have access to the parent module's internal
signals - this provides the globals without having to
specifically define them in the interface.
2. Modules allow for multiple outputs whereas functions only
return 1 value. The above code would either have to create
structures to make it work or return a concatenation of
outputs. Both of these is more work and the second is error
prone.
3. Modules are the correct way to proceed when you have a
reuse of code due to replicated structures in a block.
4. Modules provide better debugging support than functions.
The information is maintained for each instance and you are
able to view the intermediate values. With functions, you are
not able to view all the intermediate values for each call.
I propose striking the above sentence from section 10.3.
"always_comb is sensitive to changes within the contents of a
function whereas @* is only sensitive to the changes to the
arguments of the function."
We would be left with always_comb still being different from @*.
Adam Krolnik
Verification Mgr.
LSI Logic Corp.
Plano TX. 75074
This archive was generated by hypermail 2b28 : Thu Mar 28 2002 - 08:44:58 PST