From 218e9051bbdbbd00620a21e6918e6a4b9bc07867 Mon Sep 17 00:00:00 2001
From: Clifford Wolf <clifford@clifford.at>
Date: Wed, 20 Feb 2019 16:42:27 +0100
Subject: Add "synth_ice40 -dsp"

Signed-off-by: Clifford Wolf <clifford@clifford.at>
---
 passes/pmgen/ice40_dsp.cc     |  8 ++++----
 techlibs/ice40/synth_ice40.cc | 30 +++++++++++++++++++++++++++---
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/passes/pmgen/ice40_dsp.cc b/passes/pmgen/ice40_dsp.cc
index 8c50a9393..3e342453d 100644
--- a/passes/pmgen/ice40_dsp.cc
+++ b/passes/pmgen/ice40_dsp.cc
@@ -159,8 +159,8 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 		cell->setPort("\\ADDSUBBOT", State::S0);
 	}
 
-	cell->setPort("\\ORTSTOP", State::S0);
-	cell->setPort("\\ORTSBOT", State::S0);
+	cell->setPort("\\ORSTTOP", State::S0);
+	cell->setPort("\\ORSTBOT", State::S0);
 
 	cell->setPort("\\OHOLDTOP", State::S0);
 	cell->setPort("\\OHOLDBOT", State::S0);
@@ -181,8 +181,8 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 
 	cell->setParam("\\TOP_8x8_MULT_REG", pm.st.ffY ? State::S1 : State::S0);
 	cell->setParam("\\BOT_8x8_MULT_REG", pm.st.ffY ? State::S1 : State::S0);
-	cell->setParam("\\PIPELINE_16X16_MULT_REG1", pm.st.ffY ? State::S1 : State::S0);
-	cell->setParam("\\PIPELINE_16X16_MULT_REG2", State::S0);
+	cell->setParam("\\PIPELINE_16x16_MULT_REG1", pm.st.ffY ? State::S1 : State::S0);
+	cell->setParam("\\PIPELINE_16x16_MULT_REG2", State::S0);
 
 	cell->setParam("\\TOPOUTPUT_SELECT", Const(pm.st.ffS ? 1 : 3, 2));
 	cell->setParam("\\TOPADDSUB_LOWERINPUT", Const(2, 2));
diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc
index f900453e8..d6d047fe7 100644
--- a/techlibs/ice40/synth_ice40.cc
+++ b/techlibs/ice40/synth_ice40.cc
@@ -79,6 +79,9 @@ struct SynthIce40Pass : public ScriptPass
 		log("    -nobram\n");
 		log("        do not use SB_RAM40_4K* cells in output netlist\n");
 		log("\n");
+		log("    -dsp\n");
+		log("        use iCE40 UltraPlus DSP cells for large arithmetic\n");
+		log("\n");
 		log("    -noabc\n");
 		log("        use built-in Yosys LUT techmapping instead of abc\n");
 		log("\n");
@@ -96,7 +99,7 @@ struct SynthIce40Pass : public ScriptPass
 	}
 
 	string top_opt, blif_file, edif_file, json_file;
-	bool nocarry, nodffe, nobram, flatten, retime, relut, noabc, abc2, vpr;
+	bool nocarry, nodffe, nobram, dsp, flatten, retime, relut, noabc, abc2, vpr;
 	int min_ce_use;
 
 	void clear_flags() YS_OVERRIDE
@@ -109,6 +112,7 @@ struct SynthIce40Pass : public ScriptPass
 		nodffe = false;
 		min_ce_use = -1;
 		nobram = false;
+		dsp = false;
 		flatten = true;
 		retime = false;
 		relut = false;
@@ -181,6 +185,10 @@ struct SynthIce40Pass : public ScriptPass
 				nobram = true;
 				continue;
 			}
+			if (args[argidx] == "-dsp") {
+				dsp = true;
+				continue;
+			}
 			if (args[argidx] == "-noabc") {
 				noabc = true;
 				continue;
@@ -214,11 +222,11 @@ struct SynthIce40Pass : public ScriptPass
 		{
 			run("read_verilog -lib +/ice40/cells_sim.v");
 			run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
+			run("proc");
 		}
 
 		if (flatten && check_label("flatten", "(unless -noflatten)"))
 		{
-			run("proc");
 			run("flatten");
 			run("tribuf -logic");
 			run("deminout");
@@ -226,7 +234,23 @@ struct SynthIce40Pass : public ScriptPass
 
 		if (check_label("coarse"))
 		{
-			run("synth -lut 4 -run coarse");
+			run("opt_expr");
+			run("opt_clean");
+			run("check");
+			run("opt");
+			run("wreduce");
+			run("share");
+			run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
+			run("opt_expr");
+			run("opt_clean");
+			if (help_mode || dsp)
+				run("ice40_dsp", "(if -dsp)");
+			run("alumacc");
+			run("opt");
+			run("fsm");
+			run("opt -fast");
+			run("memory -nomap");
+			run("opt_clean");
 		}
 
 		if (!nobram && check_label("bram", "(skip if -nobram)"))
-- 
cgit v1.2.3