When using non-ANSI style port declarations it is possible to have both a
port and net or variable declaration for the same signal. In this case the
range specification for the two declarations have to match.
In the current implementation if the range specifications do not match an
error is reported and no signal is created. This generates follow up errors
about the signal not being declared when it is used.
In some cases it even causes the application to crash. E.g. the task
elaboration expects the port signal to exist. If it does not it will crash.
To avoid this still create the signal, even when an error is detected. Use
the range specification of the net or variable in this case. Overall
elaboration will still fail due to the error, but the application will not
crash.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Currently there is a mix of passing line information either as `struct
vlltype` or as a separate `const char *file` and `unsigned lineno`.
For consistency always use the struct vlltype variant.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
There is a function prototype for `pform_make_reals()`, but the function
is never declared nor used. Remove it.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Check that queues of packed arrays are supported. These tests are identical
to the existing queue tests for other data type, just that the data type
is a packed array.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Check that it is possible to declare a dynamic array of a packed array
type. The test is identical to the tests for the other supported dynamic
array types.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Currently only dynamic arrays and queues of atom2 and vector types are
supported. Add support for packed arrays. Since these three types are
essentially handled the same internally supporting this only requires to
allow to elaborate a packed array base type.
Factor out type elaboration into a helper function that can be shared
between the elaboration of the base type of a dynamic array or queue and
the type for other signals. This gives consistent behavior and will also
make it easier to support additional base types for dynamic arrays or
queues.
Note that it is not yet possible to index elements of packed array dynamic
arrays or queues. But neither is it possible to do a bit select for vector
or atom2 type dynamic arrays or queues yet. Supporting this needs some
additional work.
There is one test that declares a queue of a struct type, but doesn't use
it since it is not supported. With this change a error will generated when
trying to declare a queue of a struct. So update that test to not declare
the variable so it does not fail.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Each data_type_t has a elaborate_type() method that returns the
corresponding ivl_data_t for that type.
Make use of that in PWire::elaborate_sig(). This removes duplicated code
and ensures consistent behavior between the different places where types
are elaborated.
This will also make it easier to add new data type that are going to be
elaborated this way.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
In the vvp all vector signals are in canonical form. This means a single
dimension and the lsb starts at 0.
This means that there is no need to restrict new operations for dynamic
arrays of vectors to vectors with 0 or 1 packed dimensions. Multiple packed
dimensions will work just fine. All that is needed is the total packed
width for the signal.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The SystemVerilog grammar explicitly allows an empty class item
declaration. The empty class item declaration is just a semicolon and has
no effect.
E.g. the following is legal
```
class C
int x;;;
endclass
```
Add support to the parser to accept empty class item declarations.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
String literals may have escaped special characters in them. Make sure
we are processing all the special characters that the standard supports,
and also fix the handling of the assignment to strings. Note that the
vvp input has string literals sanitized so that the parser can handle
the various binary values. desanitize the strings when pushing string
literals into the string stack. This fixes string assignments, and other
string operations.
The logic that decides whether a vector is scalar or not incorrectly flags
all variables that are declared in packages as scalar. As a result it is
not possible to do a part select on a vector declared in a package.
Rather than having an independent scalar flag consider a vector as scalar
if it does not have any packed dimensions.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
While a package can not have logic defined in it. It can have
variables with initializers. These initializers currently get
ignored when converting the package to a module in the
vlog95 backend.
Make sure packages are treated the same as modules here and
that the initializers are turned into initial blocks in the
generate vlog95 code.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Using Verilog data types on module input and inout ports is an error in
Verilog. But in SystemVerilog it is allowed and the port should be a net
with the specified data type.
Check that this is supported.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Add regression tests that check that declaring a net of type class, dynamic
array, queue or string result in an error.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
In Verilog module input ports can only have a packed dimensions and a
signed flag, but no explicit data type.
In SystemVerilog an explicit data type can be specified for module input
ports. Such a port is a net, regardless of the data type, unless
explicitly made a variable using the `var` keyword.
This works for the most part in the current implementation, but for some
data types such as `reg` and `integer` the input port is turned into a
variable. And since input port's can't be variables in the current
implementation this results in an error.
Fix this by completely removing the `reg_flag` that is used to indicate
that a certain data type is always a variable. There is no such restriction
on data types for SystemVerilog and for Verilog there are already checks in
place that a input port can only have an implicit (or real) data type.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
While a variable can have any data type the data type for nets is quite
restricted.
The SystemVerilog LRM section 6.7.1 ("Net declarations with built-in net
types") requires that the data type of a wire is either a 4-state packed or
a unpacked struct or unpacked array of 4-state packed types.
As an extension to this iverilog allows real data type for wires as well as
2-state packed types.
Add a check that reports an error if a net with any other type is declared.
In addition in Verilog a net can not have an explicit data type at all. It
can only have a packed dimension and a signed flag. As an extension to this
Icarus also allows wires to be of `real` data type.
Note that in Verilog mode the data type is checked in the parser since only
the parser knows whether the data type is an implicit type (`input reg
[7:0]` and `input [7:0] x` elaborate the same). But for SystemVerilog the
type is checked during elaboration since due to forward typedefs and type
parameters the type is not necessarily known in the parser.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Consistently use ivl_assert() instead of assert() in the eval_tree()
implementations. ivl_assert() includes information about which expression
triggered the assert and it makes debugging easier.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
There is now an implicit $unit package that needs to be ignored by
the blif target. Take this opportunity to make the root module checking
for the blif target a bit more robust.
Void functions can be used in always_comb, but since the compiler
uses the check_synth() method to generate some warnings, make sure
that function is implemented for functions as well as tasks.
Check that a output port that has a explicit data type, but no explicit
net type is elaborated as a variable type port.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
In SystemVerilog output ports are a variable if either:
* They are explicitly declared a variable (with the `var` keyword)
* There is no explicit net type, but a explicit data type
This is in detail described in section 23.2.2.3 ("Rules for determining port
kind, data type, and direction") of the LRM (1800-2017).
E.g.
```
output x // Net
output [1:0] x // Net
output signed x // Net
output wire x // Net
output wire logic x // Net
output var x // Variable
output logic x // Variable
output var logic x // Variable
output int x // Variable
output real x // Variable
output string x // Variable
output some_typedef x // Variable
```
At the moment the code checks for certain data types and only makes the
output port a variable for those. And it is even different data types
depending on whether the port is declared ANSI or non-ANSI style.
Change this so that if a data type is specified and it is not a implicit
data type (i.e. only ranges or `signed`) then the output is of type
variable.
This ensures consistent and correct behavior.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Currently module ports only support vectors, atom2, enum and struct packed
types, but not packed arrays.
Generalize the code so that any packed type is supported.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Task and function item rules are identical. Consolidate them into a single
set of rules to remove some duplicated code.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
NetNet::get_isint() is never used anywhere, remove it. The information
whether a signal is an integer is always directly queried from the signal
data type.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
For signals that are declared in a block string_type_t is already used to
pass the type information to the signal elaboration.
But for task ports it is passed as IVL_VT_STRING. Switch this over to also
passing the type information as a data_type_t.
This allows to remove the special handling for IVL_VT_STRING in the signal
elaboration.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Check that it is possible to declare task ports with SystemVerilog types.
Both ANSI style and one for non-ANSI style.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
SystemVerilog allows unpacked array dimensions on non-ANSI style task and
function ports.
To support this refactor pform_make_task_ports() to accept a of
pform_port_t, which in addition to the identifier name also allows to
specify per port unpacked dimensions.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Tasks and functions support two types of port declarations. Either ANSI
style, in parenthesis after the task name, or non-ANSI style, as
declaration statements in the task body.
In the current implementation SystemVerilog types are only accept for ANSI
style port declarations, while non-ANSI style only accept Verilog types
(reg, integer, time, real).
Add support for SystemVerilog data types for non-ansi style ports.
This also makes the parsing rules simpler since we can use `data_type` to
match all data types and don't need a explicit rule for each supported data
type.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>