Refactor for one "abc_carry" attribute on module
authorEddie Hung <eddie@fpgeh.com>
Thu, 27 Jun 2019 23:07:14 +0000 (16:07 -0700)
committerEddie Hung <eddie@fpgeh.com>
Thu, 27 Jun 2019 23:07:14 +0000 (16:07 -0700)
backends/aiger/xaiger.cc
frontends/aiger/aigerparse.cc
techlibs/ecp5/cells_sim.v
techlibs/ice40/cells_sim.v
techlibs/xilinx/cells_sim.v

index 92df899c24aaaf8bd05aaf6a546b73db10b02d67..ae690ec495835d2e930facdf76caffe893b24470 100644 (file)
@@ -284,8 +284,6 @@ struct XAigerWriter
                                        for (auto user_cell : it.second)
                                                toposort.edge(driver_cell, user_cell);
 
-                       pool<RTLIL::Module*> abc_carry_modules;
-
 #if 0
                        toposort.analyze_loops = true;
 #endif
@@ -303,54 +301,54 @@ struct XAigerWriter
 #endif
                        log_assert(no_loops);
 
+                       pool<IdString> seen_boxes;
                        for (auto cell_name : toposort.sorted) {
                                RTLIL::Cell *cell = module->cell(cell_name);
+                               log_assert(cell);
+
                                RTLIL::Module* box_module = module->design->module(cell->type);
                                if (!box_module || !box_module->attributes.count("\\abc_box_id"))
                                        continue;
 
-                               if (box_module->attributes.count("\\abc_carry") && !abc_carry_modules.count(box_module)) {
-                                       RTLIL::Wire* carry_in = nullptr, *carry_out = nullptr;
-                                       auto &ports = box_module->ports;
-                                       for (auto it = ports.begin(); it != ports.end(); ) {
-                                               RTLIL::Wire* w = box_module->wire(*it);
-                                               log_assert(w);
-                                               if (w->port_input && w->attributes.count("\\abc_carry_in")) {
-                                                       if (carry_in)
-                                                               log_error("More than one port with attribute 'abc_carry_in' found in module '%s'\n", log_id(box_module));
-                                                       carry_in = w;
-                                                       it = ports.erase(it);
-                                                       continue;
-                                               }
-                                               if (w->port_output && w->attributes.count("\\abc_carry_out")) {
-                                                       if (carry_out)
-                                                               log_error("More than one port with attribute 'abc_carry_out' found in module '%s'\n", log_id(box_module));
-                                                       carry_out = w;
-                                                       it = ports.erase(it);
-                                                       continue;
+                               if (seen_boxes.insert(cell->type).second) {
+                                       auto 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();
+                                               auto pos = carry_in_out.find(',');
+                                               if (pos == std::string::npos)
+                                                       log_error("'abc_carry' attribute on module '%s' does not contain ','.\n", log_id(cell->type));
+                                               auto carry_in_name = RTLIL::escape_id(carry_in_out.substr(0, pos));
+                                               carry_in = box_module->wire(carry_in_name);
+                                               if (!carry_in || !carry_in->port_input)
+                                                       log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an input port.\n", log_id(cell->type), carry_in_name.c_str());
+
+                                               auto carry_out_name = RTLIL::escape_id(carry_in_out.substr(pos+1));
+                                               carry_out = box_module->wire(carry_out_name);
+                                               if (!carry_out || !carry_out->port_output)
+                                                       log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an output port.\n", log_id(cell->type), carry_out_name.c_str());
+
+                                               auto &ports = box_module->ports;
+                                               for (auto jt = ports.begin(); jt != ports.end(); ) {
+                                                       RTLIL::Wire* w = box_module->wire(*jt);
+                                                       log_assert(w);
+                                                       if (w == carry_in || w == carry_out) {
+                                                               jt = ports.erase(jt);
+                                                               continue;
+                                                       }
+                                                       if (w->port_id > carry_in->port_id)
+                                                               --w->port_id;
+                                                       if (w->port_id > carry_out->port_id)
+                                                               --w->port_id;
+                                                       log_assert(w->port_input || w->port_output);
+                                                       log_assert(ports[w->port_id-1] == w->name);
+                                                       ++jt;
                                                }
-                                               ++it;
-                                       }
-
-                                       if (!carry_in)
-                                               log_error("Port with attribute 'abc_carry_in' not found in module '%s'\n", log_id(box_module));
-                                       if (!carry_out)
-                                               log_error("Port with attribute 'abc_carry_out' not found in module '%s'\n", log_id(box_module));
-
-                                       for (const auto port_name : ports) {
-                                               RTLIL::Wire* w = box_module->wire(port_name);
-                                               log_assert(w);
-                                               if (w->port_id > carry_in->port_id)
-                                                       --w->port_id;
-                                               if (w->port_id > carry_out->port_id)
-                                                       --w->port_id;
-                                               log_assert(w->port_input || w->port_output);
-                                               log_assert(ports[w->port_id-1] == w->name);
+                                               ports.push_back(carry_in->name);
+                                               carry_in->port_id = ports.size();
+                                               ports.push_back(carry_out->name);
+                                               carry_out->port_id = ports.size();
                                        }
-                                       ports.push_back(carry_in->name);
-                                       carry_in->port_id = ports.size();
-                                       ports.push_back(carry_out->name);
-                                       carry_out->port_id = ports.size();
                                }
 
                                // Fully pad all unused input connections of this box cell with S0
index 43337f4c25e1a7b816147cc67a7afb67916bfe7b..7008d0542f29fdc6a56a94198d8bd8f1f445a789 100644 (file)
@@ -732,44 +732,50 @@ void AigerReader::parse_aiger_binary()
 
 void AigerReader::post_process()
 {
-       pool<RTLIL::Module*> abc_carry_modules;
+       pool<IdString> seen_boxes;
        unsigned ci_count = 0, co_count = 0;
        for (auto cell : boxes) {
                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::Wire* carry_in = nullptr, *carry_out = nullptr;
-                       RTLIL::Wire* last_in = nullptr, *last_out = nullptr;
-                       for (const auto &port_name : box_module->ports) {
-                               RTLIL::Wire* w = box_module->wire(port_name);
-                               log_assert(w);
-                               if (w->port_input) {
-                                       if (w->attributes.count("\\abc_carry_in")) {
-                                               log_assert(!carry_in);
-                                               carry_in = w;
-                                       }
-                                       log_assert(!last_in || last_in->port_id < w->port_id);
-                                       last_in = w;
-                               }
-                               if (w->port_output) {
-                                       if (w->attributes.count("\\abc_carry_out")) {
-                                               log_assert(!carry_out);
-                                               carry_out = w;
+               if (seen_boxes.insert(cell->type).second) {
+                       auto 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();
+                               auto pos = carry_in_out.find(',');
+                               if (pos == std::string::npos)
+                                       log_error("'abc_carry' attribute on module '%s' does not contain ','.\n", log_id(cell->type));
+                               auto carry_in_name = RTLIL::escape_id(carry_in_out.substr(0, pos));
+                               carry_in = box_module->wire(carry_in_name);
+                               if (!carry_in || !carry_in->port_input)
+                                       log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an input port.\n", log_id(cell->type), carry_in_name.c_str());
+
+                               auto carry_out_name = RTLIL::escape_id(carry_in_out.substr(pos+1));
+                               carry_out = box_module->wire(carry_out_name);
+                               if (!carry_out || !carry_out->port_output)
+                                       log_error("'abc_carry' on module '%s' contains '%s' which does not exist or is not an output port.\n", log_id(cell->type), carry_out_name.c_str());
+
+                               auto &ports = box_module->ports;
+                               for (auto jt = ports.begin(); jt != ports.end(); ) {
+                                       RTLIL::Wire* w = box_module->wire(*jt);
+                                       log_assert(w);
+                                       if (w == carry_in || w == carry_out) {
+                                               jt = ports.erase(jt);
+                                               continue;
                                        }
-                                       log_assert(!last_out || last_out->port_id < w->port_id);
-                                       last_out = w;
+                                       if (w->port_id > carry_in->port_id)
+                                               --w->port_id;
+                                       if (w->port_id > carry_out->port_id)
+                                               --w->port_id;
+                                       log_assert(w->port_input || w->port_output);
+                                       log_assert(ports[w->port_id-1] == w->name);
+                                       ++jt;
                                }
-                       }
-
-                       if (carry_in != last_in) {
-                               std::swap(box_module->ports[carry_in->port_id], box_module->ports[last_in->port_id]);
-                               std::swap(carry_in->port_id, last_in->port_id);
-                       }
-                       if (carry_out != last_out) {
-                               log_assert(last_out);
-                               std::swap(box_module->ports[carry_out->port_id], box_module->ports[last_out->port_id]);
-                               std::swap(carry_out->port_id, last_out->port_id);
+                               ports.push_back(carry_in->name);
+                               carry_in->port_id = ports.size();
+                               ports.push_back(carry_out->name);
+                               carry_out->port_id = ports.size();
                        }
                }
 
index 08ae0a112f3e678841e717e873e3bb6d316525f7..98f91577713ff26438029c05b5a9eaea1c1adfd1 100644 (file)
@@ -15,11 +15,9 @@ module L6MUX21 (input D0, D1, SD, output Z);
 endmodule
 
 // ---------------------------------------
-(* abc_box_id=1, abc_carry, lib_whitebox *)
-module CCU2C((* abc_carry_in *) input CIN,
-                          input A0, B0, C0, D0, A1, B1, C1, D1,
-                  output S0, S1,
-                (* abc_carry_out *) output COUT);
+(* abc_box_id=1, abc_carry="CIN,COUT", lib_whitebox *)
+module CCU2C(input CIN, A0, B0, C0, D0, A1, B1, C1, D1,
+                  output S0, S1, COUT);
 
        parameter [15:0] INIT0 = 16'h0000;
        parameter [15:0] INIT1 = 16'h0000;
index 317ae2c1f77c7c5b5bfa70b641d9a99021d6fc43..c7e4101e1ffa666ffe4c8e121cba77e4dd685430 100644 (file)
@@ -136,8 +136,8 @@ module SB_LUT4 (output O, input I0, I1, I2, I3);
        assign O = I0 ? s1[1] : s1[0];
 endmodule
 
-(* abc_box_id = 1, abc_carry, lib_whitebox *)
-module SB_CARRY ((* abc_carry_out *) output CO, input I0, I1, (* abc_carry_in *) input CI);
+(* abc_box_id = 1, abc_carry="CI,CO", lib_whitebox *)
+module SB_CARRY (output CO, input I0, I1, CI);
        assign CO = (I0 && I1) || ((I0 || I1) && CI);
 endmodule
 
index 5fd9973f4093da4cd91a05a3b345651608aa8026..5a148be01832ea173b5ca93c45b18de60df2653f 100644 (file)
@@ -173,8 +173,8 @@ module XORCY(output O, input CI, LI);
   assign O = CI ^ LI;
 endmodule
 
-(* abc_box_id = 3, abc_carry, lib_whitebox *)
-module CARRY4((* abc_carry_out *) output [3:0] CO, output [3:0] O, (* abc_carry_in *) input CI, input CYINIT, input [3:0] DI, S);
+(* abc_box_id = 3, abc_carry="CI,CO", lib_whitebox *)
+module CARRY4(output [3:0] CO, O, input CI, CYINIT, input [3:0] DI, S);
   assign O = S ^ {CO[2:0], CI | CYINIT};
   assign CO[0] = S[0] ? CI | CYINIT : DI[0];
   assign CO[1] = S[1] ? CO[0] : DI[1];