Remove the signal functor force-2 input port hack.

The vvp_net_t port 2 was used to implement force behavior, but that
is no longer how we plan to implement force, so remove it from the
implementation of signal nodes. This currently breaks much of the
force/release functionality, but we'll get it back by other means.
This commit is contained in:
Stephen Williams 2009-05-27 20:37:46 -07:00
parent 30ee9a104e
commit 29a47efa81
3 changed files with 36 additions and 70 deletions

View File

@ -179,6 +179,19 @@ void vthread_put_real(struct vthread_s*thr, unsigned addr, double val)
thr->words[addr].w_real = val;
}
template <class T> T coerce_to_width(const T&that, unsigned width)
{
if (that.size() == width)
return that;
assert(that.size() > width);
T res (width);
for (unsigned idx = 0 ; idx < width ; idx += 1)
res.set_bit(idx, that.value(idx));
return res;
}
static unsigned long* vector_to_array(struct vthread_s*thr,
unsigned addr, unsigned wid)
{
@ -2288,8 +2301,8 @@ bool of_EVCTLS(vthread_t thr, vvp_code_t cp)
static void unlink_force(vvp_net_t*net)
{
vvp_fun_signal_base*sig
= reinterpret_cast<vvp_fun_signal_base*>(net->fun);
vvp_filter_wire_base*sig
= reinterpret_cast<vvp_filter_wire_base*>(net->fun);
/* This node must be a signal... */
assert(sig);
/* This signal is being forced. */
@ -2315,8 +2328,8 @@ bool of_FORCE_LINK(vthread_t thr, vvp_code_t cp)
vvp_net_t*dst = cp->net;
vvp_net_t*src = cp->net2;
vvp_fun_signal_base*sig
= reinterpret_cast<vvp_fun_signal_base*>(dst->fun);
vvp_filter_wire_base*sig
= reinterpret_cast<vvp_filter_wire_base*>(dst->fun);
assert(sig);
/* Detect the special case that we are already forced the
@ -2359,9 +2372,13 @@ 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 2 of the destination. */
vvp_net_ptr_t ptr (net, 2);
vvp_send_vec4(ptr, value, 0);
/* Send the force value to the signal on the node. */
vvp_fun_signal4*sig = reinterpret_cast<vvp_fun_signal4*> (net->fun);
assert(sig);
if (value.size() != sig->size())
value = coerce_to_width(value, sig->size());
sig->force_vec4(value, vvp_vector2_t(vvp_vector2_t::FILL1, sig->size()));
return true;
}
@ -2371,9 +2388,10 @@ bool of_FORCE_WR(vthread_t thr, vvp_code_t cp)
vvp_net_t*net = cp->net;
double value = thr->words[cp->bit_idx[0]].w_real;
/* Set the value into port 2 of the destination. */
vvp_net_ptr_t ptr (net, 2);
vvp_send_real(ptr, value, 0);
vvp_fun_signal_real*sig = reinterpret_cast<vvp_fun_signal_real*>(net->fun);
assert(sig);
sig->force_real(value, vvp_vector2_t(vvp_vector2_t::FILL1, 1));
return true;
}

View File

@ -28,19 +28,6 @@
# include <map>
#endif
template <class T> T coerce_to_width(const T&that, unsigned width)
{
if (that.size() == width)
return that;
assert(that.size() > width);
T res (width);
for (unsigned idx = 0 ; idx < width ; idx += 1)
res.set_bit(idx, that.value(idx));
return res;
}
vvp_filter_wire_base::vvp_filter_wire_base()
{
force_propagate_ = false;
@ -285,19 +272,6 @@ void vvp_fun_signal4_sa::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit,
calculate_output_(ptr);
break;
case 2: // Force value
{ vvp_vector4_t tmp (bit);
// Force from a node may not have been sized completely
// by the source, so coerce the size here.
if (tmp.size() != size())
tmp = coerce_to_width(tmp, size());
force_vec4(tmp, vvp_vector2_t(vvp_vector2_t::FILL1,tmp.size()));
calculate_output_(ptr);
}
break;
default:
fprintf(stderr, "Unsupported port type %d.\n", ptr.port());
assert(0);
@ -354,18 +328,6 @@ void vvp_fun_signal4_sa::recv_vec4_pv(vvp_net_ptr_t ptr, const vvp_vector4_t&bit
calculate_output_(ptr);
break;
case 2: // Force value
{ vvp_vector2_t mask (vvp_vector2_t::FILL0, vwid);
vvp_vector4_t vec (vwid, BIT4_Z);
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
mask.set_bit(base+idx, 1);
vec.set_bit(base+idx, bit.value(idx));
}
force_vec4(vec, mask);
calculate_output_(ptr);
break;
}
default:
fprintf(stderr, "Unsupported port type %d.\n", ptr.port());
assert(0);
@ -593,19 +555,6 @@ void vvp_fun_signal8::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
assert(0);
break;
case 2: // Force value
{ vvp_vector8_t tmp(bit);
// Force from a node may not have been sized completely
// by the source, so coerce the size here.
if (tmp.size() != size())
tmp = coerce_to_width(tmp, size());
force_vec8(tmp, vvp_vector2_t(vvp_vector2_t::FILL1,tmp.size()));
calculate_output_(ptr);
}
break;
default:
fprintf(stderr, "Unsupported port type %d.\n", ptr.port());
assert(0);
@ -762,11 +711,6 @@ void vvp_fun_signal_real_sa::recv_real(vvp_net_ptr_t ptr, double bit,
ptr.ptr()->send_real(bit, 0);
break;
case 2: // Force value
force_real(bit, vvp_vector2_t(vvp_vector2_t::FILL1, 1));
ptr.ptr()->send_real(bit, 0);
break;
default:
fprintf(stderr, "Unsupported port type %d.\n", ptr.port());
assert(0);

View File

@ -151,6 +151,11 @@ class vvp_filter_wire_base : public vvp_net_fil_t, public vvp_vpi_callback {
virtual void release_pv(vvp_net_ptr_t ptr, bool net,
unsigned base, unsigned wid) =0;
/* The %force/link instruction needs a place to write the
source node of the force, so that subsequent %force and
%release instructions can undo the link as needed. */
struct vvp_net_t*force_link;
protected:
// Set bits of the filter force mask
void force_mask(vvp_vector2_t mask);
@ -200,10 +205,9 @@ class vvp_fun_signal_base : public vvp_net_fun_t, public vvp_filter_wire_base {
public:
/* The %force/link instruction needs a place to write the
source node of the force, so that subsequent %force and
%release instructions can undo the link as needed. */
struct vvp_net_t*force_link;
/* The %cassign/link instruction needs a place to write the
source node of the force, so that subsequent %cassign and
%deassign instructions can undo the link as needed. */
struct vvp_net_t*cassign_link;
protected: