Added new RTLIL::Cell port access methods
authorClifford Wolf <clifford@clifford.at>
Sat, 26 Jul 2014 10:22:58 +0000 (12:22 +0200)
committerClifford Wolf <clifford@clifford.at>
Sat, 26 Jul 2014 10:22:58 +0000 (12:22 +0200)
kernel/rtlil.cc
kernel/rtlil.h

index 4d0aadbb57a26a92dcad4c74143813e626a23830..27063aeac1c4842df0175a5172055f51ff7d3df8 100644 (file)
@@ -1330,6 +1330,26 @@ RTLIL::Memory::Memory()
        size = 0;
 }
 
+void RTLIL::Cell::unset(RTLIL::IdString portname)
+{
+       connections_.erase(portname);
+}
+
+void RTLIL::Cell::set(RTLIL::IdString portname, RTLIL::SigSpec signal)
+{
+       connections_[portname] = signal;
+}
+
+RTLIL::SigSpec RTLIL::Cell::get(RTLIL::IdString portname) const
+{
+       return connections_.at(portname);
+}
+
+const std::map<RTLIL::IdString, RTLIL::SigSpec> &RTLIL::Cell::connections()
+{
+       return connections_;
+}
+
 void RTLIL::Cell::check()
 {
 #ifndef NDEBUG
@@ -1338,6 +1358,49 @@ void RTLIL::Cell::check()
 #endif
 }
 
+void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
+{
+       if (type[0] != '$' || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" ||
+                       type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:")
+               return;
+
+       if (type == "$mux" || type == "$pmux" || type == "$safe_pmux")
+       {
+               parameters["\\WIDTH"] = SIZE(connections_["\\Y"]);
+               if (type == "$pmux" || type == "$safe_pmux")
+                       parameters["\\S_WIDTH"] = SIZE(connections_["\\S"]);
+               check();
+               return;
+       }
+
+       bool signedness_ab = type != "$slice" && type != "$concat";
+
+       if (connections_.count("\\A")) {
+               if (signedness_ab) {
+                       if (set_a_signed)
+                               parameters["\\A_SIGNED"] = true;
+                       else if (parameters.count("\\A_SIGNED") == 0)
+                               parameters["\\A_SIGNED"] = false;
+               }
+               parameters["\\A_WIDTH"] = SIZE(connections_["\\A"]);
+       }
+
+       if (connections_.count("\\B")) {
+               if (signedness_ab) {
+                       if (set_b_signed)
+                               parameters["\\B_SIGNED"] = true;
+                       else if (parameters.count("\\B_SIGNED") == 0)
+                               parameters["\\B_SIGNED"] = false;
+               }
+               parameters["\\B_WIDTH"] = SIZE(connections_["\\B"]);
+       }
+
+       if (connections_.count("\\Y"))
+               parameters["\\Y_WIDTH"] = SIZE(connections_["\\Y"]);
+
+       check();
+}
+
 RTLIL::SigChunk::SigChunk()
 {
        wire = NULL;
index 96bda7530448be6eb396eb221dde595f5f7e2a6e..0b92405e81d882c2ea9ab29d92508bac24c2e8f4 100644 (file)
@@ -484,7 +484,15 @@ public:
        std::map<RTLIL::IdString, RTLIL::SigSpec> connections_;
        std::map<RTLIL::IdString, RTLIL::Const> parameters;
        RTLIL_ATTRIBUTE_MEMBERS
+
+       // access cell ports
+       void unset(RTLIL::IdString portname);
+       void set(RTLIL::IdString portname, RTLIL::SigSpec signal);
+       RTLIL::SigSpec get(RTLIL::IdString portname) const;
+       const std::map<RTLIL::IdString, RTLIL::SigSpec> &connections();
+
        void check();
+       void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false);
 
        template<typename T> void rewrite_sigspecs(T functor);
 };