diff options
Diffstat (limited to 'techlibs/ice40')
-rw-r--r-- | techlibs/ice40/Makefile.inc | 6 | ||||
-rw-r--r-- | techlibs/ice40/abc_hx.box | 17 | ||||
-rw-r--r-- | techlibs/ice40/abc_hx.lut | 6 | ||||
-rw-r--r-- | techlibs/ice40/abc_lp.box | 17 | ||||
-rw-r--r-- | techlibs/ice40/abc_lp.lut | 6 | ||||
-rw-r--r-- | techlibs/ice40/abc_u.box | 17 | ||||
-rw-r--r-- | techlibs/ice40/abc_u.lut | 6 | ||||
-rw-r--r-- | techlibs/ice40/cells_map.v | 20 | ||||
-rw-r--r-- | techlibs/ice40/cells_sim.v | 2 | ||||
-rw-r--r-- | techlibs/ice40/synth_ice40.cc | 42 |
10 files changed, 125 insertions, 14 deletions
diff --git a/techlibs/ice40/Makefile.inc b/techlibs/ice40/Makefile.inc index 723b59d6f..d258d5a5d 100644 --- a/techlibs/ice40/Makefile.inc +++ b/techlibs/ice40/Makefile.inc @@ -28,6 +28,12 @@ $(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_sim.v)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/latches_map.v)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/brams.txt)) $(eval $(call add_share_file,share/ice40,techlibs/ice40/brams_map.v)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_hx.box)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_hx.lut)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_lp.box)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_lp.lut)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_u.box)) +$(eval $(call add_share_file,share/ice40,techlibs/ice40/abc_u.lut)) $(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init1.vh)) $(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init2.vh)) diff --git a/techlibs/ice40/abc_hx.box b/techlibs/ice40/abc_hx.box new file mode 100644 index 000000000..f8e12b527 --- /dev/null +++ b/techlibs/ice40/abc_hx.box @@ -0,0 +1,17 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_hx8k.txt + +# NB: Inputs/Outputs must be ordered alphabetically +# (with exceptions for carry in/out) + +# Inputs: I0 I1 CI +# Outputs: 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 +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_hx.lut b/techlibs/ice40/abc_hx.lut new file mode 100644 index 000000000..3b3bb11e2 --- /dev/null +++ b/techlibs/ice40/abc_hx.lut @@ -0,0 +1,6 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_hx8k.txt +# I3 I2 I1 I0 +1 1 316 +2 1 316 379 +3 1 316 379 400 +4 1 316 379 400 449 diff --git a/techlibs/ice40/abc_lp.box b/techlibs/ice40/abc_lp.box new file mode 100644 index 000000000..fbe4c56e6 --- /dev/null +++ b/techlibs/ice40/abc_lp.box @@ -0,0 +1,17 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_lp8k.txt + +# NB: Inputs/Outputs must be ordered alphabetically +# (with exceptions for carry in/out) + +# Inputs: CI I0 I1 +# Outputs: 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 186 + +# Inputs: I0 I1 I2 I3 +# Outputs: O +SB_LUT4 2 1 4 1 +661 589 558 465 diff --git a/techlibs/ice40/abc_lp.lut b/techlibs/ice40/abc_lp.lut new file mode 100644 index 000000000..e72f760a2 --- /dev/null +++ b/techlibs/ice40/abc_lp.lut @@ -0,0 +1,6 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_lp8k.txt +# I3 I2 I1 I0 +1 1 465 +2 1 465 558 +3 1 465 558 589 +4 1 465 558 589 661 diff --git a/techlibs/ice40/abc_u.box b/techlibs/ice40/abc_u.box new file mode 100644 index 000000000..f44deabc4 --- /dev/null +++ b/techlibs/ice40/abc_u.box @@ -0,0 +1,17 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_up5k.txt + +# NB: Inputs/Outputs must be ordered alphabetically +# (with exceptions for carry in/out) + +# Inputs: I0 I1 CI +# Outputs: 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 diff --git a/techlibs/ice40/abc_u.lut b/techlibs/ice40/abc_u.lut new file mode 100644 index 000000000..1e4fcadb6 --- /dev/null +++ b/techlibs/ice40/abc_u.lut @@ -0,0 +1,6 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_up5k.txt +# I3 I2 I1 I0 +1 1 874 +2 1 874 1205 +3 1 874 1205 1231 +4 1 874 1205 1231 1285 diff --git a/techlibs/ice40/cells_map.v b/techlibs/ice40/cells_map.v index d0ddfd02e..759549e30 100644 --- a/techlibs/ice40/cells_map.v +++ b/techlibs/ice40/cells_map.v @@ -37,20 +37,24 @@ module \$lut (A, Y); generate if (WIDTH == 1) begin - SB_LUT4 #(.LUT_INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[0]), .I1(1'b0), .I2(1'b0), .I3(1'b0)); + localparam [15:0] INIT = {{8{LUT[1]}}, {8{LUT[0]}}}; + SB_LUT4 #(.LUT_INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(1'b0), .I1(1'b0), .I2(1'b0), .I3(A[0])); end else if (WIDTH == 2) begin - SB_LUT4 #(.LUT_INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[0]), .I1(A[1]), .I2(1'b0), .I3(1'b0)); + localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[1]}}, {4{LUT[2]}}, {4{LUT[0]}}}; + SB_LUT4 #(.LUT_INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(1'b0), .I1(1'b0), .I2(A[1]), .I3(A[0])); end else if (WIDTH == 3) begin - SB_LUT4 #(.LUT_INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(1'b0)); + localparam [15:0] INIT = {{2{LUT[7]}}, {2{LUT[3]}}, {2{LUT[5]}}, {2{LUT[1]}}, {2{LUT[6]}}, {2{LUT[2]}}, {2{LUT[4]}}, {2{LUT[0]}}}; + SB_LUT4 #(.LUT_INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(1'b0), .I1(A[2]), .I2(A[1]), .I3(A[0])); end else if (WIDTH == 4) begin - SB_LUT4 #(.LUT_INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), - .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3])); + localparam [15:0] INIT = {LUT[15], LUT[7], LUT[11], LUT[3], LUT[13], LUT[5], LUT[9], LUT[1], LUT[14], LUT[6], LUT[10], LUT[2], LUT[12], LUT[4], LUT[8], LUT[0]}; + SB_LUT4 #(.LUT_INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y), + .I0(A[3]), .I1(A[2]), .I2(A[1]), .I3(A[0])); end else begin wire _TECHMAP_FAIL_ = 1; end diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index f9945b2b5..b746ba4e5 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -127,6 +127,7 @@ endmodule // SiliconBlue Logic Cells +(* abc_box_id = 2, 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]; @@ -135,6 +136,7 @@ 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 *) module SB_CARRY (output CO, input I0, I1, CI); assign CO = (I0 && I1) || ((I0 || I1) && CI); endmodule diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index bb96d66d1..9dd5d81f7 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -37,6 +37,10 @@ struct SynthIce40Pass : public ScriptPass log("\n"); log("This command runs synthesis for iCE40 FPGAs.\n"); log("\n"); + log(" -device < hx | lp | u >\n"); + log(" relevant only for '-abc9' flow, optimise timing for the specified device.\n"); + log(" default: hx\n"); + log("\n"); log(" -top <module>\n"); log(" use the specified module as top module\n"); log("\n"); @@ -92,13 +96,16 @@ struct SynthIce40Pass : public ScriptPass log(" generate an output netlist (and BLIF file) suitable for VPR\n"); log(" (this feature is experimental and incomplete)\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"); help_script(); log("\n"); } - string top_opt, blif_file, edif_file, json_file; + string top_opt, blif_file, edif_file, json_file, abc, device_opt; bool nocarry, nodffe, nobram, dsp, flatten, retime, relut, noabc, abc2, vpr; int min_ce_use; @@ -119,6 +126,8 @@ struct SynthIce40Pass : public ScriptPass noabc = false; abc2 = false; vpr = false; + abc = "abc"; + device_opt = "hx"; } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE @@ -201,12 +210,22 @@ struct SynthIce40Pass : public ScriptPass vpr = true; continue; } + if (args[argidx] == "-abc9") { + abc = "abc9"; + continue; + } + if (args[argidx] == "-device" && argidx+1 < args.size()) { + device_opt = args[++argidx]; + continue; + } break; } extra_args(args, argidx, design); if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); + if (device_opt != "hx" && device_opt != "lp" && device_opt !="u") + log_cmd_error("Invalid or no device specified: '%s'\n", device_opt.c_str()); log_header(design, "Executing SYNTH_ICE40 pass.\n"); log_push(); @@ -220,7 +239,7 @@ struct SynthIce40Pass : public ScriptPass { if (check_label("begin")) { - run("read_verilog -lib +/ice40/cells_sim.v"); + run("read_verilog -lib -D_ABC +/ice40/cells_sim.v"); run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str())); run("proc"); } @@ -277,8 +296,8 @@ struct SynthIce40Pass : public ScriptPass run("techmap"); else run("techmap -map +/techmap.v -map +/ice40/arith_map.v"); - if (retime || help_mode) - run("abc -dff", "(only if -retime)"); + if ((retime || help_mode) && abc != "abc9") + run(abc + " -dff", "(only if -retime)"); run("ice40_opt"); } @@ -302,7 +321,7 @@ struct SynthIce40Pass : public ScriptPass if (check_label("map_luts")) { if (abc2 || help_mode) { - run("abc", " (only if -abc2)"); + run(abc, " (only if -abc2)"); run("ice40_opt", "(only if -abc2)"); } run("techmap -map +/ice40/latches_map.v"); @@ -311,7 +330,18 @@ struct SynthIce40Pass : public ScriptPass run("techmap -map +/gate2lut.v -D LUT_WIDTH=4", "(only if -noabc)"); } if (!noabc) { - run("abc -dress -lut 4", "(skip if -noabc)"); + if (abc == "abc9") { + int wire_delay; + if (device_opt == "lp") + wire_delay = 400; + else if (device_opt == "u") + wire_delay = 750; + 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)"); + } + else + run(abc + " -dress -lut 4", "(skip if -noabc)"); } run("clean"); if (relut || help_mode) { |