In assignments, the expression width may be defined by the width of
operands, and not that of the l-value. Choose whichever is creater and
set (or pad) the expression to that width.
Multiply of any expression with constant 0 will always return zero.
We can handle this early, during elaboration, and save a lot of code
downstream the trouble.
Also, while we are at it, fix up test_width to re-test the left
expression width if the right expression width is unsized. This allows
for the left expression code to adapt to the unsized-ness of the
expression context.
This patch pads inputs and output ports correctly when the port
and the port expression have different widths. It does not fix
inout ports.
It also sets the file and line number information in the unsigned
pad_to_width() routine.
This patch pushes the evaluation of constant system functions into
normal elaboration vs doing them in the preliminary parameter
elaboration.
It also fixes the compiler version of clog2 to return integer_width
vs a fixed 32 bits.
There are cases where the r-value doesn't pad itself to the width
that is requested by the call to elaborate_expr. This impacts the
elaboration of PGAssign. Pad/sign extend as appropreate.
The arguments to bitwise operators are padded if *either* of the operands
is unsigned. This is according to the sign/unsigned expression rules
of Verilog, and also matches the behavior of the "Big-3."
The addition of UINT_MAX in netlist.cc requires #include <climits> when compiling with gcc-4.3.2.
I also noticed that commit 8704e3e used c style includes in c++ sources contrary to the style used in the rest of the c++ code and fixed those.
In the transition to the new expression code we forgot how to
handle the logical not (!) of a real value. This patch adds a
more appropriate error message until we get this reimplemented.
MinGW uses the GetProcAddress() function to find the address of
the vlog_startup_routines() procedure in a .vpi file. This routine
requires that the leading underscore be omitted from the name even
though the underlying routine really has one.
alloc_instance for real values was just passing a new double
to be added to the context items. The new constructor does
not set the default value so we need to do that manually.
Simple error setting the expression width of the FALSE clause of a
ternary expression when the expression is short cuirted to false.
Fix a simple error where the type of a system function is not returned
through the test_width function.
The arguments to user defined functions are self-determined. And if
the result is real valued, we can call them lossless self-determined.
Treat these arguments like r-value elaboration for assignments.
Also clean up the binary divide elaboration a little bit.
Also, floating point literals are unsized with width==1.
When a multiply expression is IVL_VT_REAL, then the default width is
the width of the operands, and not the sum of the operands. In fact, it
should turn out to be 1.
Also, the width of the multiply expression when we get to the ivl_target
API, need not be the sum of the widths of its arguments. In fact, if the
arguments are signed, that would be completely wrong. So adjust the
stub target to properly test this constraint.
Widths of real values are always 1. When paired with vectorable types
in expressions, the vectorable type is processed as losslessly self-
determined. ("unsized" in the test_width methods.)
Don't force the expression with to be different from the l-value if the
l-value is the immediate destination. This saves the effort of handling
overly wide constant values in simple cases.
Also, in determined contexts, signed unary minus does not need to pad the
width of the expression.
the PGAssign elaborate method used the test_width to get the width
of the r-value expression. This should be completely sufficient to
get the width of the expression, so always use a defined width to
elaborate the expression.
When ternary expressions are self-determined, use the test_width
method to get a proper reading of the expression width. Also improve
the test_width method to handle unsized operands.
This patch adds non-blocking event control for array words.
It also fixes a problem where the word used to put the
calculated delay for a non-blocking array assignment was
not being released. It also fixes the non-blocking array
assignments to correctly handle off the end/beginning part
selects.
Currently, parameters and localparams declared in tasks, functions,
generate blocks, and named blocks are placed in the parent module
scope. Event declarations in these scopes are not permitted (a
syntax error is reported). This patch corrects this behaviour, so
that all the above declarations are accepted and are placed in the
scope in which they are declared.
Note that the IEEE standard does not permit parameter declarations
in generate blocks. This patch causes the parser to reject such
declarations.
Since some event control assignments can be skipped we need an
event control clear so that future %evctl statements do not fail
their assert. This patch adds %evctl/c and uses it in the compiler
as appropriate to keep the event control information in sync.
This patch adds full event control for vectors and parts of a
vector. It also fixes the other non-blocking part select code
to correctly handle a negative offset ([1:-2] of a [4:0] will
have an offset of -2).
When evaluating an expression into an index register bit 4 is used
to determine if the expression had any X/Z bits. In the case of a
constant immediate value this can not happen so make sure the bit
is cleared.
We need consistent pointer output (%p) and under MinGW we need to
us _snprintf instead of snprintf to get this. The recent event
control addition missed this. This has been reported to the MinGW
developers and they are working on a solution.
The previous patch (commit 8b0ca902a6)
dealing with the possibilities of (unsigned long) and (vvp_time64_t)
being either the same or different managed to redefine UL_AND_TIME64_DIFF
in the 64-bit case. This does, of course, trigger a compiler warning.
That warning is repeated on every .cc file with a #include "config.h",
which is to say, just about every file.
This patch inverts the sense of the preprocessor conditional, calling
it UL_AND_TIME64_SAME. No more warnings!
It takes a carefully crafted source file to cause elabortion to make
an arrayed multiple-output gate that is not vectorized into a single
wide gate. But that special case does need to be handled.
While the standard is not completely clear about this, we are making
it an error for a `timescale directive to be inside a (macro)module
definition. This means that all modules and any statements contained
within have a single well defined time unit and precision.
Logic gates usually have one output and several inputs, but a few
have multiple outputs and one input. Since the NetNode objects have
only a single output, handle the case by creating multiple NetNode
objects, one for each output.
A variable that is used to set the delay of a .delay statement
must be scaled to match the local units and for real values
rounded using the precision. This value is then converted to
the simulation precision.
Signals of a nexus must have types that exactly match, but the drivers
of a signal nexus have slightly more subtle rules for the case where
the signal is IVL_VT_LOGIC. Express those rules in the function
check_signal_drive_type, and use it to check the type of constants
driving a signal.
Remove redundant pointer to the containing NetPins object by keeping
the pointer only in the first Link (pin 0) of an array of links. In
this link, replace the pin number with the NetPins pointer, and set
a pins_zero_ flag to indicate that this has happened. This way, only
the first pin in a Link array will have the pointer to the NetPins
that contains the array, and the pointer takes up practically no space
at all.
This class was old, and its original design pulled literally from
the LPM reference. But of nine pins declared, only 4 were used.
Remove all the excess junk and clean up the designed dump handling
of the device.