diff --git a/design_dump.cc b/design_dump.cc index b191a25fe..f642d6d08 100644 --- a/design_dump.cc +++ b/design_dump.cc @@ -638,7 +638,8 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const void NetTran::dump_node(ostream&o, unsigned ind) const { - o << setw(ind) << "" << type_ << " " << name() << endl; + o << setw(ind) << "" << type_ << " " << name() + << " island " << island << endl; dump_node_pins(o, ind+4); dump_obj_attr(o, ind+4); } diff --git a/elaborate.cc b/elaborate.cc index d7180f4b5..a07f6b562 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -864,6 +864,17 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const } } + + // If these new nodes can belong to an island, then run tests + // to joind islands now. + if (dynamic_cast (cur[0])) { + for (unsigned idx = 0 ; idx < count ; idx += 1) { + join_island(cur[idx]); + } + } + + // "cur" is an array of pointers, and we don't need it any more. + delete[]cur; } NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope, diff --git a/ivl.def b/ivl.def index 78064e569..4e468cca4 100644 --- a/ivl.def +++ b/ivl.def @@ -224,6 +224,7 @@ ivl_switch_b ivl_switch_basename ivl_switch_enable ivl_switch_file +ivl_switch_island ivl_switch_lineno ivl_switch_scope ivl_switch_type diff --git a/ivl_target.h b/ivl_target.h index 8391ce89c..f512058d4 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -80,6 +80,13 @@ _BEGIN_DECL * processes. Structural expressions are instead treated as logic * gates. * + * ivl_island_t + * Certain types of objects may belong to islands. The island that + * they belong to is represented by the ivl_island_t cookie. To + * know if object belong to the same island, it is sufficient to + * compare island cookies. If a==b, then island a is the same as + * island b. + * * ivl_lpm_t * This object is the base class for all the various LPM type * device nodes. This object carries a few base properties @@ -146,6 +153,7 @@ typedef struct ivl_delaypath_s*ivl_delaypath_t; typedef struct ivl_design_s *ivl_design_t; typedef struct ivl_event_s *ivl_event_t; typedef struct ivl_expr_s *ivl_expr_t; +typedef struct ivl_island_s *ivl_island_t; typedef struct ivl_lpm_s *ivl_lpm_t; typedef struct ivl_lval_s *ivl_lval_t; typedef struct ivl_net_const_s*ivl_net_const_t; @@ -713,6 +721,16 @@ extern unsigned ivl_file_table_index(const char *); extern unsigned ivl_file_table_size(void); +/* ISLAND + * + * ivl_island_flag_set + * ivl_island_flag_test + * Allow the user to test or set a boolean flag associated with the + * island. + */ +extern int ivl_island_flag_set(ivl_island_t net, int flag, int value); +extern int ivl_island_flag_test(ivl_island_t net, int flag); + /* LOGIC * These types and functions support manipulation of logic gates. The * ivl_logic_t enumeration identifies the various kinds of gates that @@ -1873,6 +1891,7 @@ extern const char*ivl_switch_basename(ivl_switch_t net); extern ivl_nexus_t ivl_switch_a(ivl_switch_t net); extern ivl_nexus_t ivl_switch_b(ivl_switch_t net); extern ivl_nexus_t ivl_switch_enable(ivl_switch_t net); +extern ivl_island_t ivl_switch_island(ivl_switch_t net); /* Not implemented yet extern unsigned ivl_switch_attr_cnt(ivl_switch_t net); diff --git a/ivl_target_priv.h b/ivl_target_priv.h new file mode 100644 index 000000000..042e0e415 --- /dev/null +++ b/ivl_target_priv.h @@ -0,0 +1,44 @@ +#ifndef __ivl_target_priv_H +#define __ivl_target_H +/* + * Copyright (c) 2008 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 + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +# include + +/* +* This deader has declarations related to the ivl_target.h API that +* are not to be exported outside of the core via the ivl_target.h +* interface. +*/ + +/* +* Information about islands. Connected branches within a net are +* collected into islands. Branches that are purely ddiscrete do not +* have disciplines and do not belong to islands. +*/ + +class discipline_t; + +struct ivl_island_s { + discipline_t*discipline; + // user accessible flags. They are initially false, always. + vector flags; +}; + +#endif diff --git a/net_tran.cc b/net_tran.cc index c2acf4787..a604b5889 100644 --- a/net_tran.cc +++ b/net_tran.cc @@ -26,6 +26,7 @@ # include "compiler.h" # include "netlist.h" # include "netmisc.h" +# include "ivl_target_priv.h" # include "ivl_assert.h" static bool has_enable(ivl_switch_type_t tt) @@ -55,3 +56,46 @@ NetTran::NetTran(NetScope*scope, perm_string n, ivl_switch_type_t tt) NetTran::~NetTran() { } + +void join_island(NetObj*obj) +{ + IslandBranch*branch = dynamic_cast (obj); + if (branch == 0) + return; + + ivl_assert(*obj, branch->island == 0); + struct ivl_island_s*use_island = 0; + + for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) { + Nexus*nex = obj->pin(idx).nexus(); + for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) { + unsigned pin; + NetObj*tmp; + cur->cur_link(tmp, pin); + if (tmp == obj) + continue; + + IslandBranch*tmp_branch = dynamic_cast (tmp); + if (tmp_branch == 0) + continue; + + ivl_assert(*tmp, tmp_branch->island); + ivl_assert(*obj, use_island==0 || use_island==tmp_branch->island); + use_island = tmp_branch->island; + } + } + + if (use_island == 0) { + use_island = new ivl_island_s; + use_island->discipline = 0; + if (debug_elaborate) + cerr << obj->get_fileline() << ": debug: " + << "Create new island for this branch" << endl; + } else { + if (debug_elaborate) + cerr << obj->get_fileline() << ": debug: " + << "Join this brach to existing island." << endl; + } + + branch->island = use_island; +} diff --git a/netlist.h b/netlist.h index 191d91e08..1cd02d099 100644 --- a/netlist.h +++ b/netlist.h @@ -52,6 +52,7 @@ class Nexus; class NetEvent; class NetNet; class NetNode; +class NetObj; class NetProc; class NetProcTop; class NetRelease; @@ -71,6 +72,8 @@ struct functor_t; ostream& operator << (ostream&o, ivl_variable_type_t val); +extern void join_island(NetObj*obj); + /* ========= * A NetObj is anything that has any kind of behavior in the * netlist. Nodes can be gates, registers, etc. and are linked @@ -131,6 +134,20 @@ class NetObj : public Attrib, public virtual LineInfo { const NetExpr* delay3_; }; +/* +* Objects that can be island branches are derived from this. (It is +* possible for an object to be a NetObj and an IslandBranch.) This is +* used to collect island information about the node. +*/ + +class IslandBranch { + public: + IslandBranch() : island(0) { } + + public: + struct ivl_island_s* island; +}; + class Link { friend void connect(Link&, Link&); @@ -1359,7 +1376,7 @@ class NetSysFunc : public NetNode { const struct sfunc_return_type*def_; }; -class NetTran : public NetNode { +class NetTran : public NetNode, public IslandBranch { public: NetTran(NetScope*scope, perm_string n, ivl_switch_type_t type); diff --git a/t-dll-api.cc b/t-dll-api.cc index 30a4274af..e8354bc99 100644 --- a/t-dll-api.cc +++ b/t-dll-api.cc @@ -555,6 +555,28 @@ extern "C" unsigned ivl_file_table_size() return fn_vector.size(); } +extern "C" int ivl_island_flag_set(ivl_island_t net, int flag, int value) +{ + if (flag >= net->flags.size()) { + if (value == 0) + return 0; + else + net->flags.resize(flag+1, false); + } + + int old_flag = net->flags[flag]; + net->flags[flag] = value != 0; + return old_flag; +} + +extern "C" int ivl_island_flag_test(ivl_island_t net, int flag) +{ + if (flag >= net->flags.size()) + return 0; + else + return net->flags[flag]; +} + extern "C" const char* ivl_logic_attr(ivl_net_logic_t net, const char*key) { assert(net); @@ -2201,6 +2223,11 @@ extern "C" const char* ivl_switch_file(ivl_switch_t net) return net->file; } +extern "C" ivl_island_t ivl_switch_island(ivl_switch_t net) +{ + return net->island; +} + extern "C" unsigned ivl_switch_lineno(ivl_switch_t net) { return net->lineno; diff --git a/t-dll.cc b/t-dll.cc index 2fd382f29..d6174238e 100644 --- a/t-dll.cc +++ b/t-dll.cc @@ -1039,7 +1039,9 @@ bool dll_target::tran(const NetTran*net) obj->type = net->type(); obj->name = net->name(); obj->scope = find_scope(des_, net->scope()); + obj->island = net->island; assert(obj->scope); + assert(obj->island); const Nexus*nex; diff --git a/t-dll.h b/t-dll.h index 247a5dae7..c444c79c2 100644 --- a/t-dll.h +++ b/t-dll.h @@ -21,6 +21,7 @@ # include "target.h" # include "ivl_target.h" +# include "ivl_target_priv.h" # include "StringHeap.h" # include "netlist.h" # include @@ -453,6 +454,7 @@ struct ivl_switch_s { perm_string name; ivl_scope_t scope; + ivl_island_t island; struct ivl_attribute_s*attr; unsigned nattr;