aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--backends/verilog/verilog_backend.cc3
-rw-r--r--kernel/yosys.cc6
-rw-r--r--kernel/yosys.h2
-rw-r--r--passes/opt/opt_clean.cc62
-rw-r--r--techlibs/xilinx/synth_xilinx.cc14
-rw-r--r--tests/simple/dff_init.v12
6 files changed, 68 insertions, 31 deletions
diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc
index 9fd4ccbc8..827af5d85 100644
--- a/backends/verilog/verilog_backend.cc
+++ b/backends/verilog/verilog_backend.cc
@@ -1618,7 +1618,8 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module)
SigSpec sig = active_sigmap(wire);
Const val = wire->attributes.at("\\init");
for (int i = 0; i < GetSize(sig) && i < GetSize(val); i++)
- active_initdata[sig[i]] = val.bits.at(i);
+ if (val[i] == State::S0 || val[i] == State::S1)
+ active_initdata[sig[i]] = val[i];
}
if (!module->processes.empty())
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index 20d972150..377572fc2 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -151,14 +151,16 @@ void yosys_banner()
int ceil_log2(int x)
{
+#if defined(__GNUC__)
+ return x > 1 ? (8*sizeof(int)) - __builtin_clz(x-1) : 0;
+#else
if (x <= 0)
return 0;
-
for (int i = 0; i < 32; i++)
if (((x-1) >> i) == 0)
return i;
-
log_abort();
+#endif
}
std::string stringf(const char *fmt, ...)
diff --git a/kernel/yosys.h b/kernel/yosys.h
index 82eb069ab..c7b671724 100644
--- a/kernel/yosys.h
+++ b/kernel/yosys.h
@@ -244,7 +244,7 @@ extern bool memhasher_active;
inline void memhasher() { if (memhasher_active) memhasher_do(); }
void yosys_banner();
-int ceil_log2(int x);
+int ceil_log2(int x) YS_ATTRIBUTE(const);
std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2));
std::string vstringf(const char *fmt, va_list ap);
int readsome(std::istream &f, char *s, int n);
diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc
index 249939876..6ca6ac820 100644
--- a/passes/opt/opt_clean.cc
+++ b/passes/opt/opt_clean.cc
@@ -320,22 +320,32 @@ void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
if (initval.is_fully_undef())
wire->attributes.erase("\\init");
- bool delete_this_wire = false;
+ if (GetSize(wire) == 0) {
+ // delete zero-width wires
+ goto delete_this_wire;
+ } else
if (wire->port_id != 0 || wire->get_bool_attribute("\\keep") || !initval.is_fully_undef()) {
- /* do not delete anything with "keep" or module ports or initialized wires */
+ // do not delete anything with "keep" or module ports or initialized wires
} else
if (!purge_mode && check_public_name(wire->name)) {
- /* do not get rid of public names unless in purge mode */
- } else {
- if (!raw_used_signals_noaliases.check_any(s1))
- delete_this_wire = true;
- if (!used_signals_nodrivers.check_any(s2))
- delete_this_wire = true;
+ // do not get rid of public names unless in purge mode
+ } else
+ if (!raw_used_signals_noaliases.check_any(s1)) {
+ // delete wires that aren't used by anything directly
+ goto delete_this_wire;
+ } else
+ if (!used_signals_nodrivers.check_any(s2)) {
+ // delete wires that aren't used by anything indirectly, even though other wires may alias it
+ goto delete_this_wire;
}
- if (delete_this_wire) {
+ if (0)
+ {
+ delete_this_wire:
del_wires_queue.insert(wire);
- } else {
+ }
+ else
+ {
RTLIL::SigSig new_conn;
for (int i = 0; i < GetSize(s1); i++)
if (s1[i] != s2[i]) {
@@ -355,25 +365,25 @@ void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
used_signals.add(new_conn.second);
module->connect(new_conn);
}
- }
- if (!used_signals_nodrivers.check_all(s2)) {
- std::string unused_bits;
- for (int i = 0; i < GetSize(s2); i++) {
- if (s2[i].wire == NULL)
- continue;
- if (!used_signals_nodrivers.check(s2[i])) {
- if (!unused_bits.empty())
- unused_bits += " ";
- unused_bits += stringf("%d", i);
+ if (!used_signals_nodrivers.check_all(s2)) {
+ std::string unused_bits;
+ for (int i = 0; i < GetSize(s2); i++) {
+ if (s2[i].wire == NULL)
+ continue;
+ if (!used_signals_nodrivers.check(s2[i])) {
+ if (!unused_bits.empty())
+ unused_bits += " ";
+ unused_bits += stringf("%d", i);
+ }
}
- }
- if (unused_bits.empty() || wire->port_id != 0)
+ if (unused_bits.empty() || wire->port_id != 0)
+ wire->attributes.erase("\\unused_bits");
+ else
+ wire->attributes["\\unused_bits"] = RTLIL::Const(unused_bits);
+ } else {
wire->attributes.erase("\\unused_bits");
- else
- wire->attributes["\\unused_bits"] = RTLIL::Const(unused_bits);
- } else {
- wire->attributes.erase("\\unused_bits");
+ }
}
}
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index 8aa7b508e..b022972c9 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -42,6 +42,10 @@ struct SynthXilinxPass : public ScriptPass
log(" -top <module>\n");
log(" use the specified module as top module\n");
log("\n");
+ log(" -arch {xcup|xcu|xc7|xc6s}\n");
+ log(" run synthesis for the specified Xilinx architecture\n");
+ log(" default: xc7\n");
+ log("\n");
log(" -edif <file>\n");
log(" write the design to the specified edif file. writing of an output file\n");
log(" is omitted if this parameter is not specified.\n");
@@ -80,7 +84,7 @@ struct SynthXilinxPass : public ScriptPass
log("\n");
}
- std::string top_opt, edif_file, blif_file;
+ std::string top_opt, edif_file, blif_file, arch;
bool flatten, retime, vpr, nobram, nodram, nosrl;
void clear_flags() YS_OVERRIDE
@@ -94,6 +98,7 @@ struct SynthXilinxPass : public ScriptPass
nobram = false;
nodram = false;
nosrl = false;
+ arch = "xc7";
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -108,6 +113,10 @@ struct SynthXilinxPass : public ScriptPass
top_opt = "-top " + args[++argidx];
continue;
}
+ if (args[argidx] == "-arch" && argidx+1 < args.size()) {
+ arch = args[++argidx];
+ continue;
+ }
if (args[argidx] == "-edif" && argidx+1 < args.size()) {
edif_file = args[++argidx];
continue;
@@ -152,6 +161,9 @@ struct SynthXilinxPass : public ScriptPass
}
extra_args(args, argidx, design);
+ if (arch != "xcup" && arch != "xcu" && arch != "xc7" && arch != "xc6s")
+ log_cmd_error("Invalid Xilinx -arch setting: %s\n", arch.c_str());
+
if (!design->full_selection())
log_cmd_error("This command only operates on fully selected designs!\n");
diff --git a/tests/simple/dff_init.v b/tests/simple/dff_init.v
index be947042e..375ea5c4d 100644
--- a/tests/simple/dff_init.v
+++ b/tests/simple/dff_init.v
@@ -40,3 +40,15 @@ module dff1a_test(n1, n1_inv, clk);
n1 <= n1_inv;
assign n1_inv = ~n1;
endmodule
+
+module dff_test_997 (y, clk, wire4);
+// https://github.com/YosysHQ/yosys/issues/997
+ output wire [1:0] y;
+ input clk;
+ input signed wire4;
+ reg [1:0] reg10 = 0;
+ always @(posedge clk) begin
+ reg10 <= wire4;
+ end
+ assign y = reg10;
+endmodule