Obvious optimizations of vvp_vector8_t handling.
The vvp_vector8_t constructor and destructor involve memory allocation so it is best to pass these objects by reference as much as possible. Also rework the resolver functor to only perform resolution after inputs are in so that it doesn't get needlessly repeated. This eliminates many resolve function calls, as well as activations throughout the net. Also have the islands take more care not to perform resolution if the inputs aren't really different.
This commit is contained in:
parent
e453b347f4
commit
2f4e5bf5b6
|
|
@ -1399,16 +1399,16 @@ void compile_resolver(char*label, char*type, unsigned argc, struct symb_s*argv)
|
|||
vvp_net_fun_t* obj = 0;
|
||||
|
||||
if (strcmp(type,"tri") == 0) {
|
||||
obj = new resolv_functor(vvp_scalar_t(BIT4_Z, 0));
|
||||
obj = new resolv_functor(vvp_scalar_t(BIT4_Z, 0,0));
|
||||
|
||||
} else if (strncmp(type,"tri$",4) == 0) {
|
||||
obj = new resolv_functor(vvp_scalar_t(BIT4_Z, 0), strdup(type+4));
|
||||
obj = new resolv_functor(vvp_scalar_t(BIT4_Z, 0,0), strdup(type+4));
|
||||
|
||||
} else if (strcmp(type,"tri0") == 0) {
|
||||
obj = new resolv_functor(vvp_scalar_t(BIT4_0, 5));
|
||||
obj = new resolv_functor(vvp_scalar_t(BIT4_0, 5,5));
|
||||
|
||||
} else if (strcmp(type,"tri1") == 0) {
|
||||
obj = new resolv_functor(vvp_scalar_t(BIT4_1, 5));
|
||||
obj = new resolv_functor(vvp_scalar_t(BIT4_1, 5,5));
|
||||
|
||||
} else if (strcmp(type,"triand") == 0) {
|
||||
obj = new resolv_triand;
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ void vvp_fun_delay::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
|
|||
}
|
||||
}
|
||||
|
||||
void vvp_fun_delay::recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit)
|
||||
void vvp_fun_delay::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit)
|
||||
{
|
||||
assert(port.port() == 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class vvp_fun_delay : public vvp_net_fun_t, private vvp_gen_event_s {
|
|||
~vvp_fun_delay();
|
||||
|
||||
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
|
||||
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
|
||||
void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit);
|
||||
void recv_real(vvp_net_ptr_t port, double bit);
|
||||
//void recv_long(vvp_net_ptr_t port, long bit);
|
||||
|
||||
|
|
|
|||
12
vvp/npmos.cc
12
vvp/npmos.cc
|
|
@ -33,7 +33,7 @@ void vvp_fun_pmos_::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit)
|
|||
/* Data input is processed through eh recv_vec8 method,
|
||||
because the strength must be preserved. */
|
||||
if (ptr.port() == 0) {
|
||||
vvp_vector8_t tmp = bit;
|
||||
vvp_vector8_t tmp = vvp_vector8_t(bit,6,6);
|
||||
recv_vec8(ptr, tmp);
|
||||
return;
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ vvp_fun_pmos::vvp_fun_pmos(bool enable_invert)
|
|||
{
|
||||
}
|
||||
|
||||
void vvp_fun_pmos::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
|
||||
void vvp_fun_pmos::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
|
||||
{
|
||||
if (ptr.port() == 1) {
|
||||
recv_vec4(ptr, reduce4(bit));
|
||||
|
|
@ -105,7 +105,7 @@ vvp_fun_rpmos::vvp_fun_rpmos(bool enable_invert)
|
|||
{
|
||||
}
|
||||
|
||||
void vvp_fun_rpmos::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
|
||||
void vvp_fun_rpmos::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
|
||||
{
|
||||
if (ptr.port() == 1) {
|
||||
recv_vec4(ptr, reduce4(bit));
|
||||
|
|
@ -133,7 +133,7 @@ void vvp_fun_cmos_::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t &bit)
|
|||
/* Data input is processed through the recv_vec8 method,
|
||||
because the strength must be preserved. */
|
||||
if (ptr.port() == 0) {
|
||||
vvp_vector8_t tmp = bit;
|
||||
vvp_vector8_t tmp = vvp_vector8_t(bit,6,6);
|
||||
recv_vec8(ptr, tmp);
|
||||
return;
|
||||
}
|
||||
|
|
@ -187,7 +187,7 @@ vvp_fun_cmos::vvp_fun_cmos()
|
|||
{
|
||||
}
|
||||
|
||||
void vvp_fun_cmos::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
|
||||
void vvp_fun_cmos::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
|
||||
{
|
||||
if (ptr.port() == 1 || ptr.port() == 2) {
|
||||
recv_vec4(ptr, reduce4(bit));
|
||||
|
|
@ -206,7 +206,7 @@ vvp_fun_rcmos::vvp_fun_rcmos()
|
|||
{
|
||||
}
|
||||
|
||||
void vvp_fun_rcmos::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
|
||||
void vvp_fun_rcmos::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
|
||||
{
|
||||
if (ptr.port() == 1) {
|
||||
recv_vec4(ptr, reduce4(bit));
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class vvp_fun_pmos : public vvp_fun_pmos_ {
|
|||
public:
|
||||
explicit vvp_fun_pmos(bool enable_invert);
|
||||
|
||||
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
|
||||
void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -79,7 +79,7 @@ class vvp_fun_rpmos : public vvp_fun_pmos_ {
|
|||
public:
|
||||
explicit vvp_fun_rpmos(bool enable_invert);
|
||||
|
||||
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
|
||||
void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -121,14 +121,14 @@ class vvp_fun_cmos : public vvp_fun_cmos_ {
|
|||
public:
|
||||
explicit vvp_fun_cmos();
|
||||
|
||||
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
|
||||
void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit);
|
||||
};
|
||||
|
||||
class vvp_fun_rcmos : public vvp_fun_cmos_ {
|
||||
public:
|
||||
explicit vvp_fun_rcmos();
|
||||
|
||||
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
|
||||
void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
|
||||
resolv_functor::resolv_functor(vvp_scalar_t hiz_value, const char*debug_l)
|
||||
: hiz_(hiz_value), debug_label_(debug_l)
|
||||
: net_(0), hiz_(hiz_value), debug_label_(debug_l)
|
||||
{
|
||||
count_functors_resolv += 1;
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ resolv_functor::~resolv_functor()
|
|||
|
||||
void resolv_functor::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
|
||||
{
|
||||
recv_vec8(port, vvp_vector8_t(bit, 6 /* STRONG */));
|
||||
recv_vec8(port, vvp_vector8_t(bit, 6,6 /* STRONG */));
|
||||
}
|
||||
|
||||
void resolv_functor::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||
|
|
@ -58,7 +58,7 @@ void resolv_functor::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
|||
recv_vec4(port, res);
|
||||
}
|
||||
|
||||
void resolv_functor::recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit)
|
||||
void resolv_functor::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit)
|
||||
{
|
||||
unsigned pdx = port.port();
|
||||
vvp_net_t*ptr = port.ptr();
|
||||
|
|
@ -68,14 +68,26 @@ void resolv_functor::recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit)
|
|||
|
||||
val_[pdx] = bit;
|
||||
|
||||
vvp_vector8_t out (bit);
|
||||
if (net_ == 0) {
|
||||
net_ = ptr;
|
||||
schedule_generic(this, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
void resolv_functor::run_run()
|
||||
{
|
||||
vvp_net_t*ptr = net_;
|
||||
net_ = 0;
|
||||
|
||||
vvp_vector8_t out;
|
||||
|
||||
for (unsigned idx = 0 ; idx < 4 ; idx += 1) {
|
||||
if (idx == pdx)
|
||||
continue;
|
||||
if (val_[idx].size() == 0)
|
||||
continue;
|
||||
out = resolve(out, val_[idx]);
|
||||
if (out.size()==0)
|
||||
out = val_[idx];
|
||||
else
|
||||
out = resolve(out, val_[idx]);
|
||||
}
|
||||
|
||||
if (! hiz_.is_hiz()) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
# include "config.h"
|
||||
# include "vvp_net.h"
|
||||
# include "schedule.h"
|
||||
|
||||
/*
|
||||
* This functor type resolves its inputs using the Verilog method of
|
||||
|
|
@ -34,19 +35,22 @@
|
|||
* strong values (or HiZ) for the sake of resolution. In any case, the
|
||||
* propagated value is a vvp_vector8_t value.
|
||||
*/
|
||||
class resolv_functor : public vvp_net_fun_t {
|
||||
class resolv_functor : public vvp_net_fun_t, private vvp_gen_event_s {
|
||||
|
||||
public:
|
||||
explicit resolv_functor(vvp_scalar_t hiz_value, const char* debug =0);
|
||||
~resolv_functor();
|
||||
|
||||
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
|
||||
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
|
||||
void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit);
|
||||
|
||||
void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||
unsigned base, unsigned wid, unsigned vwid);
|
||||
|
||||
private:
|
||||
vvp_net_t*net_;
|
||||
void run_run();
|
||||
|
||||
vvp_vector8_t val_[4];
|
||||
// Bit value to emit for HiZ bits.
|
||||
vvp_scalar_t hiz_;
|
||||
|
|
|
|||
|
|
@ -126,9 +126,10 @@ class vvp_island_port : public vvp_net_fun_t {
|
|||
virtual void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
|
||||
virtual void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||
unsigned base, unsigned wid, unsigned vwid);
|
||||
virtual void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t bit);
|
||||
virtual void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit);
|
||||
|
||||
vvp_vector8_t invalue;
|
||||
vvp_vector8_t outvalue;
|
||||
|
||||
private:
|
||||
vvp_island*island_;
|
||||
|
|
@ -138,6 +139,22 @@ class vvp_island_port : public vvp_net_fun_t {
|
|||
vvp_island_port& operator = (const vvp_island_port&);
|
||||
};
|
||||
|
||||
static vvp_vector8_t get_value(vvp_net_t*net)
|
||||
{
|
||||
vvp_island_port*fun = dynamic_cast<vvp_island_port*>(net->fun);
|
||||
return fun->invalue;
|
||||
}
|
||||
|
||||
static void send_value(vvp_net_t*net, const vvp_vector8_t&val)
|
||||
{
|
||||
vvp_island_port*fun = dynamic_cast<vvp_island_port*>(net->fun);
|
||||
if (fun->outvalue .eeq(val))
|
||||
return;
|
||||
|
||||
fun->outvalue = val;
|
||||
vvp_send_vec8(net->out, fun->outvalue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Branches are connected together to form a mesh of brances. Each
|
||||
* endpoint (there are two) connects circularly to other branch
|
||||
|
|
@ -315,8 +332,11 @@ void vvp_island_port::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
|||
}
|
||||
|
||||
|
||||
void vvp_island_port::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t bit)
|
||||
void vvp_island_port::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit)
|
||||
{
|
||||
if (invalue .eeq(bit))
|
||||
return;
|
||||
|
||||
invalue = bit;
|
||||
island_->flag_island();
|
||||
}
|
||||
|
|
@ -387,12 +407,6 @@ static void collect_node(list<vvp_branch_ptr_t>&conn, vvp_branch_ptr_t cur)
|
|||
conn.push_back(idx);
|
||||
}
|
||||
|
||||
static vvp_vector8_t get_value(vvp_net_t*net)
|
||||
{
|
||||
vvp_island_port*fun = dynamic_cast<vvp_island_port*>(net->fun);
|
||||
return fun->invalue;
|
||||
}
|
||||
|
||||
static void mark_done_flags(list<vvp_branch_ptr_t>&connections)
|
||||
{
|
||||
for (list<vvp_branch_ptr_t>::iterator idx = connections.begin()
|
||||
|
|
@ -510,13 +524,13 @@ static void push_value_through_branches(const vvp_vector8_t&val,
|
|||
if (tmp_ptr->width == 0) {
|
||||
// Mark this end as done
|
||||
tmp_ptr->flags |= (1 << other_ab);
|
||||
vvp_send_vec8(other_net->out, val);
|
||||
send_value(other_net, val);
|
||||
|
||||
} if (other_ab == 1) {
|
||||
// Mark as done
|
||||
tmp_ptr->flags |= (1 << other_ab);
|
||||
vvp_vector8_t tmp = val.subvalue(tmp_ptr->offset, tmp_ptr->part);
|
||||
vvp_send_vec8(other_net->out, tmp);
|
||||
send_value(other_net, tmp);
|
||||
} else {
|
||||
// Otherwise, the other side is not fully
|
||||
// specified, so we can't take this shortcut.
|
||||
|
|
@ -552,7 +566,7 @@ void vvp_island_branch::run_resolution()
|
|||
resolve_values_from_connections(val, connections);
|
||||
|
||||
// A side is done.
|
||||
vvp_send_vec8(a->out, val);
|
||||
send_value(a, val);
|
||||
|
||||
// Clear the visited flags. This must be done so that other
|
||||
// branches can read this input value.
|
||||
|
|
@ -598,7 +612,7 @@ void vvp_island_branch::run_resolution()
|
|||
clear_visited_flags(connections);
|
||||
}
|
||||
|
||||
vvp_send_vec8(b->out, val);
|
||||
send_value(b, val);
|
||||
}
|
||||
|
||||
/* **** COMPILE/LINK SUPPORT **** */
|
||||
|
|
|
|||
123
vvp/vvp_net.cc
123
vvp/vvp_net.cc
|
|
@ -129,7 +129,7 @@ int edge(vvp_bit4_t from, vvp_bit4_t to)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void vvp_send_vec8(vvp_net_ptr_t ptr, vvp_vector8_t val)
|
||||
void vvp_send_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&val)
|
||||
{
|
||||
while (struct vvp_net_t*cur = ptr.ptr()) {
|
||||
vvp_net_ptr_t next = cur->port[ptr.port()];
|
||||
|
|
@ -1751,38 +1751,13 @@ ostream& operator<< (ostream&out, const vvp_vector2_t&that)
|
|||
vvp_vector8_t::vvp_vector8_t(const vvp_vector8_t&that)
|
||||
{
|
||||
size_ = that.size_;
|
||||
|
||||
bits_ = new vvp_scalar_t[size_];
|
||||
|
||||
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
|
||||
bits_[idx] = that.bits_[idx];
|
||||
|
||||
}
|
||||
|
||||
vvp_vector8_t::vvp_vector8_t(unsigned size)
|
||||
: size_(size)
|
||||
{
|
||||
if (size_ == 0) {
|
||||
if (size_==0) {
|
||||
bits_ = 0;
|
||||
return;
|
||||
} else {
|
||||
bits_ = new vvp_scalar_t[size_];
|
||||
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
|
||||
bits_[idx] = that.bits_[idx];
|
||||
}
|
||||
|
||||
bits_ = new vvp_scalar_t[size_];
|
||||
}
|
||||
|
||||
vvp_vector8_t::vvp_vector8_t(const vvp_vector4_t&that, unsigned str)
|
||||
: size_(that.size())
|
||||
{
|
||||
if (size_ == 0) {
|
||||
bits_ = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
bits_ = new vvp_scalar_t[size_];
|
||||
|
||||
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
|
||||
bits_[idx] = vvp_scalar_t (that.value(idx), str);
|
||||
|
||||
}
|
||||
|
||||
vvp_vector8_t::vvp_vector8_t(const vvp_vector4_t&that,
|
||||
|
|
@ -1828,22 +1803,6 @@ vvp_vector8_t& vvp_vector8_t::operator= (const vvp_vector8_t&that)
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool vvp_vector8_t::eeq(const vvp_vector8_t&that) const
|
||||
{
|
||||
if (size_ != that.size_)
|
||||
return false;
|
||||
|
||||
if (size_ == 0)
|
||||
return true;
|
||||
|
||||
for (unsigned idx = 0 ; idx < size_ ; idx += 1) {
|
||||
if (! bits_[idx] .eeq( that.bits_[idx] ))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
vvp_vector8_t vvp_vector8_t::subvalue(unsigned base, unsigned wid) const
|
||||
{
|
||||
vvp_vector8_t tmp (wid);
|
||||
|
|
@ -1907,7 +1866,7 @@ void vvp_net_fun_t::recv_vec4_pv(vvp_net_ptr_t, const vvp_vector4_t&bits,
|
|||
assert(0);
|
||||
}
|
||||
|
||||
void vvp_net_fun_t::recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit)
|
||||
void vvp_net_fun_t::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit)
|
||||
{
|
||||
recv_vec4(port, reduce4(bit));
|
||||
}
|
||||
|
|
@ -2200,7 +2159,7 @@ void vvp_fun_signal::calculate_output_(vvp_net_ptr_t ptr)
|
|||
run_vpi_callbacks();
|
||||
}
|
||||
|
||||
void vvp_fun_signal::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
|
||||
void vvp_fun_signal::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
|
||||
{
|
||||
recv_vec4(ptr, reduce4(bit));
|
||||
}
|
||||
|
|
@ -2279,10 +2238,10 @@ vvp_fun_signal8::vvp_fun_signal8(unsigned wid)
|
|||
|
||||
void vvp_fun_signal8::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit)
|
||||
{
|
||||
recv_vec8(ptr, bit);
|
||||
recv_vec8(ptr, vvp_vector8_t(bit,6,6));
|
||||
}
|
||||
|
||||
void vvp_fun_signal8::recv_vec8(vvp_net_ptr_t ptr, vvp_vector8_t bit)
|
||||
void vvp_fun_signal8::recv_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&bit)
|
||||
{
|
||||
switch (ptr.port()) {
|
||||
case 0: // Normal input (feed from net, or set from process)
|
||||
|
|
@ -2323,10 +2282,10 @@ 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);
|
||||
recv_vec8_pv(ptr, vvp_vector8_t(bit,6,6), base, wid, vwid);
|
||||
}
|
||||
|
||||
void vvp_fun_signal8::recv_vec8_pv(vvp_net_ptr_t ptr, vvp_vector8_t bit,
|
||||
void vvp_fun_signal8::recv_vec8_pv(vvp_net_ptr_t ptr, const vvp_vector8_t&bit,
|
||||
unsigned base, unsigned wid, unsigned vwid)
|
||||
{
|
||||
assert(bit.size() == wid);
|
||||
|
|
@ -2354,7 +2313,7 @@ void vvp_fun_signal8::recv_vec8_pv(vvp_net_ptr_t ptr, vvp_vector8_t bit,
|
|||
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));
|
||||
force_ = vvp_vector8_t(vvp_vector4_t(vwid, BIT4_Z),6,6);
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
force_mask_.set_bit(base+idx, 1);
|
||||
|
|
@ -2668,51 +2627,8 @@ void vvp_wide_fun_t::recv_real(vvp_net_ptr_t port, double bit)
|
|||
*/
|
||||
# define UNAMBIG(v) (((v) & 0x0f) == (((v) >> 4) & 0x0f))
|
||||
|
||||
#if 0
|
||||
# define STREN1(v) ( ((v)&0x80)? ((v)&0xf0) : (0x70 - ((v)&0xf0)) )
|
||||
# define STREN0(v) ( ((v)&0x08)? ((v)&0x0f) : (0x07 - ((v)&0x0f)) )
|
||||
#else
|
||||
# define STREN1(v) (((v)&0x70) >> 4)
|
||||
# define STREN0(v) ((v)&0x07)
|
||||
#endif
|
||||
|
||||
vvp_scalar_t::vvp_scalar_t(vvp_bit4_t val, unsigned str0, unsigned str1)
|
||||
{
|
||||
assert(str0 <= 7);
|
||||
assert(str1 <= 7);
|
||||
|
||||
if (str0 == 0 && str1 == 0) {
|
||||
value_ = 0x00;
|
||||
} else switch (val) {
|
||||
case BIT4_0:
|
||||
value_ = str0 | (str0<<4);
|
||||
break;
|
||||
case BIT4_1:
|
||||
value_ = str1 | (str1<<4) | 0x88;
|
||||
break;
|
||||
case BIT4_X:
|
||||
value_ = str0 | (str1<<4) | 0x80;
|
||||
break;
|
||||
case BIT4_Z:
|
||||
value_ = 0x00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vvp_bit4_t vvp_scalar_t::value() const
|
||||
{
|
||||
if (value_ == 0) {
|
||||
return BIT4_Z;
|
||||
|
||||
} else switch (value_ & 0x88) {
|
||||
case 0x00:
|
||||
return BIT4_0;
|
||||
case 0x88:
|
||||
return BIT4_1;
|
||||
default:
|
||||
return BIT4_X;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned vvp_scalar_t::strength0() const
|
||||
{
|
||||
|
|
@ -2871,19 +2787,6 @@ vvp_scalar_t resolve(vvp_scalar_t a, vvp_scalar_t b)
|
|||
return res;
|
||||
}
|
||||
|
||||
vvp_vector8_t resolve(const vvp_vector8_t&a, const vvp_vector8_t&b)
|
||||
{
|
||||
assert(a.size() == b.size());
|
||||
|
||||
vvp_vector8_t out (a.size());
|
||||
|
||||
for (unsigned idx = 0 ; idx < out.size() ; idx += 1) {
|
||||
out.set_bit(idx, resolve(a.value(idx), b.value(idx)));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
vvp_vector8_t resistive_reduction(const vvp_vector8_t&that)
|
||||
{
|
||||
static unsigned rstr[8] = {
|
||||
|
|
|
|||
|
|
@ -483,7 +483,6 @@ class vvp_scalar_t {
|
|||
explicit vvp_scalar_t();
|
||||
|
||||
// Make an unambiguous value.
|
||||
explicit vvp_scalar_t(vvp_bit4_t val, unsigned str);
|
||||
explicit vvp_scalar_t(vvp_bit4_t val, unsigned str0, unsigned str1);
|
||||
|
||||
// Get the vvp_bit4_t version of the value
|
||||
|
|
@ -503,21 +502,22 @@ inline vvp_scalar_t::vvp_scalar_t()
|
|||
value_ = 0;
|
||||
}
|
||||
|
||||
inline vvp_scalar_t::vvp_scalar_t(vvp_bit4_t val, unsigned str)
|
||||
inline vvp_scalar_t::vvp_scalar_t(vvp_bit4_t val, unsigned str0, unsigned str1)
|
||||
{
|
||||
assert(str <= 7);
|
||||
assert(str0 <= 7);
|
||||
assert(str1 <= 7);
|
||||
|
||||
if (str == 0) {
|
||||
if (str0 == 0 && str1 == 0) {
|
||||
value_ = 0x00;
|
||||
} else switch (val) {
|
||||
case BIT4_0:
|
||||
value_ = str | (str<<4);
|
||||
value_ = str0 | (str0<<4);
|
||||
break;
|
||||
case BIT4_1:
|
||||
value_ = str | (str<<4) | 0x88;
|
||||
value_ = str1 | (str1<<4) | 0x88;
|
||||
break;
|
||||
case BIT4_X:
|
||||
value_ = str | (str<<4) | 0x80;
|
||||
value_ = str0 | (str1<<4) | 0x80;
|
||||
break;
|
||||
case BIT4_Z:
|
||||
value_ = 0x00;
|
||||
|
|
@ -525,6 +525,21 @@ inline vvp_scalar_t::vvp_scalar_t(vvp_bit4_t val, unsigned str)
|
|||
}
|
||||
}
|
||||
|
||||
inline vvp_bit4_t vvp_scalar_t::value() const
|
||||
{
|
||||
if (value_ == 0) {
|
||||
return BIT4_Z;
|
||||
} else switch (value_ & 0x88) {
|
||||
case 0x00:
|
||||
return BIT4_0;
|
||||
case 0x88:
|
||||
return BIT4_1;
|
||||
default:
|
||||
return BIT4_X;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern vvp_scalar_t resolve(vvp_scalar_t a, vvp_scalar_t b);
|
||||
extern ostream& operator<< (ostream&, vvp_scalar_t);
|
||||
|
||||
|
|
@ -546,8 +561,8 @@ class vvp_vector8_t {
|
|||
|
||||
public:
|
||||
explicit vvp_vector8_t(unsigned size =0);
|
||||
// Make a vvp_vector8_t from a vector4 and a specified strength.
|
||||
vvp_vector8_t(const vvp_vector4_t&that, unsigned str =6);
|
||||
// Make a vvp_vector8_t from a vector4 and a specified
|
||||
// strength.
|
||||
explicit vvp_vector8_t(const vvp_vector4_t&that,
|
||||
unsigned str0,
|
||||
unsigned str1);
|
||||
|
|
@ -572,7 +587,18 @@ class vvp_vector8_t {
|
|||
|
||||
/* Resolve uses the default Verilog resolver algorithm to resolve
|
||||
two drive vectors to a single output. */
|
||||
extern vvp_vector8_t resolve(const vvp_vector8_t&a, const vvp_vector8_t&b);
|
||||
inline vvp_vector8_t resolve(const vvp_vector8_t&a, const vvp_vector8_t&b)
|
||||
{
|
||||
assert(a.size() == b.size());
|
||||
vvp_vector8_t out (a.size());
|
||||
|
||||
for (unsigned idx = 0 ; idx < out.size() ; idx += 1) {
|
||||
out.set_bit(idx, resolve(a.value(idx), b.value(idx)));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/* This function implements the strength reduction implied by
|
||||
Verilog standard resistive devices. */
|
||||
extern vvp_vector8_t resistive_reduction(const vvp_vector8_t&a);
|
||||
|
|
@ -583,12 +609,39 @@ extern vvp_vector8_t part_expand(const vvp_vector8_t&a, unsigned wid, unsigned o
|
|||
/* Print a vector8 value to a stream. */
|
||||
extern ostream& operator<< (ostream&, const vvp_vector8_t&);
|
||||
|
||||
inline vvp_vector8_t::vvp_vector8_t(unsigned size)
|
||||
: size_(size)
|
||||
{
|
||||
if (size_ == 0) {
|
||||
bits_ = 0;
|
||||
return;
|
||||
}
|
||||
bits_ = new vvp_scalar_t[size_];
|
||||
}
|
||||
|
||||
inline vvp_vector8_t::~vvp_vector8_t()
|
||||
{
|
||||
if (size_ > 0)
|
||||
delete[]bits_;
|
||||
}
|
||||
|
||||
// Exactly-equal for vvp_vector8_t is common and should be as tight
|
||||
// as possible.
|
||||
inline bool vvp_vector8_t::eeq(const vvp_vector8_t&that) const
|
||||
{
|
||||
if (size_ != that.size_)
|
||||
return false;
|
||||
if (size_ == 0)
|
||||
return true;
|
||||
|
||||
for (unsigned idx = 0 ; idx < size_ ; idx += 1) {
|
||||
if (! bits_[idx] .eeq( that.bits_[idx] ))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline vvp_scalar_t vvp_vector8_t::value(unsigned idx) const
|
||||
{
|
||||
assert(idx < size_);
|
||||
|
|
@ -721,7 +774,7 @@ class vvp_net_fun_t {
|
|||
virtual ~vvp_net_fun_t();
|
||||
|
||||
virtual void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
|
||||
virtual void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
|
||||
virtual void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit);
|
||||
virtual void recv_real(vvp_net_ptr_t port, double bit);
|
||||
virtual void recv_long(vvp_net_ptr_t port, long bit);
|
||||
|
||||
|
|
@ -962,7 +1015,7 @@ class vvp_fun_signal : public vvp_fun_signal_vec {
|
|||
explicit vvp_fun_signal(unsigned wid, vvp_bit4_t init=BIT4_X);
|
||||
|
||||
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
|
||||
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
|
||||
void recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit);
|
||||
|
||||
// Part select variants of above
|
||||
void recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||
|
|
@ -994,12 +1047,12 @@ class vvp_fun_signal8 : public vvp_fun_signal_vec {
|
|||
explicit vvp_fun_signal8(unsigned wid);
|
||||
|
||||
void recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit);
|
||||
void recv_vec8(vvp_net_ptr_t port, vvp_vector8_t bit);
|
||||
void recv_vec8(vvp_net_ptr_t port, const 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_vec8_pv(vvp_net_ptr_t port, vvp_vector8_t bit,
|
||||
void recv_vec8_pv(vvp_net_ptr_t port, const vvp_vector8_t&bit,
|
||||
unsigned base, unsigned wid, unsigned vwid);
|
||||
|
||||
// Get information about the vector value.
|
||||
|
|
@ -1135,7 +1188,7 @@ inline void vvp_send_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&val)
|
|||
}
|
||||
}
|
||||
|
||||
extern void vvp_send_vec8(vvp_net_ptr_t ptr, vvp_vector8_t val);
|
||||
extern void vvp_send_vec8(vvp_net_ptr_t ptr, const vvp_vector8_t&val);
|
||||
extern void vvp_send_real(vvp_net_ptr_t ptr, double val);
|
||||
extern void vvp_send_long(vvp_net_ptr_t ptr, long val);
|
||||
extern void vvp_send_long_pv(vvp_net_ptr_t ptr, long val,
|
||||
|
|
|
|||
Loading…
Reference in New Issue