Add assign/deassign to bit/part selects and other fixes
This patch adds the ability to assign/deassign a bit or part select. It also cleans up the code and fixes some problem in the forcing of strength aware nets.
This commit is contained in:
parent
321114e4db
commit
9bb8e8146f
|
|
@ -802,7 +802,7 @@ static void force_vector_to_lval(ivl_statement_t net, struct vector_info rvec)
|
|||
switch (ivl_statement_type(net)) {
|
||||
case IVL_ST_CASSIGN:
|
||||
command_name = "%cassign/v";
|
||||
command_name_x0 = "ERROR";
|
||||
command_name_x0 = "%cassign/x0";
|
||||
break;
|
||||
case IVL_ST_FORCE:
|
||||
command_name = "%force/v";
|
||||
|
|
@ -842,12 +842,6 @@ static void force_vector_to_lval(ivl_statement_t net, struct vector_info rvec)
|
|||
|
||||
if (part_off != 0 || use_wid != ivl_signal_width(lsig)) {
|
||||
|
||||
if (ivl_statement_type(net) == IVL_ST_CASSIGN) {
|
||||
fprintf(stderr, "%s:%u: vvp-tgt sorry: cannot assign "
|
||||
"signal to a bit/part select.\n",
|
||||
ivl_stmt_file(net), ivl_stmt_lineno(net));
|
||||
exit(1);
|
||||
}
|
||||
command_name = command_name_x0;
|
||||
fprintf(vvp_out, " %%ix/load 0, %u;\n", part_off);
|
||||
|
||||
|
|
@ -967,15 +961,12 @@ static int show_stmt_deassign(ivl_statement_t net)
|
|||
assert(lsig != 0);
|
||||
assert(ivl_lval_mux(lval) == 0);
|
||||
|
||||
/* We do not currently support deassigning a bit or
|
||||
* part select. */
|
||||
unsigned use_wid = ivl_lval_width(lval);
|
||||
ivl_expr_t part_off_ex = ivl_lval_part_off(lval);
|
||||
if (ivl_signal_width(lsig) > ivl_lval_width(lval) ||
|
||||
(part_off_ex && get_number_immediate(part_off_ex) != 0)) {
|
||||
fprintf(stderr, "%s:%u: vvp-tgt sorry: cannot deassign "
|
||||
"a bit/part select.\n", ivl_stmt_file(net),
|
||||
ivl_stmt_lineno(net));
|
||||
exit(1);
|
||||
unsigned part_off = 0;
|
||||
if (part_off_ex != 0) {
|
||||
assert(number_is_immediate(part_off_ex, 64));
|
||||
part_off = get_number_immediate(part_off_ex);
|
||||
}
|
||||
|
||||
if (word_idx != 0) {
|
||||
|
|
@ -984,7 +975,8 @@ static int show_stmt_deassign(ivl_statement_t net)
|
|||
}
|
||||
|
||||
|
||||
fprintf(vvp_out, " %%deassign v%p_%lu;\n", lsig, use_word);
|
||||
fprintf(vvp_out, " %%deassign v%p_%lu, %u, %u;\n",
|
||||
lsig, use_word, part_off, use_wid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ extern bool of_BLEND_WR(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_BREAKPOINT(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_CASSIGN_LINK(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_CASSIGN_V(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_CASSIGN_X0(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_CMPIS(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_CMPIU(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_CMPS(vthread_t thr, vvp_code_t code);
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ const static struct opcode_table_s opcode_table[] = {
|
|||
{ "%breakpoint", of_BREAKPOINT, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%cassign/link",of_CASSIGN_LINK,2,{OA_FUNC_PTR,OA_FUNC_PTR2,OA_NONE} },
|
||||
{ "%cassign/v",of_CASSIGN_V,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
|
||||
{ "%cassign/x0",of_CASSIGN_X0,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
|
||||
{ "%cmp/s", of_CMPS, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%cmp/u", of_CMPU, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%cmp/wr", of_CMPWR, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
|
||||
|
|
@ -113,7 +114,7 @@ const static struct opcode_table_s opcode_table[] = {
|
|||
{ "%cvt/ir", of_CVT_IR, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
|
||||
{ "%cvt/ri", of_CVT_RI, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
|
||||
{ "%cvt/vr", of_CVT_VR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%deassign",of_DEASSIGN,1,{OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%deassign",of_DEASSIGN,3,{OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%delay", of_DELAY, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
|
||||
{ "%delayx", of_DELAYX, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%div", of_DIV, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
|
|
|
|||
|
|
@ -168,6 +168,13 @@ variable. This is similar to %set, but it uses the cassign port
|
|||
signal responds differently. See "VARIABLE STATEMENTS" in the
|
||||
README.txt file.
|
||||
|
||||
* %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.
|
||||
|
||||
* %cmp/u <bit-l>, <bit-r>, <wid>
|
||||
* %cmp/s <bit-l>, <bit-r>, <wid>
|
||||
|
|
@ -239,11 +246,15 @@ The %cvt/vr opcode converts a real word <bit-r> to a thread vector
|
|||
starting at <bit-l> and with the width <wid>. Non-integer precision is
|
||||
lost in the conversion.
|
||||
|
||||
* %deassign <var-label>
|
||||
* %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.
|
||||
|
||||
* %delay <delay>
|
||||
|
||||
This opcode pauses the thread, and causes it to be rescheduled for a
|
||||
|
|
@ -291,8 +302,8 @@ in the README.txt file.
|
|||
|
||||
* %force/x0 <label>, <bit>, <wid>
|
||||
|
||||
Force a constant value to part target variable. This is similar to
|
||||
%set/x instruction, but it uses the force port (port-2) of the signal
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -845,6 +845,40 @@ bool of_CASSIGN_V(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool of_CASSIGN_X0(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
vvp_net_t*net = cp->net;
|
||||
unsigned base = cp->bit_idx[0];
|
||||
unsigned wid = cp->bit_idx[1];
|
||||
|
||||
// Implicitly, we get the base into the target vector from the
|
||||
// X0 register.
|
||||
long index = thr->words[0].w_int;
|
||||
|
||||
vvp_fun_signal_vec*sig = dynamic_cast<vvp_fun_signal_vec*> (net->fun);
|
||||
|
||||
if (index < 0 && (wid <= (unsigned)-index))
|
||||
return true;
|
||||
|
||||
if (index >= (long)sig->size())
|
||||
return true;
|
||||
|
||||
if (index < 0) {
|
||||
wid -= (unsigned) -index;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
if (index+wid > sig->size())
|
||||
wid = sig->size() - index;
|
||||
|
||||
vvp_vector4_t vector = vthread_bits_to_vector(thr, base, wid);
|
||||
|
||||
vvp_net_ptr_t ptr (net, 1);
|
||||
vvp_send_vec4_pv(ptr, vector, index, wid, sig->size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_CMPS(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
vvp_bit4_t eq = BIT4_1;
|
||||
|
|
@ -1185,9 +1219,24 @@ bool of_CVT_VR(vthread_t thr, vvp_code_t cp)
|
|||
bool of_DEASSIGN(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
vvp_net_t*net = cp->net;
|
||||
unsigned base = cp->bit_idx[0];
|
||||
unsigned width = cp->bit_idx[1];
|
||||
|
||||
vvp_fun_signal_vec*sig = reinterpret_cast<vvp_fun_signal_vec*>(net->fun);
|
||||
assert(sig);
|
||||
|
||||
if (base >= sig->size()) return true;
|
||||
if (base+width > sig->size()) width = sig->size() - base;
|
||||
|
||||
bool full_sig = base == 0 && width == sig->size();
|
||||
|
||||
/* Do we release all or part of the net? */
|
||||
vvp_net_ptr_t ptr (net, 3);
|
||||
vvp_send_long(ptr, 1);
|
||||
if (full_sig) {
|
||||
vvp_send_long(ptr, 1);
|
||||
} else {
|
||||
vvp_send_long_pv(ptr, 1, base, width);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1777,7 +1826,7 @@ bool of_FORCE_V(vthread_t thr, vvp_code_t cp)
|
|||
/* Collect the thread bits into a vector4 item. */
|
||||
vvp_vector4_t value = vthread_bits_to_vector(thr, base, wid);
|
||||
|
||||
/* set the value into port 1 of the destination. */
|
||||
/* Set the value into port 2 of the destination. */
|
||||
vvp_net_ptr_t ptr (net, 2);
|
||||
vvp_send_vec4(ptr, value);
|
||||
|
||||
|
|
@ -1787,7 +1836,7 @@ bool of_FORCE_V(vthread_t thr, vvp_code_t cp)
|
|||
bool of_FORCE_X0(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
vvp_net_t*net = cp->net;
|
||||
unsigned bit = cp->bit_idx[0];
|
||||
unsigned base = cp->bit_idx[0];
|
||||
unsigned wid = cp->bit_idx[1];
|
||||
|
||||
// Implicitly, we get the base into the target vector from the
|
||||
|
|
@ -1810,19 +1859,14 @@ bool of_FORCE_X0(vthread_t thr, vvp_code_t cp)
|
|||
if (index+wid > sig->size())
|
||||
wid = sig->size() - index;
|
||||
|
||||
vvp_vector4_t bit_vec(wid);
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
vvp_bit4_t bit_val = thr_get_bit(thr, bit);
|
||||
bit_vec.set_bit(idx, bit_val);
|
||||
if (bit >= 4)
|
||||
bit += 1;
|
||||
}
|
||||
vvp_vector4_t vector = vthread_bits_to_vector(thr, base, wid);
|
||||
|
||||
vvp_net_ptr_t ptr (net, 2);
|
||||
vvp_send_vec4_pv(ptr, bit_vec, index, wid, sig->size());
|
||||
vvp_send_vec4_pv(ptr, vector, index, wid, sig->size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* The %fork instruction causes a new child to be created and pushed
|
||||
* in front of any existing child. This causes the new child to be the
|
||||
|
|
|
|||
163
vvp/vvp_net.cc
163
vvp/vvp_net.cc
|
|
@ -1133,6 +1133,18 @@ bool vvp_vector2_t::is_NaN() const
|
|||
return wid_ == 0;
|
||||
}
|
||||
|
||||
bool vvp_vector2_t::is_zero() const
|
||||
{
|
||||
const unsigned words = (wid_ + BITS_PER_WORD-1) / BITS_PER_WORD;
|
||||
|
||||
for (unsigned idx = 0; idx < words; idx += 1) {
|
||||
if (vec_[idx] == 0) continue;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic idea from "Introduction to Programming using SML" by
|
||||
* Michael R. Hansen and Hans Rischel page 261 and "Seminumerical
|
||||
|
|
@ -1659,6 +1671,18 @@ vvp_fun_signal_base::vvp_fun_signal_base()
|
|||
void vvp_fun_signal_base::deassign()
|
||||
{
|
||||
continuous_assign_active_ = false;
|
||||
assign_mask_ = vvp_vector2_t();
|
||||
}
|
||||
|
||||
void vvp_fun_signal_base::deassign_pv(unsigned base, unsigned wid)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
assign_mask_.set_bit(base+idx, 0);
|
||||
}
|
||||
|
||||
if (assign_mask_.is_zero()) {
|
||||
assign_mask_ = vvp_vector2_t();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1700,9 +1724,7 @@ void vvp_fun_signal_base::recv_long_pv(vvp_net_ptr_t ptr, long bit,
|
|||
case 3: // Command port
|
||||
switch (bit) {
|
||||
case 1: // deassign command
|
||||
fprintf(stderr, "Sorry: cannot deassign a partial signal\n");
|
||||
assert(0);
|
||||
deassign();
|
||||
deassign_pv(base, wid);
|
||||
break;
|
||||
case 2: // release/net
|
||||
release_pv(ptr, true, base, wid);
|
||||
|
|
@ -1745,22 +1767,34 @@ void vvp_fun_signal::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit)
|
|||
{
|
||||
switch (ptr.port()) {
|
||||
case 0: // Normal input (feed from net, or set from process)
|
||||
/* If continuous assign is active, then this is a var
|
||||
and the continuous assigned values overrides any
|
||||
normal input. So process input only if continuous
|
||||
assignment is not active. */
|
||||
if (!continuous_assign_active_) {
|
||||
/* If we don't have a continuous assign mask then just
|
||||
copy the bits, otherwise we need to see if there are
|
||||
any holes in the mask so we can set those bits. */
|
||||
if (assign_mask_.size() == 0) {
|
||||
if (needs_init_ || !bits4_.eeq(bit)) {
|
||||
bits4_ = bit;
|
||||
needs_init_ = false;
|
||||
calculate_output_(ptr);
|
||||
}
|
||||
} else {
|
||||
bool changed = false;
|
||||
assert(bits4_.size() == assign_mask_.size());
|
||||
for (unsigned idx = 0 ; idx < bit.size() ; idx += 1) {
|
||||
if (idx >= bits4_.size()) break;
|
||||
if (assign_mask_.value(idx)) continue;
|
||||
bits4_.set_bit(idx, bit.value(idx));
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
needs_init_ = false;
|
||||
calculate_output_(ptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // Continuous assign value
|
||||
continuous_assign_active_ = true;
|
||||
bits4_ = bit;
|
||||
assign_mask_ = vvp_vector2_t(vvp_vector2_t::FILL1, size());
|
||||
calculate_output_(ptr);
|
||||
break;
|
||||
|
||||
|
|
@ -1792,17 +1826,41 @@ void vvp_fun_signal::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
|||
|
||||
switch (ptr.port()) {
|
||||
case 0: // Normal input
|
||||
if (! continuous_assign_active_) {
|
||||
if (assign_mask_.size() == 0) {
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
if (base+idx >= bits4_.size())
|
||||
break;
|
||||
if (base+idx >= bits4_.size()) break;
|
||||
bits4_.set_bit(base+idx, bit.value(idx));
|
||||
}
|
||||
needs_init_ = false;
|
||||
calculate_output_(ptr);
|
||||
} else {
|
||||
bool changed = false;
|
||||
assert(bits4_.size() == assign_mask_.size());
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
if (base+idx >= bits4_.size()) break;
|
||||
if (assign_mask_.value(base+idx)) continue;
|
||||
bits4_.set_bit(base+idx, bit.value(idx));
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
needs_init_ = false;
|
||||
calculate_output_(ptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // Continuous assign value
|
||||
if (assign_mask_.size() == 0)
|
||||
assign_mask_ = vvp_vector2_t(vvp_vector2_t::FILL0, size());
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
if (base+idx >= bits4_.size())
|
||||
break;
|
||||
bits4_.set_bit(base+idx, bit.value(idx));
|
||||
assign_mask_.set_bit(base+idx, 1);
|
||||
}
|
||||
calculate_output_(ptr);
|
||||
break;
|
||||
|
||||
case 2: // Force value
|
||||
|
||||
if (force_mask_.size() == 0)
|
||||
|
|
@ -1870,6 +1928,7 @@ void vvp_fun_signal::release_pv(vvp_net_ptr_t ptr, bool net,
|
|||
force_mask_.set_bit(base+idx, 0);
|
||||
if (!net) bits4_.set_bit(base+idx, force_.value(base+idx));
|
||||
}
|
||||
if (force_mask_.is_zero()) force_mask_ = vvp_vector2_t();
|
||||
|
||||
if (net) calculate_output_(ptr);
|
||||
}
|
||||
|
|
@ -1929,19 +1988,18 @@ void vvp_fun_signal8::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
|
|||
{
|
||||
switch (ptr.port()) {
|
||||
case 0: // Normal input (feed from net, or set from process)
|
||||
if (!continuous_assign_active_) {
|
||||
if (needs_init_ || !bits8_.eeq(bit)) {
|
||||
bits8_ = bit;
|
||||
needs_init_ = false;
|
||||
calculate_output_(ptr);
|
||||
}
|
||||
if (needs_init_ || !bits8_.eeq(bit)) {
|
||||
bits8_ = bit;
|
||||
needs_init_ = false;
|
||||
calculate_output_(ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // Continuous assign value
|
||||
continuous_assign_active_ = true;
|
||||
bits8_ = bit;
|
||||
calculate_output_(ptr);
|
||||
/* This is a procedural continuous assign and it can
|
||||
* only be used on a register and a register is never
|
||||
* strength aware. */
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
case 2: // Force value
|
||||
|
|
@ -1964,6 +2022,57 @@ void vvp_fun_signal8::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
|
|||
}
|
||||
}
|
||||
|
||||
void vvp_fun_signal8::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
|
||||
unsigned base, unsigned wid, unsigned vwid)
|
||||
{
|
||||
recv_vec8_pv(ptr, bit, base, wid, vwid);
|
||||
}
|
||||
|
||||
void vvp_fun_signal8::recv_vec8_pv(vvp_net_ptr_t ptr, vvp_vector8_t bit,
|
||||
unsigned base, unsigned wid, unsigned vwid)
|
||||
{
|
||||
assert(bit.size() == wid);
|
||||
assert(bits8_.size() == vwid);
|
||||
|
||||
switch (ptr.port()) {
|
||||
case 0: // Normal input
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
if (base+idx >= bits8_.size()) break;
|
||||
bits8_.set_bit(base+idx, bit.value(idx));
|
||||
}
|
||||
needs_init_ = false;
|
||||
calculate_output_(ptr);
|
||||
break;
|
||||
|
||||
case 1: // Continuous assign value
|
||||
/* This is a procedural continuous assign and it can
|
||||
* only be used on a register and a register is never
|
||||
* strength aware. */
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
case 2: // Force value
|
||||
|
||||
if (force_mask_.size() == 0)
|
||||
force_mask_ = vvp_vector2_t(vvp_vector2_t::FILL0, size());
|
||||
if (force_.size() == 0)
|
||||
force_ = vvp_vector8_t(vvp_vector4_t(vwid, BIT4_Z));
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
force_mask_.set_bit(base+idx, 1);
|
||||
force_.set_bit(base+idx, bit.value(idx));
|
||||
}
|
||||
|
||||
calculate_output_(ptr);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unsupported port type %d.\n", ptr.port());
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void vvp_fun_signal8::calculate_output_(vvp_net_ptr_t ptr)
|
||||
{
|
||||
if (force_mask_.size()) {
|
||||
|
|
@ -2003,6 +2112,7 @@ void vvp_fun_signal8::release_pv(vvp_net_ptr_t ptr, bool net,
|
|||
force_mask_.set_bit(base+idx, 0);
|
||||
if (!net) bits8_.set_bit(base+idx, force_.value(base+idx));
|
||||
}
|
||||
if (force_mask_.is_zero()) force_mask_ = vvp_vector2_t();
|
||||
|
||||
if (net) calculate_output_(ptr);
|
||||
}
|
||||
|
|
@ -2025,9 +2135,14 @@ vvp_bit4_t vvp_fun_signal8::value(unsigned idx) const
|
|||
|
||||
vvp_vector4_t vvp_fun_signal8::vec4_value() const
|
||||
{
|
||||
if (force_mask_.size())
|
||||
return reduce4(force_);
|
||||
else
|
||||
if (force_mask_.size()) {
|
||||
vvp_vector8_t bits (bits8_);
|
||||
for (unsigned idx = 0 ; idx < bits.size() ; idx += 1) {
|
||||
if (force_mask_.value(idx))
|
||||
bits.set_bit(idx, force_.value(idx));
|
||||
}
|
||||
return reduce4(bits);
|
||||
} else
|
||||
return reduce4(bits8_);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -306,6 +306,7 @@ class vvp_vector2_t {
|
|||
vvp_vector2_t&operator = (const vvp_vector2_t&);
|
||||
|
||||
bool is_NaN() const;
|
||||
bool is_zero() const;
|
||||
unsigned size() const;
|
||||
int value(unsigned idx) const;
|
||||
void set_bit(unsigned idx, int bit);
|
||||
|
|
@ -834,8 +835,10 @@ class vvp_fun_signal_base : public vvp_net_fun_t, public vvp_vpi_callback {
|
|||
bool needs_init_;
|
||||
bool continuous_assign_active_;
|
||||
vvp_vector2_t force_mask_;
|
||||
vvp_vector2_t assign_mask_;
|
||||
|
||||
void deassign();
|
||||
void deassign_pv(unsigned base, unsigned wid);
|
||||
virtual void release(vvp_net_ptr_t ptr, bool net) =0;
|
||||
virtual void release_pv(vvp_net_ptr_t ptr, bool net,
|
||||
unsigned base, unsigned wid) =0;
|
||||
|
|
@ -896,8 +899,10 @@ class vvp_fun_signal8 : public vvp_fun_signal_vec {
|
|||
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
|
||||
|
||||
// Part select variants of above
|
||||
//void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||
// unsigned base, unsigned wid, unsigned vwid);
|
||||
void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||
unsigned base, unsigned wid, unsigned vwid);
|
||||
void recv_vec8_pv(vvp_net_ptr_t port, vvp_vector8_t bit,
|
||||
unsigned base, unsigned wid, unsigned vwid);
|
||||
|
||||
// Get information about the vector value.
|
||||
unsigned size() const;
|
||||
|
|
|
|||
Loading…
Reference in New Issue