Reputation: 149
I'm trying to use let-constructs instead of `define in my TB to access some signals via hierarchical paths. It's not going that great. "Normal" signals seems to work and I can access them, but typedef-signals act strange.
Here's a super simple example code that I use to trigger the error:
module dut();
// Create a type
typedef struct {
int foo;
int bar;
} ty_fooBar;
// Instantiate the type
ty_fooBar fooBar;
// Create an "alias" for fooBar
let fooBar2 = fooBar;
// Assign some values and try to access the struct members
initial begin
fooBar.foo = 3;
fooBar.bar = 7;
$display("fooBar: %p", fooBar );
$display("fooBar2: %p", fooBar2 );
$display("fooBar.fooBar: %p", fooBar.foo );
// $display("fooBar2.fooBar: %p", fooBar2.foo ); <- ERROR
end
endmodule
Simulation gives this result:
# fooBar: '{foo:3, bar:7}
# fooBar2: '{foo:3, bar:7}
# fooBar.fooBar: 3
So, fooBar should now be the same as fooBar2, ModelSim shows this with the $display command, but for some reason I can access fooBar.foo but not fooBar2.foo. I tried reading the IEEE standard but that didn't enlighten me.
What's the deal with let and typedef? Do I have some profound misunderstanding?
Upvotes: 0
Views: 515
Reputation: 42698
The let
statement combines the flexibility of a `define
macro with the well formed structure of function.
Like a macro. the let
arguments get replaced into the body of its definition. they may be typeless.
Like a function
, a let
declaration is local to a scope, including a package that can be imported. References to identifiers that are not arguments are searched from the point of the declaration. And finally the problem that you are facing is that a let
statement can only be called where an expression is allowed. In fact it places parenthesis around the body before substituting.
So your reference to fooBar2.foo
gets expanded as (fooBar).foo
which is not legal.
Upvotes: 2