diff options
Diffstat (limited to 'techlibs/ice40')
| -rw-r--r-- | techlibs/ice40/Makefile.inc | 6 | ||||
| -rw-r--r-- | techlibs/ice40/abc_hx.box | 113 | ||||
| -rw-r--r-- | techlibs/ice40/abc_hx.lut | 6 | ||||
| -rw-r--r-- | techlibs/ice40/abc_lp.box | 113 | ||||
| -rw-r--r-- | techlibs/ice40/abc_lp.lut | 6 | ||||
| -rw-r--r-- | techlibs/ice40/abc_u.box | 113 | ||||
| -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 | 9 | ||||
| -rw-r--r-- | techlibs/ice40/synth_ice40.cc | 35 | 
10 files changed, 412 insertions, 15 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..a0655643d --- /dev/null +++ b/techlibs/ice40/abc_hx.box @@ -0,0 +1,113 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_hx8k.txt + +# NB: Inputs/Outputs must be ordered alphabetically + +# Inputs: C D +# Outputs: Q +SB_DFF 1 0 2 1 +- - + +# Inputs: C D E +# Outputs: Q +SB_DFFE 2 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFSR 3 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFR 4 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFSS 5 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFS 6 0 3 1 +- - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFESR 7 0 4 1 +- - - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFER 8 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFESS 9 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFES 10 0 4 1 +- - - - + +# Inputs: C D +# Outputs: Q +SB_DFFN 11 0 2 1 +- - + +# Inputs: C D E +# Outputs: Q +SB_DFFNE 12 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFNSR 13 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFNR 14 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFNSS 15 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFNS 16 0 3 1 +- - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFNESR 17 0 4 1 +- - - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFNER 18 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFNESS 19 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFNES 20 0 4 1 +- - - - + +# Inputs: CI I0 I1 +# Outputs: CO +SB_CARRY 21 1 3 1 +126 259 231 + +# Inputs: I0 I1 I2 I3 +# Outputs: O +SB_LUT4 22 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..eb1cd0937 --- /dev/null +++ b/techlibs/ice40/abc_lp.box @@ -0,0 +1,113 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_lp8k.txt + +# NB: Inputs/Outputs must be ordered alphabetically + +# Inputs: C D +# Outputs: Q +SB_DFF 1 0 2 1 +- - + +# Inputs: C D E +# Outputs: Q +SB_DFFE 2 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFSR 3 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFR 4 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFSS 5 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFS 6 0 3 1 +- - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFESR 7 0 4 1 +- - - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFER 8 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFESS 9 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFES 10 0 4 1 +- - - - + +# Inputs: C D +# Outputs: Q +SB_DFFN 11 0 2 1 +- - + +# Inputs: C D E +# Outputs: Q +SB_DFFNE 12 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFNSR 13 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFNR 14 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFNSS 15 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFNS 16 0 3 1 +- - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFNESR 17 0 4 1 +- - - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFNER 18 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFNESS 19 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFNES 20 0 4 1 +- - - - + +# Inputs: CI I0 I1 +# Outputs: CO +SB_CARRY 21 1 3 1 +186 675 609 + +# Inputs: I0 I1 I2 I3 +# Outputs: O +SB_LUT4 22 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..3b5834e40 --- /dev/null +++ b/techlibs/ice40/abc_u.box @@ -0,0 +1,113 @@ +# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_up5k.txt + +# NB: Inputs/Outputs must be ordered alphabetically + +# Inputs: C D +# Outputs: Q +SB_DFF 1 0 2 1 +- - + +# Inputs: C D E +# Outputs: Q +SB_DFFE 2 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFSR 3 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFR 4 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFSS 5 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFS 6 0 3 1 +- - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFESR 7 0 4 1 +- - - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFER 8 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFESS 9 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFES 10 0 4 1 +- - - - + +# Inputs: C D +# Outputs: Q +SB_DFFN 11 0 2 1 +- - + +# Inputs: C D E +# Outputs: Q +SB_DFFNE 12 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFNSR 13 0 3 1 +- - - + +# Inputs: C D R +# Outputs: Q +SB_DFFNR 14 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFNSS 15 0 3 1 +- - - + +# Inputs: C D S +# Outputs: Q +SB_DFFNS 16 0 3 1 +- - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFNESR 17 0 4 1 +- - - - + +# Inputs: C D E R +# Outputs: Q +SB_DFFNER 18 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFNESS 19 0 4 1 +- - - - + +# Inputs: C D E S +# Outputs: Q +SB_DFFNES 20 0 4 1 +- - - - + +# Inputs: CI I0 I1 +# Outputs: CO +SB_CARRY 21 1 3 1 +278 675 609 + +# Inputs: I0 I1 I2 I3 +# Outputs: O +SB_LUT4 22 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..031afa85c 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -127,6 +127,7 @@ endmodule  // SiliconBlue Logic Cells +(* abc_box_id = 22, 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,15 +136,20 @@ module SB_LUT4 (output O, input I0, I1, I2, I3);  	assign O = I0 ? s1[1] : s1[0];  endmodule -module SB_CARRY (output CO, input I0, I1, CI); +(* abc_box_id = 21, abc_carry, lib_whitebox *) +module SB_CARRY ((* abc_carry_out *) output CO, input I0, I1, (* abc_carry_in *) input CI);  	assign CO = (I0 && I1) || ((I0 || I1) && CI);  endmodule  // Positive Edge SiliconBlue FF Cells  module SB_DFF (output `SB_DFF_REG, input C, D); +`ifndef _ABC  	always @(posedge C)  		Q <= D; +`else +    always @* Q <= D; +`endif  endmodule  module SB_DFFE (output `SB_DFF_REG, input C, E, D); @@ -890,6 +896,7 @@ module SB_WARMBOOT (  );  endmodule +(* nomem2reg *)  module SB_SPRAM256KA (  	input [13:0] ADDRESS,  	input [15:0] DATAIN, diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index bb96d66d1..d8e9786c5 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("        optimise the synthesis netlist for the specified device.\n"); +		log("        HX is the default target if no device argument specified.\n"); +		log("\n");  		log("    -top <module>\n");  		log("        use the specified module as top module\n");  		log("\n"); @@ -92,13 +96,17 @@ 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 +127,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 +211,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 +240,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 +297,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 +322,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 +331,10 @@ 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") +					run(abc + stringf(" -lut +/ice40/abc_%s.lut -box +/ice40/abc_%s.box", 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) { | 
