read_aiger to not require clk_name for latches, plus debug
authorEddie Hung <eddie@fpgeh.com>
Sat, 15 Jun 2019 16:07:53 +0000 (09:07 -0700)
committerEddie Hung <eddie@fpgeh.com>
Sat, 15 Jun 2019 16:07:53 +0000 (09:07 -0700)
frontends/aiger/aigerparse.cc

index d378a07b7ae4047ee26ea7276065a7580d8def2f..281e1cc9de67ff1189ad2bcb13658466e830ddc8 100644 (file)
@@ -495,8 +495,7 @@ void AigerReader::parse_aiger_ascii()
 
        // Parse latches
        RTLIL::Wire *clk_wire = nullptr;
-       if (L > 0) {
-               log_assert(clk_name != "");
+       if (L > 0 && !clk_name.empty()) {
                clk_wire = module->wire(clk_name);
                log_assert(!clk_wire);
                log_debug("Creating %s\n", clk_name.c_str());
@@ -512,7 +511,10 @@ void AigerReader::parse_aiger_ascii()
                RTLIL::Wire *q_wire = createWireIfNotExists(module, l1);
                RTLIL::Wire *d_wire = createWireIfNotExists(module, l2);
 
-               module->addDffGate(NEW_ID, clk_wire, d_wire, q_wire);
+               if (clk_wire)
+                       module->addDffGate(NEW_ID, clk_wire, d_wire, q_wire);
+               else
+                       module->addFfGate(NEW_ID, d_wire, q_wire);
 
                // Reset logic is optional in AIGER 1.9
                if (f.peek() == ' ') {
@@ -620,8 +622,7 @@ void AigerReader::parse_aiger_binary()
 
        // Parse latches
        RTLIL::Wire *clk_wire = nullptr;
-       if (L > 0) {
-               log_assert(clk_name != "");
+       if (L > 0 && !clk_name.empty()) {
                clk_wire = module->wire(clk_name);
                log_assert(!clk_wire);
                log_debug("Creating %s\n", clk_name.c_str());
@@ -637,7 +638,10 @@ void AigerReader::parse_aiger_binary()
                RTLIL::Wire *q_wire = createWireIfNotExists(module, l1);
                RTLIL::Wire *d_wire = createWireIfNotExists(module, l2);
 
-               module->addDff(NEW_ID, clk_wire, d_wire, q_wire);
+               if (clk_wire)
+                       module->addDff(NEW_ID, clk_wire, d_wire, q_wire);
+               else
+                       module->addFf(NEW_ID, d_wire, q_wire);
 
                // Reset logic is optional in AIGER 1.9
                if (f.peek() == ' ') {
@@ -731,7 +735,14 @@ void AigerReader::post_process()
                RTLIL::Module* box_module = design->module(cell->type);
                log_assert(box_module);
 
-               if (box_module->attributes.count("\\abc_carry") && !abc_carry_modules.count(box_module)) {
+               RTLIL::Module* flop_module = nullptr;
+               if (box_module->attributes.count("\\abc_flop")) {
+                       log_assert(flop_count < flopNum);
+                       log_assert(box_module->name.begins_with("$__ABC_"));
+                       flop_module = design->module("\\" + box_module->name.substr(7));
+                       log_assert(flop_module);
+               }
+               else if (box_module->attributes.count("\\abc_carry") && !abc_carry_modules.count(box_module)) {
                        RTLIL::Wire* carry_in = nullptr, *carry_out = nullptr;
                        RTLIL::Wire* last_in = nullptr, *last_out = nullptr;
                        for (const auto &port_name : box_module->ports) {
@@ -766,39 +777,36 @@ void AigerReader::post_process()
                        }
                }
 
-               bool flop = box_module->attributes.count("\\abc_flop");
-               log_assert(!flop || flop_count < flopNum);
-
                // NB: Assume box_module->ports are sorted alphabetically
                //     (as RTLIL::Module::fixup_ports() would do)
                for (auto port_name : box_module->ports) {
-                       RTLIL::Wire* w = box_module->wire(port_name);
-                       log_assert(w);
+                       RTLIL::Wire* port = box_module->wire(port_name);
+                       log_assert(port);
                        RTLIL::SigSpec rhs;
                        RTLIL::Wire* wire = nullptr;
-                       for (int i = 0; i < GetSize(w); i++) {
-                               if (w->port_input) {
+                       for (int i = 0; i < GetSize(port); i++) {
+                               if (port->port_input) {
                                        log_assert(co_count < outputs.size());
                                        wire = outputs[co_count++];
                                        log_assert(wire);
                                        log_assert(wire->port_output);
                                        wire->port_output = false;
 
-                                       if (flop && w->attributes.count("\\abc_flop_d")) {
+                                       if (flop_module && port->attributes.count("\\abc_flop_d")) {
                                                RTLIL::Wire* d = outputs[outputs.size() - flopNum + flop_count];
                                                log_assert(d);
                                                log_assert(d->port_output);
                                                d->port_output = false;
                                        }
                                }
-                               if (w->port_output) {
+                               if (port->port_output) {
                                        log_assert((piNum + ci_count) < inputs.size());
                                        wire = inputs[piNum + ci_count++];
                                        log_assert(wire);
                                        log_assert(wire->port_input);
                                        wire->port_input = false;
 
-                                       if (flop && w->attributes.count("\\abc_flop_q")) {
+                                       if (flop_module && port->attributes.count("\\abc_flop_q")) {
                                                wire = inputs[piNum - flopNum + flop_count];
                                                log_assert(wire);
                                                log_assert(wire->port_input);
@@ -807,10 +815,14 @@ void AigerReader::post_process()
                                }
                                rhs.append(wire);
                        }
-                       cell->setPort(port_name, rhs);
+                       if (!flop_module || !port->attributes.count("\\abc_discard"))
+                               cell->setPort(port_name, rhs);
                }
 
-               if (flop) flop_count++;
+               if (flop_module) {
+                       flop_count++;
+                       cell->type = flop_module->name;
+               }
        }
 
        dict<RTLIL::IdString, int> wideports_cache;
@@ -826,6 +838,7 @@ void AigerReader::post_process()
                                RTLIL::Wire* wire = inputs[variable];
                                log_assert(wire);
                                log_assert(wire->port_input);
+                               log_debug("Renaming input %s", log_id(wire));
 
                                if (index == 0) {
                                        // Cope with the fact that a CI might be identical
@@ -852,12 +865,14 @@ void AigerReader::post_process()
                                                wire->port_input = false;
                                        }
                                }
+                               log_debug(" -> %s\n", log_id(wire));
                        }
                        else if (type == "output") {
                                log_assert(static_cast<unsigned>(variable + co_count) < outputs.size());
                                RTLIL::Wire* wire = outputs[variable + co_count];
                                log_assert(wire);
                                log_assert(wire->port_output);
+                               log_debug("Renaming output %s", log_id(wire));
 
                                if (index == 0) {
                                        // Cope with the fact that a CO might be identical
@@ -904,6 +919,7 @@ void AigerReader::post_process()
                                                wire->port_output = false;
                                        }
                                }
+                               log_debug(" -> %s\n", log_id(wire));
                        }
                        else if (type == "box") {
                                RTLIL::Cell* cell = module->cell(stringf("$__box%d__", variable));
@@ -1009,8 +1025,8 @@ struct AigerFrontend : public Frontend {
                log("        Name of module to be created (default: <filename>)\n");
                log("\n");
                log("    -clk_name <wire_name>\n");
-               log("        AIGER latches to be transformed into posedge DFFs clocked by wire of");
-               log("        this name (default: clk)\n");
+               log("        If specified, AIGER latches to be transformed into $_DFF_P_ cells\n"
+               log("        clocked by wire of this name. Otherwise, $_FF_ cells will be used.\n");
                log("\n");
                log("    -map <filename>\n");
                log("        read file with port and latch symbols\n");