When you have an expression like this (extreme example):
a[idx[1]][idx[2]*4 +: 4] <= #(idx[3]) 4'ha;
where a is a reg array and idx is a reg or net array. The retrieval
of idx[2] was clobbering index register 3, which was set before
evaluating the part offset expression, then used in the %set/av of the
array value. (likewise for idx[1] and idx[3]])
To avoid this issue, this patch adds and uses a new instruction
%ix/mov which simply copies one indexed register to another. When
necessary, expressions are first evaluated into temporary registers to
avoid clobbering, then moved in to place before the %*/av instruction.
When a fork/join contains a task, the task completion may become
confused with the completion of another thread if any of the
threads are embedded in the main thread. So always create threads
for all the fork paths, and joins to match.
Instead of just translating a generate scope to a named begin/end scope
this patch creates a generate specific scope (vpiScopeGenerate) that is
of the vpiGenScope type. This may not match the standard 100%, but does
allow the FST dumper to denote generate scopes differently than the
other scope types. Most of the VPI code treats a vpiGenScope just like a
named block so only the FST dumper should have different behavior.
If a VPI call with real arguments has no calltf function, we still
need to pop the arguments off the vthread stack. Similarly, if it
has a real result, we need to push a value onto the vthread stack.
This patch adds support for implicit casts to the elaborate_rval_expr()
function. This will handle the majority of cases where an implicit cast
can occur.
Currently, when a variable expression is passed to a system task,
the expression value is stored in thread memory. Values stored
in thread memory cannot safely be passed to $strobe or $monitor,
because the thread memory may get reused or deallocated before
the $strobe or $monitor task actually executes. As a temporary
measure, we just trap this case and terminate with a "sorry"
message. A proper fix would require the expression value to be
calculated at the time the $strobe or $monitor executes, not at
the time it is called.
This is rather a pointless sort of thing, but it does turn from
from time to time, for example when constant literals (with no x or
z bits) are given strengths. So handle .net8/2s and .net8/2u the
same as .net8.s and .net8 objects.
If a strength aware net has an unambiguous HiZ1 strength, VVP treats
it as a logic '1'. It should be treated as a logic 'z'. An ambiguous
HiZ1/HiZ0 strength should also be treated as a logic 'z'.
When VVP compiles a .array statement for a net array, it does not
know the data type, so initialises the array signed_flag to false.
We need to set the signed_flag to the correct value once we know
the data type, to allow the VPI routines to correctly format the
data.
When checking with valgrind clean up the following:
The arguments for invalid task/function calls.
The simulation callback queues (only needed when the runtime aborts).
Call pthread_exit(NULL) just before exiting to cleanup dynamic loading.
The vvp_darray_real class cal be used for static arrays as well
and this is a more general solution anyhow. Kill the now useless
vvp_realarray_t class.
This provides the ivl_target.h interface for class definitions
and expressions, the vvp code generator support for class objects
and properties, and the vvp run time support. Trivial class objects
now seem to work.
Create stub class objects at the vvp level and generate the code
to invoke that stub. Implement the routines needed to implement
a test for null object references.
This will hopefully improve performance slightly, but also this
intended as a model for what to do when I get around to doing the
same thing to other data types.
Strings, when put into dynamic arrays, are treated as first class
types much line reals. Add the code generator and vvp support for
this situation. Also fix a bug distinguishing between character
selects from strings and select form arrays of strings.
This involves working out the code to get the base type of a select
expression of a darray. Also added the runtime support for darrays
with real value elements.
Clean up the vector4_to_value to use templates and explicit
instantiations. This makes the interface much cleaner for a
wider variety of integral types.
This patch updates the vvp code so it will compile with the valgrind hooks
again. There are still new constructs that need to be cleaned up correctly
and some old constructs were changed enough that the old code no longer
works, but the rest of this can be done as an incremental improvement.
Windows and hence mingw does not follow the standard regarding the return
value of vsnprintf(). The mingw code needs to iteratively search for a
buffer large enough to print the output.
The second call to vsnprintf() needs to have a copy of the argument list
so it can run correctly. On some system vsnprintf() destorys the original
argument list.
When sending a string to a system task/function allocate the space needed
to avoid truncating the string vs using a large fixed buffer.
In vvp allocate and use an exactly sized buffer for the MCD print routine if
the fixed buffer is not large enough. Using a fixed buffer keeps normal
printing fast.
This patch implements the $countdrivers system function. It does not
yet support wires connected to islands (and outputs a suitable "sorry"
message when this is detected).
To implement the $countdrivers system function, we need to be able to
find all the driver values for a given wire. Currently, if a wire has
has more than four drivers, the compiler builds a resolver tree out
of 4-input nodes to resolve the driven values, and there is no way at
run time to work back from the output node to the original driver
values. This patch moves the implementation of the resolver tree into
a single vvp functor (using a mechanism similar to wide functors to
support more than 4 inputs), thus gathering all the driver values into
a single place.