From 1122a2e0671ed00b7c03658f5012e34df12f26de Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 9 Jul 2019 15:49:16 -0700 Subject: [PATCH 01/43] Fix first divergence in #1178 --- passes/opt/wreduce.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 1fbc41082..65068238b 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -430,6 +430,7 @@ struct WreduceWorker for (auto w : module->wires()) complete_wires.insert(mi.sigmap(w)); + std::vector> swap_wire_names; for (auto w : module->selected_wires()) { int unused_top_bits = 0; @@ -454,9 +455,12 @@ struct WreduceWorker log("Removed top %d bits (of %d) from wire %s.%s.\n", unused_top_bits, GetSize(w), log_id(module), log_id(w)); Wire *nw = module->addWire(NEW_ID, GetSize(w) - unused_top_bits); module->connect(nw, SigSpec(w).extract(0, GetSize(nw))); - module->swap_names(w, nw); + swap_wire_names.emplace_back(w, nw); } + for (const auto &i : swap_wire_names) + module->swap_names(i.first, i.second); + if (!remove_init_bits.empty()) { for (auto w : module->wires()) { if (w->attributes.count("\\init")) { From fc3d74616f284eaccdc7d105cd77572953602d7f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 00:50:42 -0700 Subject: [PATCH 02/43] Combine SB_CARRY+SB_LUT into one $__ICE40_CARRY_LUT4 box --- techlibs/ice40/abc_hx.box | 12 ++++-------- techlibs/ice40/abc_lp.box | 12 ++++-------- techlibs/ice40/abc_u.box | 14 +++++--------- 3 files changed, 13 insertions(+), 25 deletions(-) diff --git a/techlibs/ice40/abc_hx.box b/techlibs/ice40/abc_hx.box index f8e12b527..4b55297dd 100644 --- a/techlibs/ice40/abc_hx.box +++ b/techlibs/ice40/abc_hx.box @@ -3,15 +3,11 @@ # NB: Inputs/Outputs must be ordered alphabetically # (with exceptions for carry in/out) -# Inputs: I0 I1 CI -# Outputs: CO +# Inputs: A B CI +# Outputs: O CO # (NB: carry chain input/output must be last # input/output and have been moved there # overriding the alphabetical ordering) -SB_CARRY 1 1 3 1 +$__ICE40_CARRY_LUT4 1 1 3 2 +400 379 316 259 231 126 - -# Inputs: I0 I1 I2 I3 -# Outputs: O -SB_LUT4 2 1 4 1 -449 400 379 316 diff --git a/techlibs/ice40/abc_lp.box b/techlibs/ice40/abc_lp.box index fbe4c56e6..b85346370 100644 --- a/techlibs/ice40/abc_lp.box +++ b/techlibs/ice40/abc_lp.box @@ -3,15 +3,11 @@ # NB: Inputs/Outputs must be ordered alphabetically # (with exceptions for carry in/out) -# Inputs: CI I0 I1 -# Outputs: CO +# Inputs: A B CI +# Outputs: O CO # (NB: carry chain input/output must be last # input/output and have been moved there # overriding the alphabetical ordering) -SB_CARRY 1 1 3 1 +$__ICE40_CARRY_LUT4 1 1 3 2 +589 558 465 675 609 186 - -# Inputs: I0 I1 I2 I3 -# Outputs: O -SB_LUT4 2 1 4 1 -661 589 558 465 diff --git a/techlibs/ice40/abc_u.box b/techlibs/ice40/abc_u.box index f44deabc4..3a71addef 100644 --- a/techlibs/ice40/abc_u.box +++ b/techlibs/ice40/abc_u.box @@ -3,15 +3,11 @@ # NB: Inputs/Outputs must be ordered alphabetically # (with exceptions for carry in/out) -# Inputs: I0 I1 CI -# Outputs: CO +# Inputs: A B CI +# Outputs: O CO # (NB: carry chain input/output must be last # input/output and have been moved there # overriding the alphabetical ordering) -SB_CARRY 1 1 3 1 -675 609 278 - -# Inputs: I0 I1 I2 I3 -# Outputs: O -SB_LUT4 2 1 4 1 -1285 1231 1205 874 +$__ICE40_CARRY_LUT4 1 1 3 2 +1231 1205 875 +675 609 278 From c6e16e1334dcbd8bb556ab566130cc7936f06a69 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 00:51:37 -0700 Subject: [PATCH 03/43] _ABC macro will map and unmap to this new box --- techlibs/ice40/arith_map.v | 10 ++++++++++ techlibs/ice40/cells_map.v | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/techlibs/ice40/arith_map.v b/techlibs/ice40/arith_map.v index 4449fdc1b..6d45e4a6b 100644 --- a/techlibs/ice40/arith_map.v +++ b/techlibs/ice40/arith_map.v @@ -44,6 +44,15 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO); genvar i; generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice +`ifdef _ABC + \$__ICE40_CARRY_LUT4 carry ( + .A(AA[i]), + .B(BB[i]), + .CI(C[i]), + .CO(CO[i]), + .O(Y[i]) + ); +`else SB_CARRY carry ( .I0(AA[i]), .I1(BB[i]), @@ -63,6 +72,7 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO); .I3(C[i]), .O(Y[i]) ); +`endif end endgenerate assign X = AA ^ BB; diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v index 759549e30..5dca63e19 100644 --- a/techlibs/ice40/cells_map.v +++ b/techlibs/ice40/cells_map.v @@ -61,3 +61,27 @@ module \$lut (A, Y); endgenerate endmodule `endif + +`ifdef _ABC +module \$__ICE40_CARRY_LUT4 (output CO, O, input A, B, CI); + SB_CARRY carry ( + .I0(A), + .I1(B), + .CI(CI), + .CO(CO) + ); + SB_LUT4 #( + // I0: 1010 1010 1010 1010 + // I1: 1100 1100 1100 1100 + // I2: 1111 0000 1111 0000 + // I3: 1111 1111 0000 0000 + .LUT_INIT(16'b 0110_1001_1001_0110) + ) adder ( + .I0(1'b0), + .I1(A), + .I2(B), + .I3(CI), + .O(O) + ); +endmodule +`endif From a79ff2501e7b73b4af958d23d247951b107bb054 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 00:52:19 -0700 Subject: [PATCH 04/43] Add new box to cells_sim.v --- techlibs/ice40/cells_sim.v | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index b746ba4e5..cf36f5cfb 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -127,7 +127,7 @@ endmodule // SiliconBlue Logic Cells -(* abc_box_id = 2, lib_whitebox *) +(* lib_whitebox *) module SB_LUT4 (output O, input I0, I1, I2, I3); parameter [15:0] LUT_INIT = 0; wire [7:0] s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0]; @@ -136,11 +136,34 @@ module SB_LUT4 (output O, input I0, I1, I2, I3); assign O = I0 ? s1[1] : s1[0]; endmodule -(* abc_box_id = 1, abc_carry="CI,CO", lib_whitebox *) +(* lib_whitebox *) module SB_CARRY (output CO, input I0, I1, CI); assign CO = (I0 && I1) || ((I0 || I1) && CI); endmodule +(* abc_box_id = 1, abc_carry="CI,CO", lib_whitebox *) +module \$__ICE40_CARRY_LUT4 (output CO, O, input A, B, CI); + SB_CARRY carry ( + .I0(A), + .I1(B), + .CI(CI), + .CO(CO) + ); + SB_LUT4 #( + // I0: 1010 1010 1010 1010 + // I1: 1100 1100 1100 1100 + // I2: 1111 0000 1111 0000 + // I3: 1111 1111 0000 0000 + .LUT_INIT(16'b 0110_1001_1001_0110) + ) adder ( + .I0(1'b0), + .I1(A), + .I2(B), + .I3(CI), + .O(O) + ); +endmodule + // Positive Edge SiliconBlue FF Cells module SB_DFF (output `SB_DFF_REG, input C, D); From 0f5bddcd792ed2da2b9a3eb12e775537f394e771 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 00:52:31 -0700 Subject: [PATCH 05/43] ice40_opt to handle this box and opt back to SB_LUT4 --- techlibs/ice40/ice40_opt.cc | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index f528607d6..b22fc83fe 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -83,6 +83,54 @@ static void run_ice40_opts(Module *module) } continue; } + + if (cell->type == "$__ICE40_CARRY_LUT4") + { + SigSpec non_const_inputs, replacement_output; + int count_zeros = 0, count_ones = 0; + + SigBit inbit[3] = { + cell->getPort("\\A"), + cell->getPort("\\B"), + cell->getPort("\\CI") + }; + for (int i = 0; i < 3; i++) + if (inbit[i].wire == nullptr) { + if (inbit[i] == State::S1) + count_ones++; + else + count_zeros++; + } else + non_const_inputs.append(inbit[i]); + + if (count_zeros >= 2) + replacement_output = State::S0; + else if (count_ones >= 2) + replacement_output = State::S1; + else if (GetSize(non_const_inputs) == 1) + replacement_output = non_const_inputs; + + if (GetSize(replacement_output)) { + optimized_co.insert(sigmap(cell->getPort("\\CO")[0])); + module->connect(cell->getPort("\\CO")[0], replacement_output); + module->design->scratchpad_set_bool("opt.did_something", true); + log("Optimized SB_CARRY from $__ICE40_CARRY_LUT4 cell (leaving behind SB_LUT4) %s.%s: CO=%s\n", + log_id(module), log_id(cell), log_signal(replacement_output)); + cell->type = "\\SB_LUT4"; + sb_lut_cells.push_back(cell); + cell->setPort("\\I0", RTLIL::S0); + cell->setPort("\\I1", inbit[0]); + cell->setPort("\\I2", inbit[1]); + cell->setPort("\\I3", inbit[2]); + cell->unsetPort("\\A"); + cell->unsetPort("\\B"); + cell->unsetPort("\\CI"); + cell->unsetPort("\\CO"); + cell->setParam("\\LUT_INIT", std::string("0110100110010110")); + sb_lut_cells.push_back(cell); + } + continue; + } } for (auto cell : sb_lut_cells) From 62ac5ebd02e18add18a11f4c19002f4059b091b7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 00:53:01 -0700 Subject: [PATCH 06/43] Map to and from this box if -abc9 --- techlibs/ice40/synth_ice40.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 2c75215cb..59f6d1863 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -242,7 +242,7 @@ struct SynthIce40Pass : public ScriptPass { if (check_label("begin")) { - run("read_verilog -lib -D_ABC +/ice40/cells_sim.v"); + run("read_verilog -icells -lib -D_ABC +/ice40/cells_sim.v"); run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); run("proc"); } @@ -298,7 +298,7 @@ struct SynthIce40Pass : public ScriptPass if (nocarry) run("techmap"); else - run("techmap -map +/techmap.v -map +/ice40/arith_map.v"); + run("techmap -map +/techmap.v -map +/ice40/arith_map.v" + std::string(abc == "abc9" ? " -D _ABC" : "")); if (retime || help_mode) run(abc + " -dff", "(only if -retime)"); run("ice40_opt"); @@ -342,6 +342,7 @@ struct SynthIce40Pass : public ScriptPass else wire_delay = 250; run(abc + stringf(" -W %d -lut +/ice40/abc_%s.lut -box +/ice40/abc_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)"); + run("techmap -D NO_LUT -D _ABC -map +/ice40/cells_map.v"); } else run(abc + " -dress -lut 4", "(skip if -noabc)"); From 4de03bd5e6cd72b3eb2a70d5735e7526d7a6f8a8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 01:08:48 -0700 Subject: [PATCH 07/43] Remove double push --- techlibs/ice40/ice40_opt.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index b22fc83fe..4e50b250e 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -117,7 +117,6 @@ static void run_ice40_opts(Module *module) log("Optimized SB_CARRY from $__ICE40_CARRY_LUT4 cell (leaving behind SB_LUT4) %s.%s: CO=%s\n", log_id(module), log_id(cell), log_signal(replacement_output)); cell->type = "\\SB_LUT4"; - sb_lut_cells.push_back(cell); cell->setPort("\\I0", RTLIL::S0); cell->setPort("\\I1", inbit[0]); cell->setPort("\\I2", inbit[1]); From e0e5d7d68eee0d1a83b048d9d9fde94673ff5673 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 01:15:22 -0700 Subject: [PATCH 08/43] Fix spacing --- techlibs/ice40/arith_map.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/ice40/arith_map.v b/techlibs/ice40/arith_map.v index 6d45e4a6b..abba18c37 100644 --- a/techlibs/ice40/arith_map.v +++ b/techlibs/ice40/arith_map.v @@ -50,7 +50,7 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO); .B(BB[i]), .CI(C[i]), .CO(CO[i]), - .O(Y[i]) + .O(Y[i]) ); `else SB_CARRY carry ( From 28274dfb09fb48637f82949ce601a417eb3d0b82 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 01:17:53 -0700 Subject: [PATCH 09/43] Off by one --- techlibs/ice40/abc_u.box | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/ice40/abc_u.box b/techlibs/ice40/abc_u.box index 3a71addef..95c2c3d81 100644 --- a/techlibs/ice40/abc_u.box +++ b/techlibs/ice40/abc_u.box @@ -9,5 +9,5 @@ # input/output and have been moved there # overriding the alphabetical ordering) $__ICE40_CARRY_LUT4 1 1 3 2 -1231 1205 875 +1231 1205 874 675 609 278 From 7a912f22b2c3976d72a25ffd605a1cf598b67983 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 01:32:10 -0700 Subject: [PATCH 10/43] Use Const::from_string() not its constructor... --- techlibs/ice40/ice40_opt.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index 4e50b250e..67e8771b4 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -125,7 +125,7 @@ static void run_ice40_opts(Module *module) cell->unsetPort("\\B"); cell->unsetPort("\\CI"); cell->unsetPort("\\CO"); - cell->setParam("\\LUT_INIT", std::string("0110100110010110")); + cell->setParam("\\LUT_INIT", RTLIL::Const::from_string("0110100110010110")); sb_lut_cells.push_back(cell); } continue; From 7dc15bdd2dff8493ee5786845a5e39427bf3779d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 08:22:26 -0700 Subject: [PATCH 11/43] Do not double count cells in abc --- passes/techmap/abc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 15e79f9d1..65c7d1bb8 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -1172,8 +1172,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin continue; } } - - cell_stats[RTLIL::unescape_id(c->type)]++; + else + cell_stats[RTLIL::unescape_id(c->type)]++; if (c->type == "\\_const0_" || c->type == "\\_const1_") { RTLIL::SigSig conn; From 58dbb28fd3e1176d9f8a1355897cf4b56b7b46b2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 15:29:04 -0700 Subject: [PATCH 12/43] Cleanup --- passes/techmap/abc9.cc | 122 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 109 insertions(+), 13 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 5f448e37a..224a2d504 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -24,12 +24,14 @@ #if 0 // Based on &flow3 - better QoR but more experimental -#define ABC_COMMAND_LUT "&st; &ps -l; "/*"&sweep -v;"*/" &scorr; " \ - "&st; &if {W}; &save; &st; &syn2; &if {W}; &save; &load; "\ - "&st; &if -g -K 6; &dch -f; &if {W}; &save; &load; "\ - "&st; &if -g -K 6; &synch2; &if {W}; &save; &load" +#define ABC_COMMAND_LUT "&st; &ps -l; &sweep -v; &scorr; " \ + "&st; &if {W}; &save; &st; &syn2; &if {W} -v; &save; &load; "\ + "&st; &if -g -K 6; &dch -f; &if {W} -v; &save; &load; "\ + "&st; &if -g -K 6; &synch2; &if {W} -v; &save; &load; "\ + "&mfs; &ps -l" #else -#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps -l; &if {W} {D} -v; &mfs; &ps -l" +#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs -b; &ps -l" +//#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &put -v; dch -f; if {W} {D} -vo; mfs2; &get -vm; &ps -l" #endif @@ -570,13 +572,15 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri boxes.emplace_back(cell); } + std::vector> not_gates; + dict> bit2sinks; std::map cell_stats; for (auto c : mapped_mod->cells()) { RTLIL::Cell *cell = nullptr; if (c->type == "$_NOT_") { - RTLIL::SigBit a_bit = c->getPort("\\A").as_bit(); - RTLIL::SigBit y_bit = c->getPort("\\Y").as_bit(); + RTLIL::SigBit a_bit = c->getPort("\\A"); + RTLIL::SigBit y_bit = c->getPort("\\Y"); if (!a_bit.wire) { c->setPort("\\Y", module->addWire(NEW_ID)); RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name)); @@ -600,14 +604,16 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } if (!driving_lut) { - // If a driver couldn't be found (could be from PI, - // or from a box) then implement using a LUT + // If a driver couldn't be found (could be from PI or box CI) + // then implement using a LUT cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())), RTLIL::SigBit(module->wires_[remap_name(a_bit.wire->name)], a_bit.offset), RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset), - 1); + RTLIL::Const::from_string("01")); + bit2sinks[cell->getPort("\\A")].push_back(cell); } else { +#if 0 auto driver_a = driving_lut->getPort("\\A").chunks(); for (auto &chunk : driver_a) chunk.wire = module->wires_[remap_name(chunk.wire->name)]; @@ -620,6 +626,19 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri driver_a, RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset), driver_lut); +#elif 0 + cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())), + RTLIL::SigBit(module->wires_[remap_name(a_bit.wire->name)], a_bit.offset), + RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset), + RTLIL::Const::from_string("01")); + +#else + cell = module->addCell(remap_name(c->name), "$_NOT_"); + cell->setPort("\\A", RTLIL::SigBit(module->wires_[remap_name(a_bit.wire->name)], a_bit.offset)); + cell->setPort("\\Y", RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset)); + not_gates.emplace_back(cell, driving_lut); +#endif + cell_stats[RTLIL::unescape_id(c->type)]++; } } else { @@ -627,19 +646,21 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri cell->setPort("\\A", RTLIL::SigBit(module->wires_[remap_name(a_bit.wire->name)], a_bit.offset)); cell->setPort("\\Y", RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset)); cell_stats[RTLIL::unescape_id(c->type)]++; + log_abort(); } if (cell && markgroups) cell->attributes["\\abcgroup"] = map_autoidx; continue; } cell_stats[RTLIL::unescape_id(c->type)]++; - RTLIL::Cell *existing_cell = nullptr; + RTLIL::Cell *existing_cell = nullptr; if (c->type == "$lut") { - if (GetSize(c->getPort("\\A")) == 1 && c->getParam("\\LUT").as_int() == 2) { + if (GetSize(c->getPort("\\A")) == 1 && c->getParam("\\LUT") == RTLIL::Const::from_string("01")) { SigSpec my_a = module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]; SigSpec my_y = module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]; module->connect(my_y, my_a); - if (markgroups) c->attributes["\\abcgroup"] = map_autoidx; + if (markgroups) c->attributes["\\abcgroup"] = map_autoidx; + log_abort(); continue; } cell = module->addCell(remap_name(c->name), c->type); @@ -670,6 +691,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri newsig.append(c); } cell->setPort(conn.first, newsig); + + if (cell->input(conn.first)) + for (auto i : newsig) + bit2sinks[i].push_back(cell); } } @@ -725,6 +750,77 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } } + for (auto i : not_gates) { + RTLIL::Cell *not_cell = i.first; + auto driving_lut = i.second; + log_assert(driving_lut); + RTLIL::SigBit a_bit = not_cell->getPort("\\A"); + RTLIL::SigBit y_bit = not_cell->getPort("\\Y"); + driving_lut = module->cell(remap_name(driving_lut->name)); + log_assert(driving_lut); + RTLIL::Const driver_lut = driving_lut->getParam("\\LUT"); + for (auto &b : driver_lut.bits) { + if (b == RTLIL::State::S0) b = RTLIL::State::S1; + else if (b == RTLIL::State::S1) b = RTLIL::State::S0; + } + + auto it = bit2sinks.find(a_bit); + if (it == bit2sinks.end()) + goto duplicate_lut; + + for (auto sink_cell : it->second) + if (sink_cell->type != "$lut") + goto duplicate_lut; + + //static int count = 0; + //log_warning("%d\n", count); + //if (count++ >= 41) + // goto duplicate_lut; + + for (auto sink_cell : it->second) { + SigSpec A = sink_cell->getPort("\\A"); + RTLIL::Const mask = sink_cell->getParam("\\LUT"); + int index = 0; + for (; index < GetSize(A); index++) + if (A[index] == a_bit) + break; + log_assert(index < GetSize(A)); + int i = 0; + while (i < GetSize(mask)) { + for (int j = 0; j < (1 << index); j++) + std::swap(mask[i+j], mask[i+j+(1 << index)]); + i += 1 << (index+1); + } + A[index] = y_bit; + sink_cell->setPort("\\A", A); + sink_cell->setParam("\\LUT", mask); + } + + // FIXME: Since we have rewritten all sink_LUTs, + // we should be able to continue here + // and expect the $_NOT_ gate to be optimised + // away as it will have no sinks... + //continue; + +duplicate_lut: + auto not_cell_name = not_cell->name; + module->remove(not_cell); +#if 0 + auto driver_a = driving_lut->getPort("\\A").chunks(); + for (auto &chunk : driver_a) + chunk.wire = module->wires_[remap_name(chunk.wire->name)]; + module->addLut(not_cell_name, + driver_a, + y_bit, + driver_lut); +#else + module->addLut(not_cell_name, + a_bit, + y_bit, + RTLIL::Const::from_string("01")); +#endif + } + //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); log("ABC RESULTS: input signals: %8d\n", in_wires); log("ABC RESULTS: output signals: %8d\n", out_wires); From 399e1ec87033d44d8d9e55b6a15a06e4412eb81a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 15:31:02 -0700 Subject: [PATCH 13/43] Cleanup --- passes/techmap/abc9.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 224a2d504..f6592098b 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -756,7 +756,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri log_assert(driving_lut); RTLIL::SigBit a_bit = not_cell->getPort("\\A"); RTLIL::SigBit y_bit = not_cell->getPort("\\Y"); - driving_lut = module->cell(remap_name(driving_lut->name)); log_assert(driving_lut); RTLIL::Const driver_lut = driving_lut->getParam("\\LUT"); for (auto &b : driver_lut.bits) { @@ -772,11 +771,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (sink_cell->type != "$lut") goto duplicate_lut; - //static int count = 0; - //log_warning("%d\n", count); - //if (count++ >= 41) - // goto duplicate_lut; - for (auto sink_cell : it->second) { SigSpec A = sink_cell->getPort("\\A"); RTLIL::Const mask = sink_cell->getParam("\\LUT"); @@ -805,7 +799,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri duplicate_lut: auto not_cell_name = not_cell->name; module->remove(not_cell); -#if 0 +#if 1 auto driver_a = driving_lut->getPort("\\A").chunks(); for (auto &chunk : driver_a) chunk.wire = module->wires_[remap_name(chunk.wire->name)]; From 91c07be196c71cc172834dcbddd30f5944972b41 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 15:41:06 -0700 Subject: [PATCH 14/43] Cleanup --- passes/techmap/abc9.cc | 62 +++++++++++------------------------------- 1 file changed, 16 insertions(+), 46 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index f6592098b..cdad38c9e 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -572,7 +572,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri boxes.emplace_back(cell); } - std::vector> not_gates; + std::vector> push_inverters; dict> bit2sinks; std::map cell_stats; for (auto c : mapped_mod->cells()) @@ -613,32 +613,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri bit2sinks[cell->getPort("\\A")].push_back(cell); } else { -#if 0 - auto driver_a = driving_lut->getPort("\\A").chunks(); - for (auto &chunk : driver_a) - chunk.wire = module->wires_[remap_name(chunk.wire->name)]; - RTLIL::Const driver_lut = driving_lut->getParam("\\LUT"); - for (auto &b : driver_lut.bits) { - if (b == RTLIL::State::S0) b = RTLIL::State::S1; - else if (b == RTLIL::State::S1) b = RTLIL::State::S0; - } - cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())), - driver_a, - RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset), - driver_lut); -#elif 0 - cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())), - RTLIL::SigBit(module->wires_[remap_name(a_bit.wire->name)], a_bit.offset), - RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset), - RTLIL::Const::from_string("01")); - -#else - cell = module->addCell(remap_name(c->name), "$_NOT_"); - cell->setPort("\\A", RTLIL::SigBit(module->wires_[remap_name(a_bit.wire->name)], a_bit.offset)); - cell->setPort("\\Y", RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset)); - not_gates.emplace_back(cell, driving_lut); -#endif - cell_stats[RTLIL::unescape_id(c->type)]++; + push_inverters.emplace_back(c, driving_lut); + continue; } } else { @@ -649,6 +625,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri log_abort(); } if (cell && markgroups) cell->attributes["\\abcgroup"] = map_autoidx; + cell_stats[RTLIL::unescape_id(c->type)]++; continue; } cell_stats[RTLIL::unescape_id(c->type)]++; @@ -750,18 +727,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } } - for (auto i : not_gates) { + for (auto i : push_inverters) { RTLIL::Cell *not_cell = i.first; - auto driving_lut = i.second; - log_assert(driving_lut); + RTLIL::Cell *driving_lut = i.second; RTLIL::SigBit a_bit = not_cell->getPort("\\A"); RTLIL::SigBit y_bit = not_cell->getPort("\\Y"); - log_assert(driving_lut); - RTLIL::Const driver_lut = driving_lut->getParam("\\LUT"); - for (auto &b : driver_lut.bits) { - if (b == RTLIL::State::S0) b = RTLIL::State::S1; - else if (b == RTLIL::State::S1) b = RTLIL::State::S0; - } + + a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); + y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name)); auto it = bit2sinks.find(a_bit); if (it == bit2sinks.end()) @@ -797,22 +770,19 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri //continue; duplicate_lut: - auto not_cell_name = not_cell->name; - module->remove(not_cell); -#if 1 + RTLIL::Const driver_lut = driving_lut->getParam("\\LUT"); + for (auto &b : driver_lut.bits) { + if (b == RTLIL::State::S0) b = RTLIL::State::S1; + else if (b == RTLIL::State::S1) b = RTLIL::State::S0; + } auto driver_a = driving_lut->getPort("\\A").chunks(); for (auto &chunk : driver_a) chunk.wire = module->wires_[remap_name(chunk.wire->name)]; - module->addLut(not_cell_name, + module->addLut(remap_name(not_cell->name), driver_a, y_bit, driver_lut); -#else - module->addLut(not_cell_name, - a_bit, - y_bit, - RTLIL::Const::from_string("01")); -#endif + //mapped_mod->remove(not_cell); } //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); From 39a7c7c54c1845ee4d13c33745085318a9a44b96 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 15:43:39 -0700 Subject: [PATCH 15/43] More cleanup --- passes/techmap/abc9.cc | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index cdad38c9e..2b4a5cdba 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -607,8 +607,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri // If a driver couldn't be found (could be from PI or box CI) // then implement using a LUT cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())), - RTLIL::SigBit(module->wires_[remap_name(a_bit.wire->name)], a_bit.offset), - RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset), + RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset), + RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset), RTLIL::Const::from_string("01")); bit2sinks[cell->getPort("\\A")].push_back(cell); } @@ -619,8 +619,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } else { cell = module->addCell(remap_name(c->name), "$_NOT_"); - cell->setPort("\\A", RTLIL::SigBit(module->wires_[remap_name(a_bit.wire->name)], a_bit.offset)); - cell->setPort("\\Y", RTLIL::SigBit(module->wires_[remap_name(y_bit.wire->name)], y_bit.offset)); + cell->setPort("\\A", RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset)); + cell->setPort("\\Y", RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset)); cell_stats[RTLIL::unescape_id(c->type)]++; log_abort(); } @@ -633,8 +633,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::Cell *existing_cell = nullptr; if (c->type == "$lut") { if (GetSize(c->getPort("\\A")) == 1 && c->getParam("\\LUT") == RTLIL::Const::from_string("01")) { - SigSpec my_a = module->wires_[remap_name(c->getPort("\\A").as_wire()->name)]; - SigSpec my_y = module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)]; + SigSpec my_a = module->wires_.at(remap_name(c->getPort("\\A").as_wire()->name)); + SigSpec my_y = module->wires_.at(remap_name(c->getPort("\\Y").as_wire()->name)); module->connect(my_y, my_a); if (markgroups) c->attributes["\\abcgroup"] = map_autoidx; log_abort(); @@ -664,7 +664,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri continue; //log_assert(c.width == 1); if (c.wire) - c.wire = module->wires_[remap_name(c.wire->name)]; + c.wire = module->wires_.at(remap_name(c.wire->name)); newsig.append(c); } cell->setPort(conn.first, newsig); @@ -683,14 +683,14 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (!conn.first.is_fully_const()) { auto chunks = conn.first.chunks(); for (auto &c : chunks) - c.wire = module->wires_[remap_name(c.wire->name)]; + c.wire = module->wires_.at(remap_name(c.wire->name)); conn.first = std::move(chunks); } if (!conn.second.is_fully_const()) { auto chunks = conn.second.chunks(); for (auto &c : chunks) if (c.wire) - c.wire = module->wires_[remap_name(c.wire->name)]; + c.wire = module->wires_.at(remap_name(c.wire->name)); conn.second = std::move(chunks); } module->connect(conn); @@ -777,12 +777,11 @@ duplicate_lut: } auto driver_a = driving_lut->getPort("\\A").chunks(); for (auto &chunk : driver_a) - chunk.wire = module->wires_[remap_name(chunk.wire->name)]; + chunk.wire = module->wires_.at(remap_name(chunk.wire->name)); module->addLut(remap_name(not_cell->name), driver_a, y_bit, driver_lut); - //mapped_mod->remove(not_cell); } //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); From 1adbfb55338fdb29eae638f988ae361b9e401d8b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 16:01:11 -0700 Subject: [PATCH 16/43] Cleanup --- passes/techmap/abc9.cc | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 2b4a5cdba..5da5efcdc 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -588,11 +588,11 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri module->connect(RTLIL::SigBit(wire, y_bit.offset), RTLIL::S1); } else if (!lut_costs.empty() || !lut_file.empty()) { - RTLIL::Cell* driving_lut = nullptr; + RTLIL::Cell* driver_lut = nullptr; // ABC can return NOT gates that drive POs if (!a_bit.wire->port_input) { // If it's not a NOT gate that that comes from a PI directly, - // find the driving LUT and clone that to guarantee that we won't + // find the driver LUT and clone that to guarantee that we won't // increase the max logic depth // (TODO: Optimise by not cloning unless will increase depth) RTLIL::IdString driver_name; @@ -600,10 +600,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri driver_name = stringf("%s$lut", a_bit.wire->name.c_str()); else driver_name = stringf("%s[%d]$lut", a_bit.wire->name.c_str(), a_bit.offset); - driving_lut = mapped_mod->cell(driver_name); + driver_lut = mapped_mod->cell(driver_name); } - if (!driving_lut) { + if (!driver_lut) { // If a driver couldn't be found (could be from PI or box CI) // then implement using a LUT cell = module->addLut(remap_name(stringf("%s$lut", c->name.c_str())), @@ -613,7 +613,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri bit2sinks[cell->getPort("\\A")].push_back(cell); } else { - push_inverters.emplace_back(c, driving_lut); + push_inverters.emplace_back(c, driver_lut); continue; } } @@ -729,13 +729,19 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri for (auto i : push_inverters) { RTLIL::Cell *not_cell = i.first; - RTLIL::Cell *driving_lut = i.second; + RTLIL::Cell *driver_lut = i.second; RTLIL::SigBit a_bit = not_cell->getPort("\\A"); RTLIL::SigBit y_bit = not_cell->getPort("\\Y"); + RTLIL::Const driver_mask = driver_lut->getParam("\\LUT"); a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name)); + for (auto &b : driver_mask.bits) { + if (b == RTLIL::State::S0) b = RTLIL::State::S1; + else if (b == RTLIL::State::S1) b = RTLIL::State::S0; + } + auto it = bit2sinks.find(a_bit); if (it == bit2sinks.end()) goto duplicate_lut; @@ -744,6 +750,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri if (sink_cell->type != "$lut") goto duplicate_lut; + // Push downstream LUTs past inverter for (auto sink_cell : it->second) { SigSpec A = sink_cell->getPort("\\A"); RTLIL::Const mask = sink_cell->getParam("\\LUT"); @@ -763,25 +770,27 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri sink_cell->setParam("\\LUT", mask); } - // FIXME: Since we have rewritten all sink_LUTs, - // we should be able to continue here - // and expect the $_NOT_ gate to be optimised - // away as it will have no sinks... + // FIXME: Since we have rewritten all sinks + // (which we know to be only LUTs) + // to be after the inverter, we can now + // merge the inverter into the driving LUT + // and let the (now dangling) $_NOT_ cell + // from mapped_mod get cleaned away + //driver_lut->setParam("\\INIT", driver_mask); + //driver_lut->setPort("\\Y", y_bit); //continue; - duplicate_lut: - RTLIL::Const driver_lut = driving_lut->getParam("\\LUT"); - for (auto &b : driver_lut.bits) { + for (auto &b : driver_mask.bits) { if (b == RTLIL::State::S0) b = RTLIL::State::S1; else if (b == RTLIL::State::S1) b = RTLIL::State::S0; } - auto driver_a = driving_lut->getPort("\\A").chunks(); + auto driver_a = driver_lut->getPort("\\A").chunks(); for (auto &chunk : driver_a) chunk.wire = module->wires_.at(remap_name(chunk.wire->name)); module->addLut(remap_name(not_cell->name), driver_a, y_bit, - driver_lut); + driver_mask); } //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); From 83f23a24a880fb3cd40ea16b478540bdbdfe597c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 16:06:14 -0700 Subject: [PATCH 17/43] Cleanup --- passes/techmap/abc9.cc | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 5da5efcdc..867b06cbe 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -611,21 +611,15 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset), RTLIL::Const::from_string("01")); bit2sinks[cell->getPort("\\A")].push_back(cell); + cell_stats["$lut"]++; } - else { + else push_inverters.emplace_back(c, driver_lut); - continue; - } + continue; } - else { - cell = module->addCell(remap_name(c->name), "$_NOT_"); - cell->setPort("\\A", RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset)); - cell->setPort("\\Y", RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset)); - cell_stats[RTLIL::unescape_id(c->type)]++; + else log_abort(); - } if (cell && markgroups) cell->attributes["\\abcgroup"] = map_autoidx; - cell_stats[RTLIL::unescape_id(c->type)]++; continue; } cell_stats[RTLIL::unescape_id(c->type)]++; From 7d583f9e57dc3feb7e525c5ad120b1ba3959fdcd Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 19:17:32 -0700 Subject: [PATCH 18/43] Cleanup --- passes/techmap/abc9.cc | 82 ++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 30 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 867b06cbe..7b1c9f815 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -55,6 +55,7 @@ #endif #include "frontends/aiger/aigerparse.h" +#include "kernel/utils.h" #ifdef YOSYS_LINK_ABC extern "C" int Abc_RealMain(int argc, char *argv[]); @@ -572,15 +573,23 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri boxes.emplace_back(cell); } - std::vector> push_inverters; + dict> bit_drivers, bit_users; + TopoSort toposort; + dict not2drivers; dict> bit2sinks; + std::map cell_stats; for (auto c : mapped_mod->cells()) { + toposort.node(c->name); + RTLIL::Cell *cell = nullptr; if (c->type == "$_NOT_") { RTLIL::SigBit a_bit = c->getPort("\\A"); RTLIL::SigBit y_bit = c->getPort("\\Y"); + bit_users[a_bit].insert(c->name); + bit_drivers[y_bit].insert(c->name); + if (!a_bit.wire) { c->setPort("\\Y", module->addWire(NEW_ID)); RTLIL::Wire *wire = module->wire(remap_name(y_bit.wire->name)); @@ -614,7 +623,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri cell_stats["$lut"]++; } else - push_inverters.emplace_back(c, driver_lut); + not2drivers[c] = driver_lut; continue; } else @@ -663,9 +672,15 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } cell->setPort(conn.first, newsig); - if (cell->input(conn.first)) + if (cell->input(conn.first)) { for (auto i : newsig) bit2sinks[i].push_back(cell); + for (auto i : conn.second) + bit_users[i].insert(c->name); + } + if (cell->output(conn.first)) + for (auto i : conn.second) + bit_drivers[i].insert(c->name); } } @@ -721,31 +736,45 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri } } - for (auto i : push_inverters) { - RTLIL::Cell *not_cell = i.first; - RTLIL::Cell *driver_lut = i.second; + for (auto &it : bit_users) + if (bit_drivers.count(it.first)) + for (auto driver_cell : bit_drivers.at(it.first)) + for (auto user_cell : it.second) + toposort.edge(driver_cell, user_cell); + bool no_loops = toposort.sort(); + log_assert(no_loops); + + for (auto ii = toposort.sorted.rbegin(); ii != toposort.sorted.rend(); ii++) { + RTLIL::Cell *not_cell = mapped_mod->cell(*ii); + log_assert(not_cell); + if (not_cell->type != "$_NOT_") + continue; + auto it = not2drivers.find(not_cell); + if (it == not2drivers.end()) + continue; + RTLIL::Cell *driver_lut = it->second; RTLIL::SigBit a_bit = not_cell->getPort("\\A"); RTLIL::SigBit y_bit = not_cell->getPort("\\Y"); - RTLIL::Const driver_mask = driver_lut->getParam("\\LUT"); + RTLIL::Const driver_mask; + RTLIL::Wire *orig_a_bit_wire = a_bit.wire; + decltype(bit2sinks)::const_iterator jt; a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name)); - for (auto &b : driver_mask.bits) { - if (b == RTLIL::State::S0) b = RTLIL::State::S1; - else if (b == RTLIL::State::S1) b = RTLIL::State::S0; - } - - auto it = bit2sinks.find(a_bit); - if (it == bit2sinks.end()) + if (orig_a_bit_wire->port_output) goto duplicate_lut; - for (auto sink_cell : it->second) + jt = bit2sinks.find(a_bit); + if (jt == bit2sinks.end()) + goto duplicate_lut; + + for (auto sink_cell : jt->second) if (sink_cell->type != "$lut") goto duplicate_lut; // Push downstream LUTs past inverter - for (auto sink_cell : it->second) { + for (auto sink_cell : jt->second) { SigSpec A = sink_cell->getPort("\\A"); RTLIL::Const mask = sink_cell->getParam("\\LUT"); int index = 0; @@ -764,27 +793,20 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri sink_cell->setParam("\\LUT", mask); } - // FIXME: Since we have rewritten all sinks - // (which we know to be only LUTs) - // to be after the inverter, we can now - // merge the inverter into the driving LUT - // and let the (now dangling) $_NOT_ cell - // from mapped_mod get cleaned away - //driver_lut->setParam("\\INIT", driver_mask); - //driver_lut->setPort("\\Y", y_bit); - //continue; duplicate_lut: + driver_mask = driver_lut->getParam("\\LUT"); for (auto &b : driver_mask.bits) { if (b == RTLIL::State::S0) b = RTLIL::State::S1; else if (b == RTLIL::State::S1) b = RTLIL::State::S0; } - auto driver_a = driver_lut->getPort("\\A").chunks(); - for (auto &chunk : driver_a) - chunk.wire = module->wires_.at(remap_name(chunk.wire->name)); - module->addLut(remap_name(not_cell->name), - driver_a, + auto cell = module->addLut(NEW_ID, + driver_lut->getPort("\\A"), y_bit, driver_mask); + for (auto &bit : cell->connections_.at("\\A")) { + bit.wire = module->wires_.at(remap_name(bit.wire->name)); + bit2sinks[bit].push_back(cell); + } } //log("ABC RESULTS: internal signals: %8d\n", int(signal_list.size()) - in_wires - out_wires); From be0cb7f4b81af91ce47a8baf57d0aff716eecddc Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 19:21:03 -0700 Subject: [PATCH 19/43] More cleanup --- passes/techmap/abc9.cc | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 7b1c9f815..36f2fafc3 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -30,8 +30,7 @@ "&st; &if -g -K 6; &synch2; &if {W} -v; &save; &load; "\ "&mfs; &ps -l" #else -#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs -b; &ps -l" -//#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &put -v; dch -f; if {W} {D} -vo; mfs2; &get -vm; &ps -l" +#define ABC_COMMAND_LUT "&st; &scorr; &sweep; &dc2; &st; &dch -f; &ps; &if {W} {D} -v; &mfs; &ps -l" #endif @@ -756,16 +755,11 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri RTLIL::SigBit a_bit = not_cell->getPort("\\A"); RTLIL::SigBit y_bit = not_cell->getPort("\\Y"); RTLIL::Const driver_mask; - RTLIL::Wire *orig_a_bit_wire = a_bit.wire; - decltype(bit2sinks)::const_iterator jt; a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name)); - if (orig_a_bit_wire->port_output) - goto duplicate_lut; - - jt = bit2sinks.find(a_bit); + auto jt = bit2sinks.find(a_bit); if (jt == bit2sinks.end()) goto duplicate_lut; From e9bdc86c0e0ea41d1ee8a610b7f1304c3eaf43e9 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 19:33:02 -0700 Subject: [PATCH 20/43] duplicate -> clone --- passes/techmap/abc9.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 36f2fafc3..4a6ec3a47 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -761,11 +761,11 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri auto jt = bit2sinks.find(a_bit); if (jt == bit2sinks.end()) - goto duplicate_lut; + goto clone_lut; for (auto sink_cell : jt->second) if (sink_cell->type != "$lut") - goto duplicate_lut; + goto clone_lut; // Push downstream LUTs past inverter for (auto sink_cell : jt->second) { @@ -787,7 +787,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri sink_cell->setParam("\\LUT", mask); } -duplicate_lut: +clone_lut: driver_mask = driver_lut->getParam("\\LUT"); for (auto &b : driver_mask.bits) { if (b == RTLIL::State::S0) b = RTLIL::State::S1; From 41243a53b384a9ecfadd7b424c9e22c7c84fb721 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 12 Jul 2019 21:00:13 -0700 Subject: [PATCH 21/43] Update test with more accurate LUT mask --- tests/various/abc9.ys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/various/abc9.ys b/tests/various/abc9.ys index a84b637d9..5c9a4075d 100644 --- a/tests/various/abc9.ys +++ b/tests/various/abc9.ys @@ -19,6 +19,6 @@ hierarchy -top abc9_test028 proc abc9 -lut 4 -select -assert-count 1 t:$lut r:LUT=1 r:WIDTH=1 %i %i +select -assert-count 1 t:$lut r:LUT=2'b01 r:WIDTH=1 %i %i select -assert-count 1 t:unknown select -assert-none t:$lut t:unknown %% t: %D From fb062c3426e8acb5b3f54dfed7209631208fec81 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 13 Jul 2019 00:52:21 -0700 Subject: [PATCH 22/43] Add comment --- passes/techmap/abc9.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 4a6ec3a47..658bb1225 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -787,6 +787,11 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri sink_cell->setParam("\\LUT", mask); } + // Since we have rewritten all sinks (which we know + // to be only LUTs) to be after the inverter, we can + // go ahead and clone the LUT with the expectation + // that the original driving LUT will become dangling + // and get cleaned away clone_lut: driver_mask = driver_lut->getParam("\\LUT"); for (auto &b : driver_mask.bits) { From d032198facc05634bd617328e1865e7f0d8d953c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 13 Jul 2019 01:11:00 -0700 Subject: [PATCH 23/43] ice40_opt to $__ICE40_CARRY_LUT4 into $lut not SB_LUT --- techlibs/ice40/ice40_opt.cc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index 67e8771b4..38910dffa 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -114,19 +114,17 @@ static void run_ice40_opts(Module *module) optimized_co.insert(sigmap(cell->getPort("\\CO")[0])); module->connect(cell->getPort("\\CO")[0], replacement_output); module->design->scratchpad_set_bool("opt.did_something", true); - log("Optimized SB_CARRY from $__ICE40_CARRY_LUT4 cell (leaving behind SB_LUT4) %s.%s: CO=%s\n", + log("Optimized $__ICE40_CARRY_LUT4 cell into $lut (without SB_CARRY) %s.%s: CO=%s\n", log_id(module), log_id(cell), log_signal(replacement_output)); - cell->type = "\\SB_LUT4"; - cell->setPort("\\I0", RTLIL::S0); - cell->setPort("\\I1", inbit[0]); - cell->setPort("\\I2", inbit[1]); - cell->setPort("\\I3", inbit[2]); - cell->unsetPort("\\A"); + cell->type = "$lut"; + cell->setPort("\\A", { RTLIL::S0, inbit[0], inbit[1], inbit[2] }); + cell->setPort("\\Y", cell->getPort("\\O")); cell->unsetPort("\\B"); cell->unsetPort("\\CI"); cell->unsetPort("\\CO"); - cell->setParam("\\LUT_INIT", RTLIL::Const::from_string("0110100110010110")); - sb_lut_cells.push_back(cell); + cell->unsetPort("\\O"); + cell->setParam("\\LUT", RTLIL::Const::from_string("0110100110010110")); + cell->setParam("\\WIDTH", 4); } continue; } From ab3917d0791874bab845ca74203c5aaa2ec842d2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 13 Jul 2019 03:39:23 -0700 Subject: [PATCH 24/43] Error out if enable > dbits --- passes/memory/memory_bram.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/passes/memory/memory_bram.cc b/passes/memory/memory_bram.cc index ddc56d9b5..aa8f94149 100644 --- a/passes/memory/memory_bram.cc +++ b/passes/memory/memory_bram.cc @@ -68,6 +68,10 @@ struct rules_t if (groups != GetSize(transp)) log_error("Bram %s variant %d has %d groups but only %d entries in 'transp'.\n", log_id(name), variant, groups, GetSize(transp)); if (groups != GetSize(clocks)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clocks'.\n", log_id(name), variant, groups, GetSize(clocks)); if (groups != GetSize(clkpol)) log_error("Bram %s variant %d has %d groups but only %d entries in 'clkpol'.\n", log_id(name), variant, groups, GetSize(clkpol)); + + int group = 0; + for (auto e : enable) + if (e > dbits) log_error("Bram %s variant %d group %d has %d enable bits but only %d dbits.\n", log_id(name), variant, group, e, dbits); } vector make_portinfos() const From 9b91d815b55343630c3c2d4a5a7d2a593c344f07 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sat, 13 Jul 2019 04:13:57 -0700 Subject: [PATCH 25/43] If ConstEval fails do not log_abort() but return gracefully --- passes/techmap/extract_fa.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc index 9e6dc0d24..8de57e769 100644 --- a/passes/techmap/extract_fa.cc +++ b/passes/techmap/extract_fa.cc @@ -174,8 +174,10 @@ struct ExtractFaWorker SigSpec sig = root; - if (!ce.eval(sig)) - log_abort(); + if (ce.eval(sig)) { + ce.pop(); + return; + } if (sig == State::S1) func |= 1 << i; @@ -214,8 +216,10 @@ struct ExtractFaWorker SigSpec sig = root; - if (!ce.eval(sig)) - log_abort(); + if (ce.eval(sig)) { + ce.pop(); + return; + } if (sig == State::S1) func |= 1 << i; From 2de7e92bb847edef65f418c9034709649f6c1185 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sat, 13 Jul 2019 16:49:56 +0000 Subject: [PATCH 26/43] opt_lut: make less chatty. --- passes/opt/opt_lut.cc | 94 +++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 56 deletions(-) diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index 26855fd70..182f63d99 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -105,7 +105,7 @@ struct OptLutWorker SigSpec lut_input = cell->getPort("\\A"); int lut_arity = 0; - log("Found $lut\\WIDTH=%d cell %s.%s.\n", lut_width, log_id(module), log_id(cell)); + log_debug("Found $lut\\WIDTH=%d cell %s.%s.\n", lut_width, log_id(module), log_id(cell)); luts.insert(cell); // First, find all dedicated logic we're connected to. This results in an overapproximation @@ -147,15 +147,15 @@ struct OptLutWorker { if (lut_width <= dlogic_conn.first) { - log(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic->type.c_str(), log_id(module), log_id(lut_dlogic)); - log(" LUT input A[%d] not present.\n", dlogic_conn.first); + log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic->type.c_str(), log_id(module), log_id(lut_dlogic)); + log_debug(" LUT input A[%d] not present.\n", dlogic_conn.first); legal = false; break; } if (sigmap(lut_input[dlogic_conn.first]) != sigmap(lut_dlogic->getPort(dlogic_conn.second))) { - log(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic->type.c_str(), log_id(module), log_id(lut_dlogic)); - log(" LUT input A[%d] (wire %s) not connected to %s port %s (wire %s).\n", dlogic_conn.first, log_signal(lut_input[dlogic_conn.first]), lut_dlogic->type.c_str(), dlogic_conn.second.c_str(), log_signal(lut_dlogic->getPort(dlogic_conn.second))); + log_debug(" LUT has illegal connection to %s cell %s.%s.\n", lut_dlogic->type.c_str(), log_id(module), log_id(lut_dlogic)); + log_debug(" LUT input A[%d] (wire %s) not connected to %s port %s (wire %s).\n", dlogic_conn.first, log_signal(lut_input[dlogic_conn.first]), lut_dlogic->type.c_str(), dlogic_conn.second.c_str(), log_signal(lut_dlogic->getPort(dlogic_conn.second))); legal = false; break; } @@ -163,7 +163,7 @@ struct OptLutWorker if (legal) { - log(" LUT has legal connection to %s cell %s.%s.\n", lut_dlogic->type.c_str(), log_id(module), log_id(lut_dlogic)); + log_debug(" LUT has legal connection to %s cell %s.%s.\n", lut_dlogic->type.c_str(), log_id(module), log_id(lut_dlogic)); lut_legal_dlogics.insert(lut_dlogic); for (auto &dlogic_conn : dlogic_map) lut_dlogic_inputs.insert(dlogic_conn.first); @@ -179,7 +179,7 @@ struct OptLutWorker lut_arity++; } - log(" Cell implements a %d-LUT.\n", lut_arity); + log_debug(" Cell implements a %d-LUT.\n", lut_arity); luts_arity[cell] = lut_arity; luts_dlogics[cell] = lut_legal_dlogics; luts_dlogic_inputs[cell] = lut_dlogic_inputs; @@ -239,28 +239,26 @@ struct OptLutWorker if (const0_match || const1_match || input_match != -1) { - log("Found redundant cell %s.%s.\n", log_id(module), log_id(lut)); + log_debug("Found redundant cell %s.%s.\n", log_id(module), log_id(lut)); SigBit value; if (const0_match) { - log(" Cell evaluates constant 0.\n"); + log_debug(" Cell evaluates constant 0.\n"); value = State::S0; } if (const1_match) { - log(" Cell evaluates constant 1.\n"); + log_debug(" Cell evaluates constant 1.\n"); value = State::S1; } if (input_match != -1) { - log(" Cell evaluates signal %s.\n", log_signal(lut_inputs[input_match])); + log_debug(" Cell evaluates signal %s.\n", log_signal(lut_inputs[input_match])); value = lut_inputs[input_match]; } if (lut_dlogic_inputs.size()) - { - log(" Not eliminating cell (connected to dedicated logic).\n"); - } + log_debug(" Not eliminating cell (connected to dedicated logic).\n"); else { SigSpec lut_output = lut->getPort("\\Y"); @@ -323,11 +321,11 @@ struct OptLutWorker int lutB_arity = luts_arity[lutB]; pool &lutB_dlogic_inputs = luts_dlogic_inputs[lutB]; - log("Found %s.%s (cell A) feeding %s.%s (cell B).\n", log_id(module), log_id(lutA), log_id(module), log_id(lutB)); + log_debug("Found %s.%s (cell A) feeding %s.%s (cell B).\n", log_id(module), log_id(lutA), log_id(module), log_id(lutB)); if (index.query_is_output(lutA->getPort("\\Y"))) { - log(" Not combining LUTs (cascade connection feeds module output).\n"); + log_debug(" Not combining LUTs (cascade connection feeds module output).\n"); continue; } @@ -353,67 +351,51 @@ struct OptLutWorker int lutM_arity = lutA_arity + lutB_arity - 1 - common_inputs.size(); if (lutA_dlogic_inputs.size()) - log(" Cell A is a %d-LUT with %zu dedicated connections. ", lutA_arity, lutA_dlogic_inputs.size()); + log_debug(" Cell A is a %d-LUT with %zu dedicated connections. ", lutA_arity, lutA_dlogic_inputs.size()); else - log(" Cell A is a %d-LUT. ", lutA_arity); + log_debug(" Cell A is a %d-LUT. ", lutA_arity); if (lutB_dlogic_inputs.size()) - log("Cell B is a %d-LUT with %zu dedicated connections.\n", lutB_arity, lutB_dlogic_inputs.size()); + log_debug("Cell B is a %d-LUT with %zu dedicated connections.\n", lutB_arity, lutB_dlogic_inputs.size()); else - log("Cell B is a %d-LUT.\n", lutB_arity); - log(" Cells share %zu input(s) and can be merged into one %d-LUT.\n", common_inputs.size(), lutM_arity); + log_debug("Cell B is a %d-LUT.\n", lutB_arity); + log_debug(" Cells share %zu input(s) and can be merged into one %d-LUT.\n", common_inputs.size(), lutM_arity); const int COMBINE_A = 1, COMBINE_B = 2, COMBINE_EITHER = COMBINE_A | COMBINE_B; int combine_mask = 0; if (lutM_arity > lutA_width) - { - log(" Not combining LUTs into cell A (combined LUT wider than cell A).\n"); - } + log_debug(" Not combining LUTs into cell A (combined LUT wider than cell A).\n"); else if (lutB_dlogic_inputs.size() > 0) - { - log(" Not combining LUTs into cell A (cell B is connected to dedicated logic).\n"); - } + log_debug(" Not combining LUTs into cell A (cell B is connected to dedicated logic).\n"); else if (lutB->get_bool_attribute("\\lut_keep")) - { - log(" Not combining LUTs into cell A (cell B has attribute \\lut_keep).\n"); - } + log_debug(" Not combining LUTs into cell A (cell B has attribute \\lut_keep).\n"); else - { combine_mask |= COMBINE_A; - } if (lutM_arity > lutB_width) - { - log(" Not combining LUTs into cell B (combined LUT wider than cell B).\n"); - } + log_debug(" Not combining LUTs into cell B (combined LUT wider than cell B).\n"); else if (lutA_dlogic_inputs.size() > 0) - { - log(" Not combining LUTs into cell B (cell A is connected to dedicated logic).\n"); - } + log_debug(" Not combining LUTs into cell B (cell A is connected to dedicated logic).\n"); else if (lutA->get_bool_attribute("\\lut_keep")) - { - log(" Not combining LUTs into cell B (cell A has attribute \\lut_keep).\n"); - } + log_debug(" Not combining LUTs into cell B (cell A has attribute \\lut_keep).\n"); else - { combine_mask |= COMBINE_B; - } int combine = combine_mask; if (combine == COMBINE_EITHER) { - log(" Can combine into either cell.\n"); + log_debug(" Can combine into either cell.\n"); if (lutA_arity == 1) { - log(" Cell A is a buffer or inverter, combining into cell B.\n"); + log_debug(" Cell A is a buffer or inverter, combining into cell B.\n"); combine = COMBINE_B; } else if (lutB_arity == 1) { - log(" Cell B is a buffer or inverter, combining into cell A.\n"); + log_debug(" Cell B is a buffer or inverter, combining into cell A.\n"); combine = COMBINE_A; } else { - log(" Arbitrarily combining into cell A.\n"); + log_debug(" Arbitrarily combining into cell A.\n"); combine = COMBINE_A; } } @@ -423,7 +405,7 @@ struct OptLutWorker pool lutM_dlogic_inputs; if (combine == COMBINE_A) { - log(" Combining LUTs into cell A.\n"); + log_debug(" Combining LUTs into cell A.\n"); lutM = lutA; lutM_inputs = lutA_inputs; lutM_dlogic_inputs = lutA_dlogic_inputs; @@ -432,7 +414,7 @@ struct OptLutWorker } else if (combine == COMBINE_B) { - log(" Combining LUTs into cell B.\n"); + log_debug(" Combining LUTs into cell B.\n"); lutM = lutB; lutM_inputs = lutB_inputs; lutM_dlogic_inputs = lutB_dlogic_inputs; @@ -441,7 +423,7 @@ struct OptLutWorker } else { - log(" Cannot combine LUTs.\n"); + log_debug(" Cannot combine LUTs.\n"); continue; } @@ -466,17 +448,17 @@ struct OptLutWorker if (input_unused && lutR_unique.size()) { SigBit new_input = lutR_unique.pop(); - log(" Connecting input %d as %s.\n", i, log_signal(new_input)); + log_debug(" Connecting input %d as %s.\n", i, log_signal(new_input)); lutM_new_inputs.push_back(new_input); } else if (sigmap(lutM_input[i]) == lutA_output) { - log(" Disconnecting cascade input %d.\n", i); + log_debug(" Disconnecting cascade input %d.\n", i); lutM_new_inputs.push_back(SigBit()); } else { - log(" Leaving input %d as %s.\n", i, log_signal(lutM_input[i])); + log_debug(" Leaving input %d as %s.\n", i, log_signal(lutM_input[i])); lutM_new_inputs.push_back(lutM_input[i]); } } @@ -494,9 +476,9 @@ struct OptLutWorker lutM_new_table[eval] = (RTLIL::State) evaluate_lut(lutB, eval_inputs); } - log(" Cell A truth table: %s.\n", lutA->getParam("\\LUT").as_string().c_str()); - log(" Cell B truth table: %s.\n", lutB->getParam("\\LUT").as_string().c_str()); - log(" Merged truth table: %s.\n", lutM_new_table.as_string().c_str()); + log_debug(" Cell A truth table: %s.\n", lutA->getParam("\\LUT").as_string().c_str()); + log_debug(" Cell B truth table: %s.\n", lutB->getParam("\\LUT").as_string().c_str()); + log_debug(" Merged truth table: %s.\n", lutM_new_table.as_string().c_str()); lutM->setParam("\\LUT", lutM_new_table); lutM->setPort("\\A", lutM_new_inputs); From f7ab7a418cac110834fb7c8b89e29cb4d9a2a1fb Mon Sep 17 00:00:00 2001 From: Roman-Parise Date: Sun, 14 Jul 2019 09:25:07 -0700 Subject: [PATCH 27/43] Updated FreeBSD dependencies in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 42f972c8e..9e221be38 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Similarily, on Mac OS X MacPorts or Homebrew can be used to install dependencies On FreeBSD use the following command to install all prerequisites: # pkg install bison flex readline gawk libffi\ - git graphviz pkgconfig python3 python36 tcl-wrapper boost-libs + git graphviz pkgconf python3 python36 tcl-wrapper boost-libs On FreeBSD system use gmake instead of make. To run tests use: % MAKE=gmake CC=cc gmake test From 0e6c83027f24cdf7082606a5631468ad28f41574 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 15 Jul 2019 12:12:21 +0200 Subject: [PATCH 28/43] Add log_checkpoint function and use it in opt_muxtree Signed-off-by: Clifford Wolf --- kernel/log.cc | 7 +++++++ kernel/log.h | 1 + passes/opt/opt_muxtree.cc | 1 + 3 files changed, 9 insertions(+) diff --git a/kernel/log.cc b/kernel/log.cc index a7820950c..1a2c89a9c 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -420,6 +420,13 @@ void log_pop() log_flush(); } +void log_checkpoint() +{ + log_id_cache.clear(); + IdString::checkpoint(); + log_flush(); +} + #if (defined(__linux__) || defined(__FreeBSD__)) && defined(YOSYS_ENABLE_PLUGINS) void log_backtrace(const char *prefix, int levels) { diff --git a/kernel/log.h b/kernel/log.h index 3e1facae8..3328018f3 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -130,6 +130,7 @@ void log_spacer(); void log_push(); void log_pop(); +void log_checkpoint(); void log_backtrace(const char *prefix, int levels); void log_reset_stack(); void log_flush(); diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 6511e091b..79f0e9639 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -204,6 +204,7 @@ struct OptMuxtreeWorker log(" Analyzing evaluation results.\n"); log_assert(glob_abort_cnt > 0); + log_checkpoint(); for (auto &mi : mux2info) { From 44fd459c799e393d13d664102cf381264c80649f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 15 Jul 2019 17:10:42 +0200 Subject: [PATCH 29/43] Redesign log_id_cache so that it doesn't keep IdString instances referenced, fixes #1178 Signed-off-by: Clifford Wolf --- kernel/log.cc | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index 1a2c89a9c..08ebe7af7 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -61,7 +61,7 @@ int log_force_debug = 0; int log_debug_suppressed = 0; vector header_count; -pool log_id_cache; +vector log_id_cache; vector string_buf; int string_buf_index = -1; @@ -69,6 +69,13 @@ static struct timeval initial_tv = { 0, 0 }; static bool next_print_log = false; static int log_newline_count = 0; +static void log_id_cache_clear() +{ + for (auto p : log_id_cache) + free(p); + log_id_cache.clear(); +} + #if defined(_WIN32) && !defined(__MINGW32__) // this will get time information and return it in timeval, simulating gettimeofday() int gettimeofday(struct timeval *tv, struct timezone *tz) @@ -414,7 +421,7 @@ void log_push() void log_pop() { header_count.pop_back(); - log_id_cache.clear(); + log_id_cache_clear(); string_buf.clear(); string_buf_index = -1; log_flush(); @@ -422,7 +429,7 @@ void log_pop() void log_checkpoint() { - log_id_cache.clear(); + log_id_cache_clear(); IdString::checkpoint(); log_flush(); } @@ -528,7 +535,7 @@ void log_reset_stack() { while (header_count.size() > 1) header_count.pop_back(); - log_id_cache.clear(); + log_id_cache_clear(); string_buf.clear(); string_buf_index = -1; log_flush(); @@ -587,8 +594,8 @@ const char *log_const(const RTLIL::Const &value, bool autoint) const char *log_id(RTLIL::IdString str) { - log_id_cache.insert(str); - const char *p = str.c_str(); + log_id_cache.push_back(strdup(str.c_str())); + const char *p = log_id_cache.back(); if (p[0] != '\\') return p; if (p[1] == '$' || p[1] == '\\' || p[1] == 0) From 78560aac86b763306798192aa375ed04a5b192a0 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 15 Jul 2019 08:31:26 -0700 Subject: [PATCH 30/43] Revert "Fix first divergence in #1178" This reverts commit 1122a2e0671ed00b7c03658f5012e34df12f26de. --- passes/opt/wreduce.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 65068238b..1fbc41082 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -430,7 +430,6 @@ struct WreduceWorker for (auto w : module->wires()) complete_wires.insert(mi.sigmap(w)); - std::vector> swap_wire_names; for (auto w : module->selected_wires()) { int unused_top_bits = 0; @@ -455,12 +454,9 @@ struct WreduceWorker log("Removed top %d bits (of %d) from wire %s.%s.\n", unused_top_bits, GetSize(w), log_id(module), log_id(w)); Wire *nw = module->addWire(NEW_ID, GetSize(w) - unused_top_bits); module->connect(nw, SigSpec(w).extract(0, GetSize(nw))); - swap_wire_names.emplace_back(w, nw); + module->swap_names(w, nw); } - for (const auto &i : swap_wire_names) - module->swap_names(i.first, i.second); - if (!remove_init_bits.empty()) { for (auto w : module->wires()) { if (w->attributes.count("\\init")) { From ab4b9e8db481cd24b61cc0dc14bb5bf74d08006d Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Mon, 15 Jul 2019 23:33:18 +0800 Subject: [PATCH 31/43] smt: handle failure of setrlimit syscall --- backends/smt2/smtio.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index ae7968a1b..bac68ac70 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -43,7 +43,11 @@ if os.name == "posix": if current_rlimit_stack[1] != resource.RLIM_INFINITY: smtio_stacksize = min(smtio_stacksize, current_rlimit_stack[1]) if current_rlimit_stack[0] < smtio_stacksize: - resource.setrlimit(resource.RLIMIT_STACK, (smtio_stacksize, current_rlimit_stack[1])) + try: + resource.setrlimit(resource.RLIMIT_STACK, (smtio_stacksize, current_rlimit_stack[1])) + except ValueError: + # couldn't get more stack, just run with what we have + pass # currently running solvers (so we can kill them) From 06f94c92d49a82faad492026f2b0fe6cf0495fcf Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 15 Jul 2019 08:35:48 -0700 Subject: [PATCH 32/43] Revert "Add log_checkpoint function and use it in opt_muxtree" This reverts commit 0e6c83027f24cdf7082606a5631468ad28f41574. --- kernel/log.cc | 7 ------- kernel/log.h | 1 - passes/opt/opt_muxtree.cc | 1 - 3 files changed, 9 deletions(-) diff --git a/kernel/log.cc b/kernel/log.cc index 08ebe7af7..e0a60ca12 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -427,13 +427,6 @@ void log_pop() log_flush(); } -void log_checkpoint() -{ - log_id_cache_clear(); - IdString::checkpoint(); - log_flush(); -} - #if (defined(__linux__) || defined(__FreeBSD__)) && defined(YOSYS_ENABLE_PLUGINS) void log_backtrace(const char *prefix, int levels) { diff --git a/kernel/log.h b/kernel/log.h index 3328018f3..3e1facae8 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -130,7 +130,6 @@ void log_spacer(); void log_push(); void log_pop(); -void log_checkpoint(); void log_backtrace(const char *prefix, int levels); void log_reset_stack(); void log_flush(); diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 79f0e9639..6511e091b 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -204,7 +204,6 @@ struct OptMuxtreeWorker log(" Analyzing evaluation results.\n"); log_assert(glob_abort_cnt > 0); - log_checkpoint(); for (auto &mi : mux2info) { From 5fb27c071bb072644dbb38cf8a516628c2afe15b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 15 Jul 2019 12:03:51 -0700 Subject: [PATCH 33/43] $__ICE40_CARRY_LUT4 -> $__ICE40_FULL_ADDER as per @whitequark --- techlibs/ice40/abc_hx.box | 2 +- techlibs/ice40/abc_lp.box | 2 +- techlibs/ice40/abc_u.box | 2 +- techlibs/ice40/arith_map.v | 2 +- techlibs/ice40/cells_map.v | 2 +- techlibs/ice40/cells_sim.v | 2 +- techlibs/ice40/ice40_opt.cc | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/techlibs/ice40/abc_hx.box b/techlibs/ice40/abc_hx.box index 4b55297dd..c0ea742e2 100644 --- a/techlibs/ice40/abc_hx.box +++ b/techlibs/ice40/abc_hx.box @@ -8,6 +8,6 @@ # (NB: carry chain input/output must be last # input/output and have been moved there # overriding the alphabetical ordering) -$__ICE40_CARRY_LUT4 1 1 3 2 +$__ICE40_FULL_ADDER 1 1 3 2 400 379 316 259 231 126 diff --git a/techlibs/ice40/abc_lp.box b/techlibs/ice40/abc_lp.box index b85346370..d73b6d649 100644 --- a/techlibs/ice40/abc_lp.box +++ b/techlibs/ice40/abc_lp.box @@ -8,6 +8,6 @@ # (NB: carry chain input/output must be last # input/output and have been moved there # overriding the alphabetical ordering) -$__ICE40_CARRY_LUT4 1 1 3 2 +$__ICE40_FULL_ADDER 1 1 3 2 589 558 465 675 609 186 diff --git a/techlibs/ice40/abc_u.box b/techlibs/ice40/abc_u.box index 95c2c3d81..42d666051 100644 --- a/techlibs/ice40/abc_u.box +++ b/techlibs/ice40/abc_u.box @@ -8,6 +8,6 @@ # (NB: carry chain input/output must be last # input/output and have been moved there # overriding the alphabetical ordering) -$__ICE40_CARRY_LUT4 1 1 3 2 +$__ICE40_FULL_ADDER 1 1 3 2 1231 1205 874 675 609 278 diff --git a/techlibs/ice40/arith_map.v b/techlibs/ice40/arith_map.v index abba18c37..fe83a8e38 100644 --- a/techlibs/ice40/arith_map.v +++ b/techlibs/ice40/arith_map.v @@ -45,7 +45,7 @@ module _80_ice40_alu (A, B, CI, BI, X, Y, CO); genvar i; generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice `ifdef _ABC - \$__ICE40_CARRY_LUT4 carry ( + \$__ICE40_FULL_ADDER carry ( .A(AA[i]), .B(BB[i]), .CI(C[i]), diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v index 5dca63e19..b4b831165 100644 --- a/techlibs/ice40/cells_map.v +++ b/techlibs/ice40/cells_map.v @@ -63,7 +63,7 @@ endmodule `endif `ifdef _ABC -module \$__ICE40_CARRY_LUT4 (output CO, O, input A, B, CI); +module \$__ICE40_FULL_ADDER (output CO, O, input A, B, CI); SB_CARRY carry ( .I0(A), .I1(B), diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index cf36f5cfb..609facc93 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -142,7 +142,7 @@ module SB_CARRY (output CO, input I0, I1, CI); endmodule (* abc_box_id = 1, abc_carry="CI,CO", lib_whitebox *) -module \$__ICE40_CARRY_LUT4 (output CO, O, input A, B, CI); +module \$__ICE40_FULL_ADDER (output CO, O, input A, B, CI); SB_CARRY carry ( .I0(A), .I1(B), diff --git a/techlibs/ice40/ice40_opt.cc b/techlibs/ice40/ice40_opt.cc index 38910dffa..e492454fb 100644 --- a/techlibs/ice40/ice40_opt.cc +++ b/techlibs/ice40/ice40_opt.cc @@ -84,7 +84,7 @@ static void run_ice40_opts(Module *module) continue; } - if (cell->type == "$__ICE40_CARRY_LUT4") + if (cell->type == "$__ICE40_FULL_ADDER") { SigSpec non_const_inputs, replacement_output; int count_zeros = 0, count_ones = 0; @@ -114,7 +114,7 @@ static void run_ice40_opts(Module *module) optimized_co.insert(sigmap(cell->getPort("\\CO")[0])); module->connect(cell->getPort("\\CO")[0], replacement_output); module->design->scratchpad_set_bool("opt.did_something", true); - log("Optimized $__ICE40_CARRY_LUT4 cell into $lut (without SB_CARRY) %s.%s: CO=%s\n", + log("Optimized $__ICE40_FULL_ADDER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n", log_id(module), log_id(cell), log_signal(replacement_output)); cell->type = "$lut"; cell->setPort("\\A", { RTLIL::S0, inbit[0], inbit[1], inbit[2] }); From 2b469e82a78aa6bb46dbdc2ea8460e3209d5432b Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 16 Jul 2019 10:35:18 +0200 Subject: [PATCH 34/43] Fix check logic in extract_fa --- passes/techmap/extract_fa.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/techmap/extract_fa.cc b/passes/techmap/extract_fa.cc index 8de57e769..591bc43dd 100644 --- a/passes/techmap/extract_fa.cc +++ b/passes/techmap/extract_fa.cc @@ -174,7 +174,7 @@ struct ExtractFaWorker SigSpec sig = root; - if (ce.eval(sig)) { + if (!ce.eval(sig)) { ce.pop(); return; } @@ -216,7 +216,7 @@ struct ExtractFaWorker SigSpec sig = root; - if (ce.eval(sig)) { + if (!ce.eval(sig)) { ce.pop(); return; } From 6cce679b35d7eab2b620eed7b8b697d10974307a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 16 Jul 2019 11:03:30 +0200 Subject: [PATCH 35/43] Fix typo, double "of" --- frontends/liberty/liberty.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 6e3cffaca..14de95e07 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -551,7 +551,7 @@ struct LibertyFrontend : public Frontend { if (design->has(cell_name)) { Module *existing_mod = design->module(cell_name); if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute("\\blackbox")) { - log_error("Re-definition of of cell/module %s!\n", log_id(cell_name)); + log_error("Re-definition of cell/module %s!\n", log_id(cell_name)); } else if (flag_nooverwrite) { log("Ignoring re-definition of module %s.\n", log_id(cell_name)); continue; From dd10d2b00d6760f2d09f55c90591855afcae409e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 16 Jul 2019 12:11:59 -0700 Subject: [PATCH 36/43] Add tests for cmp2lut on LUT6 --- tests/lut/map_cmp.v | 47 ++++++++++++++++++++++--------------------- tests/lut/run-test.sh | 5 +++++ 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/tests/lut/map_cmp.v b/tests/lut/map_cmp.v index 5e413f894..0014eb9ac 100644 --- a/tests/lut/map_cmp.v +++ b/tests/lut/map_cmp.v @@ -1,29 +1,30 @@ module top(...); - input [3:0] a; + parameter LUT_WIDTH = 4; // Multiples of 2 only + input [LUT_WIDTH-1:0] a; - output o1_1 = 4'b1010 <= a; - output o1_2 = 4'b1010 < a; - output o1_3 = 4'b1010 >= a; - output o1_4 = 4'b1010 > a; - output o1_5 = 4'b1010 == a; - output o1_6 = 4'b1010 != a; + output o1_1 = {(LUT_WIDTH/2){2'b10}} <= a; + output o1_2 = {(LUT_WIDTH/2){2'b10}} < a; + output o1_3 = {(LUT_WIDTH/2){2'b10}} >= a; + output o1_4 = {(LUT_WIDTH/2){2'b10}} > a; + output o1_5 = {(LUT_WIDTH/2){2'b10}} == a; + output o1_6 = {(LUT_WIDTH/2){2'b10}} != a; - output o2_1 = a <= 4'b1010; - output o2_2 = a < 4'b1010; - output o2_3 = a >= 4'b1010; - output o2_4 = a > 4'b1010; - output o2_5 = a == 4'b1010; - output o2_6 = a != 4'b1010; + output o2_1 = a <= {(LUT_WIDTH/2){2'b10}}; + output o2_2 = a < {(LUT_WIDTH/2){2'b10}}; + output o2_3 = a >= {(LUT_WIDTH/2){2'b10}}; + output o2_4 = a > {(LUT_WIDTH/2){2'b10}}; + output o2_5 = a == {(LUT_WIDTH/2){2'b10}}; + output o2_6 = a != {(LUT_WIDTH/2){2'b10}}; - output o3_1 = 4'sb0101 <= $signed(a); - output o3_2 = 4'sb0101 < $signed(a); - output o3_3 = 4'sb0101 >= $signed(a); - output o3_4 = 4'sb0101 > $signed(a); - output o3_5 = 4'sb0101 == $signed(a); - output o3_6 = 4'sb0101 != $signed(a); + output o3_1 = {(LUT_WIDTH/2){2'sb01}} <= $signed(a); + output o3_2 = {(LUT_WIDTH/2){2'sb01}} < $signed(a); + output o3_3 = {(LUT_WIDTH/2){2'sb01}} >= $signed(a); + output o3_4 = {(LUT_WIDTH/2){2'sb01}} > $signed(a); + output o3_5 = {(LUT_WIDTH/2){2'sb01}} == $signed(a); + output o3_6 = {(LUT_WIDTH/2){2'sb01}} != $signed(a); - output o4_1 = $signed(a) <= 4'sb0000; - output o4_2 = $signed(a) < 4'sb0000; - output o4_3 = $signed(a) >= 4'sb0000; - output o4_4 = $signed(a) > 4'sb0000; + output o4_1 = $signed(a) <= {LUT_WIDTH{1'sb0}}; + output o4_2 = $signed(a) < {LUT_WIDTH{1'sb0}}; + output o4_3 = $signed(a) >= {LUT_WIDTH{1'sb0}}; + output o4_4 = $signed(a) > {LUT_WIDTH{1'sb0}}; endmodule diff --git a/tests/lut/run-test.sh b/tests/lut/run-test.sh index 207417fa6..f8964f146 100755 --- a/tests/lut/run-test.sh +++ b/tests/lut/run-test.sh @@ -4,3 +4,8 @@ for x in *.v; do echo "Running $x.." ../../yosys -q -s check_map.ys -l ${x%.v}.log $x done + +for x in map_cmp.v; do + echo "Running $x.." + ../../yosys -q -s check_map_lut6.ys -l ${x%.v}_lut6.log $x +done From 8a2a2cd035d5fe931899256711ed972fd1da3a3b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 16 Jul 2019 12:44:26 -0700 Subject: [PATCH 37/43] Forgot to commit --- tests/lut/check_map_lut6.ys | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tests/lut/check_map_lut6.ys diff --git a/tests/lut/check_map_lut6.ys b/tests/lut/check_map_lut6.ys new file mode 100644 index 000000000..8a32e4d10 --- /dev/null +++ b/tests/lut/check_map_lut6.ys @@ -0,0 +1,7 @@ +chparam -set LUT_WIDTH 6 top +simplemap +equiv_opt -assert techmap -D LUT_WIDTH=6 -map +/cmp2lut.v +design -load postopt +equiv_opt -assert techmap -D LUT_WIDTH=6 -map +/gate2lut.v +design -load postopt +select -assert-count 0 t:* t:$lut %d From 7a58ee78dc8bd2c257498dc947081a1bba7bb54f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 16 Jul 2019 12:45:29 -0700 Subject: [PATCH 38/43] gen_lut to return correctly sized LUT mask --- techlibs/common/cmp2lut.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/common/cmp2lut.v b/techlibs/common/cmp2lut.v index 8aa1eb957..0d0757767 100644 --- a/techlibs/common/cmp2lut.v +++ b/techlibs/common/cmp2lut.v @@ -27,7 +27,7 @@ parameter _TECHMAP_CONSTVAL_A_ = 0; parameter _TECHMAP_CONSTMSK_B_ = 0; parameter _TECHMAP_CONSTVAL_B_ = 0; -function automatic integer gen_lut; +function automatic [(1 << `LUT_WIDTH)-1:0] gen_lut; input integer width; input integer operation; input integer swap; From ba099bfe9befccc42df99d2930fdbc686152187c Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 11 Jul 2019 10:56:59 +0000 Subject: [PATCH 39/43] synth_{ice40,ecp5}: more sensible pass label naming. --- techlibs/ecp5/synth_ecp5.cc | 10 +++++++--- techlibs/ice40/synth_ice40.cc | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 9f409ca51..3d189a9f1 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -231,23 +231,27 @@ struct SynthEcp5Pass : public ScriptPass run("synth -run coarse"); } - if (!nobram && check_label("bram", "(skip if -nobram)")) + if (!nobram && check_label("map_bram", "(skip if -nobram)")) { run("memory_bram -rules +/ecp5/bram.txt"); run("techmap -map +/ecp5/brams_map.v"); } - if (!nodram && check_label("dram", "(skip if -nodram)")) + if (!nodram && check_label("map_dram", "(skip if -nodram)")) { run("memory_bram -rules +/ecp5/dram.txt"); run("techmap -map +/ecp5/drams_map.v"); } - if (check_label("fine")) + if (check_label("map_ffram")) { run("opt -fast -mux_undef -undriven -fine"); run("memory_map"); run("opt -undriven -fine"); + } + + if (check_label("map_gates")) + { if (noccu2) run("techmap"); else diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 0474e76e9..1a20f7049 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -275,14 +275,14 @@ struct SynthIce40Pass : public ScriptPass run("opt_clean"); } - if (!nobram && check_label("bram", "(skip if -nobram)")) + if (!nobram && check_label("map_bram", "(skip if -nobram)")) { run("memory_bram -rules +/ice40/brams.txt"); run("techmap -map +/ice40/brams_map.v"); run("ice40_braminit"); } - if (check_label("map")) + if (check_label("map_ffram")) { run("opt -fast -mux_undef -undriven -fine"); run("memory_map"); From 698ab9beeed7ee585117cc1e5f5126a9092942df Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 16 Jul 2019 20:44:55 +0000 Subject: [PATCH 40/43] synth_ecp5: rename dram to lutram everywhere. --- techlibs/ecp5/Makefile.inc | 4 ++-- techlibs/ecp5/{dram.txt => lutram.txt} | 0 techlibs/ecp5/{drams_map.v => lutrams_map.v} | 0 techlibs/ecp5/synth_ecp5.cc | 22 ++++++++++---------- 4 files changed, 13 insertions(+), 13 deletions(-) rename techlibs/ecp5/{dram.txt => lutram.txt} (100%) rename techlibs/ecp5/{drams_map.v => lutrams_map.v} (100%) diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc index ff39ba4fe..73e18112f 100644 --- a/techlibs/ecp5/Makefile.inc +++ b/techlibs/ecp5/Makefile.inc @@ -4,8 +4,8 @@ OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_ffinit.o $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_map.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_sim.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_bb.v)) -$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/drams_map.v)) -$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/dram.txt)) +$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/lutrams_map.v)) +$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/lutram.txt)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/brams_map.v)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/bram.txt)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/arith_map.v)) diff --git a/techlibs/ecp5/dram.txt b/techlibs/ecp5/lutram.txt similarity index 100% rename from techlibs/ecp5/dram.txt rename to techlibs/ecp5/lutram.txt diff --git a/techlibs/ecp5/drams_map.v b/techlibs/ecp5/lutrams_map.v similarity index 100% rename from techlibs/ecp5/drams_map.v rename to techlibs/ecp5/lutrams_map.v diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 3d189a9f1..143d1f95c 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -71,10 +71,10 @@ struct SynthEcp5Pass : public ScriptPass log(" do not use flipflops with CE in output netlist\n"); log("\n"); log(" -nobram\n"); - log(" do not use BRAM cells in output netlist\n"); + log(" do not use block RAM cells in output netlist\n"); log("\n"); - log(" -nodram\n"); - log(" do not use distributed RAM cells in output netlist\n"); + log(" -nolutram\n"); + log(" do not use LUT RAM cells in output netlist\n"); log("\n"); log(" -nowidelut\n"); log(" do not use PFU muxes to implement LUTs larger than LUT4s\n"); @@ -96,7 +96,7 @@ struct SynthEcp5Pass : public ScriptPass } string top_opt, blif_file, edif_file, json_file; - bool noccu2, nodffe, nobram, nodram, nowidelut, flatten, retime, abc2, abc9, vpr; + bool noccu2, nodffe, nobram, nolutram, nowidelut, flatten, retime, abc2, abc9, vpr; void clear_flags() YS_OVERRIDE { @@ -107,7 +107,7 @@ struct SynthEcp5Pass : public ScriptPass noccu2 = false; nodffe = false; nobram = false; - nodram = false; + nolutram = false; nowidelut = false; flatten = true; retime = false; @@ -172,11 +172,11 @@ struct SynthEcp5Pass : public ScriptPass nobram = true; continue; } - if (args[argidx] == "-nodram") { - nodram = true; + if (args[argidx] == "-nolutram" || /*deprecated alias*/ args[argidx] == "-nodram") { + nolutram = true; continue; } - if (args[argidx] == "-nowidelut" || args[argidx] == "-nomux") { + if (args[argidx] == "-nowidelut" || /*deprecated alias*/ args[argidx] == "-nomux") { nowidelut = true; continue; } @@ -237,10 +237,10 @@ struct SynthEcp5Pass : public ScriptPass run("techmap -map +/ecp5/brams_map.v"); } - if (!nodram && check_label("map_dram", "(skip if -nodram)")) + if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) { - run("memory_bram -rules +/ecp5/dram.txt"); - run("techmap -map +/ecp5/drams_map.v"); + run("memory_bram -rules +/ecp5/lutram.txt"); + run("techmap -map +/ecp5/lutrams_map.v"); } if (check_label("map_ffram")) From 4ff44d85a5cb63c7b3f67c2f2398e62db7f199eb Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 16 Jul 2019 20:57:05 +0000 Subject: [PATCH 41/43] write_verilog: dump zero width constants correctly. Before this commit, zero width constants were dumped as "" (empty string). Unfortunately, 1364-2005 5.2.3.3 indicates that an empty string is equivalent to "\0", and is 8 bits wide, so that's wrong. After this commit, a replication operation with a count of zero is used instead, which is explicitly permitted per 1364-2005 5.1.14, and is defined to have size zero. (Its operand has to have a non-zero size for it to be legal, though.) Fixes #948 (again). --- backends/verilog/verilog_backend.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index a020d82b6..48404b34c 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -189,7 +189,8 @@ void dump_const(std::ostream &f, const RTLIL::Const &data, int width = -1, int o if (width < 0) width = data.bits.size() - offset; if (width == 0) { - f << "\"\""; + // See IEEE 1364-2005 Clause 5.1.14. + f << "{0{1'b0}}"; return; } if (nostr) From f28e38de9994151ea4e22608441dbc9e116d7b8c Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Tue, 16 Jul 2019 23:57:15 +0200 Subject: [PATCH 42/43] ice40: Adapt the relut process passes to the new $lut <=> SB_LUT4 port map The new mapping introduced in 437fec0d88b4a2ad172edf0d1a861a38845f3b1d needed matching adaptation when converting and optimizing LUTs during the relut process Fixes #1187 (Diagnosis of the issue by @daveshah1 on IRC) Signed-off-by: Sylvain Munaut --- techlibs/ice40/ice40_unlut.cc | 6 +++--- techlibs/ice40/synth_ice40.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/techlibs/ice40/ice40_unlut.cc b/techlibs/ice40/ice40_unlut.cc index d16e6e6a3..f3f70ac1f 100644 --- a/techlibs/ice40/ice40_unlut.cc +++ b/techlibs/ice40/ice40_unlut.cc @@ -56,10 +56,10 @@ static void run_ice40_unlut(Module *module) cell->unsetParam("\\LUT_INIT"); cell->setPort("\\A", SigSpec({ - get_bit_or_zero(cell->getPort("\\I3")), - get_bit_or_zero(cell->getPort("\\I2")), + get_bit_or_zero(cell->getPort("\\I0")), get_bit_or_zero(cell->getPort("\\I1")), - get_bit_or_zero(cell->getPort("\\I0")) + get_bit_or_zero(cell->getPort("\\I2")), + get_bit_or_zero(cell->getPort("\\I3")) })); cell->setPort("\\Y", cell->getPort("\\O")[0]); cell->unsetPort("\\I0"); diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index b3d30791a..78ac5ea13 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -345,7 +345,7 @@ struct SynthIce40Pass : public ScriptPass } run("clean"); run("ice40_unlut"); - run("opt_lut -dlogic SB_CARRY:I0=1:I1=2:CI=3"); + run("opt_lut -dlogic SB_CARRY:I0=2:I1=1:CI=0"); } if (check_label("map_cells")) From 56c00e871fbb73649d3b6f7ccee31c90942a020c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 17 Jul 2019 11:49:04 +0200 Subject: [PATCH 43/43] Remove old $pmux_safe code from write_verilog Signed-off-by: Clifford Wolf --- backends/verilog/verilog_backend.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index a020d82b6..778f9b855 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -788,7 +788,7 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) return true; } - if (cell->type == "$pmux" || cell->type == "$pmux_safe") + if (cell->type == "$pmux") { int width = cell->parameters["\\WIDTH"].as_int(); int s_width = cell->getPort("\\S").size(); @@ -800,18 +800,17 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) f << stringf("%s" " input [%d:0] s;\n", indent.c_str(), s_width-1); dump_attributes(f, indent + " ", cell->attributes); - if (cell->type != "$pmux_safe" && !noattr) + if (!noattr) f << stringf("%s" " (* parallel_case *)\n", indent.c_str()); f << stringf("%s" " casez (s)", indent.c_str()); - if (cell->type != "$pmux_safe") - f << stringf(noattr ? " // synopsys parallel_case\n" : "\n"); + f << stringf(noattr ? " // synopsys parallel_case\n" : "\n"); for (int i = 0; i < s_width; i++) { f << stringf("%s" " %d'b", indent.c_str(), s_width); for (int j = s_width-1; j >= 0; j--) - f << stringf("%c", j == i ? '1' : cell->type == "$pmux_safe" ? '0' : '?'); + f << stringf("%c", j == i ? '1' : '?'); f << stringf(":\n"); f << stringf("%s" " %s = b[%d:%d];\n", indent.c_str(), func_name.c_str(), (i+1)*width-1, i*width);