summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/rtlil.cc33
-rw-r--r--kernel/rtlil.h48
2 files changed, 79 insertions, 2 deletions
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 2c255285..dacefa21 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -340,18 +340,47 @@ void RTLIL::Module::optimize()
}
}
-void RTLIL::Module::add(RTLIL::Wire *wire) {
+void RTLIL::Module::add(RTLIL::Wire *wire)
+{
assert(!wire->name.empty());
assert(count_id(wire->name) == 0);
wires[wire->name] = wire;
}
-void RTLIL::Module::add(RTLIL::Cell *cell) {
+void RTLIL::Module::add(RTLIL::Cell *cell)
+{
assert(!cell->name.empty());
assert(count_id(cell->name) == 0);
cells[cell->name] = cell;
}
+static bool fixup_ports_compare(const RTLIL::Wire *a, const RTLIL::Wire *b)
+{
+ if (a->port_id && !b->port_id)
+ return true;
+ if (!a->port_id && b->port_id)
+ return false;
+
+ if (a->port_id == b->port_id)
+ return a->name < b->name;
+ return a->port_id < b->port_id;
+}
+
+void RTLIL::Module::fixup_ports()
+{
+ std::vector<RTLIL::Wire*> all_ports;
+
+ for (auto &w : wires)
+ if (w.second->port_input || w.second->port_output)
+ all_ports.push_back(w.second);
+ else
+ w.second->port_id = 0;
+
+ std::sort(all_ports.begin(), all_ports.end(), fixup_ports_compare);
+ for (size_t i = 0; i < all_ports.size(); i++)
+ all_ports[i]->port_id = i+1;
+}
+
RTLIL::Wire::Wire()
{
width = 1;
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index b1508288..69513924 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -237,6 +237,18 @@ struct RTLIL::Module {
virtual void optimize();
void add(RTLIL::Wire *wire);
void add(RTLIL::Cell *cell);
+ void fixup_ports();
+
+ template<typename T> void rewrite_sigspecs(T functor) {
+ for (auto &it : cells)
+ it.second->rewrite_sigspecs(functor);
+ for (auto &it : processes)
+ it.second->rewrite_sigspecs(functor);
+ for (auto &it : connections) {
+ functor(it.first);
+ functor(it.second);
+ }
+ }
};
struct RTLIL::Wire {
@@ -261,6 +273,11 @@ struct RTLIL::Cell {
std::map<RTLIL::IdString, RTLIL::Const> attributes;
std::map<RTLIL::IdString, RTLIL::Const> parameters;
void optimize();
+
+ template<typename T> void rewrite_sigspecs(T functor) {
+ for (auto &it : connections)
+ functor(it.second);
+ }
};
struct RTLIL::SigChunk {
@@ -328,6 +345,17 @@ struct RTLIL::CaseRule {
std::vector<RTLIL::SwitchRule*> switches;
~CaseRule();
void optimize();
+
+ template<typename T> void rewrite_sigspecs(T functor) {
+ for (auto &it : compare)
+ functor(it);
+ for (auto &it : actions) {
+ functor(it.first);
+ functor(it.second);
+ }
+ for (auto it : switches)
+ it->rewrite_sigspecs(functor);
+ }
};
struct RTLIL::SwitchRule {
@@ -336,6 +364,12 @@ struct RTLIL::SwitchRule {
std::vector<RTLIL::CaseRule*> cases;
~SwitchRule();
void optimize();
+
+ template<typename T> void rewrite_sigspecs(T functor) {
+ functor(signal);
+ for (auto it : cases)
+ it->rewrite_sigspecs(functor);
+ }
};
struct RTLIL::SyncRule {
@@ -343,6 +377,14 @@ struct RTLIL::SyncRule {
RTLIL::SigSpec signal;
std::vector<RTLIL::SigSig> actions;
void optimize();
+
+ template<typename T> void rewrite_sigspecs(T functor) {
+ functor(signal);
+ for (auto &it : actions) {
+ functor(it.first);
+ functor(it.second);
+ }
+ }
};
struct RTLIL::Process {
@@ -352,6 +394,12 @@ struct RTLIL::Process {
std::vector<RTLIL::SyncRule*> syncs;
~Process();
void optimize();
+
+ template<typename T> void rewrite_sigspecs(T functor) {
+ root_case.rewrite_sigspecs(functor);
+ for (auto it : syncs)
+ it->rewrite_sigspecs(functor);
+ }
};
#endif