From 1122a2e0671ed00b7c03658f5012e34df12f26de Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 9 Jul 2019 15:49:16 -0700 Subject: [PATCH 01/51] 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/51] 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/51] _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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] $__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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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); From c78ab8ebc53bc78d5f1910e311b1e4305df4ca48 Mon Sep 17 00:00:00 2001 From: Dan Ravensloft Date: Thu, 18 Jul 2019 16:46:21 +0100 Subject: [PATCH 44/51] synth_intel: rename for consistency with #1184 Also fix a typo in the help message. --- techlibs/intel/synth_intel.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index 09c9ba3af..4f355ce88 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -62,10 +62,10 @@ struct SynthIntelPass : public ScriptPass { log(" synonymous to the end of the command list.\n"); log("\n"); log(" -noiopads\n"); - log(" do not use altsyncram cells in output netlist\n"); + log(" do not use IO pad cells in output netlist\n"); log("\n"); log(" -nobram\n"); - log(" do not use altsyncram cells in output netlist\n"); + log(" do not use block RAM cells in output netlist\n"); log("\n"); log(" -noflatten\n"); log(" do not flatten design before synthesis\n"); @@ -191,12 +191,12 @@ struct SynthIntelPass : 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 +/intel/common/brams.txt"); run("techmap -map +/intel/common/brams_map.v"); } - if (check_label("fine")) { + if (check_label("map_ffram")) { run("opt -fast -mux_undef -undriven -fine -full"); run("memory_map"); run("opt -undriven -fine"); From 060e77c09b51aabe712315d5fd655f62a765d62f Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 8 Jul 2019 12:03:00 -0700 Subject: [PATCH 45/51] intel_synth: Minor code cleanups Signed-off-by: Ben Widawsky --- techlibs/intel/synth_intel.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index 09c9ba3af..69f3b6334 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -147,8 +147,12 @@ struct SynthIntelPass : public ScriptPass { if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); - if (family_opt != "max10" && family_opt != "a10gx" && family_opt != "cyclonev" && family_opt != "cycloneiv" && - family_opt != "cycloneive" && family_opt != "cyclone10") + if (family_opt != "max10" && + family_opt != "a10gx" && + family_opt != "cyclonev" && + family_opt != "cycloneiv" && + family_opt != "cycloneive" && + family_opt != "cyclone10") log_cmd_error("Invalid or not family specified: '%s'\n", family_opt.c_str()); log_header(design, "Executing SYNTH_INTEL pass.\n"); From 809b94a67b0b666018b35536d4de327e99378a6f Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 8 Jul 2019 12:24:24 -0700 Subject: [PATCH 46/51] intel_synth: Make family explicit and match The help and code default to MAX10 for the family, however the couple of if ladders defaulted to cycloneive. Fix this inconsistency and the next patch will clean it up. Signed-off-by: Ben Widawsky --- techlibs/intel/synth_intel.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index 69f3b6334..9d5d593a4 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -176,8 +176,10 @@ struct SynthIntelPass : public ScriptPass { run("read_verilog -sv -lib +/intel/cyclone10/cells_sim.v"); else if (check_label("family") && family_opt == "cycloneiv") run("read_verilog -sv -lib +/intel/cycloneiv/cells_sim.v"); - else + else if (check_label("family") && family_opt == "cycloneive") run("read_verilog -sv -lib +/intel/cycloneive/cells_sim.v"); + else + log_cmd_error("Invalid or not family specified: '%s'\n", family_opt.c_str()); // Misc and common cells run("read_verilog -sv -lib +/intel/common/m9k_bb.v"); run("read_verilog -sv -lib +/intel/common/altpll_bb.v"); @@ -236,8 +238,10 @@ struct SynthIntelPass : public ScriptPass { run("techmap -map +/intel/cyclone10/cells_map.v"); else if (family_opt == "cycloneiv") run("techmap -map +/intel/cycloneiv/cells_map.v"); - else + else if (family_opt == "cycloneive") run("techmap -map +/intel/cycloneive/cells_map.v"); + else + log_cmd_error("Invalid or not family specified: '%s'\n", family_opt.c_str()); run("dffinit -highlow -ff dffeas q power_up"); run("clean -purge"); } From f950a7a75d4353e0e31c523365a10926bc6180af Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 8 Jul 2019 12:37:24 -0700 Subject: [PATCH 47/51] intel_synth: Small code cleanup to remove if ladder Signed-off-by: Ben Widawsky --- examples/intel/MAX10/run_max10 | 2 +- techlibs/intel/synth_intel.cc | 38 +++++++++------------------------- 2 files changed, 11 insertions(+), 29 deletions(-) diff --git a/examples/intel/MAX10/run_max10 b/examples/intel/MAX10/run_max10 index 0378e4fa7..5bf4fc141 100644 --- a/examples/intel/MAX10/run_max10 +++ b/examples/intel/MAX10/run_max10 @@ -1 +1 @@ -yosys -p "synth_intel -family max10 -top top -vqm top.vqm" top.v sevenseg.v +../../../yosys -p "synth_intel -family max10 -top top -vqm top.vqm" top.v sevenseg.v diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index 9d5d593a4..5d6254ff6 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -166,20 +166,12 @@ struct SynthIntelPass : public ScriptPass { void script() YS_OVERRIDE { if (check_label("begin")) { - if (check_label("family") && family_opt == "max10") - run("read_verilog -sv -lib +/intel/max10/cells_sim.v"); - else if (check_label("family") && family_opt == "a10gx") - run("read_verilog -sv -lib +/intel/a10gx/cells_sim.v"); - else if (check_label("family") && family_opt == "cyclonev") - run("read_verilog -sv -lib +/intel/cyclonev/cells_sim.v"); - else if (check_label("family") && family_opt == "cyclone10") - run("read_verilog -sv -lib +/intel/cyclone10/cells_sim.v"); - else if (check_label("family") && family_opt == "cycloneiv") - run("read_verilog -sv -lib +/intel/cycloneiv/cells_sim.v"); - else if (check_label("family") && family_opt == "cycloneive") - run("read_verilog -sv -lib +/intel/cycloneive/cells_sim.v"); - else - log_cmd_error("Invalid or not family specified: '%s'\n", family_opt.c_str()); + string cmd = "read_verilog -sv -lib +/intel/FAMILY/cells_sim.v"; + cmd.replace(cmd.find("FAMILY"), 6, family_opt); + + if (check_label("family")) + run(cmd); + // Misc and common cells run("read_verilog -sv -lib +/intel/common/m9k_bb.v"); run("read_verilog -sv -lib +/intel/common/altpll_bb.v"); @@ -228,20 +220,10 @@ struct SynthIntelPass : public ScriptPass { if (check_label("map_cells")) { if (!noiopads) run("iopadmap -bits -outpad $__outpad I:O -inpad $__inpad O:I", "(unless -noiopads)"); - if (family_opt == "max10") - run("techmap -map +/intel/max10/cells_map.v"); - else if (family_opt == "a10gx") - run("techmap -map +/intel/a10gx/cells_map.v"); - else if (family_opt == "cyclonev") - run("techmap -map +/intel/cyclonev/cells_map.v"); - else if (family_opt == "cyclone10") - run("techmap -map +/intel/cyclone10/cells_map.v"); - else if (family_opt == "cycloneiv") - run("techmap -map +/intel/cycloneiv/cells_map.v"); - else if (family_opt == "cycloneive") - run("techmap -map +/intel/cycloneive/cells_map.v"); - else - log_cmd_error("Invalid or not family specified: '%s'\n", family_opt.c_str()); + string cmd = "techmap -map +/intel/FAMILY/cells_map.v"; + cmd.replace(cmd.find("FAMILY"), 6, family_opt); + run(cmd); + run("dffinit -highlow -ff dffeas q power_up"); run("clean -purge"); } From 999811572a652a60003b98b120a5e2da20aad059 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 8 Jul 2019 12:41:22 -0700 Subject: [PATCH 48/51] intel_synth: Fix help message cyclonev has been a "supported" family since the initial commit. The old commit message suggested to use a10gx which is incorrect. Aside from the obvious lack of functional change due to this just being a help message, users who were previously using "a10gx" for "cyclonev" will also have no functional change by using "cyclonev" instead. Signed-off-by: Ben Widawsky --- techlibs/intel/synth_intel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index 5d6254ff6..0b44a835f 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -40,7 +40,7 @@ struct SynthIntelPass : public ScriptPass { log(" generate the synthesis netlist for the specified family.\n"); log(" MAX10 is the default target if not family argument specified.\n"); log(" For Cyclone GX devices, use cycloneiv argument; For Cyclone E, use cycloneive.\n"); - log(" Cyclone V and Arria 10 GX devices are experimental, use it with a10gx argument.\n"); + log(" Cyclone V and Arria 10 GX devices are experimental.\n"); log("\n"); log(" -top \n"); log(" use the specified module as top module (default='top')\n"); From d5b3b3bc6f9461fcdbad3dce849b4ab8988515db Mon Sep 17 00:00:00 2001 From: Dan Ravensloft Date: Thu, 18 Jul 2019 17:08:52 +0100 Subject: [PATCH 49/51] synth_intel: revert change to run_max10 --- examples/intel/MAX10/run_max10 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/intel/MAX10/run_max10 b/examples/intel/MAX10/run_max10 index 5bf4fc141..0378e4fa7 100644 --- a/examples/intel/MAX10/run_max10 +++ b/examples/intel/MAX10/run_max10 @@ -1 +1 @@ -../../../yosys -p "synth_intel -family max10 -top top -vqm top.vqm" top.v sevenseg.v +yosys -p "synth_intel -family max10 -top top -vqm top.vqm" top.v sevenseg.v From 50f5e29724bb6ea7f19279be7613ce693b7ea2da Mon Sep 17 00:00:00 2001 From: Dan Ravensloft Date: Thu, 18 Jul 2019 17:28:21 +0100 Subject: [PATCH 50/51] synth_intel: s/not family/no family/ --- techlibs/intel/synth_intel.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index 0b44a835f..9a6df8c45 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -38,7 +38,7 @@ struct SynthIntelPass : public ScriptPass { log("\n"); log(" -family < max10 | a10gx | cyclone10 | cyclonev | cycloneiv | cycloneive>\n"); log(" generate the synthesis netlist for the specified family.\n"); - log(" MAX10 is the default target if not family argument specified.\n"); + log(" MAX10 is the default target if no family argument specified.\n"); log(" For Cyclone GX devices, use cycloneiv argument; For Cyclone E, use cycloneive.\n"); log(" Cyclone V and Arria 10 GX devices are experimental.\n"); log("\n"); @@ -153,7 +153,7 @@ struct SynthIntelPass : public ScriptPass { family_opt != "cycloneiv" && family_opt != "cycloneive" && family_opt != "cyclone10") - log_cmd_error("Invalid or not family specified: '%s'\n", family_opt.c_str()); + log_cmd_error("Invalid or no family specified: '%s'\n", family_opt.c_str()); log_header(design, "Executing SYNTH_INTEL pass.\n"); log_push(); From 0c999ac2c4379273d560319d28591627de345a6a Mon Sep 17 00:00:00 2001 From: Dan Ravensloft Date: Thu, 18 Jul 2019 18:41:34 +0100 Subject: [PATCH 51/51] synth_intel: Use stringf --- techlibs/intel/synth_intel.cc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc index 9a6df8c45..58ef25e17 100644 --- a/techlibs/intel/synth_intel.cc +++ b/techlibs/intel/synth_intel.cc @@ -166,11 +166,8 @@ struct SynthIntelPass : public ScriptPass { void script() YS_OVERRIDE { if (check_label("begin")) { - string cmd = "read_verilog -sv -lib +/intel/FAMILY/cells_sim.v"; - cmd.replace(cmd.find("FAMILY"), 6, family_opt); - if (check_label("family")) - run(cmd); + run(stringf("read_verilog -sv -lib +/intel/%s/cells_sim.v", family_opt.c_str())); // Misc and common cells run("read_verilog -sv -lib +/intel/common/m9k_bb.v"); @@ -220,9 +217,7 @@ struct SynthIntelPass : public ScriptPass { if (check_label("map_cells")) { if (!noiopads) run("iopadmap -bits -outpad $__outpad I:O -inpad $__inpad O:I", "(unless -noiopads)"); - string cmd = "techmap -map +/intel/FAMILY/cells_map.v"; - cmd.replace(cmd.find("FAMILY"), 6, family_opt); - run(cmd); + run(stringf("techmap -map +/intel/%s/cells_map.v", family_opt.c_str())); run("dffinit -highlow -ff dffeas q power_up"); run("clean -purge");