Skip to content
Browse files

Support collapse of PartSelect::PV to concatenation

During elaboration, it is sometimes efficient to collapse a
collections of PV drivers to a net to a single concatenation.
This removes a bunch of resolutions and other nodes, and also
is the only way that 2-value logic should work.
  • Loading branch information...
1 parent 7d53ac3 commit 098bbeea7c2e668fcfe82ee47662c7a947e329d5 @steveicarus committed Apr 3, 2011
Showing with 79 additions and 0 deletions.
  1. +1 −0 elab_net.cc
  2. +76 −0 netmisc.cc
  3. +2 −0 netmisc.h
View
1 elab_net.cc
@@ -616,6 +616,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
des->add_node(sub);
sub->set_line(*this);
connect(sub->pin(0), subsig->pin(0));
+ collapse_partselect_pv_to_concat(des, sig);
}
sig = subsig;
}
View
76 netmisc.cc
@@ -791,3 +791,79 @@ uint64_t get_scaled_time_from_real(Design*des, NetScope*scope, NetECReal*val)
return delay;
}
+
+/*
+ * This function looks at the NetNet signal to see if there are any
+ * NetPartSelect::PV nodes driving this signal. If so, See if they can
+ * be collapsed into a single concatenation.
+ */
+void collapse_partselect_pv_to_concat(Design*des, NetNet*sig)
+{
+ NetScope*scope = sig->scope();
+ vector<NetPartSelect*> ps_map (sig->vector_width());
+
+ Nexus*nex = sig->pin(0).nexus();
+
+ for (Link*cur = nex->first_nlink(); cur ; cur = cur->next_nlink()) {
+ NetPins*obj;
+ unsigned obj_pin;
+ cur->cur_link(obj, obj_pin);
+
+ // Look for NetPartSelect devices, where this signal is
+ // connected to pin 1 of a NetPartSelect::PV.
+ NetPartSelect*ps_obj = dynamic_cast<NetPartSelect*> (obj);
+ if (ps_obj == 0)
+ continue;
+ if (ps_obj->dir() != NetPartSelect::PV)
+ continue;
+ if (obj_pin != 1)
+ continue;
+
+ ivl_assert(*ps_obj, ps_obj->base() < ps_map.size());
+ ivl_assert(*ps_obj, ps_obj->base()+ps_obj->width() <= ps_map.size());
+ ps_map[ps_obj->base()] = ps_obj;
+ }
+
+ // Check the collected NetPartSelect::PV objects to see if
+ // they cover the vector.
+ unsigned idx = 0;
+ unsigned device_count = 0;
+ while (idx < ps_map.size()) {
+ NetPartSelect*ps_obj = ps_map[idx];
+ if (ps_obj == 0)
+ return;
+
+ idx += ps_obj->width();
+ device_count += 1;
+ }
+
+ ivl_assert(*sig, idx == ps_map.size());
+
+ // Ah HAH! The NetPartSelect::PV objects exactly cover the
+ // target signal. We can replace all of them with a single
+ // concatenation.
+
+ if (debug_elaborate) {
+ cerr << sig->get_fileline() << ": debug: "
+ << "Collapse " << device_count
+ << " NetPartSelect::PV devices into a concatenation." << endl;
+ }
+
+ NetConcat*cat = new NetConcat(scope, scope->local_symbol(),
+ ps_map.size(), device_count);
+ des->add_node(cat);
+ cat->set_line(*sig);
+
+ connect(cat->pin(0), sig->pin(0));
+
+ idx = 0;
+ unsigned concat_position = 1;
+ while (idx < ps_map.size()) {
+ assert(ps_map[idx]);
+ NetPartSelect*ps_obj = ps_map[idx];
+ connect(cat->pin(concat_position), ps_obj->pin(0));
+ concat_position += 1;
+ idx += ps_obj->width();
+ delete ps_obj;
+ }
+}
View
2 netmisc.h
@@ -241,4 +241,6 @@ extern uint64_t get_scaled_time_from_real(Design*des,
NetScope*scope,
NetECReal*val);
+extern void collapse_partselect_pv_to_concat(Design*des, NetNet*sig);
+
#endif

0 comments on commit 098bbee

Please sign in to comment.
Something went wrong with that request. Please try again.