Optimized Nexus handling during code generation.
Once code generation starts, the Nexus structure no longer needs to support fast insertion/connect operations. So have the code generator lock down the Nexus structures and adjust the Link lists for optimal access during readout.
This commit is contained in:
parent
f7aef3f966
commit
534207bb83
20
net_link.cc
20
net_link.cc
|
|
@ -476,16 +476,20 @@ const Link* Nexus::first_nlink() const
|
|||
else return 0;
|
||||
}
|
||||
|
||||
ivl_nexus_t Nexus::t_cookie() const
|
||||
/*
|
||||
* The t_cookie can be set exactly once. This attaches an ivl_nexus_t
|
||||
* object to the Nexus, and causes the Link list to be marked up for
|
||||
* efficient use by the code generator. The change is to give all the
|
||||
* links a valid nexus_ pointer. This breaks most of the other
|
||||
* methods, but they are not used during code generation.
|
||||
*/
|
||||
void Nexus::t_cookie(ivl_nexus_t val) const
|
||||
{
|
||||
return t_cookie_;
|
||||
}
|
||||
|
||||
ivl_nexus_t Nexus::t_cookie(ivl_nexus_t val)const
|
||||
{
|
||||
ivl_nexus_t tmp = t_cookie_;
|
||||
assert(val && !t_cookie_);
|
||||
t_cookie_ = val;
|
||||
return tmp;
|
||||
|
||||
for (Link*cur = list_->next_ ; cur->nexus_ == 0 ; cur = cur->next_)
|
||||
cur->nexus_ = const_cast<Nexus*> (this);
|
||||
}
|
||||
|
||||
unsigned Nexus::vector_width() const
|
||||
|
|
|
|||
14
netlist.cc
14
netlist.cc
|
|
@ -491,9 +491,9 @@ const Link& NetDelaySrc::condit_pin() const
|
|||
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
|
||||
: NetObj(s, n, 1),
|
||||
type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE),
|
||||
signed_(false), isint_(false), is_scalar_(false),
|
||||
signed_(false), isint_(false), is_scalar_(false), local_flag_(false),
|
||||
discipline_(0), msb_(npins-1), lsb_(0), dimensions_(0),
|
||||
s0_(0), e0_(0), local_flag_(false), eref_count_(0), lref_count_(0)
|
||||
s0_(0), e0_(0), eref_count_(0), lref_count_(0)
|
||||
{
|
||||
assert(s);
|
||||
assert(npins>0);
|
||||
|
|
@ -544,9 +544,10 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
|||
long ms, long ls)
|
||||
: NetObj(s, n, 1), type_(t),
|
||||
port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false),
|
||||
isint_(false), is_scalar_(false), discipline_(0), msb_(ms), lsb_(ls),
|
||||
isint_(false), is_scalar_(false), local_flag_(false), discipline_(0),
|
||||
msb_(ms), lsb_(ls),
|
||||
dimensions_(0), s0_(0), e0_(0),
|
||||
local_flag_(false), eref_count_(0), lref_count_(0)
|
||||
eref_count_(0), lref_count_(0)
|
||||
{
|
||||
assert(s);
|
||||
|
||||
|
|
@ -595,9 +596,10 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
|
|||
: NetObj(s, n, calculate_count(array_s, array_e)),
|
||||
type_(t), port_type_(NOT_A_PORT),
|
||||
data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false),
|
||||
is_scalar_(false), discipline_(0), msb_(ms), lsb_(ls),
|
||||
is_scalar_(false), local_flag_(false), discipline_(0),
|
||||
msb_(ms), lsb_(ls),
|
||||
dimensions_(1), s0_(array_s), e0_(array_e),
|
||||
local_flag_(false), eref_count_(0), lref_count_(0)
|
||||
eref_count_(0), lref_count_(0)
|
||||
{
|
||||
ivl_assert(*this, s);
|
||||
if (pin_count() == 0) {
|
||||
|
|
|
|||
29
netlist.h
29
netlist.h
|
|
@ -322,9 +322,12 @@ class NetBranch : public NetPins, public IslandBranch {
|
|||
* the first. The last link also has a non-nil nexus_ pointer back to
|
||||
* this nexus.
|
||||
*
|
||||
* The t_cookie() is a void* that targets can use to store information
|
||||
* in a Nexus. ivl guarantees that the t_cookie will be 0 when the
|
||||
* target is invoked.
|
||||
* The t_cookie() is an ivl_nexus_t that the code generator uses to
|
||||
* store data in the nexus. When a Nexus is created, this cookie is
|
||||
* set to nil. The code generator may set the cookie once. This locks
|
||||
* the nexus, and rewrites the Link list to be optimal for the code
|
||||
* generator. In the process, *all* of the other methods are no longer
|
||||
* functional.
|
||||
*/
|
||||
class Nexus {
|
||||
|
||||
|
|
@ -373,8 +376,10 @@ class Nexus {
|
|||
the value that has been driven. */
|
||||
verinum::V driven_value() const;
|
||||
|
||||
ivl_nexus_t t_cookie() const;
|
||||
ivl_nexus_t t_cookie(ivl_nexus_t) const;
|
||||
/* The code generator sets an ivl_nexus_t to attach code
|
||||
generation details to the nexus. */
|
||||
ivl_nexus_t t_cookie() const { return t_cookie_; }
|
||||
void t_cookie(ivl_nexus_t) const;
|
||||
|
||||
private:
|
||||
Link*list_;
|
||||
|
|
@ -662,19 +667,19 @@ class NetNet : public NetObj {
|
|||
void initialize_value_and_dir(verinum::V init_value, Link::DIR dir);
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
PortType port_type_;
|
||||
ivl_variable_type_t data_type_;
|
||||
bool signed_;
|
||||
bool isint_; // original type of integer
|
||||
bool is_scalar_;
|
||||
Type type_ : 5;
|
||||
PortType port_type_ : 3;
|
||||
ivl_variable_type_t data_type_ : 3;
|
||||
bool signed_ : 1;
|
||||
bool isint_ : 1; // original type of integer
|
||||
bool is_scalar_ : 1;
|
||||
bool local_flag_: 1;
|
||||
ivl_discipline_t discipline_;
|
||||
|
||||
long msb_, lsb_;
|
||||
const unsigned dimensions_;
|
||||
long s0_, e0_;
|
||||
|
||||
bool local_flag_;
|
||||
unsigned eref_count_;
|
||||
unsigned lref_count_;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue