From f88335a8a5284a8e69230ec20eeeca6c02b055bf Mon Sep 17 00:00:00 2001 From: Pepijn de Vos Date: Mon, 28 Oct 2019 12:49:08 +0100 Subject: [PATCH] add wide luts --- techlibs/gowin/cells_map.v | 24 +++++++++ techlibs/gowin/cells_sim.v | 35 +++++++++++++ techlibs/gowin/synth_gowin.cc | 96 ++++++++++++++++++++++------------- 3 files changed, 119 insertions(+), 36 deletions(-) diff --git a/techlibs/gowin/cells_map.v b/techlibs/gowin/cells_map.v index 425cf7f59..62cb080d9 100644 --- a/techlibs/gowin/cells_map.v +++ b/techlibs/gowin/cells_map.v @@ -101,6 +101,30 @@ module \$lut (A, Y); if (WIDTH == 4) begin LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3])); + end else + if (WIDTH == 5) begin + wire f0, f1; + \$lut #(.LUT(LUT[15: 0]), .WIDTH(4)) lut0 (.A(A[1:4]), .Y(f0)); + \$lut #(.LUT(LUT[31:16]), .WIDTH(4)) lut1 (.A(A[1:4]), .Y(f1)); + MUX2_LUT5 mux5(.I0(f0), .I1(f1), .S0(A[0]), .O(Y)); + end else + if (WIDTH == 6) begin + wire f0, f1; + \$lut #(.LUT(LUT[31: 0]), .WIDTH(5)) lut0 (.A(A[1:5]), .Y(f0)); + \$lut #(.LUT(LUT[63:32]), .WIDTH(5)) lut1 (.A(A[1:5]), .Y(f1)); + MUX2_LUT6 mux6(.I0(f0), .I1(f1), .S0(A[0]), .O(Y)); + end else + if (WIDTH == 7) begin + wire f0, f1; + \$lut #(.LUT(LUT[63: 0]), .WIDTH(6)) lut0 (.A(A[1:6]), .Y(f0)); + \$lut #(.LUT(LUT[127:64]), .WIDTH(6)) lut1 (.A(A[1:6]), .Y(f1)); + MUX2_LUT7 mux7(.I0(f0), .I1(f1), .S0(A[0]), .O(Y)); + end else + if (WIDTH == 8) begin + wire f0, f1; + \$lut #(.LUT(LUT[127: 0]), .WIDTH(7)) lut0 (.A(A[1:7]), .Y(f0)); + \$lut #(.LUT(LUT[255:128]), .WIDTH(7)) lut1 (.A(A[1:7]), .Y(f1)); + MUX2_LUT8 mux8(.I0(f0), .I1(f1), .S0(A[0]), .O(Y)); end else begin wire _TECHMAP_FAIL_ = 1; end diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index 9dac2c2c2..0fe2c8c52 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -24,6 +24,41 @@ module LUT4(output F, input I0, I1, I2, I3); assign F = I0 ? s1[1] : s1[0]; endmodule +module MUX2 (O, I0, I1, S0); + input I0,I1; + input S0; + output O; + assign O = S0 ? I1 : I0; +endmodule + +module MUX2_LUT5 (O, I0, I1, S0); + input I0,I1; + input S0; + output O; + MUX2 mux2_lut5 (O, I0, I1, S0); +endmodule + +module MUX2_LUT6 (O, I0, I1, S0); + input I0,I1; + input S0; + output O; + MUX2 mux2_lut6 (O, I0, I1, S0); +endmodule + +module MUX2_LUT7 (O, I0, I1, S0); + input I0,I1; + input S0; + output O; + MUX2 mux2_lut7 (O, I0, I1, S0); +endmodule + +module MUX2_LUT8 (O, I0, I1, S0); + input I0,I1; + input S0; + output O; + MUX2 mux2_lut8 (O, I0, I1, S0); +endmodule + module DFF (output reg Q, input CLK, D); parameter [0:0] INIT = 1'b0; initial Q = INIT; diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index e93225fab..89cbc50ab 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -1,19 +1,19 @@ /* - * yosys -- Yosys Open SYnthesis Suite + * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf + * Copyright (C) 2012 Clifford Wolf * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ @@ -31,38 +31,44 @@ struct SynthGowinPass : public ScriptPass void help() YS_OVERRIDE { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" synth_gowin [options]\n"); + log(" synth_gowin [options]\n"); log("\n"); log("This command runs synthesis for Gowin FPGAs. This work is experimental.\n"); log("\n"); - log(" -top \n"); - log(" use the specified module as top module (default='top')\n"); + log(" -top \n"); + log(" use the specified module as top module (default='top')\n"); log("\n"); - log(" -vout \n"); - log(" write the design to the specified Verilog netlist file. writing of an\n"); - log(" output file is omitted if this parameter is not specified.\n"); + log(" -vout \n"); + log(" write the design to the specified Verilog netlist file. writing of an\n"); + log(" output file is omitted if this parameter is not specified.\n"); log("\n"); - log(" -run :\n"); - log(" only run the commands between the labels (see below). an empty\n"); - log(" from label is synonymous to 'begin', and empty to label is\n"); - log(" synonymous to the end of the command list.\n"); + log(" -run :\n"); + log(" only run the commands between the labels (see below). an empty\n"); + log(" from label is synonymous to 'begin', and empty to label is\n"); + log(" synonymous to the end of the command list.\n"); log("\n"); - log(" -nodffe\n"); - log(" do not use flipflops with CE in output netlist\n"); + log(" -nodffe\n"); + 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(" -nobram\n"); + log(" do not use BRAM cells in output netlist\n"); log("\n"); - log(" -nodram\n"); - log(" do not use distributed RAM cells in output netlist\n"); + log(" -nodram\n"); + log(" do not use distributed RAM cells in output netlist\n"); log("\n"); - log(" -noflatten\n"); - log(" do not flatten design before synthesis\n"); + log(" -noflatten\n"); + log(" do not flatten design before synthesis\n"); log("\n"); - log(" -retime\n"); - log(" run 'abc' with -dff option\n"); + log(" -retime\n"); + log(" run 'abc' with -dff option\n"); + log("\n"); + log(" -nowidelut\n"); + log(" do not use muxes to implement LUTs larger than LUT4s\n"); + log("\n"); + log(" -abc9\n"); + log(" use new ABC9 flow (EXPERIMENTAL)\n"); log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); @@ -71,7 +77,7 @@ struct SynthGowinPass : public ScriptPass } string top_opt, vout_file; - bool retime, nobram, nodram, flatten, nodffe; + bool retime, nobram, nodram, flatten, nodffe, nowidelut, abc9; void clear_flags() YS_OVERRIDE { @@ -82,6 +88,8 @@ struct SynthGowinPass : public ScriptPass nobram = false; nodffe = false; nodram = false; + nowidelut = false; + abc9 = false; } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE @@ -128,6 +136,14 @@ struct SynthGowinPass : public ScriptPass flatten = false; continue; } + if (args[argidx] == "-nowidelut") { + nowidelut = true; + continue; + } + if (args[argidx] == "-abc9") { + abc9 = true; + continue; + } break; } extra_args(args, argidx, design); @@ -164,7 +180,7 @@ struct SynthGowinPass : public ScriptPass run("synth -run coarse"); } - if (!nobram && check_label("bram", "(skip if -nobram)")) + if (!nobram && check_label("bram", "(skip if -nobram)")) { run("memory_bram -rules +/gowin/bram.txt"); run("techmap -map +/gowin/brams_map.v -map +/gowin/cells_sim.v"); @@ -203,7 +219,15 @@ struct SynthGowinPass : public ScriptPass if (check_label("map_luts")) { - run("abc -lut 4"); + if (nowidelut && abc9) { + run("abc9 -lut 4"); + } else if (nowidelut && !abc9) { + run("abc -lut 4"); + } else if (!nowidelut && abc9) { + run("abc9 -lut 4:8"); + } else if (!nowidelut && !abc9) { + run("abc -lut 4:8"); + } run("clean"); } -- 2.30.2