Reputation: 972
I am a bit confused as to if it is legal, from a standards stand point, to read a parameter from an interface.
Like so
interface foo_if #(parameter BAR=5)();
...
logic [BAR-1:0] data;
modport slave(input data, ...);
endinterface
module foobar(foo_if.slave s);
...
logic [s.BAR-1:0] bar;
logic [$bits(s.data)-1:0] m_data;
...
endmodule
I have a problem where a major synthesis tool vendor can not even handle this. And they explicitly tell you in the help message that it is not allowed to use $bits() with a interface member.
However a simulation tool from another vendor handles this perfectly as does another synthesis tool I have.
However in SystemVerilog for Design by S. Sutherland et al. it is stated:
Because the design hierarchy may not be yet fully resolved during elaboration, it is illegal to assign a parameter, specparam, or localparam constants a value that is derived from elsewhere in the design hierarchy
However if I am not allowed to use parameters from interfaces, it really cripples the usefulness of interfaces.
The SystemVerilog 1800-2012 Standard on the other hand states:
25.10 Access to interface objects
Access to objects declared in an interface shall be available by hierarchical name reference, regardless of whether the interface is also accessed through a port connection or through a virtual interface, and regardless of the existence of any declared modports in that interface. A modport may be used to restrict access to objects declared in an interface that are referenced through a port connection or virtual interface by explicitly listing the accessible objects in the modport. However, objects that are not permissible to be listed in a modport shall remain accessible.
Upvotes: 8
Views: 5255
Reputation: 42788
The issue here is not about access, but what is allowed in places that require constant expressions. The LRM is not very clear that interface port references are not considered hierarchical references. But the tool is not complaining about s.BAR
, it is complaining about s.data
, which is a variable, not a parameter. Normally, you can't use variables in constant expressions, but the LRM 20.6.2 says
The $bits function can be used as an elaboration time constant when used on fixed-size data types; hence, it can be used in the declaration of other data types, variables, or nets.
So $bits(s.data) should have been treated like a parameter expression.
BTW, you should be using the latest freely available IEEE 1800-2012 LRM.
Upvotes: 3