Issue #300
Macro name == module name interferes with module location via -y
| Status: | Closed | Start date: | 11/03/2010 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | Wilson Snyder | % Done: | 0% |
|
| Category: | - | |||
| Target version: | - |
Description
Some Verilog RTL we received from a vendor (i.e. we can't easily change it) uses an ifdef to control the instantiation of a module. The macro name in the ifdef is the same as the module name. Something like this simplified example:
module top; `define MYMOD `ifdef MYMOD MYMOD uMYMOD(); `endif endmodule
MYMOD.v exists in a subdirectory (subdir/MYMOD.v). Vhier cannot locate it when I use -y to point to the subdir:
vhier --module-files top.v -y subdir +libext+.v %Error: top.v:7: Cannot find MYMOD %Error: top.v:7: Module/Program/Interface reference not found: MYMOD Exiting due to errorsListing the MYMOD file explicitly on the command line works:
vhier --module-files top.v subdir/MYMOD.v
top.v
subdir/MYMOD.v
The culprit appears to be this bit of code in Netlist.pm:
sub remove_defines {
my $self = shift;
my $sym = shift;
# This function is HOT
# We only remove defines one level deep, for historical reasons.
# We don't require a ` as SystemC also uses this function and doesn't use `.
(my $xsym = $sym) =~ s/^\`//;
my $val = $self->defvalue_nowarn($xsym); #Undef if not found
$sym = $val if defined $val;
return $sym;
}
In top.v, the module name MYMOD does not have a leading ` so it shouldn't be treated as a macro. But it is expanded to the macro's value (the empty string) which prevents MYMOD.v from being found.
History
Updated by Wilson Snyder over 1 year ago
- Status changed from New to Resolved
- Assignee set to Wilson Snyder
Should have suspected that one would bite back.
Fixed in git for 3.305+. SystemC users will need the latest SystemC git change.
Updated by John Dickol over 1 year ago
Thanks for the quick update, but I think the fix will have the same problem. (Disclaimer: I only examined the modified code using git diff. I had trouble building the code I got from git.)
It looks like the non-backticked module name ("MYMOD") passed to remove_defines() will still get passed to defvalue_nowarn which returns the defined value "" which gets returned to the caller.
I think something like this (untried) will work:
sub remove_defines {
my $self = shift;
my $sym = shift;
# This function is HOT
my $xsym = $sym;
# We only remove defines one level deep, for historical reasons.
# We optionally don't require a ` as SystemC also uses this function and doesn't use `.
my $val = undef;
if($self->{remove_defines_without_tick}) {
# SystemC - always do lookup
$val = $self->defvalue_nowarn($xsym); #Undef if not found
} else {
# Verilog - only do lookup if $sym starts with `
if($sym =~ /^\`(.+)/) {
$xsym = $1;
$val = $self->defvalue_nowarn($xsym); #Undef if not found
}
}
$sym = $val if defined $val;
return $sym;
}
I see similar remove_defines subroutines in Getopt and Preproc - do they need a similar fix?
Updated by Wilson Snyder over 1 year ago
You're right, I added a test, saw it fail, then added the fix.
Also available in: Atom
![[logo]](/img/veripool_small.png)