Is it legal SystemVerilog syntax to declare a class inside a program? What about a function inside a generate block? The table below summarizes the syntactically legal combinations (marked with a check ✔ sign). The number of possible combinations is astonishing. And yet I bet some of the valid combinations have never crossed your mind! On the other hand, some combinations may not make any sense at all, for example – of what use might a class inside a generate be?! If you do have a use case for that, please leave a comment!
A few side notes:
- This is a purely syntactical analysis, according to the IEEE 1800-2012 standard.
- Implementations of the IEEE standard may allow a smaller or larger set of combinations.
- You can decorate types, functions, blocks or even assignments in your code with attributes; attributes can be attached to virtually any statement in the code. They are not rigorously speaking members, so that’s why they did not go into the table below.
- Access modifiers are also an interesting case. You may use access modifiers only in classes and only for function declarations, task declarations, variable declarations, type declarations (typedefs) and nettype declarations. Compared to Java for instance, you cannot declare a local (private) inner class in SystemVerilog. Parameters also make an interesting case, as they cannot be hidden; even a localparam is always public.
- A generate block is actually a for begin…end or if begin…end block inside a module, and is referred as such in the table below. Wrapping these blocks in generate … endgenerate blocks is optional syntax.
- Rigorously speaking, a library may only contain design elements, such as modules, primitives, interfaces, programs, packages, or configurations (IEEE 1800-2012 section 33.2.1). However, for brevity we have also checked under the library column the members of “compilation-unit scope name space”, that is functions, tasks, etc. which are not encapsulated by any other language construct (IEEE 1800-2012 section 3.13).
CONTAINERS | |||||||||||||||
library | package | class | module | interface | program | struct | union | enum | checker | generate | config | primitive | |||
M E M B E R S |
function | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||
task | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||||
event | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |||||||
variable | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |||||
parameter | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |||||||
#parameter | ✔ | ✔ | ✔ | ✔ | |||||||||||
port | ✔ | ✔ | ✔ | ✔ | |||||||||||
initial block | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||||||
final block | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||||||
always block | ✔ | ✔ | ✔ | ✔ | |||||||||||
modport | ✔ | ✔ | |||||||||||||
clocking block | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||||||
constraint | ✔ | ||||||||||||||
properties | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||||
sequence | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||||
instance | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||||||
assertion | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||||||
enum item | ✔ | ||||||||||||||
generate | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||||||
T Y P E S |
covergoup | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||
class | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||||
module | ✔ | ✔ | |||||||||||||
interface | ✔ | ✔ | ✔ | ||||||||||||
program | ✔ | ✔ | ✔ | ||||||||||||
struct | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |||||||
union | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |||||||
enum | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | |||||||
checker | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ||||||||
typedef | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
Shalom Bresticker
November 18th, 2014 10:51:19