Fix for pr2973532.

Under certain circumnstances, the vvp code generator can generate
a .part/pv that directly feeds an input port of a .concat. This
patch adds a recv_vec4_pv method to the vvp_fun_concat class to
handle this case. It also changes the initial value of the stored
vector from X to Z to correctly handle bits which are not driven.
This commit is contained in:
Martin Whitaker 2010-03-20 16:53:56 +00:00 committed by Stephen Williams
parent da9edeacc7
commit 483afd5dc9
2 changed files with 34 additions and 1 deletions

View File

@ -37,7 +37,7 @@ vvp_fun_concat::vvp_fun_concat(unsigned w0, unsigned w1,
wid_[3] = w3;
for (unsigned idx = 0 ; idx < val_.size() ; idx += 1)
val_.set_bit(idx, BIT4_X);
val_.set_bit(idx, BIT4_Z);
}
vvp_fun_concat::~vvp_fun_concat()
@ -67,6 +67,36 @@ void vvp_fun_concat::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
port.ptr()->send_vec4(val_, 0);
}
void vvp_fun_concat::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t)
{
assert(bit.size() == wid);
unsigned pdx = port.port();
if (vwid != wid_[pdx]) {
cerr << "internal error: port " << pdx
<< " expects wid=" << wid_[pdx]
<< ", got wid=" << vwid << endl;
assert(0);
}
unsigned off = 0;
for (unsigned idx = 0 ; idx < pdx ; idx += 1)
off += wid_[idx];
unsigned limit = off + wid_[pdx];
off += base;
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
if (off+idx >= limit) break;
val_.set_bit(off+idx, bit.value(idx));
}
port.ptr()->send_vec4(val_, 0);
}
void compile_concat(char*label, unsigned w0, unsigned w1,
unsigned w2, unsigned w3,
unsigned argc, struct symb_s*argv)

View File

@ -1248,6 +1248,9 @@ class vvp_fun_concat : public vvp_net_fun_t {
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
vvp_context_t context);
void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
unsigned base, unsigned wid, unsigned vwid,
vvp_context_t);
private:
unsigned wid_[4];
vvp_vector4_t val_;