Check that it is possible to declare a registered output of a user defined
primitive using the `output reg` syntax.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The parser currently expects `reg output` for UDP registered output. But
the correct syntax is `output reg`. Fix this to accept the correct syntax.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The `net_type` and `dt` parameter of `pform_set_net_range()` always get
passed the same value, NetNet::NONE and IVL_VT_NO_TYPE respectively. Both
these values are ignore by the function. So these parameters don't do
anything useful, remove them.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
There are a couple of different functions for the different data types that
are called when the type of a signal is set. But they all effectively do
the same.
Consolidate this code by moving the common code into the main
pform_set_data_type() function.
This allows to remove most of the type specific functions and eliminates
some duplicated code. It ensures consistent and data type independent
behavior at the parser level. Something that will be required to eventually
support type parameters.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
When creating a PWire for a enum type the signedness as well as whether
the base type is an integer is assigned to the wire.
But this information is never queried again. When creating the netenum_t
this information is directly taken from the enum_type_t.
The signedness and integer information of the PWire is only used when
elaborating a netvector_t.
Removing this makes the pfrom_set_enum() function similar to those for
other types and will allow us to consolidate them in follow up patches.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Check that it is possible to define the data type of a non-ANSI task port
in a separate declaration from the port direction. Add tests for both the
type declared before the port direction and for the type declared after the
port direction.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Check that it is possible to define the data type of a non-ANSI module port
in a separate declaration from the port direction. Add tests for both the
type declared before the port direction and for the type declared after the
port direction.
Note that this doesn't work yet correctly for integer type module ports
yet, so there are no tests for this. This will be addressed in follow up
work.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
When using non-ANSI ports (System)Verilog allows to have separate
declarations for the port direction and data type. E.g.
```
input x;
reg x;
```
It is also allowed to first declare the data type and then the port type.
E.g.
```
reg x;
input x;
```
Currently this fails with an error message. Add support for handling this
by allowing to change the port type of a signal from `NOT_A_PORT` to port
direction.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
For some data types the value returned by the `elaborate_type()` method is
shared among different signals of that type. E.g. all string or real types
get elaborated to the same ivl_type_s. This means the returned value must
not be modified, otherwise the data type for unrelated signals might get
changed.
To enforce this and protect against accidental breakage make the return
type of the `elaborate_type()` and the related `elaborate_type_raw()`
methods const.
Note that `ivl_type_t` is used for the new return type which is a typedef
for `const ivl_type_s*`.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Check that a range mismatch is detected for non-ANSI task ports when
port direction and data type are declared separately.
An error should be reported and no crash should occur.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Check that a range mismatch is detected for non-ANSI module ports when port
direction and data type are declared separately.
An error should be reported and no crash should occur.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
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.