A well known SystemVerilog limitation is that the same literal cannot appear in more enumerated types within a package (or more precisely within a scope).
Let's look at a concrete example.
package my_pkg1;
typedef enum {
NONE,
TX,
RX
} direction_e;
typedef enum {
NONE,
TX,
RX
} direction_e;
typedef enum {
NONE,
ADD,
SUB
} math_action_e;
endpackage : my_pkg1
module top();
import my_pkg1 :: *;
direction_e dir_type;
math_action_e math_action;
initial begin
dir_type = my_pkg1 :: NONE;
math_action = my_pkg1 :: NONE;
$display("dir_type=%s, math_action=%s", dir_type.name(), math_action.name());
end
endmodule : top
As discussed above, this code won't compile, because NONE is declared in both types.
//Output:
//** Error: Enum literal name 'NONE' already exists.
//** Error: Enum literal name 'NONE' already exists.
What I've seen people do in this case is try to uniquely the names by adding either prefixes or suffixes. For example, the math_action_e type would contain the value NONE2, in order not to clash with the NONE from direction_e.
Other simple solution would be to define each type in its own package. In the main package we would then import both of these packages:
package my_pkg1;
typedef enum {
NONE,
TX,
RX
} direction_e;
endpackage : my_pkg1
package my_pkg2;
typedef enum {
NONE,
ADD,
SUB
} math_action_e;
endpackage : my_pkg2
module top();
import my_pkg1 :: *;
import my_pkg2 :: *;
direction_e dir_type;
math_action_e math_action;
initial begin
dir_type = my_pkg1 :: NONE;
math_action = my_pkg2 :: NONE;
$display("dir_type=%s, math_action=%s", dir_type.name(), math_action.name());
end
endmodule : top
typedef enum {
NONE,
TX,
RX
} direction_e;
endpackage : my_pkg1
package my_pkg2;
typedef enum {
NONE,
ADD,
SUB
} math_action_e;
endpackage : my_pkg2
module top();
import my_pkg1 :: *;
import my_pkg2 :: *;
direction_e dir_type;
math_action_e math_action;
initial begin
dir_type = my_pkg1 :: NONE;
math_action = my_pkg2 :: NONE;
$display("dir_type=%s, math_action=%s", dir_type.name(), math_action.name());
end
endmodule : top
We've solved the collision problem, because each type is now defined in its own scope.
In above example if I assign NONE directly without using any scope then simulator would cowardly refuse to compile the code
above, because the literal NONE was imported via wildcards multiple
times and it's ambiguous.
initial begin
dir_type = NONE;
math_action = NONE;
$display("dir_type=%s, math_action=%s", dir_type.name(), math_action.name());
end
dir_type = NONE;
math_action = NONE;
$display("dir_type=%s, math_action=%s", dir_type.name(), math_action.name());
end
//Output:
//** Error: Identifier 'NONE' is not directly visible.
// Found multiple Declaration of 'NONE' through wildcard imports from these packages : my_pkg1, my_pkg2
//** Error: Undefined variable: 'NONE'.
// Found multiple Declaration of 'NONE' through wildcard imports from these packages : my_pkg1, my_pkg2
//** Error: Undefined variable: 'NONE'.
You can read more about it here
Thanks
ReplyDeleteCowardly refuse :)
ReplyDelete