diff --git a/net_link.cc b/net_link.cc index 056ad089b..3cd433039 100644 --- a/net_link.cc +++ b/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 (this); } unsigned Nexus::vector_width() const diff --git a/netlist.cc b/netlist.cc index add9690f0..ea6618db5 100644 --- a/netlist.cc +++ b/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) { diff --git a/netlist.h b/netlist.h index 0a09755ab..5bc381fb9 100644 --- a/netlist.h +++ b/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_;