Commit Graph

250 Commits

Author SHA1 Message Date
Lars-Peter Clausen 8f78590bd2 Remove most references to ivl_variable_type_t from the parser
The parser used to have behavior that was dependent on the
`ivl_variable_type_t` of a signal. It also used the `ivl_variable_type_t`
of a signal to decide whether a signal can be re-declared as part of a
non-ANSI port declaration.

Neither of these is done anymore and most of the reference to
`ivl_variable_type_t` can be removed from the parser. The only thing it is
still needed for is to decide whether a vector type is 4-state or 2-state.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-09-15 09:36:19 +02:00
Lars-Peter Clausen b307da0831 pform_make_task_ports(): Reuse `pform_set_net_range()`
`pform_make_task_ports()` has code very similar to `pform_set_net_range()`.
Use that helper function instead of duplicating the code.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-09-15 09:36:19 +02:00
Lars-Peter Clausen f1e50e927b Remove unused `make_range_from_width()`
The last user of the `make_range_from_width()` was removed in commit
f6042033d0 ("Correctly handle separate port type declaration for
`integer` and `time`").

Remove the function itself as well.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-09-14 13:50:31 +02:00
Lars-Peter Clausen e15b125da8 Replace svector with std::vector
The custom `svector` class is essentially a subset of `std::vector`. There
is no inherent advantage to using `svector`. Both have the same memory
footprint.

`svector` was designed to be of static size, but there are a few places in
the parser where it has to grow at runtime. Handling this becomes a bit
easier by switching to `std::vector` since it is possible to use its
methods which take care of resizing the vector.

This also allows to remove the unused parameter of the `lgate` struct
constructor, which was only needed for compatibility with `svector`.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-05-15 21:56:48 +02:00
Lars-Peter Clausen dddc41891e lgate: Inherit from LineInfo
The lgate struct has its own fields for tracking file and line number,
while everything else that has this information attached inherits from the
LineInfo class.

Make lgate also inherit from LineInfo for consistency.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-24 17:00:46 +02:00
Lars-Peter Clausen 254e9dc094 pform_set_data_type(): Avoid signal look-up by name
The `pform_set_data_type()` function is used to set the data type as well
as attributes on a list of signals. Currently the signals are passed as a
list of signal names and then the function looks up the actual signals from
the names.

Refactor the code to directly pass a list of signals. This will allow to
skip the look-up by name.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-18 12:07:16 +02:00
Stephen Williams 66a5cfe660
Merge pull request #691 from larsclausen/cleanup-pform-makewire
Small cleanups for `pform_makewire()`
2022-04-17 18:38:15 -07:00
Lars-Peter Clausen 52da910313 Move pform_set_reg_idx() into pform_makewire()
`pform_set_reg_idx()` is always called right after `pform_makewire()`. Move
it into the function. This avoids the extra lookup that
`pform_set_reg_idx()` does to get the PWire from the name.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-17 09:22:47 +02:00
Lars-Peter Clausen 7aee124cfe pform_makewire(): Remove unused parameters
There are a few parameters for `pform_makewire()` and related functions
that always get passed the same value.

 * port_type is always NetNet::NOT_A_PORT
 * attr is always 0

Remove these parameters.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-17 09:22:31 +02:00
Lars-Peter Clausen b2516ead66 Remove unused function `pform_set_param_from_type()`
The `pform_set_param_from_type()` function is not used. The last user was
removed in commit 16646c547c ("Rework parsing of parameter types").

Remove the function itself.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-04-16 15:28:35 +02:00
Lars-Peter Clausen aa7e253026 Consolidate most pform_set_<type>_data_type() functions
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>
2022-03-16 11:41:27 +01:00
Lars-Peter Clausen 56f36a96d3 parser: Consistently pass line information as `vlltype`
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>
2022-03-12 16:18:31 +01:00
Lars-Peter Clausen 3906d043b9 Remove unused pform_make_reals() function prototype
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>
2022-03-12 16:18:15 +01:00
Lars-Peter Clausen 472598dd74 Report errors for nets with invalid data type
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>
2022-03-03 10:30:12 +01:00
Stephen Williams 978717f914
Merge pull request #623 from larsclausen/task-ports-sv
Support SystemVerilog non-ansi task/function port declarations
2022-02-26 09:16:33 -08:00
Lars-Peter Clausen b0c386182a Support unpacked array dimensions on non-ansi style task ports
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>
2022-02-25 10:43:28 +01:00
Lars-Peter Clausen c631ff2483 Support SystemVerilog types for non-ansi task port declarations
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>
2022-02-25 10:42:56 +01:00
Lars-Peter Clausen d104e28dbf Support non-overridable parameters in classes
SystemVerilog allows `parameter` and `localparam` to declare constants
within a class scope.  E.g.

```SystemVerilog
class C;
localparam A = 10;
endclass
```

In this context both declare a local parameter that can not be overwritten.

Supporting this can be achieved for the most part by adding a parser
sub-rule in class declaration rule. In addition some extra support code is
needed to mark the parameter as non-overridable.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-19 13:45:22 +01:00
Stephen Williams cc0a8c8dd2
Merge pull request #618 from larsclausen/signal-decl-consolidation
Consolidate signal declaration
2022-02-18 08:27:52 -08:00
Lars-Peter Clausen 9da057ceb1 Add helper function for creating variable declarations
Variables don't have a delay or strength and the NetNet::Type is known. Add
a small wrapper around pform_makewire() that can be used to create
variables. This will allow to reduce the boilerplate code for variable
declarations.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-18 11:59:09 +01:00
Lars-Peter Clausen 6708c0f6df pform_makewire(): Allow to specify attributes
There are a few places where pform_makewire() is used and attributes can be
attached to the created net or variable. At the moment pform_makewire()
doesn't allow to specify the attributes, and they either get dropped
silently or with a warning.

Add support for passing the attributes to pform_makewire() which will then
pass it on to pform_set_data_type() to attach it to the declared net or
variable.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-18 11:59:09 +01:00
Lars-Peter Clausen a5e9358d42 Consolidate pform_makewire() variants
There are currently two very similar implementations of pform_makewire().
One that takes a `net_decl_assign_t`, the other a `std::list<decl_assignment_t*>`.

The one that takes a `std::list<decl_assignment_t*>` is a superset of the
other. It can handle both wires and variables, while the other can only
handle wires.

Update the parser to generate a `std::list<decl_assignment_t*>` for wire
declarations. This allows to remove one of the two functions.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-18 11:58:31 +01:00
Lars-Peter Clausen 47b6ee714d Remove unused pform_makewire() variants
There are two versions of pform_makewire() that are not used anywhere,
remove them.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-18 10:40:53 +01:00
Lars-Peter Clausen 6730ead119 Generate error for invalid declarations within generate block
Most things that can be declared in a module can also be declared in a
generate block.

But there are a few exceptions that can not be declared in generate block
 * module, program or interface declaration
 * specify block or specparam
 * timeunit

Some of these currently work while some of them trigger an assertion and
cause and application crash.

Add checks to make sure that all of them these are reported as an error and
do not cause a crash.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-16 11:23:39 +01:00
Lars-Peter Clausen 4a87bee3c0 Support parameters without default value
SystemVerilog allows to omit the default value of a parameter declared in a
parameter port list. In this case the parameter must be overridden for
every module instance. This is defined in section 6.20.1 ("Parameter
declaration syntax") of the LRM (1800-2017).

In addition a module that has a parameter without a default value does not
qualify for automatic toplevel module selection.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-13 18:21:56 +01:00
Lars-Peter Clausen 618959d147 Add helper function to emit error when SystemVerilog is requried
When encountering a construct that requires SystemVerilog in most cases an
error message is generated when SystemVerilog is not enabled and parsing
simply continues.

Factor the checking and generating of the error message into a helper
function. This slightly reduces boiler plate code and gives consistent
error messages.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-02-11 10:46:02 +01:00
Lars-Peter Clausen ac040dae42 Consolidate parameter and localparam declaration handling
The code for handling parameter and localparameter declarations is very
similar. Consolidate this into a single helper function.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-27 18:51:13 +01:00
Lars-Peter Clausen 9e6f651e09 Put enum type into scope when declaring it
When creating an enum type it must be added to the scope where it is
declared so it can later be elaborated and the enum and its names can be
referenced in expressions.

In addition the names of the enum must be added to the lexor scope so that
name collisions are detected and can be reported as errors.

This is done with pform_put_enum_type_in_scope() function.

At the moment the function is called from two different places
 * When adding a typedef of a enum type
 * When creating a signal of a enum type

In addition the enum_type_t is added to a class scope `enum_sets` when
declaring a enum property in a class. But this only makes sure that the
enum gets elaborated, its names are not added to the lexor scope.

This works fine for the most part, but breaks for a few corner cases.

E.g. it is possible to declare a enum type as part of the subtype of
another packed type such as structs or packed arrays. E.g.

```
struct packed {
  enum {
    A
  } e;
} s;
```

This is not covered by either of the cases above and neither do the names
of the enum get added to the lexor scope, nor is the enum type elaborated.

Another corner case that is currently not working is declaring a class
property where the type is a typedef of a enum that is declared outside of
the class. In this case the enum is elaborated again inside the class
scope. E.g. the below is supposed to work, but fails with an already
declared symbol error.

```
typedef enum {
  A
} e_t;

class C;
  typedef enum {
    A
  } e1;
  e_t e2;
endclass
```

In addition since for enums declared in classes they are only added to
`enum_sets`, but names are not added to the lexor scope, it is possible to
declare a different symbol in the class scope with the same name.

E.g. the following elaborates fine

```
class C;
  enum {
    A
  } e;
  typedef int A;
endclass
```

To fix this call pform_put_enum_type_in_scope() when the enum_type_t is
created in the parser. This makes sure that it is handled the same
regardless where the type is declared or used.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
2022-01-15 21:24:23 +01:00
Martin Whitaker dcc9b59f6d Support SV [size] dimension for module and gate instances (issue #553).
Also output a proper error message if multiple dimensions are supplied
instead of failing an assertion.
2021-11-06 00:02:38 +00:00
Martin Whitaker ecbbb60fb6 Remove "using namespace std" from compiler header files and fix the fallout. 2021-11-04 16:55:03 +00:00
Martin Whitaker c34167b2c0 Fix detection of directly nested generate constructs.
If a generate construct is enclosed in a begin-end pair, it can't
be directly nested (1364-2005 section 12.4.2).
2021-08-04 10:37:26 +01:00
Cary R 60a77b08d2 Add compiler and the start of vvp support for ->> 2021-02-19 23:21:51 -08:00
Cary R 7bb8a4463f Time literals need to be rounded using the time precision 2021-02-13 01:11:43 -08:00
Cary R 18392a464d Some clean up and add initial support for elaboration system tasks 2021-02-01 00:22:01 -08:00
Cary R d1eb4befcc Add initial parsing for let construct 2021-01-18 13:06:44 -08:00
Stephen Williams 16646c547c Rework parsing of parameter types
Use the common data_type_or_implicit rules to support type
definitions for parameters. This eliminates a bunch of special
rules in parse.y, and opens the door for parameters having
more complex types.
2020-12-27 21:17:57 -08:00
Martin Whitaker 33b822d997 Add support for local genvar declaration in generate loops.
As requested in GitHub issue #304.
2020-01-31 20:29:22 +00:00
Martin Whitaker 0023804777 Add support for increment/decrement operators in generate loop iteration.
As requested in GitHub issue #303.
2020-01-30 21:45:04 +00:00
Martin Whitaker c5c264400e Add support for package scope resolution for named events. 2019-10-01 09:07:54 +01:00
Martin Whitaker 12fe4f2bf3 Fix handling of wildcard-imported types.
Don't add them to the explicit imports until they are referenced legally.
Stop searching when a matching name is found, even if it isn't a type name.
2019-10-01 09:07:48 +01:00
Martin Whitaker b0142a6406 Add support for named events in packages. 2019-10-01 09:07:39 +01:00
Martin Whitaker 03c4c63df1 Fix file/line reported for duplicate named blocks. 2019-09-27 22:19:30 +01:00
Martin Whitaker d3bced57cc Correctly handle explicit and wildcard package imports.
Explicit imports should always conflict with local declarations using
the same name. Wildcard imports only conflict if they are referenced
before a local declaration with the same name.

This also unifies the detection of identifier conflicts.
2019-09-27 22:19:30 +01:00
Martin Whitaker 269ec2f042 Remove redundant checks for package imports during parsing.
The find_* and symbol_search functions now handle this.
2019-09-27 22:19:30 +01:00
Martin Whitaker 2a21fe77ac Output an error message when a SV variable declaration reuses a name.
Assertion failures are not the right way to handle user code errors.
2018-02-18 17:51:56 +00:00
Martin Whitaker f83e01847a Fix a couple of minor bugs in the timescale parsing rework. 2017-11-06 00:37:56 +00:00
Martin Whitaker fd807a7700 Rework handling of timescales in parser.
This implements and enforces the full set of rules for determining
timescales in SystemVerilog. The previous relaxation of the rules
that allowed timescales to be redefined within the compilation unit
scope has been removed. Time unit and precision redeclarations are
now recognised after a nested module declaration.
2017-11-05 17:50:05 +00:00
Vamsi Vytla cfd3b893be Add support to handle attributes at module instantiation sites.
(* my_fancy_attribute *)
foobar1 foobar (clk(clk), rst(rst) ...);

  - Modifies PGModule to hold the attribute map (can be verified with pform_dump)
  - pform_make_modgate(s) bind the attributes from the parser to the above map
  - The attributes from PGModule are inserted into the NetScope of that module
    PGModule::elaborate_scope_mod_instances_
  - Currently these attributes automatically make it into netlist
  - These attributes are accessible via ivl_scope_attr_cnt and ivl_scope_attr_val
    from ivl_target.h
2017-03-16 07:41:10 -07:00
Cary R 45fbf55806 Add basic support for parameters using typedefs 2016-05-14 10:34:50 -07:00
Martin Whitaker 6ba2bee977 Fix for br974 - support SV types in non-ansi port declarations. 2016-04-04 20:40:30 +01:00