aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--kernel/yosys.cc4
-rw-r--r--passes/opt/wreduce.cc2
-rw-r--r--passes/techmap/muxcover.cc27
-rw-r--r--techlibs/common/synth.cc15
-rw-r--r--techlibs/intel/synth_intel.cc3
-rw-r--r--techlibs/xilinx/cells_map.v44
7 files changed, 66 insertions, 30 deletions
diff --git a/CHANGELOG b/CHANGELOG
index ae7d28236..646d63a63 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,6 +12,7 @@ Yosys 0.9 .. Yosys 0.9-dev
- Added "synth_xilinx -abc9" (experimental)
- Added "synth_ice40 -abc9" (experimental)
- Added "synth -abc9" (experimental)
+ - Added "synth -keepdc"
- Added "script -scriptwire
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index f95c0127b..a42a7c0b8 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -1273,6 +1273,10 @@ struct ScriptCmdPass : public Pass {
log("If only one label is specified (without ':') then only the block\n");
log("marked with that label (until the next label) is executed.\n");
log("\n");
+ log("In \"-scriptwire\" mode, the commands on the selected wire(s) will be executed\n");
+ log("in the scope of (and thus, relative to) the wires' owning module(s). This\n");
+ log("'-module' mode can be exited by using the 'cd' command.\n");
+ log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc
index 1fbc41082..f749c8249 100644
--- a/passes/opt/wreduce.cc
+++ b/passes/opt/wreduce.cc
@@ -497,7 +497,7 @@ struct WreducePass : public Pass {
log(" flows that use the 'memory_memx' pass.\n");
log("\n");
log(" -keepdc\n");
- log(" Do not optimize explicit don't-care values.\n");
+ log(" Do not optimize explicit don't-care values on $mux cells.\n");
log("\n");
}
void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE
diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc
index c84cfc39a..d53378a29 100644
--- a/passes/techmap/muxcover.cc
+++ b/passes/techmap/muxcover.cc
@@ -632,10 +632,15 @@ struct MuxcoverPass : public Pass {
log("Cover trees of $_MUX_ cells with $_MUX{4,8,16}_ cells\n");
log("\n");
log(" -mux4[=cost], -mux8[=cost], -mux16[=cost]\n");
- log(" Use the specified types of MUXes (with optional integer costs). If none\n");
- log(" of these options are given, the effect is the same as if all of them are.\n");
- log(" Default costs: $_MUX_ = %d, $_MUX4_ = %d,\n", COST_MUX2, COST_MUX4);
- log(" $_MUX8_ = %d, $_MUX16_ = %d\n", COST_MUX8, COST_MUX16);
+ log(" Cover $_MUX_ trees using the specified types of MUXes (with optional\n");
+ log(" integer costs). If none of these options are given, the effect is the\n");
+ log(" same as if all of them are.\n");
+ log(" Default costs: $_MUX4_ = %d, $_MUX8_ = %d, \n", COST_MUX4, COST_MUX8);
+ log(" $_MUX16_ = %d\n", COST_MUX16);
+ log("\n");
+ log(" -mux2=cost\n");
+ log(" Use the specified cost for $_MUX_ cells when making covering decisions.\n");
+ log(" Default cost: $_MUX_ = %d\n", COST_MUX2);
log("\n");
log(" -dmux=cost\n");
log(" Use the specified cost for $_MUX_ cells used in decoders.\n");
@@ -661,6 +666,7 @@ struct MuxcoverPass : public Pass {
bool nodecode = false;
bool nopartial = false;
int cost_dmux = COST_DMUX;
+ int cost_mux2 = COST_MUX2;
int cost_mux4 = COST_MUX4;
int cost_mux8 = COST_MUX8;
int cost_mux16 = COST_MUX16;
@@ -669,11 +675,15 @@ struct MuxcoverPass : public Pass {
for (argidx = 1; argidx < args.size(); argidx++)
{
const auto &arg = args[argidx];
+ if (arg.size() >= 6 && arg.substr(0,6) == "-mux2=") {
+ cost_mux2 = std::stoi(arg.substr(6));
+ continue;
+ }
if (arg.size() >= 5 && arg.substr(0,5) == "-mux4") {
use_mux4 = true;
if (arg.size() > 5) {
if (arg[5] != '=') break;
- cost_mux4 = atoi(arg.substr(6).c_str());
+ cost_mux4 = std::stoi(arg.substr(6));
}
continue;
}
@@ -681,7 +691,7 @@ struct MuxcoverPass : public Pass {
use_mux8 = true;
if (arg.size() > 5) {
if (arg[5] != '=') break;
- cost_mux8 = atoi(arg.substr(6).c_str());
+ cost_mux8 = std::stoi(arg.substr(6));
}
continue;
}
@@ -689,12 +699,12 @@ struct MuxcoverPass : public Pass {
use_mux16 = true;
if (arg.size() > 6) {
if (arg[6] != '=') break;
- cost_mux16 = atoi(arg.substr(7).c_str());
+ cost_mux16 = std::stoi(arg.substr(7));
}
continue;
}
if (arg.size() >= 6 && arg.substr(0,6) == "-dmux=") {
- cost_dmux = atoi(arg.substr(6).c_str());
+ cost_dmux = std::stoi(arg.substr(6));
continue;
}
if (arg == "-nodecode") {
@@ -722,6 +732,7 @@ struct MuxcoverPass : public Pass {
worker.use_mux8 = use_mux8;
worker.use_mux16 = use_mux16;
worker.cost_dmux = cost_dmux;
+ worker.cost_mux2 = cost_mux2;
worker.cost_mux4 = cost_mux4;
worker.cost_mux8 = cost_mux8;
worker.cost_mux16 = cost_mux16;
diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc
index 555de9fba..af70cc498 100644
--- a/techlibs/common/synth.cc
+++ b/techlibs/common/synth.cc
@@ -78,6 +78,9 @@ struct SynthPass : public ScriptPass
log(" -abc9\n");
log(" use new ABC9 flow (EXPERIMENTAL)\n");
log("\n");
+ log(" -keepdc\n");
+ log(" do not optimize explicit don't-care values on $mux cells.\n");
+ log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
@@ -85,7 +88,7 @@ struct SynthPass : public ScriptPass
}
string top_module, fsm_opts, memory_opts, abc;
- bool autotop, flatten, noalumacc, nofsm, noabc, noshare;
+ bool autotop, flatten, noalumacc, nofsm, noabc, noshare, keepdc;
int lut;
void clear_flags() YS_OVERRIDE
@@ -102,6 +105,7 @@ struct SynthPass : public ScriptPass
noabc = false;
noshare = false;
abc = "abc";
+ keepdc = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -167,6 +171,10 @@ struct SynthPass : public ScriptPass
abc = "abc9";
continue;
}
+ if (args[argidx] == "-keepdc") {
+ keepdc = true;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -211,7 +219,10 @@ struct SynthPass : public ScriptPass
run("opt_clean");
run("check");
run("opt");
- run("wreduce");
+ if (help_mode)
+ run("wreduce [-keepdc]");
+ else
+ run("wreduce" + std::string(keepdc ? " -keepdc" : ""));
run("peepopt");
run("opt_clean");
if (help_mode)
diff --git a/techlibs/intel/synth_intel.cc b/techlibs/intel/synth_intel.cc
index 639cba2c2..09c9ba3af 100644
--- a/techlibs/intel/synth_intel.cc
+++ b/techlibs/intel/synth_intel.cc
@@ -48,6 +48,8 @@ struct SynthIntelPass : public ScriptPass {
log(" -vqm <file>\n");
log(" write the design to the specified Verilog Quartus Mapping File. Writing of an\n");
log(" output file is omitted if this parameter is not specified.\n");
+ log(" Note that this backend has not been tested and is likely incompatible\n");
+ log(" with recent versions of Quartus.\n");
log("\n");
log(" -vpr <file>\n");
log(" write BLIF files for VPR flow experiments. The synthesized BLIF output file is not\n");
@@ -108,6 +110,7 @@ struct SynthIntelPass : public ScriptPass {
}
if (args[argidx] == "-vqm" && argidx + 1 < args.size()) {
vout_file = args[++argidx];
+ log_warning("The Quartus backend has not been tested recently and is likely incompatible with modern versions of Quartus.\n");
continue;
}
if (args[argidx] == "-vpr" && argidx + 1 < args.size()) {
diff --git a/techlibs/xilinx/cells_map.v b/techlibs/xilinx/cells_map.v
index 9a316fc96..89671c0fc 100644
--- a/techlibs/xilinx/cells_map.v
+++ b/techlibs/xilinx/cells_map.v
@@ -56,7 +56,6 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o
localparam [DEPTH-1:0] INIT_R = brev(INIT);
parameter _TECHMAP_CONSTMSK_L_ = 0;
- parameter _TECHMAP_CONSTVAL_L_ = 0;
wire CE;
generate
@@ -129,26 +128,33 @@ module \$__XILINX_SHREG_ (input C, input D, input [31:0] L, input E, output Q, o
MUXF8 fpga_mux_2 (.O(Q), .I0(T7), .I1(T8), .S(L[6]));
end
end
- else if (DEPTH <= 129 && ~&_TECHMAP_CONSTMSK_L_) begin
- // Handle cases where fixed-length depth is
- // just 1 over a convenient value
- \$__XILINX_SHREG_ #(.DEPTH(DEPTH+1), .INIT({INIT,1'b0}), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) _TECHMAP_REPLACE_ (.C(C), .D(D), .L(L), .E(E), .Q(Q));
+ // For fixed length, if just 1 over a convenient value, decompose
+ else if (DEPTH <= 129 && &_TECHMAP_CONSTMSK_L_) begin
+ wire T;
+ \$__XILINX_SHREG_ #(.DEPTH(DEPTH-1), .INIT(INIT[DEPTH-1:1]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl (.C(C), .D(D), .L({32{1'b1}}), .E(E), .Q(T));
+ \$__XILINX_SHREG_ #(.DEPTH(1), .INIT(INIT[0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_last (.C(C), .D(T), .L(L), .E(E), .Q(Q));
end
+ // For variable length, if just 1 over a convenient value, then bump up one more
+ else if (DEPTH < 129 && ~&_TECHMAP_CONSTMSK_L_)
+ \$__XILINX_SHREG_ #(.DEPTH(DEPTH+1), .INIT({INIT,1'b0}), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) _TECHMAP_REPLACE_ (.C(C), .D(D), .L(L), .E(E), .Q(Q));
else begin
- localparam lower_clog2 = $clog2((DEPTH+1)/2);
- localparam lower_depth = 2 ** lower_clog2;
- wire T0, T1, T2, T3;
- if (&_TECHMAP_CONSTMSK_L_) begin
- \$__XILINX_SHREG_ #(.DEPTH(lower_depth), .INIT(INIT[DEPTH-1:DEPTH-lower_depth]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_0 (.C(C), .D(D), .L(lower_depth-1), .E(E), .Q(T0));
- \$__XILINX_SHREG_ #(.DEPTH(DEPTH-lower_depth), .INIT(INIT[DEPTH-lower_depth-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_1 (.C(C), .D(T0), .L(DEPTH-lower_depth-1), .E(E), .Q(Q), .SO(T3));
- end
- else begin
- \$__XILINX_SHREG_ #(.DEPTH(lower_depth), .INIT(INIT[DEPTH-1:DEPTH-lower_depth]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_0 (.C(C), .D(D), .L(L[lower_clog2-1:0]), .E(E), .Q(T0), .SO(T1));
- \$__XILINX_SHREG_ #(.DEPTH(DEPTH-lower_depth), .INIT(INIT[DEPTH-lower_depth-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_1 (.C(C), .D(T1), .L(L[lower_clog2-1:0]), .E(E), .Q(T2), .SO(T3));
- assign Q = L[lower_clog2] ? T2 : T0;
- end
- if (DEPTH == 2 * lower_depth)
- assign SO = T3;
+ localparam depth0 = 128;
+ localparam num_srl128 = DEPTH / depth0;
+ localparam depthN = DEPTH % depth0;
+ wire [num_srl128 + (depthN > 0 ? 1 : 0) - 1:0] T;
+ wire [num_srl128 + (depthN > 0 ? 1 : 0) :0] S;
+ assign S[0] = D;
+ genvar i;
+ for (i = 0; i < num_srl128; i++)
+ \$__XILINX_SHREG_ #(.DEPTH(depth0), .INIT(INIT[DEPTH-1-i*depth0-:depth0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl (.C(C), .D(S[i]), .L(L[$clog2(depth0)-1:0]), .E(E), .Q(T[i]), .SO(S[i+1]));
+
+ if (depthN > 0)
+ \$__XILINX_SHREG_ #(.DEPTH(depthN), .INIT(INIT[depthN-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_last (.C(C), .D(S[num_srl128]), .L(L[$clog2(depth0)-1:0]), .E(E), .Q(T[num_srl128]));
+
+ if (&_TECHMAP_CONSTMSK_L_)
+ assign Q = T[num_srl128 + (depthN > 0 ? 1 : 0) - 1];
+ else
+ assign Q = T[L[DEPTH-1:$clog2(depth0)]];
end
endgenerate
endmodule