Hardware Reference
In-Depth Information
After macro substitution, module m is quite different from the one after let
substitution
module m;
logic clk,a,b,c,d;
always @( posedge clk) begin :B1
a <= c || d;
b<=a;
end
assign c = c || d;
assign d=b;
endmodule
The difference is in the assign statement where in the case of let ,itisthe
definition from the module scope that is used, whereas in the case of a macro, it
is the latest definition in the lexical order. 1 To imitate the scoping of let using
macro definition, the symbol would have to be explicitly undefined when exiting the
scope and again defined to the original expression, as shown next. Clearly, this is
much more tedious and error prone.
'define macro_exp a && b
module m;
logic clk,a,b,c,d;
always @( posedge clk) begin
'define macro_exp c || d
a <= 'macro_exp;
b<=a;
'undef macro_exp
'define macro_exp a && b
end
assign c = 'macro_exp;
assign d=b;
endmodule
t
Unlike macro definitions, let declarations follow normal scoping rules. The
right-hand side expression from the definition is substituted in place of the
instance.
The instantiation of let is quite different from, e.g., calling a function because
the let body is substituted in the place of the instance. Unlike functions, let
instantiations cannot be recursive.
let declarations can have formal arguments. Again, unlike in functions, the
actual arguments are substituted for every occurrence of the corresponding formal
argument when the instance is replaced by the let body. The actual argument
variables must be visible in the instance scope. The formal argument types are
1 The compiler may issue a warning for the second macro definition, saying that the symbol has
been redefined.
 
Search WWH ::




Custom Search