iverilog/vvp/opcodes.txt

1170 lines
40 KiB
Plaintext

/*
* Copyright (c) 2001-2013 Stephen Williams (steve@icarus.com)
*
*/
EXECUTABLE INSTRUCTION OPCODES
Instruction opcodes all start with a % character and have 0 or more
operands. In no case are there more than 3 operands. This chapter
describes the specific behavior of each opcode, in enough detail
(I hope) that its complete effect can be predicted.
General Principles of Arithmetic (current plan):
The binary arithmetic instruction in general takes three parameters,
the left operand, the right operand, and the base. The left operand is
replaced with the result, which is the same width as the left and
right operands.
General Principles of Arithmetic (new plan):
For strings, all arithmetic is stack based. That is, there is an
abstract stack of strings from which operations pull their operands
and push their results. This is somewhat like FORTH (or an HP calculator
RPN notation) and spares the need to keep register addresses in
operands. I may find this leads to a more compact form of instruction
code, and may lead to more efficient operators overall, and in
particular I may find improved efficiency overall; so after the
experience of implementing it for strings, I'll want to change other
types around to using this method as well. Keep this in mind whenever
considering adding new instructions to vvp.
* %abs/wr <bit-o>, <bit-i>
This instruction calculates the absolute value of a real value. It uses
the fabs() function in the run-time to do the work.
* %add <bit-l>, <bit-r>, <wid>
This instruction adds the right vector into the left vector, the
vectors having the width <wid>. If any of the bits of either vector
are x or z, the result is x. Otherwise, the result is the arithmetic
sum.
See also the %sub instruction.
* %add/wr <bit-l>, <bit-r>
This is the real valued version of the %add instruction. The arguments
are popped from the stack, right operand then left, and the result
pushed in place
See also the %sub/wr instruction.
* %addi <bit-l>, <imm>, <wid>
This instruction adds the immediate value (no x or z bits) into the
left vector. The imm value is limited to 16 significant bits, but it
is zero extended to match any width.
* %alloc <scope-label>
This instruction allocates the storage for a new instance of an
automatically allocated scope.
* %and <bit-l>, <bit-r>, <wid>
Perform the bitwise AND of the two vectors, and store the result in
the left vector. Each bit is calculated independent of other bits. AND
means the following:
0 and ? --> 0
? and 0 --> 0
1 and 1 --> 1
otherwise x
* %assign/ar <array-label>, <delay>
* %assign/ar/d <array-label>, <delayx>
* %assign/ar/e <array-label>
The %assign/ar instruction assigns a real value to a word in the
labeled real array. The <delay> is the delay in simulation time to
the assignment (0 for non-blocking assignment) and the value is popped
from the real value stack.
The memory word address is read from index register 3. The address is
in canonical form.
The %assign/ar/d variation reads the delay from an integer register that
is given by the <delayx> value. This should not be 3 or the <bit> index,
of course, since these registers contain the word address and the value.
The %assign/ar/e variation uses the information in the thread
event control registers to determine when to perform the assign.
%evctl is used to set the event control information.
* %assign/av <array-label>, <delay>, <bit>
* %assign/av/d <array-label>, <delayx>, <bit>
* %assign/av/e <array-label>, <bit>
The %assign/av instruction assigns a vector value to a word in the
labeled array. The <delay> is the delay in simulation time to the
assignment (0 for non-blocking assignment) and the <bit> is the base
of the vector to write.
The width of the vector is retrieved from index register 0.
The base of a part select is retrieved from index register 1.
The address of the word in the memory is from index register 3. The
address is canonical form.
The %assign/av/d variation reads the delay from an integer register that
is given by the <delayx> value. This should not be 0, 1 or 3, of course,
since these registers contain the vector width, base part select and
word address.
The %assign/av/e variation uses the information in the thread
event control registers to determine when to perform the assign.
%evctl is used to set the event control information.
* %assign/v0 <var-label>, <delay>, <bit>
* %assign/v0/d <var-label>, <delayx>, <bit>
* %assign/v0/e <var-label>, <bit>
The %assign/v0 instruction is a vector version of non-blocking
assignment. The <delay> is the number of clock ticks in the future
where the assignment should be schedule, and the <bit> is the base of
the vector to be assigned to the destination. The vector width is in
index register 0.
The %assign/v0/d variation gets the delay instead from an integer
register that is given by the <delayx> value. This should not be 0, of
course, because integer 0 is taken with the vector width.
The %assign/v0/e variation uses the information in the thread
event control registers to determine when to perform the assign.
%evctl is used to set the event control information.
The <var-label> references a .var object that can receive non-blocking
assignments. For blocking assignments, see %set/v.
* %assign/v0/x1 <var-label>, <delay>, <bit>
* %assign/v0/x1/d <var-label>, <delayx>, <bit>
* %assign/v0/x1/e <var-label>, <bit>
This is similar to the %assign/v0 instruction, but adds the index-1
index register with the canonical index of the destination where the
vector is to be written. This allows for part writes into the vector.
* %assign/wr <vpi-label>, <delay>
* %assign/wr/d <vpi-label>, <delayx>
* %assign/wr/e <vpi-label>
This instruction provides a non-blocking assign of the real value
given in <index> to the real object addressed by the <vpi-label>
label after the given <delay>. The real value is popped from the stack.
The %assign/wr/d variation gets the delay from integer register
<delayx>.
The %assign/wr/e variation uses the information in the thread
event control registers to determine when to perform the assign.
%evctl is used to set the event control information.
* %assign/x0 <var-label>, <delay>, <bit> (OBSOLETE -- See %assign/v0x)
This does a non-blocking assignment to a functor, similar to the
%assign instruction. The <var-label> identifies the base functor of
the affected variable, and the <delay> gives the delay when the
assignment takes place. The delay may be 0. The actual functor used is
calculated by using <var-label> as a base, and indexing with the
index[0] index register. This supports indexed assignment.
The <bit> is the address of the thread register that contains the bit
value to assign.
* %blend <bit-l>, <bit-r>, <wid>
This instruction blends the bits of a vector into the destination in a
manner like the expression (x ? <a> : <b>). The truth table is:
1 1 --> 1
0 0 --> 0
z z --> z
x x --> x
.... --> x
In other words, if the bits are identical, then take that
value. Otherwise, the value is x.
* %blend/wr
This instruction blends real values for the ternary operator. If the
values match return that otherwise return 0.0. Two values are popped
from the stack, one is pushed back.
* %breakpoint
This instruction unconditionally breaks the simulator into the
interactive debugger. The idea is to stop the simulator here and give
the user a chance to display the state of the simulation using
debugger commands.
This may not work on all platforms. If run-time debugging is compiled
out, then this function is a no-op.
* %cassign/v <var-label>, <bit>, <wid>
Perform a continuous assign of a constant value to the target
variable. This is similar to %set, but it uses the cassign port
(port-1) of the signal functor instead of the normal assign, so the
signal responds differently. See "VARIABLE STATEMENTS" in the
README.txt file.
* %cassign/wr <var-label>
Perform a continuous assign of a constant real value to the target
variable. See %cassign/v above. The value is popped from the real
value stack.
* %cassign/x0 <label>, <bit>, <wid>
Perform continuous assign of a constant value to part of the target
variable. This is similar to %set/x instruction, but it uses the
cassign port (port-1) of the signal functor instead of the normal
assign port (port-0), so the signal responds differently. See
"VARIABLE STATEMENTS" and "NET STATEMENTS" in the README.txt file.
* %cast2 <dst>, <src>, <wid>
Convert the source vector, of type logic, to a bool vector by
changing all the X and Z bits to 0. The source and destinations may
overlap.
* %cmp/u <bit-l>, <bit-r>, <wid>
* %cmp/s <bit-l>, <bit-r>, <wid>
These instructions perform a generic comparison of two vectors of equal
size. The <bit-l> and <bit-r> numbers address the least-significant
bit of each vector, and <wid> is the width. If either operand is 0,
1, 2 or 3 then it is taken to be a constant replicated to the selected
width.
The results of the comparison go into bits 4, 5, 6 and 7:
4: eq (equal)
5: lt (less than)
6: eeq (case equal)
The eeq bit is set to 1 if all the bits in the vectors are exactly the
same, or 0 otherwise. The eq bit is true if the values are logically
the same. That is, x and z are considered equal. In other words the eq
bit is the same as ``=='' and the eeq bit ``===''.
The lt bit is 1 if the left vector is less than the right vector, or 0
if greater than or equal to the right vector. It is the equivalent of
the Verilog < operator. Combinations of these three bits can be used
to implement all the Verilog comparison operators.
The %cmp/u and %cmp/s differ only in the handling of the lt bit. The
%cmp/u does an unsigned compare, whereas the %cmp/s does a signed
compare. In either case, if either operand contains x or z, then lt
bit gets the x value.
* %cmpi/s <bit-l>, <immr>, <wid>
* %cmpi/u <bit-l>, <immr>, <wid>
These instructions are similar to the %cmp instructions above, except
that the right hand operand is an immediate value. This is a positive
number that the vector is compared with.
* %cmp/wr
Compare real values for equality and less-then. This opcode pops to
values from the real-value stack and writes the comparison result to
bits 4/5. The expressions (a < b) and (a==b) are calculated, with (b)
poped from the stack first, then (a).
* %cmp/ws <bit-l>, <bit-r>
* %cmp/wu <bit-l>, <bit-r>
[compare signed/unsigned integer words.]
* %cmp/z <bit-l>, <bit-r>, <wid>
* %cmp/x <bit-l>, <bit-r>, <wid>
These instructions are for implementing the casez and casex
comparisons. These work similar to the %cmp/u instructions, except
only an eq bit is calculated. These comparisons both treat z values in
the left or right operand as don't care positions. The %cmp/x
instruction will also treat x values in either operand as don't care.
Only bit 4 is set by these instructions.
* %cmp/str
This instruction pops the top two strings from the string stack and
compares them. The results of the comparison go into bits 4 and 5:
4: eq (equal)
5: lt (less than)
For the purposes of calculating the lt bit, the top string is the
right operand and the string underneath is the left operand. This
instruction removes two strings from the stack.
* %concat/str
* %concati/str <string>
Pop the top string, and concatenate it to the new top string. Or think
of it as possing the tail, then the head, concatenating them, and
pushing the result. The stack starts with two strings in the stack,
and ends with one string in the stack.
* %cvt/sr <bit-l>
* %cvt/rs <bit-l>
Copy a word from r to l, converting it from real to signed integer (sr)
or signed integer to real (rs) in the process. The source and destination
may be the same word address, leading to a convert in place. Precision
may be lost in the conversion.
The %cvt/sr <bit-l> gets the real value from the top of the real value
stack (and pops the value) and writes it to the indexed register.
* %cvt/ur <bit-l>
* %cvt/ru <bit-r>
Copy a word from r to l, converting it from real to unsigned integer (ur)
or signed integer to real (ru) in the process. The source and destination
may be the same word address, leading to a convert in place. Precision
may be lost in the conversion.
* %cvt/rv <bit-r>, <wid>
* %cvt/rv/s <bit-r>, <wid>
The %cvt/rv instruction converts a thread vector starting at <bit-r>
and with the width <wid> to a real word. Push the result onto the real
value stack. Precision may be lost in the conversion.
The %cvt/rv/s instruction is the same as %cvt/rv, but treats the thread
vector as a signed value.
* %cvt/vr <bit-l>, <wid>
The %cvt/vr opcode converts a real word from the stack to a thread vector
starting at <bit-l> and with the width <wid>. Non-integer precision is
lost in the conversion, and the real value is popped from the stack.
* %deassign <var-label>, <base>, <width>
Deactivate and disconnect a procedural continuous assignment to a
variable. The <var-label> identifies the affected variable.
The <base> and <width> are used to determine what part of the signal
will be deactivated. For a full deactivation the <base> is 0 and
<width> is the entire signal width.
* %deassign/wr <var-label>
The same as %deassign above except this is used for real variables.
* %delay <low>, <high>
This opcode pauses the thread, and causes it to be rescheduled for a
time in the future. The amount is the number of the ticks in the
future to reschedule, and is >= 0. If the %delay is zero, then the
thread yields the processor for another thread, but will be resumed in
the current time step.
The delay amount is given as 2 32bit numbers, so that 64bit times may
be represented.
* %delayx <idx>
This is similar to the %delay opcode, except that the parameter
selects an index register, which contains the actual delay. This
supports run-time calculated delays.
* %delete/obj <var-label>
Arrange for the dynamic object at the target label to be deleted.
This has no effect on the object or string stack. Note that this is
the same as:
%null ;
%store/obj <var-label>
but that idiom is expected to be common enough that it warrants an
optimized shorthand.
* %disable <scope-label>
This instruction terminates threads that are part of a specific
scope. The label identifies the scope in question, and the threads are
the threads that are currently within that scope.
* %div <bit-l>, <bit-r>, <wid>
* %div/s <bit-l>, <bit-r>, <wid>
This instruction arithmetically divides the <bit-l> vector by the
<bit-r> vector, and leaves the result in the <bit-l> vector. IF any of
the bits in either vector are x or z, the entire result is x.
The %div/s instruction is the same as %div, but does signed division.
* %div/wr
This opcode divides the left operand by the right operand. If the
right operand is 0, then the result is NaN.
* dup/real
These opcodes duplicate the value on the top of the stack for the
corresponding type.
* %evctl <functor-label> <idx>
* %evctl/c
* %evctl/s <functor-label> <idx>
* %evctl/i <functor-label> <value>
These instructions are used to put event and repetition information
into the thread event control registers. These values are then used
by the %assign/e instructions to do not blocking event control. The
<functor-label> is the event to trigger on and the <idx> is an index
register to read the repetition count from (signed or unsigned).
%evctl/i sets the repetition to an immediate unsigned value.
%evctl/c clears the event control information. This is needed if a
%assign/e may be skipped since the %assign/e statements clear the
event control information and the other %evctl statements assert
that this information has been cleared. You can get an assert if
this information is not managed correctly.
* %file_line <file> <line> <description>
This command emits the provided file and line information along with
the description when it is executed. The output is sent to stderr and
the format of the output is:
<file>:<line>: <description>
<file> is the unsigned numeric file index.
<line> is the unsigned line number.
<description> is a string, if string is 0 then the following default
message is used: "Procedural tracing.".
* %force/v <label>, <bit>, <wid>
Force a constant value to the target variable. This is similar to %set
and %cassign/v, but it uses the force port (port-2) of the signal
functor instead of the normal assign port (port-0), so the signal
responds differently. See "VARIABLE STATEMENTS" and "NET STATEMENTS"
in the README.txt file.
* %force/wr <var-label>
Force a constant real value to the target variable. See %force/v
above. The value is popped from the real value stack.
* %force/x0 <label>, <bit>, <wid>
Force a constant value to part of the target variable. This is similar
to %set/x instruction, but it uses the force port (port-2) of the signal
functor instead of the normal assign port (port-0), so the signal
responds differently. See "VARIABLE STATEMENTS" and "NET STATEMENTS"
in the README.txt file.
* %fork <code-label>, <scope-label>
This instruction is similar to %jmp, except that it creates a new
thread to start executing at the specified address. The new thread is
created and pushed onto the child stack. It is also marked runnable,
but is not necessarily started until the current thread yields.
The %fork instruction has no effect other than to push a child thread.
See also %join.
* %free <scope-label>
This instruction de-allocates the storage for a previously allocated
instance of as automatically allocated scope.
* %inv <bit>, <wid>
Perform a bitwise invert of the vector starting at <bit>. The result
replaces the input. Invert means the following, independently for each
bit:
0 --> 1
1 --> 0
x --> x
z --> x
* %ix/get <idx>, <bit>, <wid>
* %ix/get/s <idx>, <bit>, <wid>
This instruction loads a thread vector starting at <bit>, size <wid>,
into the index register <idx>. The <bit> is the LSB of the value in
thread bit space, and <wid> is the width of the vector.
The function converts the 4-value bits into a binary number, without
sign extension. If any of the bits of the vector is x or z, then the
index register gets the value 0. The %ix/get/s is the same, except
that it assumes the source vector is sign extended to fit the index
register.
The function also writes into bit 4 a 1 if any of the bits of the
input vector are x or z. This is a flag that the 0 value written into
the index register is really the result of calculating from unknown
bits.
4: unknown value
5: (reserved)
6: (reserved)
* %ix/getv <idx>, <functor-label>
* %ix/getv/s <idx>, <functor-label>
These instructions are like the %ix/get instructions, except that they
read directly from a functor label instead of from thread bits. They
set bit 4 just like %ix/get.
* %ix/load <idx>, <low>, <high>
This instruction loads an immediate value into the addressed index
register. The index register holds 64 bit numeric values, so <low>
and <high> are used to separate the value in two 32 bit chunks.
The idx value selects the index register. This is different from
%ix/get, which loads the index register from a value in the thread bit
vector. The values are unsigned decimal values and are combined as
<high> << 32 | <low> to produce the final value.
* %ix/add <idx>, <low>, <high>
* %ix/sub <idx>, <low>, <high>
* %ix/mul <idx>, <low>, <high>
These instructions add, subtract, or multiply the selected index
register by the immediate value. The 64 bit immediate value is built
from the two 32 bit chunks <low> and <high> (see %ix/load above).
The <idx> value selects the index register.
* %jmp <code-label>
The %jmp instruction performs an unconditional branch to a given
location. The parameter is the label of the destination instruction.
* %jmp/[01xz] <code-label>, <bit>
This is a conditional version of the %jmp instruction. In this case,
a single bit (addressed by <bit>) is tested. If it is one of the
values in the part after the /, the jump is taken. For example:
%jmp/xz T_label, 8;
will jump to T_label if bit 8 is x or z.
* %join
This is the partner to %fork. This instruction causes the thread to
wait for the top thread in the child stack to terminate, then
continues. It has no effect in the current thread other than to wait
until the top child is cleared.
It is an error to execute %join if there are no children in the child
stack. Every %join in the thread must have a matching %fork that
spawned off a child thread.
If the matching child instruction is still running, a %join suspends
the calling thread until the child ends. If the child is already
ended, then the %join does not block or yield the thread.
* %join/detach <n>
This is also a partner to %fork. This instruction causes the thread
to detach <n> threads from the current thread. The <n> should be ALL
the children, and none of those children may be automatic. This
instruction is used to implement join_none and join_any from the
Verilog source.
* %load/av <bit>, <array-label>, <wid>
This instruction loads a word from the specified array. The word
address is in index register 3. Like %load/v below the width does
not have to match the width of the array word. See the %load/v
description for more information.
* %load/avp0 <bit>, <array-label>, <wid>
* %load/avp0/s <bit>, <array-label>, <wid>
This instruction is a mix of %load/av and %load/vp0. It loads an array
value like %load/av and then adds a value from index register 0 to the
result like %load/vp0. The loaded value is zero-extended to <wid>,
then added arithmetically to the signed index register 0. The result
is then stored in <bit>.
The %load/avp0/s instruction is the same, except that the loaded
vector is sign extended (instead of 0-extended) before the addition.
* %load/avx.p <bit>, <array-label>, <index>
This instruction is similar to %load/av, but it loads only a single
bit, and the <index> is the selector for the bit to use. If <index> is
out of range, then x is loaded. The index value is incremented by one
if it is defined (bit 4 is not 1).
* %load/dar <bit>, <functor-label>, <wid>
* %load/dar/r <functor-label>
This instruction loads an array word from a dynamic array. The
<label> refers to the variable object, and the <bit>/<wid> are the
location in local vector space where the extracted word goes. The
index is implicitly extracted from index register 3.
The dar/r variant reads a real-value into a real-valued register.
(See also %set/dar)
* %load/obj <var-label>
This instruction loads an object handle and pushes it to the top of
the object handle stack.
See also %store/obj.
* %load/prop/v <pid>, <bit>, <wid>
This instruction loads from a class object property into the specified
thread register bit. The <pid> is the number of the property and the
<bit> is the location where the loaded value goes.
The handle for the class object is found on the top of the object
stack, and the stack is NOT popped.
* %load/real <vpi-label>
The %load/real instruction reads a real value from the vpi-like object
and pushes it to the top of the real value stack.
* %load/str <var-label>
* %load/stra <array-label>, <index>
* %load/dar/str <var-label>
The %load/str instruction gets the string from the string variable and
pushes in to the string stack. (See also %store/str)
The %load/dar/str is similar, but the variable is a dynamic array of
strings, and there is an index value in index register 3.
(See also %store/dar/str)
* %load/v <bit>, <functor-label>, <wid>
This instruction loads a vector value from the given functor node into
the specified thread register bit. The functor-label can refer to a
.net, a .var or a .functor with a vector output. The entire vector,
from the least significant up to <wid> bits, is loaded starting at
thread bit <bit>. It is an OK for the width to not match the vector
width at the functor. If the <wid> is less than the width at the
functor, then the most significant bits are dropped. If the <wid> is
more than the width at the functor, the value is padded with X bits.
* %load/vp0 <bit>, <functor-label>, <wid>
* %load/vp0/s <bit>, <functor-label>, <wid>
This instruction is the similar %load/v above, except that it also
adds the signed integer value in index register 0 into the loaded
value. The addition is a Verilog-style add, which means that if any of
the input bits are X or Z, the entire result is turned into a vector
of X bits.
The <wid> is, line the %load/v, the result width. But unlike the
%load/v, the vector is padded with 0s (%load/vp0) or sign extended
(%load/vp0/s) to the desired width.
* %load/ar <array-label>, <index>
The %load/ar instruction reads a real value from an array. The <index>
is the index register that contains the canonical word address into
the array.
* %load/x1p <bit>, <functor-label>, <wid>
This is an indexed load. It uses the contents of index register 1 to
select a part from a vector functor at <functor-label>. The
part is pulled from the indexed bit of the addressed functor and loaded
into the destination thread bit. The <wid> is the width of the
part. If any bit of the desired value is outside the vector, then that
bit is set to X.
The index register 1 is interpreted as a signed value. Even though the
address is canonical (from 0 to the width of the signal) the value in
index register 1 may be <0 or >=wid. The load instruction handles
filling in the out-of-bounds bits with x.
When the operation is done, the <wid> is added to index register 1, to
provide a basic auto-increment behavior.
* %loadi/wr <bit>, <mant>, <exp>
This opcode loads an immediate value, floating point, into the word
register selected by <bit>. The mantissa is an unsigned integer value,
up to 32 bits, that multiplied by 2**(<exp>-0x1000) to make a real
value. The sign bit is OR-ed into the <exp> value at bit 0x4000, and
is removed from the <exp> before calculating the real value.
If <exp>==0x3fff and <mant> == 0, the value is +inf.
If <exp>==0x7fff and <mant> == 0, the value is -inf.
If <exp>==0x3fff and <mant> != 0, the value is NaN.
* %max/wr
* %min/wr
This instruction pops the top two values from the real stack and
pushes back the max(min) value. Avoid returning NaN by selecting the
other if either is NaN.
* %mod <bit-l>, <bit-r>, <wid>
* %mod/s <bit-l>, <bit-r>, <wid>
This instruction calculates the modulus %r of the left operand, and
replaces the left operand with the result. The <wid> gives the width
of the left and the right vectors, and the left vector is completely
replaced with the result.
The /s form does signed %.
* %mod/wr
This opcode is the real-valued modulus of the two real values.
* %mov <dst>, <src>, <wid>
* %mov/wu <dst>, <src>
* %movi <dst>, <value>, <wid>
This instruction copies a vector from one place in register space to
another. The destination and source vectors are assumed to be the same
width and non-overlapping. The <dst> may not be 0-3, but if the <src>
is one of the 4 constant bits, the effect is to replicate the value
into the destination vector. This is useful for filling a vector.
The %movi variant moves a binary value, LSB first, into the
destination vector. The immediate value is up to 32bits, padded with
zeros to fill out the width.
* %mul <bit-l>, <bit-r>, <wid>
This instruction multiplies the left vector by the right vector, the
vectors having the width <wid>. If any of the bits of either vector
are x or z, the result is x. Otherwise, the result is the arithmetic
product.
* %mul/wr
This opcode multiplies two real words together.
* %muli <bit-l>, <imm>, <wid>
This instruction is the same as %mul, but the second operand is an
immediate value that is padded to the width of the result.
* %nand <dst>, <src>, <wid>
Perform the bitwise NAND of the two vectors, and store the result in
the left vector. Each bit is calculated independent of other bits. NAND
means the following:
0 and ? --> 1
? and 0 --> 1
1 and 1 --> 0
otherwise x
* %new/cobj <label>
Create a new class object. The <label> is the VPI label for a class
type definition.
* %new/darray <idx>, "<type>"
Create a new array (of int objects) with a size. the <idx> is the
address of an index variable that contains the computed array size to
use. The <type> is a string that expresses the type of the elements of
the array. See also %delete/obj
The supported types are:
"b<N>" - unsigned bool <N>-bits
"sb<N>" - signed bool <N>-bits
"r" - real
"S" - SystemVerilog string
* %nor <dst>, <src>, <wid>
Perform the bitwise nor of the vectors. Each bit in the <dst> is
combined with the corresponding bit in the source, according to the
truth table:
1 nor ? --> 0
? nor 1 --> 0
0 nor 0 --> 1
otherwise x
* %nor/r <dst>, <src>, <wid>
The %nor/r instruction is a reduction nor. That is, the <src> is a
vector with width, but the result is a single bit. The <src> vector is
not affected by the operation unless the <dst> bit is within the
vector. The result is calculated before the <dst> bit is written, so
it is valid to place the <dst> within the <src>.
The actual operation performed is the inverted or of all the bits in
the vector.
* %null
Push a null object and push it to the object stack. The null object
can be used with any class or darray object, so it is not typed.
* %or <dst>, <src>, <wid>
Perform the bitwise or of the vectors. Each bit in the <dst> is
combined with the corresponding bit in the source, according to the
truth table:
1 or ? --> 1
? or 1 --> 1
0 or 0 --> 0
otherwise x
* %or/r <dst>, <src>, <wid>
This is a reduction version of the %or opcode. The <src> is a vector,
and the <dst> is a writable scalar. The <dst> gets the value of the
or of all the bits of the src vector.
* %pad <dst>, <src>, <wid>
This instruction replicates a single bit in register space into a
destination vector in register space. The destination may overlap
the source bit. The <dst> may not be 0-3. This is useful for zero
or sign extending a vector.
* %pop/str <num>
* %pop/real <num>
* %pop/obj <num>
Pop this many items from the string/real/object stack. This is the
opposite of the %pushX/str opcode which pushes a string to the
stack. The %pop/str is not normally needed because the %store/str
includes an implicit pop, but sometimes it is necessary to pop
explicitly.
* %pow <bit-l>, <bit-r>, <wid>
* %pow/s <bit-l>, <bit-r>, <wid>
The %pow opcode raises <bit-l> (unsigned) to the power of <bit-r>
(unsigned) giving an exact integer result. The %pow/s opcode does
the same for signed values, except it uses the double pow() function
to calculate the result so may not produce exact results. The result
replaces the left operand.
* %pow/wr
This opcode raises the left operand by the right operand, and pushes
the result.
* %prop/v <pid>, <base>, <wid>
* %prop/r <pid>
Write the vector (/v) or real value (/r) into property number <pid> of
the class object on the top of the object stack. The real value is popped.
The class object stack is NOT popped.
* %pushi/real <mant>, <exp>
This opcode loads an immediate value, floating point, into the real
value stack. The mantissa is an unsigned integer value, up to 32 bits,
that multiplied by 2**(<exp>-0x1000) to make a real value. The sign
bit is OR-ed into the <exp> value at bit 0x4000, and is removed from
the <exp> before calculating the real value.
If <exp>==0x3fff and <mant> == 0, the value is +inf.
If <exp>==0x7fff and <mant> == 0, the value is -inf.
If <exp>==0x3fff and <mant> != 0, the value is NaN.
* %pushi/str <text>
Push a literal string to the string stack.
* %pushv/str <src>, <wid>
Convert a vector to a string and push the string to the string stack.
* %release/net <functor-label>, <base>, <width>
* %release/reg <functor-label>, <base>, <width>
Release the force on the signal that is represented by the functor
<functor-label>. The force was previously activated with a %force/v
statement. If no force was active on this functor the statement does
nothing. The %release/net sends to the labeled functor the release
command with net semantics: the unforced value is propagated to the
output of the signal after the release is complete. The %release/reg
sends the release command with reg semantics: the signal holds its
forced value until another value propagates through.
The <base> and <width> are used to determine what part of the signal
will be released. For a full release the <base> is 0 and <width> is
the entire signal width.
* %release/wr <functor-label>, <type>
Release the force on the real signal that is represented by the functor
<functor-label>. The force was previously activated with a %force/wr
statement. The <type> is 0 for nets and 1 for registers. See the other
%release commands above.
* %set/dar <var-label>, <bit>, <wid>
This sets a vector to a word of the dynamic array. Index register 3
contains the word address within the dynamic array, and <bit>,<wid>
specifies the thread vector to be written.
* %set/v <var-label>, <bit>, <wid>
This sets a vector to a variable, and is used to implement blocking
assignments. The <var-label> identifies the variable to receive the
new value. Once the set completes, the value is immediately available
to be read out of the variable. The <bit> is the address of the thread
register that contains the LSB of the vector, and the <wid> is the
size of the vector. The width must exactly match the width of the
signal.
* %set/av <array-label>, <bit>, <wid>
This sets a thread vector to an array word. The <array-label>
addresses an array device, and the <bit>,<wid> describe a vector to be
written. Index register 3 contains the address of the word within the
array.
The base of a part select is retrieved from index register 1. The
width is implied from the <wid> that is the argument. This is the part
*within* the word.
The address (in canonical form) is precalculated and loaded into index
register 3. This is the address of the word within the array.
* %set/x0 <var-label>, <bit>, <wid>
This sets the part of a signal vector, the address calculated by
using the index register 0 to index the base within the vector of
<var-label>. The destination must be a signal of some sort. Otherwise,
the instruction will fail.
The addressing is canonical (0-based) so the compiler must figure out
non-zero offsets, if any. The width is the width of the part being
written. The other bits of the vector are not touched.
The index may be signed, and if less than 0, the beginning bits are
not assigned. Also, if the bits go beyond the end of the signal, those
bits are not written anywhere.
* %shiftl/i0 <bit>, <wid>
This instruction shifts the vector left (towards more significant
bits) by the amount in index register 0. The <bit> is the address of
the LSB of the vector, and <wid> the width of the vector. The shift is
done in place. Zero values are shifted in.
For a negative shift the value is padded with 'bx.
* %shiftr/i0 <bit>, <wid>
* %shiftr/s/i0 <bit>, <wid>
This instruction shifts the vector right (towards the less significant
bits) by the amount in the index register 0. The <bit> is the address
of the LSB of the vector, and <wid> is the width of the vector. The
shift is done in place.
%shiftr/i0 is an unsigned down shift, so zeros are shifted into the
top bits. %shiftr/s/i0 is a signed shift, so the value is sign-extended.
For a negative shift %shiftr/i0 will pad the value with 'bx.
* %store/obj <var-label>
This pops the top of the object stack and writes it to the object
variable given by the label.
See also %load/obj.
* %store/prop/r <index>
* %store/prop/v <index>, <bit>, <wid>
The %store/prop/r pops a real value from the real stack and stores it
into the the property number <index> of a cobject in the top of the
object stack. The cobject is NOT popped.
* %store/real <var-label>
* %store/reala <var-label>, <index>
This pops the top of the real variable stack and write it to the
object variable given bu the label.
The areal version is similar, but writes to a real array using the
index in the index register <index>
* %store/str <var-label>
* %store/stra <array-label>, <index>
* %store/dar/r <var-label>
* %store/dar/str <var-label>
The %store/str instruction pops the top of the string stack and writes
it to the string variable.
The %store/stra targets an array.
The %store/dar/str is similar, but the target is a dynamic array of
string string. The index is taken from signed index register 3.
* %sub <bit-l>, <bit-r>, <wid>
This instruction arithmetically subtracts the right vector out of the
left vector. It accomplishes this by adding to the left vector 1 plus
the 1s complement of the right vector. The carry value is dropped, and
the result, placed in <bit-l>, is the subtraction of <bit-r> from the
input <bit-l>. Both vectors have the same width. If any bits in either
operand are x, then the entire result is x.
See also the %add instruction.
* %subi <bit-l>, <imm>, <wid>
This instruction arithmetically subtracts the immediate value from the
left vector. The <imm> value is a 16bit unsigned value zero-extended to
the <wid> of the left vector. The result replaces the left vector.
See also the %addi instruction.
* %sub/wr
This instruction operates on real values in word registers. The right
value is popped, the left value is popped, the right is subtracted
from the left, and the result pushed.
* %substr <start>, <end>
This instruction takes the substring of the top string in the string
stack. This implements the SystemVerilog style substring. The string
stack is popped and replaced with the result.
* %substr/v <bit-l>, <sel>, <wid>
This instruction extracts the substring of the top string in the string
stack and delivers the result to vector space. The <bit>,<wid> part is
the location where the result goes, and <sel> is the index register
that holds the index. This is the general method for getting string
values into the vector space. The string value is NOT popped.
* %test_nul <var-label>
This instruction tests the contents of the addressed variable to see
if it is null. If it is, set bit 4 to 1. Otherwise, set bit 4 to 0.
This is intended to implement the SystemVerilog expression
(<var>==null), where <var> is a class variable.
* %vpi_call <name> [, ...] {<real> <str>}
This instruction makes a call to a system task that was declared using
VPI. The operands are compiled down to a vpiHandle for the call. The
instruction contains only the vpiHandle for the call. See the vpi.txt
file for more on system task/function calls.
The {...} part is stack information. This tells the run-time how many
stack items the call uses so that it knows how many to pop off the
stack when the call returns.
* %vpi_func <name>, <dst>, <wid> [, ...] {<real> <str>}
This instruction is similar to %vpi_call, except that it is for
calling system functions. The difference here is the <dst> and <wid>
parameters that specify where the return value is to go. The normal
means that the VPI code uses to write the return value causes those
bits to go here.
The {...} part is stack information. This tells the run-time how many
stack items the call uses so that it knows how many to pop off the
stack when the call returns. The function call will pop the real and
string stacks, and will push any return value.
* %wait <functor-label>
When a thread executes this instruction, it places itself in the
sensitive list for the addressed functor. The functor holds all the
threads that await the functor. When the defined sort of event occurs
on the functor, a thread schedule event is created for all the threads
in its list and the list is cleared.
* %xnor <dst>, <src>, <wid>
This does a bitwise exclusive nor (~^) of the <src> and <dst> vector,
and leaves the result in the <dst> vector. xnor is this:
0 xnor 0 --> 1
0 xnor 1 --> 0
1 xnor 0 --> 0
1 xnor 1 --> 1
otherwise x
* %xor <dst>, <src>, <wid>
This does a bitwise exclusive or (^) of the <src> and <dst> vector,
and leaves the result in the <dst> vector. xor is this:
0 xor 0 --> 0
0 xor 1 --> 1
1 xor 0 --> 1
1 xor 1 --> 0
otherwise x
/*
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/