The vlog95 code generator collects all the constant assignments to a net
within each scope and then emits them. The old code only recorded the
ivl_signal_t for each constant assignment, which meant it had to iterate
through the nexus pointers in the assicated nexus to find the constant.
When there were multiple constant assignments to the same net, it needed
to record which assignments had already been emitted, which it did by
keeping a count in the nexus private data and skipping that many constants
on each successive assignment. However the count did not get reset after
emitting all the assignments in that scope, so if there were assignments
to the same net made in another scope, the count would already be positive
and those assignments would also be skipped.
This could probably have been fixed by clearing the nexus private data
after processing the constant assignment list for each scope, but it is
more efficient to record the ivl_nexus_ptr_t for each constant along with
the ivl_signal_t, eliminating the need to search for the associated nexus
pointer.
This includes support at the parser (pform) through enaboration
and the netlist format for the break and continue statements.
Elaboration actually already worked for for-loops, but since the code
generators need more information, this is a rewire of that support to
be explicit about for-loops. This means they are not rewritten as fancy
while loops. The code generators will have to handle that.
Given the elaboration of for-loops now work, write the vvp code generator
support needed to implement it.
Now that for-loops are presented as for-loops to the code generator, the
vlog95 code generator doesn't need to infer them anymore. Generate the code
more directly.
Also update the tests list so that the vlog95_reg tests all pass.
The vlog95 backend currently strips null-bytes from strings in structural
elements. E.g. `assign y = "a\000b"` gets translated to `assign y = "ab"`.
This changes the behavior of the generated output compared to the input.
Don't ignore the null-bytes to make sure the behavior stays the same.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
When a string literal is used in a context where it needs to be wider than
it is it will get left-padded with null-bytes. When the vlog95 backend
emits the string literal it will strip the leading null-bytes as it results
in much more legible code.
Unfortunately there are some corner cases where this results in a change of
behavior of the generated code compared to the original. E.g. if the
context that caused the width expansion has been removed by optimization.
`$display(0 ? "Yes" : "No")` should print " No" due to width expansion, but
when running through the vlog95 backend it will print "No".
Another scenario where there is a change in behavior is when a null byte
was explicitly added at the front of a string literal. E.g. $bits("\000ab")
should print 24, but will print 16 when running through the vlog95 backend.
To mitigate this remove the stripping of the leading null-bytes from the
vlog95 backend. This results in slightly less legible code being generated
in some cases, but makes sure that the code is always correct.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The vlog95 backend currently ignores the sign of a function return value.
Check for it and if `-pallowsigned=1` was specified emit the `signed`
keyword. Otherwise report an error.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
SystemVerilog supports type parameters. These are similar to value
parameters, but they allow to pass a type to a module or similar when
instantiating it.
E.g.
```
module A #(parameter type T = int);
endmodule
module B;
A #(.T(real)) i_a;
endmodule
```
Add support for handling type parameters.
For the vlog95 and vhdl backends type parameters, similar to typedefs, get
replaced with their actual value. For modules with non-local type
parameters for each module instance a unique module or architecture is
generated with the actual type.
Querying type parameters through VPI is not yet supported.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
For modules with parameters the vlog95 backend generates one module
declaration for each module instance. This is done so that different values
for the module parameters can be supported.
Local parameters are guaranteed to have the same value for all module
instances though. Add support for detecting the case that all module
parameters are local parameters and in that case only create one shared
module declaration. This is similar to what the vhdl backend does.
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>
In PR #300, @xdch47 pointed out a stable way to fix parallel
installation problems.
This fix applied the method, thanks!
Signed-off-by: Huang Rui <vowstar@gmail.com>