Refactor and cope with new abc_flop format
authorEddie Hung <eddie@fpgeh.com>
Mon, 1 Jul 2019 18:50:34 +0000 (11:50 -0700)
committerEddie Hung <eddie@fpgeh.com>
Mon, 1 Jul 2019 18:50:34 +0000 (11:50 -0700)
backends/aiger/xaiger.cc
frontends/aiger/aigerparse.cc

index 8a35e06fa140cd3ac926926f4fc5a1bdf971cb7b..19e6c8369c2a03a9c152152b9e48a8cd47d5b8de 100644 (file)
@@ -211,6 +211,7 @@ struct XAigerWriter
                //       box ordering, but not individual AIG cells
                dict<SigBit, pool<IdString>> bit_drivers, bit_users;
                TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
+               dict<IdString, std::pair<IdString,IdString>> flop_data;
                bool abc_box_seen = false;
 
                for (auto cell : module->selected_cells()) {
@@ -264,36 +265,57 @@ struct XAigerWriter
                                abc_box_seen = true;
 
                                toposort.node(cell->name);
-                               auto abc_flop_d = inst_module->attributes.at("\\abc_flop_d", RTLIL::Const());
-                               if (abc_flop_d.size() == 0) {
-                                       for (const auto &conn : cell->connections()) {
-                                               if (cell->input(conn.first)) {
-                                                       // Ignore inout for the sake of topographical ordering
-                                                       if (cell->output(conn.first)) continue;
-                                                       for (auto bit : sigmap(conn.second))
-                                                               bit_users[bit].insert(cell->name);
-                                               }
 
-                                               if (cell->output(conn.first))
-                                                       for (auto bit : sigmap(conn.second))
-                                                               bit_drivers[bit].insert(cell->name);
+                               auto r = flop_data.insert(std::make_pair(cell->type, std::make_pair(IdString(), IdString())));
+                               if (r.second) {
+                                       auto it = inst_module->attributes.find("\\abc_flop");
+                                       if (it != inst_module->attributes.end()) {
+                                               std::string abc_flop = it->second.decode_string();
+                                               size_t start, end;
+                                               end = abc_flop.find(','); // Ignore original module
+                                               log_assert(end != std::string::npos);
+                                               start = end + 1;
+                                               end = abc_flop.find(',', start + 1);
+                                               log_assert(start != std::string::npos && end != std::string::npos);
+                                               auto abc_flop_d = RTLIL::escape_id(abc_flop.substr(start, end-start));
+                                               start = end + 1;
+                                               end = abc_flop.find(',', start + 1);
+                                               log_assert(start != std::string::npos && end != std::string::npos);
+                                               auto abc_flop_q = RTLIL::escape_id(abc_flop.substr(start, end-start));
+                                               r.first->second = std::make_pair(abc_flop_d, abc_flop_q);
                                        }
                                }
-                               else {
-                                       auto abc_flop_q = inst_module->attributes.at("\\abc_flop_q");
 
-                                       SigBit d = cell->getPort(RTLIL::escape_id(abc_flop_d.decode_string()));
+                               auto abc_flop_d = r.first->second.first;
+                               if (abc_flop_d != IdString()) {
+                                       SigBit d = cell->getPort(abc_flop_d);
                                        SigBit I = sigmap(d);
                                        if (I != d)
                                                alias_map[I] = d;
                                        unused_bits.erase(d);
 
-                                       SigBit q = cell->getPort(RTLIL::escape_id(abc_flop_q.decode_string()));
+                                       auto abc_flop_q = r.first->second.second;
+                                       SigBit q = cell->getPort(abc_flop_q);
                                        SigBit O = sigmap(q);
                                        if (O != q)
                                                alias_map[O] = q;
                                        undriven_bits.erase(O);
                                        ff_bits.emplace_back(q);
+
+                               }
+                               else {
+                                       for (const auto &conn : cell->connections()) {
+                                               if (cell->input(conn.first)) {
+                                                       // Ignore inout for the sake of topographical ordering
+                                                       if (cell->output(conn.first)) continue;
+                                                       for (auto bit : sigmap(conn.second))
+                                                               bit_users[bit].insert(cell->name);
+                                               }
+
+                                               if (cell->output(conn.first))
+                                                       for (auto bit : sigmap(conn.second))
+                                                               bit_drivers[bit].insert(cell->name);
+                                       }
                                }
                        }
                        else {
index 57a164f1b2bd3d5244e70f61161882dbae77e901..30e35da011a8fddb57795ace84fee065a7c048b5 100644 (file)
@@ -742,22 +742,29 @@ void AigerReader::parse_aiger_binary()
 void AigerReader::post_process()
 {
        pool<IdString> seen_boxes;
+       dict<IdString, std::pair<RTLIL::Module*,IdString>> flop_data;
        unsigned ci_count = 0, co_count = 0, flop_count = 0;
        for (auto cell : boxes) {
                RTLIL::Module* box_module = design->module(cell->type);
                log_assert(box_module);
 
                RTLIL::Module* flop_module = nullptr;
-               auto flop_module_name = box_module->attributes.at("\\abc_flop", RTLIL::Const());
                RTLIL::IdString flop_past_q;
-               if (flop_module_name.size() > 0) {
-                       log_assert(flop_count < flopNum);
-                       flop_module = design->module(RTLIL::escape_id(flop_module_name.decode_string()));
-                       log_assert(flop_module);
-                       flop_past_q = box_module->attributes.at("\\abc_flop_past_q").decode_string();
-               }
-               else if (seen_boxes.insert(cell->type).second) {
-                       auto it = box_module->attributes.find("\\abc_carry");
+               if (seen_boxes.insert(cell->type).second) {
+                       auto it = box_module->attributes.find("\\abc_flop");
+                       if (it != box_module->attributes.end()) {
+                               log_assert(flop_count < flopNum);
+                               std::string abc_flop = it->second.decode_string();
+                               auto pos = abc_flop.find(',');
+                               log_assert(pos != std::string::npos);
+                               flop_module = design->module(RTLIL::escape_id(abc_flop.substr(0, pos)));
+                               log_assert(flop_module);
+                               pos = abc_flop.rfind(',');
+                               log_assert(pos != std::string::npos);
+                               flop_past_q = RTLIL::escape_id(abc_flop.substr(pos+1));
+                               flop_data[cell->type] = std::make_pair(flop_module, flop_past_q);
+                       }
+                       it = box_module->attributes.find("\\abc_carry");
                        if (it != box_module->attributes.end()) {
                                RTLIL::Wire *carry_in = nullptr, *carry_out = nullptr;
                                auto carry_in_out = it->second.decode_string();
@@ -796,6 +803,11 @@ void AigerReader::post_process()
                                carry_out->port_id = ports.size();
                        }
                }
+               else {
+                       auto it = flop_data.find(cell->type);
+                       if (it != flop_data.end())
+                               std::tie(flop_module,flop_past_q) = it->second;
+               }
 
                // NB: Assume box_module->ports are sorted alphabetically
                //     (as RTLIL::Module::fixup_ports() would do)