Permalink
Browse files

Replace the NetPartSelect:BI with NetTran(VP).

Fold the bi-directional part select into the pass switch (tran) support
so that it can be really bi-directional. This involves adding a new
tranvp device that does part select in tran islands, and reworking the
tran island resolution to handle non-identical nodes. This will be needed
for resistive tran devices anyhow.
  • Loading branch information...
1 parent 6e5373c commit 73e2b297df13e925fe6ee3901d18960afd9c2ee4 @steveicarus committed Jun 3, 2008
Showing with 395 additions and 286 deletions.
  1. +10 −4 design_dump.cc
  2. +60 −27 elab_net.cc
  3. +27 −9 elaborate.cc
  4. +3 −0 ivl.def
  5. +15 −5 ivl_target.h
  6. +23 −1 net_tran.cc
  7. +15 −7 netlist.h
  8. +17 −6 t-dll-api.cc
  9. +10 −27 t-dll.cc
  10. +3 −0 t-dll.h
  11. +0 −37 tgt-stub/stub.c
  12. +42 −10 tgt-stub/switches.c
  13. +11 −14 tgt-vvp/draw_net_input.c
  14. +8 −3 tgt-vvp/draw_switch.c
  15. +0 −92 tgt-vvp/vvp_scope.c
  16. +2 −0 vvp/compile.h
  17. +1 −0 vvp/lexor.lex
  18. +4 −1 vvp/parse.y
  19. +143 −42 vvp/vvp_island.cc
  20. +1 −1 vvp/vvp_net.h
View
@@ -109,6 +109,9 @@ ostream& operator << (ostream&o, ivl_switch_type_t val)
case IVL_SW_RTRANIF1:
o << "rtranif1";
break;
+ case IVL_SW_TRAN_VP:
+ o << "tran(VP)";
+ break;
}
return o;
}
@@ -518,9 +521,6 @@ void NetPartSelect::dump_node(ostream&o, unsigned ind) const
case PV:
pt = "PV";
break;
- case BI:
- pt = "BI";
- break;
}
o << setw(ind) << "" << "NetPartSelect(" << pt << "): "
<< name();
@@ -639,7 +639,13 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const
void NetTran::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << type_ << " " << name()
- << " island " << island << endl;
+ << " island " << island;
+ if (type_ == IVL_SW_TRAN_VP) {
+ o << " width=" << vector_width()
+ << " part=" << part_width()
+ << " offset=" << part_offset();
+ }
+ o << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
View
@@ -2375,29 +2375,54 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
osig->local_flag(true);
osig->set_line(*this);
- if (debug_elaborate) {
- cerr << get_fileline() << ": debug: Generating part selects "
- << "to connect input l-value to subexpressions."
- << endl;
- }
+ if (bidirectional_flag) {
+ if (debug_elaborate) {
+ cerr << get_fileline() << ": debug: Generating tran(VP) "
+ << "to connect input l-value to subexpressions."
+ << endl;
+ }
- NetPartSelect::dir_t part_dir = bidirectional_flag
- ? NetPartSelect::BI
- : NetPartSelect::VP;
+ for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
+ unsigned wid = nets[idx]->vector_width();
+ unsigned off = width - wid;
+ NetTran*ps = new NetTran(scope, scope->local_symbol(),
+ osig->vector_width(), wid, off);
+ des->add_node(ps);
+ ps->set_line(*this);
- for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
- unsigned wid = nets[idx]->vector_width();
- unsigned off = width - wid;
- NetPartSelect*ps = new NetPartSelect(osig, off, wid, part_dir);
- des->add_node(ps);
+ connect(ps->pin(0), osig->pin(0));
+ connect(ps->pin(1), nets[idx]->pin(0));
- connect(ps->pin(1), osig->pin(0));
- connect(ps->pin(0), nets[idx]->pin(0));
+ join_island(ps);
+
+ ivl_assert(*this, wid <= width);
+ width -= wid;
+ }
+
+ } else {
+ if (debug_elaborate) {
+ cerr << get_fileline() << ": debug: Generating part selects "
+ << "to connect input l-value to subexpressions."
+ << endl;
+ }
- assert(wid <= width);
- width -= wid;
+ NetPartSelect::dir_t part_dir = NetPartSelect::VP;
+
+ for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
+ unsigned wid = nets[idx]->vector_width();
+ unsigned off = width - wid;
+ NetPartSelect*ps = new NetPartSelect(osig, off, wid, part_dir);
+ des->add_node(ps);
+ ps->set_line(*this);
+
+ connect(ps->pin(1), osig->pin(0));
+ connect(ps->pin(0), nets[idx]->pin(0));
+
+ assert(wid <= width);
+ width -= wid;
+ }
+ assert(width == 0);
}
- assert(width == 0);
osig->data_type(nets[0]->data_type());
osig->local_flag(true);
@@ -2751,11 +2776,6 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
/* If we are processing a tran or inout, then the
partselect is bi-directional. Otherwise, it is a
Part-to-Vector select. */
- NetPartSelect::dir_t part_dir;
- if (bidirectional_flag)
- part_dir = NetPartSelect::BI;
- else
- part_dir = NetPartSelect::PV;
if (debug_elaborate)
cerr << get_fileline() << ": debug: "
@@ -2772,11 +2792,24 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
subsig->local_flag(true);
subsig->set_line(*this);
- NetPartSelect*sub = new NetPartSelect(sig, lidx, subnet_wid,
- part_dir);
- des->add_node(sub);
- connect(sub->pin(0), subsig->pin(0));
+ if (bidirectional_flag) {
+ // Make a tran(VP)
+ NetTran*sub = new NetTran(scope, scope->local_symbol(),
+ sig->vector_width(),
+ subnet_wid, lidx);
+ sub->set_line(*this);
+ des->add_node(sub);
+ connect(sub->pin(0), sig->pin(0));
+ connect(sub->pin(1), subsig->pin(0));
+ join_island(sub);
+ } else {
+ NetPartSelect*sub = new NetPartSelect(sig, lidx, subnet_wid,
+ NetPartSelect::PV);
+ des->add_node(sub);
+ sub->set_line(*this);
+ connect(sub->pin(0), subsig->pin(0));
+ }
sig = subsig;
}
View
@@ -889,6 +889,32 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
tmp->local_flag(true);
tmp->set_line(*sig);
+ // Handle the special case of a bi-directional part
+ // select. Create a NetTran(VP) instead of a uni-directional
+ // NetPartSelect node.
+ if (dir == NetNet::PINOUT) {
+ unsigned wida = sig->vector_width();
+ unsigned widb = tmp->vector_width();
+ bool part_b = widb < wida;
+ NetTran*node = new NetTran(scope, scope->local_symbol(),
+ part_b? wida : widb,
+ part_b? widb : wida,
+ 0);
+ if (part_b) {
+ connect(node->pin(0), tmp->pin(0));
+ connect(node->pin(1), sig->pin(0));
+ } else {
+ connect(node->pin(0), sig->pin(0));
+ connect(node->pin(1), tmp->pin(0));
+ }
+
+ node->set_line(*this);
+ des->add_node(node);
+ join_island(node);
+
+ return tmp;
+ }
+
NetPartSelect*node = 0;
switch (dir) {
@@ -917,15 +943,7 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
break;
case NetNet::PINOUT:
- if (sig->vector_width() > tmp->vector_width()) {
- node = new NetPartSelect(sig, 0, tmp->vector_width(),
- NetPartSelect::BI);
- connect(node->pin(0), tmp->pin(0));
- } else {
- node = new NetPartSelect(tmp, 0, sig->vector_width(),
- NetPartSelect::BI);
- connect(node->pin(0), sig->pin(0));
- }
+ ivl_assert(*this, 0);
break;
default:
View
@@ -226,8 +226,11 @@ ivl_switch_enable
ivl_switch_file
ivl_switch_island
ivl_switch_lineno
+ivl_switch_offset
+ivl_switch_part
ivl_switch_scope
ivl_switch_type
+ivl_switch_width
ivl_udp_init
ivl_udp_name
View
@@ -245,7 +245,8 @@ typedef enum ivl_switch_type_e {
IVL_SW_TRANIF1 = 2,
IVL_SW_RTRAN = 3,
IVL_SW_RTRANIF0 = 4,
- IVL_SW_RTRANIF1 = 5
+ IVL_SW_RTRANIF1 = 5,
+ IVL_SW_TRAN_VP = 6
} ivl_switch_type_t;
/* This is the type of an LPM object. */
@@ -265,7 +266,7 @@ typedef enum ivl_lpm_type_e {
IVL_LPM_MOD = 13,
IVL_LPM_MULT = 4,
IVL_LPM_MUX = 5,
- IVL_LPM_PART_BI= 28, /* part select: bi-directional (part on 0) */
+ /* IVL_LPM_PART_BI= 28, / obsolete */
IVL_LPM_PART_VP= 15, /* part select: vector to part */
IVL_LPM_PART_PV= 17, /* part select: part written to vector */
IVL_LPM_POW = 31,
@@ -728,8 +729,8 @@ extern unsigned ivl_file_table_size(void);
* 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);
+extern int ivl_island_flag_set(ivl_island_t net, unsigned flag, int value);
+extern int ivl_island_flag_test(ivl_island_t net, unsigned flag);
/* LOGIC
* These types and functions support manipulation of logic gates. The
@@ -1883,7 +1884,11 @@ extern ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net);
*
* SEMANTIC NOTES
* The a/b ports can be any type, but the types must exactly
- * match. The enable must be a scalar.
+ * match, including vector widths. The enable must be a scalar.
+ *
+ * The IVL_SW_TRAN_VP is an exception to the above. In this case,
+ * the B side may be a different size, and the a side will have a
+ * a fixed width. The unused bits are padded to Z on the A side.
*/
extern ivl_switch_type_t ivl_switch_type(ivl_switch_t net);
extern ivl_scope_t ivl_switch_scope(ivl_switch_t net);
@@ -1893,6 +1898,11 @@ 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);
+ /* These are only support for IVL_SW_TRAN_VP switches. */
+extern unsigned ivl_switch_width(ivl_switch_t net);
+extern unsigned ivl_switch_part(ivl_switch_t net);
+extern unsigned ivl_switch_offset(ivl_switch_t net);
+
/* Not implemented yet
extern unsigned ivl_switch_attr_cnt(ivl_switch_t net);
extern ivl_attribute_t ivl_switch_attr_val(ivl_switch_t net, unsigned idx);
View
@@ -43,7 +43,7 @@ static bool has_enable(ivl_switch_type_t tt)
}
NetTran::NetTran(NetScope*scope, perm_string n, ivl_switch_type_t tt)
- : NetNode(scope, n, has_enable(tt)? 3 : 2), type_(tt)
+: NetNode(scope, n, has_enable(tt)? 3 : 2), type_(tt)
{
pin(0).set_dir(Link::PASSIVE); pin(0).set_name(perm_string::literal("A"), 0);
pin(1).set_dir(Link::PASSIVE); pin(1).set_name(perm_string::literal("B"), 0);
@@ -53,10 +53,32 @@ NetTran::NetTran(NetScope*scope, perm_string n, ivl_switch_type_t tt)
}
}
+NetTran::NetTran(NetScope*scope, perm_string n, unsigned wid, unsigned part, unsigned off)
+: NetNode(scope, n, 2), type_(IVL_SW_TRAN_VP), wid_(wid), part_(part), off_(off)
+{
+ pin(0).set_dir(Link::PASSIVE); pin(0).set_name(perm_string::literal("A"), 0);
+ pin(1).set_dir(Link::PASSIVE); pin(1).set_name(perm_string::literal("B"), 0);
+}
+
NetTran::~NetTran()
{
}
+unsigned NetTran::vector_width() const
+{
+ return wid_;
+}
+
+unsigned NetTran::part_width() const
+{
+ return part_;
+}
+
+unsigned NetTran::part_offset() const
+{
+ return off_;
+}
+
void join_island(NetObj*obj)
{
IslandBranch*branch = dynamic_cast<IslandBranch*> (obj);
View
@@ -1379,16 +1379,28 @@ class NetSysFunc : public NetNode {
class NetTran : public NetNode, public IslandBranch {
public:
+ // Tran devices other then TRAN_VP
NetTran(NetScope*scope, perm_string n, ivl_switch_type_t type);
+ // Create a TRAN_VP
+ NetTran(NetScope*scope, perm_string n, unsigned wid,
+ unsigned part, unsigned off);
~NetTran();
ivl_switch_type_t type() const { return type_; }
+ // These are only used for IVL_SW_TRAN_PV
+ unsigned vector_width() const;
+ unsigned part_width() const;
+ unsigned part_offset() const;
+
virtual void dump_node(ostream&, unsigned ind) const;
virtual bool emit_node(struct target_t*) const;
private:
ivl_switch_type_t type_;
+ unsigned wid_;
+ unsigned part_;
+ unsigned off_;
};
/* =========
@@ -1605,8 +1617,8 @@ class NetECRealParam : public NetECReal {
* selector as the input.
*
* The NetPartSelect can be output from the signal (i.e. reading a
- * part), input into the signal, or bi-directional. The DIR method
- * gives the type of the node.
+ * part) or input into the signal. The DIR method gives the type of
+ * the node.
*
* VP (Vector-to-Part)
* Output pin 0 is the part select, and input pin 1 is connected to
@@ -1616,18 +1628,14 @@ class NetECRealParam : public NetECReal {
* Output pin 1 is connected to the NetNet, and input pin 0 is the
* part select. In this case, the node is driving the NetNet.
*
- * BI (BI-directional)
- * Pin 0 is the part select and pin 1 is connected to the NetNet, but
- * the ports are intended to be bi-directional.
- *
* Note that whatever the direction that data is intended to flow,
* pin-0 is the part select and pin-1 is connected to the NetNet.
*/
class NetPartSelect : public NetNode {
public:
// enum for the device direction
- enum dir_t { VP, PV, BI };
+ enum dir_t { VP, PV};
explicit NetPartSelect(NetNet*sig,
unsigned off, unsigned wid, dir_t dir);
Oops, something went wrong.

0 comments on commit 73e2b29

Please sign in to comment.