Merge branch 'master' into verilog-ams
This commit is contained in:
commit
30570adf31
|
|
@ -386,82 +386,6 @@ at <src>.
|
||||||
|
|
||||||
<label> .array "name", <src> ;
|
<label> .array "name", <src> ;
|
||||||
|
|
||||||
MEMORY STATEMENTS:
|
|
||||||
|
|
||||||
Memories are arrays of words, each word a vvp_vector4_t vector of the
|
|
||||||
same width. The memory is canonically addressed as a 1-dimensional
|
|
||||||
array of words, although indices are stored with the memory for
|
|
||||||
calculating a canonical address from a multi-dimensional address.
|
|
||||||
|
|
||||||
Three types of memory statement perform (1) creation of a memory, (2)
|
|
||||||
connecting a read port to an existing memory, and (3) initializing the
|
|
||||||
memory's contents.
|
|
||||||
|
|
||||||
<label> .mem "name", <msb>,<lsb>, <last>,<first> ... ;
|
|
||||||
|
|
||||||
The pair of numbers <msb>,<lsb> defines the word width. The pair
|
|
||||||
<last>,<first> defines the address range. Multiple address ranges are
|
|
||||||
allowed for multidimensional indexing. This statement creates the
|
|
||||||
memory array and makes it available to procedural code.
|
|
||||||
|
|
||||||
Procedural access to the memory references the memory as single array
|
|
||||||
of words, with the base address==0, and the last address the size (in
|
|
||||||
words) of the memory -1. It is up to the compiler to convert Verilog
|
|
||||||
index sets to a canonical address. The multi-dimensional index set is
|
|
||||||
available for VPI use.
|
|
||||||
|
|
||||||
Structural read access is implemented in terms of address and data
|
|
||||||
ports. The addresses applied to the address port are expected to be
|
|
||||||
in canonical form.
|
|
||||||
|
|
||||||
A read port is a functor that takes a single input, the read address,
|
|
||||||
and outputs the word value at the given (canonical) address.
|
|
||||||
|
|
||||||
<label> .mem/port <memid>, <address> ;
|
|
||||||
|
|
||||||
<label> identifies the vector of output functors, to allow connections
|
|
||||||
to the data output. <memid> is the label of the memory.
|
|
||||||
|
|
||||||
Any address input change, or any change in the addressed memory
|
|
||||||
contents, is immediately propagated to the port output.
|
|
||||||
|
|
||||||
A write port is a superset of a read port. It is a 4-input functor
|
|
||||||
that accepts the word address, an event input, a write enable input,
|
|
||||||
and the data input.
|
|
||||||
|
|
||||||
<label> .mem/port <memid>, <address>, <event>, <we>, <data> ;
|
|
||||||
|
|
||||||
<event> is an event functor that triggers a write, if the <we> input
|
|
||||||
is true. <data> is the input that connect to the data input
|
|
||||||
port. For asynchronous transparent write operation, connect
|
|
||||||
<event> to C4<z>, the RAM will transparently follow any changes on
|
|
||||||
address and data lines, while <we> is true.
|
|
||||||
|
|
||||||
There is no Verilog construct that calls for a structural write port
|
|
||||||
to a memory, but synthesis may ask for lpm_ram_d[pq] objects.
|
|
||||||
|
|
||||||
To initialize a memory, use:
|
|
||||||
|
|
||||||
.mem/init <memid> <start>, val , val ... ;
|
|
||||||
|
|
||||||
<memid> is the label of the memory, and the <start> is the start
|
|
||||||
address (canonical) of the first word to be initialized. The start
|
|
||||||
address allows multiple statements be used to initialize words of a
|
|
||||||
memory.
|
|
||||||
|
|
||||||
The values are one per word.
|
|
||||||
|
|
||||||
Procedural access to the memory employs an index register to address a
|
|
||||||
bit location in the memory, via the commands:
|
|
||||||
|
|
||||||
%load/m <bit>, <memid> ;
|
|
||||||
%set/m <memid>, <bit> ;
|
|
||||||
%assign/m <memid>, <delay>, <bit> ;
|
|
||||||
|
|
||||||
The memory bit is addressed by index register 3. The value of
|
|
||||||
register 3 is the index in the memory's bit space, where each data
|
|
||||||
word occupies a multiple of four bits.
|
|
||||||
|
|
||||||
|
|
||||||
EVENT STATEMENTS
|
EVENT STATEMENTS
|
||||||
|
|
||||||
|
|
|
||||||
20
vvp/array.cc
20
vvp/array.cc
|
|
@ -354,9 +354,14 @@ static void vpi_array_var_word_get_value(vpiHandle ref, p_vpi_value value)
|
||||||
|
|
||||||
assert(obj);
|
assert(obj);
|
||||||
unsigned index = decode_array_word_pointer(obj, parent);
|
unsigned index = decode_array_word_pointer(obj, parent);
|
||||||
|
unsigned width = parent->vals_width;
|
||||||
|
|
||||||
vpip_vec4_get_value(parent->vals[index], parent->vals_width,
|
/* If we don't have a value yet just return X. */
|
||||||
false, value);
|
if (parent->vals[index].size() == 0) {
|
||||||
|
vpip_vec4_get_value(vvp_vector4_t(width), width, false, value);
|
||||||
|
} else {
|
||||||
|
vpip_vec4_get_value(parent->vals[index], width, false, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static vpiHandle vpi_array_var_word_put_value(vpiHandle ref, p_vpi_value vp, int flags)
|
static vpiHandle vpi_array_var_word_put_value(vpiHandle ref, p_vpi_value vp, int flags)
|
||||||
|
|
@ -493,8 +498,15 @@ static void vpi_array_vthr_A_get_value(vpiHandle ref, p_vpi_value value)
|
||||||
assert(parent->vals);
|
assert(parent->vals);
|
||||||
assert(obj->address < parent->array_count);
|
assert(obj->address < parent->array_count);
|
||||||
|
|
||||||
vpip_vec4_get_value(parent->vals[obj->address],
|
unsigned index = obj->address;
|
||||||
parent->vals_width, false, value);
|
unsigned width = parent->vals_width;
|
||||||
|
|
||||||
|
/* If we don't have a value yet just return X. */
|
||||||
|
if (parent->vals[index].size() == 0) {
|
||||||
|
vpip_vec4_get_value(vvp_vector4_t(width), width, false, value);
|
||||||
|
} else {
|
||||||
|
vpip_vec4_get_value(parent->vals[index], width, false, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static vpiHandle vpi_array_vthr_A_put_value(vpiHandle ref, p_vpi_value vp, int)
|
static vpiHandle vpi_array_vthr_A_put_value(vpiHandle ref, p_vpi_value vp, int)
|
||||||
|
|
|
||||||
|
|
@ -80,20 +80,6 @@ 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
|
since these registers contain the vector width, base part select and
|
||||||
word address.
|
word address.
|
||||||
|
|
||||||
* %assign/mv <memory-label>, <delay>, <bit> (DEPRECATED)
|
|
||||||
|
|
||||||
the %assign/mv instruction assigns a vector value to a word in the
|
|
||||||
labeled memory. 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 word 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.
|
|
||||||
|
|
||||||
* %assign/v0 <var-label>, <delay>, <bit>
|
* %assign/v0 <var-label>, <delay>, <bit>
|
||||||
* %assign/v0/d <var-label>, <delayx>, <bit>
|
* %assign/v0/d <var-label>, <delayx>, <bit>
|
||||||
|
|
||||||
|
|
@ -443,12 +429,6 @@ 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
|
bit, and the <index> is the selector for the bit to use. If <index> is
|
||||||
out of range, then x is loaded.
|
out of range, then x is loaded.
|
||||||
|
|
||||||
* %load/mv <bit>, <memory-label>, <wid>
|
|
||||||
|
|
||||||
this instruction loads a word from the specified memory. The word
|
|
||||||
address is in index register 3. The width should match the width of
|
|
||||||
the memory word.
|
|
||||||
|
|
||||||
* %load/nx <bit>, <vpi-label>, <idx>
|
* %load/nx <bit>, <vpi-label>, <idx>
|
||||||
|
|
||||||
This instruction load a value from a .net object bit. Since .net
|
This instruction load a value from a .net object bit. Since .net
|
||||||
|
|
@ -668,19 +648,6 @@ width is implied from the <wid> that is the argument. This is the part
|
||||||
The address (in canonical form) is precalculated and loaded into index
|
The address (in canonical form) is precalculated and loaded into index
|
||||||
register 3. This is the address of the word within the array.
|
register 3. This is the address of the word within the array.
|
||||||
|
|
||||||
* %set/mv <memory-label>, <bit>, <wid>
|
|
||||||
|
|
||||||
This sets a thread vector to a memory word. The <memory-label>
|
|
||||||
addresses a memory device, and the <bit>,<wid> describe a vector to be
|
|
||||||
written. Index register 3 contains the address of the word within the
|
|
||||||
memory.
|
|
||||||
|
|
||||||
The base of a part select is retrieved from index register 1.
|
|
||||||
|
|
||||||
The address (in canonical form) is precalculated and loaded into index
|
|
||||||
register 3.
|
|
||||||
|
|
||||||
|
|
||||||
* %set/wr <vpi-label>, <bit>
|
* %set/wr <vpi-label>, <bit>
|
||||||
|
|
||||||
This instruction writes a real word to the specified VPI-like object.
|
This instruction writes a real word to the specified VPI-like object.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue