Rework last value storage in vvp_fun_anyedge functors.
This prepares the way to support strings and object handle values.
This commit is contained in:
parent
0a69303164
commit
a69de8b94a
172
vvp/event.cc
172
vvp/event.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2018 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2004-2020 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -343,29 +343,114 @@ void vvp_fun_edge_aa::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
|||
}
|
||||
}
|
||||
|
||||
class anyedge_value {
|
||||
|
||||
public:
|
||||
anyedge_value() {};
|
||||
virtual ~anyedge_value() {};
|
||||
|
||||
virtual void reset() = 0;
|
||||
|
||||
virtual void duplicate(anyedge_value*&dup) = 0;
|
||||
};
|
||||
|
||||
class anyedge_vec4_value : public anyedge_value {
|
||||
|
||||
public:
|
||||
anyedge_vec4_value() {};
|
||||
virtual ~anyedge_vec4_value() {};
|
||||
|
||||
void reset() { old_bits.set_to_x(); }
|
||||
|
||||
void set(const vvp_vector4_t&bit) { old_bits = bit; };
|
||||
|
||||
void duplicate(anyedge_value*&dup);
|
||||
|
||||
bool recv_vec4(const vvp_vector4_t&bit);
|
||||
|
||||
bool recv_vec4_pv(const vvp_vector4_t&bit, unsigned base,
|
||||
unsigned wid, unsigned vwid);
|
||||
|
||||
private:
|
||||
vvp_vector4_t old_bits;
|
||||
};
|
||||
|
||||
static anyedge_vec4_value*get_vec4_value(anyedge_value*&value)
|
||||
{
|
||||
anyedge_vec4_value*vec4_value = dynamic_cast<anyedge_vec4_value*>(value);
|
||||
if (!value) {
|
||||
vec4_value = new anyedge_vec4_value();
|
||||
delete value;
|
||||
value = vec4_value;
|
||||
}
|
||||
return vec4_value;
|
||||
}
|
||||
|
||||
class anyedge_real_value : public anyedge_value {
|
||||
|
||||
public:
|
||||
anyedge_real_value() : old_bits(0.0) {};
|
||||
virtual ~anyedge_real_value() {};
|
||||
|
||||
void reset() { old_bits = 0.0; }
|
||||
|
||||
void set(double bit) { old_bits = bit; };
|
||||
|
||||
void duplicate(anyedge_value*&dup);
|
||||
|
||||
bool recv_real(double bit);
|
||||
|
||||
private:
|
||||
double old_bits;
|
||||
};
|
||||
|
||||
static anyedge_real_value*get_real_value(anyedge_value*&value)
|
||||
{
|
||||
anyedge_real_value*real_value = dynamic_cast<anyedge_real_value*>(value);
|
||||
if (!value) {
|
||||
real_value = new anyedge_real_value();
|
||||
delete value;
|
||||
value = real_value;
|
||||
}
|
||||
return real_value;
|
||||
}
|
||||
|
||||
struct vvp_fun_anyedge_state_s : public waitable_state_s {
|
||||
vvp_fun_anyedge_state_s()
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < 4 ; idx += 1)
|
||||
bitsr[idx] = 0.0;
|
||||
last_value_[idx] = 0;
|
||||
}
|
||||
|
||||
vvp_vector4_t bits[4];
|
||||
double bitsr[4];
|
||||
~vvp_fun_anyedge_state_s()
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < 4 ; idx += 1)
|
||||
delete last_value_[idx];
|
||||
}
|
||||
|
||||
anyedge_value *last_value_[4];
|
||||
};
|
||||
|
||||
vvp_fun_anyedge::vvp_fun_anyedge()
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < 4 ; idx += 1)
|
||||
bitsr_[idx] = 0.0;
|
||||
last_value_[idx] = 0;
|
||||
}
|
||||
|
||||
vvp_fun_anyedge::~vvp_fun_anyedge()
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < 4 ; idx += 1)
|
||||
delete last_value_[idx];
|
||||
}
|
||||
|
||||
bool vvp_fun_anyedge::recv_vec4_(const vvp_vector4_t&bit,
|
||||
vvp_vector4_t&old_bits, vthread_t&threads)
|
||||
void anyedge_vec4_value::duplicate(anyedge_value*&dup)
|
||||
{
|
||||
anyedge_vec4_value*dup_vec4 = get_vec4_value(dup);
|
||||
assert(dup_vec4);
|
||||
dup_vec4->set(old_bits);
|
||||
}
|
||||
|
||||
bool anyedge_vec4_value::recv_vec4(const vvp_vector4_t&bit)
|
||||
{
|
||||
bool flag = false;
|
||||
|
||||
|
|
@ -396,18 +481,36 @@ bool vvp_fun_anyedge::recv_vec4_(const vvp_vector4_t&bit,
|
|||
|
||||
if (flag) {
|
||||
old_bits = bit;
|
||||
run_waiting_threads_(threads);
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
bool vvp_fun_anyedge::recv_real_(double bit,
|
||||
double&old_bits, vthread_t&threads)
|
||||
bool anyedge_vec4_value::recv_vec4_pv(const vvp_vector4_t&bit, unsigned base,
|
||||
unsigned wid, unsigned vwid)
|
||||
{
|
||||
vvp_vector4_t tmp = old_bits;
|
||||
if (tmp.size() == 0)
|
||||
tmp = vvp_vector4_t(vwid, BIT4_Z);
|
||||
assert(wid == bit.size());
|
||||
assert(base+wid <= vwid);
|
||||
assert(tmp.size() == vwid);
|
||||
tmp.set_vec(base, bit);
|
||||
|
||||
return recv_vec4(tmp);
|
||||
}
|
||||
|
||||
void anyedge_real_value::duplicate(anyedge_value*&dup)
|
||||
{
|
||||
anyedge_real_value*dup_real = get_real_value(dup);
|
||||
assert(dup_real);
|
||||
dup_real->set(old_bits);
|
||||
}
|
||||
|
||||
bool anyedge_real_value::recv_real(double bit)
|
||||
{
|
||||
if (old_bits != bit) {
|
||||
old_bits = bit;
|
||||
run_waiting_threads_(threads);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -433,7 +536,10 @@ vthread_t vvp_fun_anyedge_sa::add_waiting_thread(vthread_t thread)
|
|||
void vvp_fun_anyedge_sa::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||
vvp_context_t)
|
||||
{
|
||||
if (recv_vec4_(bit, bits_[port.port()], threads_)) {
|
||||
anyedge_vec4_value*value = get_vec4_value(last_value_[port.port()]);
|
||||
assert(value);
|
||||
if (value->recv_vec4(bit)) {
|
||||
run_waiting_threads_(threads_);
|
||||
vvp_net_t*net = port.ptr();
|
||||
net->send_vec4(bit, 0);
|
||||
}
|
||||
|
|
@ -443,15 +549,10 @@ void vvp_fun_anyedge_sa::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bi
|
|||
unsigned base, unsigned wid, unsigned vwid,
|
||||
vvp_context_t)
|
||||
{
|
||||
vvp_vector4_t tmp = bits_[port.port()];
|
||||
if (tmp.size() == 0)
|
||||
tmp = vvp_vector4_t(vwid, BIT4_Z);
|
||||
assert(wid == bit.size());
|
||||
assert(base+wid <= vwid);
|
||||
assert(tmp.size() == vwid);
|
||||
tmp.set_vec(base, bit);
|
||||
|
||||
if (recv_vec4_(tmp, bits_[port.port()], threads_)) {
|
||||
anyedge_vec4_value*value = get_vec4_value(last_value_[port.port()]);
|
||||
assert(value);
|
||||
if (value->recv_vec4_pv(bit, base, wid, vwid)) {
|
||||
run_waiting_threads_(threads_);
|
||||
vvp_net_t*net = port.ptr();
|
||||
net->send_vec4(bit, 0);
|
||||
}
|
||||
|
|
@ -460,7 +561,10 @@ void vvp_fun_anyedge_sa::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bi
|
|||
void vvp_fun_anyedge_sa::recv_real(vvp_net_ptr_t port, double bit,
|
||||
vvp_context_t)
|
||||
{
|
||||
if (recv_real_(bit, bitsr_[port.port()], threads_)) {
|
||||
anyedge_real_value*value = get_real_value(last_value_[port.port()]);
|
||||
assert(value);
|
||||
if (value->recv_real(bit)) {
|
||||
run_waiting_threads_(threads_);
|
||||
vvp_net_t*net = port.ptr();
|
||||
net->send_vec4(vvp_vector4_t(), 0);
|
||||
}
|
||||
|
|
@ -489,8 +593,10 @@ void vvp_fun_anyedge_aa::reset_instance(vvp_context_t context)
|
|||
|
||||
state->threads = 0;
|
||||
for (unsigned idx = 0 ; idx < 4 ; idx += 1) {
|
||||
state->bits[idx] = bits_[idx];
|
||||
state->bitsr[idx] = bitsr_[idx];
|
||||
if (last_value_[idx])
|
||||
last_value_[idx]->duplicate(state->last_value_[idx]);
|
||||
else if (state->last_value_[idx])
|
||||
state->last_value_[idx]->reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -521,7 +627,10 @@ void vvp_fun_anyedge_aa::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
|||
vvp_fun_anyedge_state_s*state = static_cast<vvp_fun_anyedge_state_s*>
|
||||
(vvp_get_context_item(context, context_idx_));
|
||||
|
||||
if (recv_vec4_(bit, state->bits[port.port()], state->threads)) {
|
||||
anyedge_vec4_value*value = get_vec4_value(state->last_value_[port.port()]);
|
||||
assert(value);
|
||||
if (value->recv_vec4(bit)) {
|
||||
run_waiting_threads_(state->threads);
|
||||
vvp_net_t*net = port.ptr();
|
||||
net->send_vec4(bit, context);
|
||||
}
|
||||
|
|
@ -531,7 +640,9 @@ void vvp_fun_anyedge_aa::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
|||
recv_vec4(port, bit, context);
|
||||
context = vvp_get_next_context(context);
|
||||
}
|
||||
bits_[port.port()] = bit;
|
||||
anyedge_vec4_value*value = get_vec4_value(last_value_[port.port()]);
|
||||
assert(value);
|
||||
value->set(bit);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -542,7 +653,10 @@ void vvp_fun_anyedge_aa::recv_real(vvp_net_ptr_t port, double bit,
|
|||
vvp_fun_anyedge_state_s*state = static_cast<vvp_fun_anyedge_state_s*>
|
||||
(vvp_get_context_item(context, context_idx_));
|
||||
|
||||
if (recv_real_(bit, state->bitsr[port.port()], state->threads)) {
|
||||
anyedge_real_value*value = get_real_value(state->last_value_[port.port()]);
|
||||
assert(value);
|
||||
if (value->recv_real(bit)) {
|
||||
run_waiting_threads_(state->threads);
|
||||
vvp_net_t*net = port.ptr();
|
||||
net->send_vec4(vvp_vector4_t(), context);
|
||||
}
|
||||
|
|
@ -552,7 +666,9 @@ void vvp_fun_anyedge_aa::recv_real(vvp_net_ptr_t port, double bit,
|
|||
recv_real(port, bit, context);
|
||||
context = vvp_get_next_context(context);
|
||||
}
|
||||
bitsr_[port.port()] = bit;
|
||||
anyedge_real_value*value = get_real_value(last_value_[port.port()]);
|
||||
assert(value);
|
||||
value->set(bit);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
17
vvp/event.h
17
vvp/event.h
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_event_H
|
||||
#define IVL_event_H
|
||||
/*
|
||||
* Copyright (c) 2004-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2004-2020 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -216,6 +216,12 @@ class vvp_fun_edge_aa : public vvp_fun_edge, public automatic_hooks_s {
|
|||
unsigned context_idx_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the base object for storing the last received values for a
|
||||
* vvp_fun_anyedge functor.
|
||||
*/
|
||||
class anyedge_value;
|
||||
|
||||
/*
|
||||
* The vvp_fun_anyedge functor checks to see if any value in an input
|
||||
* vector changes. Unlike the vvp_fun_edge, which watches for the LSB
|
||||
|
|
@ -233,14 +239,7 @@ class vvp_fun_anyedge : public vvp_net_fun_t, public waitable_hooks_s {
|
|||
virtual ~vvp_fun_anyedge();
|
||||
|
||||
protected:
|
||||
bool recv_vec4_(const vvp_vector4_t&bit,
|
||||
vvp_vector4_t&old_bits, vthread_t&threads);
|
||||
bool recv_real_(double bit,
|
||||
double&old_bits, vthread_t&threads);
|
||||
|
||||
vvp_vector4_t bits_[4];
|
||||
// In case I'm a real-valued event.
|
||||
double bitsr_[4];
|
||||
anyedge_value*last_value_[4];
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue