Skip to content

Commit

Permalink
Replace the NetPartSelect:BI with NetTran(VP).
Browse files Browse the repository at this point in the history
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
steveicarus committed Jun 3, 2008
1 parent 6e5373c commit 73e2b29
Show file tree
Hide file tree
Showing 20 changed files with 395 additions and 286 deletions.
14 changes: 10 additions & 4 deletions design_dump.cc
Expand Up @@ -109,6 +109,9 @@ ostream& operator << (ostream&o, ivl_switch_type_t val)
case IVL_SW_RTRANIF1: case IVL_SW_RTRANIF1:
o << "rtranif1"; o << "rtranif1";
break; break;
case IVL_SW_TRAN_VP:
o << "tran(VP)";
break;
} }
return o; return o;
} }
Expand Down Expand Up @@ -518,9 +521,6 @@ void NetPartSelect::dump_node(ostream&o, unsigned ind) const
case PV: case PV:
pt = "PV"; pt = "PV";
break; break;
case BI:
pt = "BI";
break;
} }
o << setw(ind) << "" << "NetPartSelect(" << pt << "): " o << setw(ind) << "" << "NetPartSelect(" << pt << "): "
<< name(); << name();
Expand Down Expand Up @@ -639,7 +639,13 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const
void NetTran::dump_node(ostream&o, unsigned ind) const void NetTran::dump_node(ostream&o, unsigned ind) const
{ {
o << setw(ind) << "" << type_ << " " << name() 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_node_pins(o, ind+4);
dump_obj_attr(o, ind+4); dump_obj_attr(o, ind+4);
} }
Expand Down
87 changes: 60 additions & 27 deletions elab_net.cc
Expand Up @@ -2375,29 +2375,54 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
osig->local_flag(true); osig->local_flag(true);
osig->set_line(*this); osig->set_line(*this);


if (debug_elaborate) { if (bidirectional_flag) {
cerr << get_fileline() << ": debug: Generating part selects " if (debug_elaborate) {
<< "to connect input l-value to subexpressions." cerr << get_fileline() << ": debug: Generating tran(VP) "
<< endl; << "to connect input l-value to subexpressions."
} << endl;
}


NetPartSelect::dir_t part_dir = bidirectional_flag for (unsigned idx = 0 ; idx < nets.count() ; idx += 1) {
? NetPartSelect::BI unsigned wid = nets[idx]->vector_width();
: NetPartSelect::VP; 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) { connect(ps->pin(0), osig->pin(0));
unsigned wid = nets[idx]->vector_width(); connect(ps->pin(1), nets[idx]->pin(0));
unsigned off = width - wid;
NetPartSelect*ps = new NetPartSelect(osig, off, wid, part_dir);
des->add_node(ps);


connect(ps->pin(1), osig->pin(0)); join_island(ps);
connect(ps->pin(0), nets[idx]->pin(0));
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); NetPartSelect::dir_t part_dir = NetPartSelect::VP;
width -= wid;
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->data_type(nets[0]->data_type());
osig->local_flag(true); osig->local_flag(true);
Expand Down Expand Up @@ -2751,11 +2776,6 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
/* If we are processing a tran or inout, then the /* If we are processing a tran or inout, then the
partselect is bi-directional. Otherwise, it is a partselect is bi-directional. Otherwise, it is a
Part-to-Vector select. */ Part-to-Vector select. */
NetPartSelect::dir_t part_dir;
if (bidirectional_flag)
part_dir = NetPartSelect::BI;
else
part_dir = NetPartSelect::PV;


if (debug_elaborate) if (debug_elaborate)
cerr << get_fileline() << ": debug: " cerr << get_fileline() << ": debug: "
Expand All @@ -2772,11 +2792,24 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
subsig->local_flag(true); subsig->local_flag(true);
subsig->set_line(*this); subsig->set_line(*this);


NetPartSelect*sub = new NetPartSelect(sig, lidx, subnet_wid, if (bidirectional_flag) {
part_dir); // Make a tran(VP)
des->add_node(sub); NetTran*sub = new NetTran(scope, scope->local_symbol(),
connect(sub->pin(0), subsig->pin(0)); 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; sig = subsig;
} }


Expand Down
36 changes: 27 additions & 9 deletions elaborate.cc
Expand Up @@ -889,6 +889,32 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
tmp->local_flag(true); tmp->local_flag(true);
tmp->set_line(*sig); 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; NetPartSelect*node = 0;


switch (dir) { switch (dir) {
Expand Down Expand Up @@ -917,15 +943,7 @@ NetNet*PGModule::resize_net_to_port_(Design*des, NetScope*scope,
break; break;


case NetNet::PINOUT: case NetNet::PINOUT:
if (sig->vector_width() > tmp->vector_width()) { ivl_assert(*this, 0);
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));
}
break; break;


default: default:
Expand Down
3 changes: 3 additions & 0 deletions ivl.def
Expand Up @@ -226,8 +226,11 @@ ivl_switch_enable
ivl_switch_file ivl_switch_file
ivl_switch_island ivl_switch_island
ivl_switch_lineno ivl_switch_lineno
ivl_switch_offset
ivl_switch_part
ivl_switch_scope ivl_switch_scope
ivl_switch_type ivl_switch_type
ivl_switch_width


ivl_udp_init ivl_udp_init
ivl_udp_name ivl_udp_name
Expand Down
20 changes: 15 additions & 5 deletions ivl_target.h
Expand Up @@ -245,7 +245,8 @@ typedef enum ivl_switch_type_e {
IVL_SW_TRANIF1 = 2, IVL_SW_TRANIF1 = 2,
IVL_SW_RTRAN = 3, IVL_SW_RTRAN = 3,
IVL_SW_RTRANIF0 = 4, IVL_SW_RTRANIF0 = 4,
IVL_SW_RTRANIF1 = 5 IVL_SW_RTRANIF1 = 5,
IVL_SW_TRAN_VP = 6
} ivl_switch_type_t; } ivl_switch_type_t;


/* This is the type of an LPM object. */ /* This is the type of an LPM object. */
Expand All @@ -265,7 +266,7 @@ typedef enum ivl_lpm_type_e {
IVL_LPM_MOD = 13, IVL_LPM_MOD = 13,
IVL_LPM_MULT = 4, IVL_LPM_MULT = 4,
IVL_LPM_MUX = 5, 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_VP= 15, /* part select: vector to part */
IVL_LPM_PART_PV= 17, /* part select: part written to vector */ IVL_LPM_PART_PV= 17, /* part select: part written to vector */
IVL_LPM_POW = 31, IVL_LPM_POW = 31,
Expand Down Expand Up @@ -728,8 +729,8 @@ extern unsigned ivl_file_table_size(void);
* Allow the user to test or set a boolean flag associated with the * Allow the user to test or set a boolean flag associated with the
* island. * island.
*/ */
extern int ivl_island_flag_set(ivl_island_t net, int flag, int value); extern int ivl_island_flag_set(ivl_island_t net, unsigned flag, int value);
extern int ivl_island_flag_test(ivl_island_t net, int flag); extern int ivl_island_flag_test(ivl_island_t net, unsigned flag);


/* LOGIC /* LOGIC
* These types and functions support manipulation of logic gates. The * These types and functions support manipulation of logic gates. The
Expand Down Expand Up @@ -1883,7 +1884,11 @@ extern ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net);
* *
* SEMANTIC NOTES * SEMANTIC NOTES
* The a/b ports can be any type, but the types must exactly * 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_switch_type_t ivl_switch_type(ivl_switch_t net);
extern ivl_scope_t ivl_switch_scope(ivl_switch_t net); extern ivl_scope_t ivl_switch_scope(ivl_switch_t net);
Expand All @@ -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_nexus_t ivl_switch_enable(ivl_switch_t net);
extern ivl_island_t ivl_switch_island(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 /* Not implemented yet
extern unsigned ivl_switch_attr_cnt(ivl_switch_t net); extern unsigned ivl_switch_attr_cnt(ivl_switch_t net);
extern ivl_attribute_t ivl_switch_attr_val(ivl_switch_t net, unsigned idx); extern ivl_attribute_t ivl_switch_attr_val(ivl_switch_t net, unsigned idx);
Expand Down
24 changes: 23 additions & 1 deletion net_tran.cc
Expand Up @@ -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) 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(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); pin(1).set_dir(Link::PASSIVE); pin(1).set_name(perm_string::literal("B"), 0);
Expand All @@ -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() 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) void join_island(NetObj*obj)
{ {
IslandBranch*branch = dynamic_cast<IslandBranch*> (obj); IslandBranch*branch = dynamic_cast<IslandBranch*> (obj);
Expand Down
22 changes: 15 additions & 7 deletions netlist.h
Expand Up @@ -1379,16 +1379,28 @@ class NetSysFunc : public NetNode {
class NetTran : public NetNode, public IslandBranch { class NetTran : public NetNode, public IslandBranch {


public: public:
// Tran devices other then TRAN_VP
NetTran(NetScope*scope, perm_string n, ivl_switch_type_t type); 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(); ~NetTran();


ivl_switch_type_t type() const { return type_; } 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 void dump_node(ostream&, unsigned ind) const;
virtual bool emit_node(struct target_t*) const; virtual bool emit_node(struct target_t*) const;


private: private:
ivl_switch_type_t type_; ivl_switch_type_t type_;
unsigned wid_;
unsigned part_;
unsigned off_;
}; };


/* ========= /* =========
Expand Down Expand Up @@ -1605,8 +1617,8 @@ class NetECRealParam : public NetECReal {
* selector as the input. * selector as the input.
* *
* The NetPartSelect can be output from the signal (i.e. reading a * The NetPartSelect can be output from the signal (i.e. reading a
* part), input into the signal, or bi-directional. The DIR method * part) or input into the signal. The DIR method gives the type of
* gives the type of the node. * the node.
* *
* VP (Vector-to-Part) * VP (Vector-to-Part)
* Output pin 0 is the part select, and input pin 1 is connected to * Output pin 0 is the part select, and input pin 1 is connected to
Expand All @@ -1616,18 +1628,14 @@ class NetECRealParam : public NetECReal {
* Output pin 1 is connected to the NetNet, and input pin 0 is the * 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. * 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, * 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. * pin-0 is the part select and pin-1 is connected to the NetNet.
*/ */
class NetPartSelect : public NetNode { class NetPartSelect : public NetNode {


public: public:
// enum for the device direction // enum for the device direction
enum dir_t { VP, PV, BI }; enum dir_t { VP, PV};


explicit NetPartSelect(NetNet*sig, explicit NetPartSelect(NetNet*sig,
unsigned off, unsigned wid, dir_t dir); unsigned off, unsigned wid, dir_t dir);
Expand Down

0 comments on commit 73e2b29

Please sign in to comment.