Merge branch 'xaig' into xc7mux
authorEddie Hung <eddie@fpgeh.com>
Fri, 31 May 2019 20:03:03 +0000 (13:03 -0700)
committerEddie Hung <eddie@fpgeh.com>
Fri, 31 May 2019 20:03:03 +0000 (13:03 -0700)
1  2 
backends/aiger/xaiger.cc
frontends/aiger/aigerparse.cc
passes/techmap/abc9.cc
techlibs/ice40/cells_sim.v
techlibs/xilinx/synth_xilinx.cc

index cd15b61605fd2276bfbffa5cbf20298f590b18f5,7126002f65bcf94b0e4dbfc491dd88cf6ece5b2b..7a139f68f42a24f0eb04726c8a94d542de33d45b
@@@ -49,8 -49,8 +49,9 @@@ struct XAigerWrite
        dict<SigBit, SigBit> not_map, ff_map, alias_map;
        dict<SigBit, pair<SigBit, SigBit>> and_map;
        //pool<SigBit> initstate_bits;
 -      vector<std::pair<SigBit,int>> ci_bits, co_bits;
 +      vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int>> ci_bits;
 +      vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int,int>> co_bits;
+       vector<std::pair<SigBit,SigBit>> ff_bits;
  
        vector<pair<int, int>> aig_gates;
        vector<int> aig_latchin, aig_latchinit, aig_outputs;
                        aig_map[bit] = 2*aig_m;
                }
  
+               for (auto &f : ff_bits) {
+                       auto bit = f.second;
+                       aig_m++, aig_i++;
+                       aig_map[bit] = 2*aig_m;
+               }
+               dict<SigBit, int> ff_aig_map;
                for (auto &c : ci_bits) {
 +                      RTLIL::SigBit bit = std::get<0>(c);
                        aig_m++, aig_i++;
 -                      c.second = 2*aig_m;
 -                      auto r = aig_map.insert(std::make_pair(c.first, c.second));
 -                      if (!r.second) {
 -                              ff_aig_map[c.first] = c.second;
 -                      }
 +                      log_assert(!aig_map.count(bit));
 +                      aig_map[bit] = 2*aig_m;
++                      //auto r = aig_map.insert(std::make_pair(c.first, c.second));
++                      //if (!r.second) {
++                      //      ff_aig_map[std::get<0>(c)] = 2*aig_m;
++                      //}
                }
  
                if (imode && input_bits.empty()) {
                        if (omode && num_outputs == 0)
                                num_outputs = 1;
                        write_h_buffer(1);
-                       log_debug("ciNum = %zu\n", input_bits.size() + ci_bits.size());
-                       write_h_buffer(input_bits.size() + ci_bits.size());
-                       log_debug("coNum = %zu\n", num_outputs + co_bits.size());
-                       write_h_buffer(num_outputs + co_bits.size());
-                       log_debug("piNum = %zu\n", input_bits.size());
-                       write_h_buffer(input_bits.size());
++                      log_debug("ciNum = %zu\n", input_bits.size() + ff_bits.size() + ci_bits.size());
+                       write_h_buffer(input_bits.size() + ff_bits.size() + ci_bits.size());
 -                      write_h_buffer(num_outputs + ff_bits.size() + co_bits.size());
 -                      write_h_buffer(input_bits.size() + ff_bits.size());
 -                      write_h_buffer(num_outputs + ff_bits.size());
++                      log_debug("coNum = %zu\n", num_outputs + ff_bits.size() + co_bits.size());
++                      write_h_buffer(num_outputs + ff_bits.size()+ co_bits.size());
++                      log_debug("piNum = %zu\n", input_bits.size() + ff_bits.size());
++                      write_h_buffer(input_bits.size()+ ff_bits.size());
 +                      log_debug("poNum = %d\n", num_outputs);
 +                      write_h_buffer(num_outputs);
 +                      log_debug("boxNum = %zu\n", box_list.size());
                        write_h_buffer(box_list.size());
  
                        RTLIL::Module *holes_module = nullptr;
                        f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
                        f.write(buffer_str.data(), buffer_str.size());
  
+                       if (!ff_bits.empty()) {
+                               std::stringstream r_buffer;
+                               auto write_r_buffer = [&r_buffer](int i32) {
+                                       // TODO: Don't assume we're on little endian
+ #ifdef _WIN32
+                                       int i32_be = _byteswap_ulong(i32);
+ #else
+                                       int i32_be = __builtin_bswap32(i32);
+ #endif
+                                       r_buffer.write(reinterpret_cast<const char*>(&i32_be), sizeof(i32_be));
+                               };
+                               write_r_buffer(ff_bits.size());
+                               int mergeability_class = 1;
+                               for (auto cell : ff_bits)
+                                       write_r_buffer(mergeability_class++);
+                               f << "r";
+                               std::string buffer_str = r_buffer.str();
+                               // TODO: Don't assume we're on little endian
+ #ifdef _WIN32
+                               int buffer_size_be = _byteswap_ulong(buffer_str.size());
+ #else
+                               int buffer_size_be = __builtin_bswap32(buffer_str.size());
+ #endif
+                               f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
+                               f.write(buffer_str.data(), buffer_str.size());
+                       }
                        if (holes_module) {
 -                              holes_module->fixup_ports();
 +                              // NB: fixup_ports() will sort ports by name
 +                              //holes_module->fixup_ports();
 +                              holes_module->check();
  
                                holes_module->design->selection_stack.emplace_back(false);
                                RTLIL::Selection& sel = holes_module->design->selection_stack.back();
Simple merge
index f148287454c08dd43a33ecaf01df299eea114b4d,2aa19b348fec78afd508e751642b0a3185215d13..01842dbf228f7e22653c82a193a8e50dcd5170ce
@@@ -537,14 -562,9 +537,9 @@@ void abc9_module(RTLIL::Design *design
                                                output_bits.insert({wire, i});
                                }
                                else {
-                                       //if (w->name == "\\__dummy_o__") {
-                                       //      log("Don't call ABC as there is nothing to map.\n");
-                                       //      goto cleanup;
-                                       //}
                                        // Attempt another wideports_split here because there
                                        // exists the possibility that different bits of a port
 -                                      // could be an input and output, therefore parse_xiager()
 +                                      // could be an input and output, therefore parse_xaiger()
                                        // could not combine it into a wideport
                                        auto r = wideports_split(w->name.str());
                                        wire = module->wire(r.first);
Simple merge
index ecfb94610c2f9030c37172a9b3b6be463362c64b,5820d6d618e9828e1b4b24716ac9db34d6423fc7..cc667b91968c833614d4e8b20fa8e9d0289be313
@@@ -252,73 -270,79 +252,74 @@@ struct SynthXilinxPass : public ScriptP
                        }
                }
  
 -              if (check_label(active, run_from, run_to, "fine"))
 -              {
 -                      Pass::call(design, "opt -fast");
 -                      Pass::call(design, "memory_map");
 -                      Pass::call(design, "dffsr2dff");
 -                      Pass::call(design, "dff2dffe");
 -
 -                      if (vpr) {
 -                              Pass::call(design, "techmap -map +/xilinx/arith_map.v -D _EXPLICIT_CARRY");
 -                      } else {
 -                              Pass::call(design, "techmap -map +/xilinx/arith_map.v");
 -                      }
 +              if (check_label("fine")) {
 +                      run("opt -fast -full");
 +                      run("memory_map");
 +                      run("dffsr2dff");
 +                      run("dff2dffe");
 +                      run("opt -full");
  
 -                      Pass::call(design, "hierarchy -check");
 -                      Pass::call(design, "opt -fast");
 -              }
 +                      if (vpr && !nocarry && !help_mode)
 +                              run("techmap -map +/xilinx/arith_map.v -D _EXPLICIT_CARRY");
 +                      else if (abc == "abc9" && !nocarry && !help_mode)
 +                              run("techmap -map +/xilinx/arith_map.v -D _CLB_CARRY", "(skip if '-nocarry')");
 +                      else if (!nocarry || help_mode)
 +                              run("techmap -map +/xilinx/arith_map.v", "(skip if '-nocarry')");
  
 -              if (check_label(active, run_from, run_to, "map_cells"))
 -              {
 -                      if (!nosrl) {
 +                      if (!nosrl || help_mode) {
                                // shregmap operates on bit-level flops, not word-level,
                                //   so break those down here
 -                              Pass::call(design, "simplemap t:$dff t:$dffe");
 -                              // shregmap -tech xilinx can cope with $shiftx and $mux
 -                              //   cells for identifiying variable-length shift registers,
 -                              //   so attempt to convert $pmux-es to the former
 -                              Pass::call(design, "pmux2shiftx");
 -                              // pmux2shiftx can leave behind a $pmux with a single entry
 -                              //   -- need this to clean that up before shregmap
 -                              Pass::call(design, "opt_expr -mux_undef");
 +                              run("simplemap t:$dff t:$dffe", "(skip if '-nosrl')");
                                // shregmap with '-tech xilinx' infers variable length shift regs
 -                              Pass::call(design, "shregmap -tech xilinx -minlen 3");
 +                              run("shregmap -tech xilinx -minlen 3", "(skip if '-nosrl')");
                        }
  
 -                      Pass::call(design, "techmap -map +/xilinx/cells_map.v");
 -                      Pass::call(design, "clean");
 +                      if (!nomux || help_mode)
 +                              run("techmap -map +/xilinx/cells_map.v");
 +
 +                      run("techmap");
 +                      run("opt -fast");
                }
  
 -              if (check_label(active, run_from, run_to, "map_luts"))
 -              {
 -                      Pass::call(design, "opt -full");
 -                      Pass::call(design, "techmap -map +/techmap.v -D _NO_POS_SR -map +/xilinx/ff_map.v");
 -                      Pass::call(design, abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
 -                      Pass::call(design, "clean");
 +              if (check_label("map_cells")) {
 +                      run("techmap -map +/techmap.v -map +/xilinx/cells_map.v");
 +                      run("clean");
 +              }
 +
 +              if (check_label("map_luts")) {
 +                      if (abc == "abc9")
 +                              run(abc + " -lut +/xilinx/abc.lut -box +/xilinx/abc.box" + string(retime ? " -dff" : ""));
 +                      else if (help_mode)
 +                              run(abc + " -luts 2:2,3,6:5,10,20 [-dff]");
 +                      else
 +                              run(abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
 +                      run("clean");
++
                        // This shregmap call infers fixed length shift registers after abc
                        //   has performed any necessary retiming
 -                      if (!nosrl)
 -                              Pass::call(design, "shregmap -minlen 3 -init -params -enpol any_or_none");
 -                      Pass::call(design, "techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v");
 -                      Pass::call(design, "dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT "
 +                      if (!nosrl || help_mode)
 +                              run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')");
 +                      run("techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v");
 +                      run("dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT "
                                        "-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT");
 -                      Pass::call(design, "clean");
 +                      run("clean");
                }
  
 -              if (check_label(active, run_from, run_to, "check"))
 -              {
 -                      Pass::call(design, "hierarchy -check");
 -                      Pass::call(design, "stat");
 -                      Pass::call(design, "check -noinit");
 +              if (check_label("check")) {
 +                      run("hierarchy -check");
 +                      run("stat -tech xilinx");
 +                      run("check -noinit");
                }
  
 -              if (check_label(active, run_from, run_to, "edif"))
 -              {
 -                      if (!edif_file.empty())
 -                              Pass::call(design, stringf("write_edif -pvector bra %s", edif_file.c_str()));
 -              }
 -              if (check_label(active, run_from, run_to, "blif"))
 -              {
 -                      if (!blif_file.empty())
 -                              Pass::call(design, stringf("write_blif %s", edif_file.c_str()));
 +              if (check_label("edif")) {
 +                      if (!edif_file.empty() || help_mode)
 +                              run(stringf("write_edif -pvector bra %s", edif_file.c_str()));
                }
  
 -              log_pop();
 +              if (check_label("blif")) {
 +                      if (!blif_file.empty() || help_mode)
 +                              run(stringf("write_blif %s", edif_file.c_str()));
 +              }
        }
  } SynthXilinxPass;