aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile11
-rw-r--r--backends/firrtl/firrtl.cc352
-rw-r--r--backends/verilog/verilog_backend.cc32
-rw-r--r--frontends/rtlil/rtlil_lexer.l1
-rw-r--r--frontends/verific/verific.cc2
-rw-r--r--frontends/verilog/preproc.cc1
-rw-r--r--frontends/verilog/verilog_frontend.cc3
-rw-r--r--kernel/driver.cc2
-rw-r--r--passes/cmds/check.cc77
-rw-r--r--passes/sat/sim.cc4
-rw-r--r--techlibs/gowin/synth_gowin.cc35
-rw-r--r--tests/various/dynamic_part_select.ys76
-rw-r--r--tests/various/dynamic_part_select/forloop_select.v16
-rw-r--r--tests/various/dynamic_part_select/forloop_select_gate.v9
-rw-r--r--tests/various/dynamic_part_select/latch_002.v13
-rw-r--r--tests/various/dynamic_part_select/latch_002_gate.v18
-rw-r--r--tests/various/dynamic_part_select/latch_002_gate_good.v141
-rw-r--r--tests/various/dynamic_part_select/latch_1990.v12
-rw-r--r--tests/various/dynamic_part_select/latch_1990_gate.v6
-rw-r--r--tests/various/dynamic_part_select/multiple_blocking.v9
-rw-r--r--tests/various/dynamic_part_select/multiple_blocking_gate.v9
-rw-r--r--tests/various/dynamic_part_select/nonblocking.v9
-rw-r--r--tests/various/dynamic_part_select/nonblocking_gate.v9
-rw-r--r--tests/various/dynamic_part_select/original.v9
-rw-r--r--tests/various/dynamic_part_select/original_gate.v9
-rw-r--r--tests/various/dynamic_part_select/reset_test.v12
-rw-r--r--tests/various/dynamic_part_select/reset_test_gate.v12
-rw-r--r--tests/various/dynamic_part_select/reversed.v9
-rw-r--r--tests/various/dynamic_part_select/reversed_gate.v9
29 files changed, 746 insertions, 161 deletions
diff --git a/Makefile b/Makefile
index 01060dedf..c561b0c72 100644
--- a/Makefile
+++ b/Makefile
@@ -31,6 +31,8 @@ ENABLE_GPROF := 0
ENABLE_DEBUG := 0
ENABLE_NDEBUG := 0
ENABLE_CCACHE := 0
+# sccache is not always a drop-in replacement for ccache in practice
+ENABLE_SCCACHE := 0
LINK_CURSES := 0
LINK_TERMCAP := 0
LINK_ABC := 0
@@ -123,7 +125,7 @@ LDFLAGS += -rdynamic
LDLIBS += -lrt
endif
-YOSYS_VER := 0.9+3686
+YOSYS_VER := 0.9+3715
GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN)
OBJS = kernel/version_$(GIT_REV).o
@@ -136,7 +138,7 @@ bumpversion:
# is just a symlink to your actual ABC working directory, as 'make mrproper'
# will remove the 'abc' directory and you do not want to accidentally
# delete your work on ABC..
-ABCREV = 341db25
+ABCREV = 4f5f73d
ABCPULL = 1
ABCURL ?= https://github.com/YosysHQ/abc
ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1
@@ -530,6 +532,10 @@ endif
ifeq ($(ENABLE_CCACHE),1)
CXX := ccache $(CXX)
+else
+ifeq ($(ENABLE_SCCACHE),1)
+CXX := sccache $(CXX)
+endif
endif
define add_share_file
@@ -1019,4 +1025,3 @@ echo-abc-rev:
.PHONY: all top-all abc test install install-abc manual clean mrproper qtcreator coverage vcxsrc mxebin
.PHONY: config-clean config-clang config-gcc config-gcc-static config-gcc-4.8 config-afl-gcc config-gprof config-sudo
-
diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc
index 9739a7a9f..44c3397da 100644
--- a/backends/firrtl/firrtl.cc
+++ b/backends/firrtl/firrtl.cc
@@ -102,6 +102,260 @@ const char *make_id(IdString id)
return namecache.at(id).c_str();
}
+std::string dump_const_string(const RTLIL::Const &data)
+{
+ std::string res_str;
+
+ std::string str = data.decode_string();
+ for (size_t i = 0; i < str.size(); i++)
+ {
+ if (str[i] == '\n')
+ res_str += "\\n";
+ else if (str[i] == '\t')
+ res_str += "\\t";
+ else if (str[i] < 32)
+ res_str += stringf("\\%03o", str[i]);
+ else if (str[i] == '"')
+ res_str += "\\\"";
+ else if (str[i] == '\\')
+ res_str += "\\\\";
+ else
+ res_str += str[i];
+ }
+
+ return res_str;
+}
+
+std::string dump_const(const RTLIL::Const &data)
+{
+ std::string res_str;
+
+ // // For debugging purposes to find out how Yosys encodes flags.
+ // res_str += stringf("flags_%x --> ", data.flags);
+
+ // Real-valued parameter.
+ if (data.flags & RTLIL::CONST_FLAG_REAL)
+ {
+ // Yosys stores real values as strings, so we call the string dumping code.
+ res_str += dump_const_string(data);
+ }
+ // String parameter.
+ else if (data.flags & RTLIL::CONST_FLAG_STRING)
+ {
+ res_str += "\"";
+ res_str += dump_const_string(data);
+ res_str += "\"";
+ }
+ // Numeric (non-real) parameter.
+ else
+ {
+ int width = data.bits.size();
+
+ // If a standard 32-bit int, then emit standard int value like "56" or
+ // "-56". Firrtl supports negative-valued int literals.
+ //
+ // SignedInt
+ // : ( '+' | '-' ) PosInt
+ // ;
+ if (width <= 32)
+ {
+ int32_t int_val = 0;
+
+ for (int i = 0; i < width; i++)
+ {
+ switch (data.bits[i])
+ {
+ case State::S0: break;
+ case State::S1: int_val |= (1 << i); break;
+ default:
+ log_error("Unexpected int value\n");
+ break;
+ }
+ }
+
+ res_str += stringf("%d", int_val);
+ }
+ else
+ {
+ // If value is larger than 32 bits, then emit a binary representation of
+ // the number as integers are not large enough to contain the result.
+ // There is a caveat to this approach though:
+ //
+ // Note that parameter may be defined as having a fixed width as follows:
+ //
+ // parameter signed [26:0] test_signed;
+ // parameter [26:0] test_unsigned;
+ // parameter signed [40:0] test_signed_large;
+ //
+ // However, if you assign a value on the RHS without specifying the
+ // precision, then yosys considers the value you used as an int and
+ // assigns it a width of 32 bits regardless of the type of the parameter.
+ //
+ // defparam <inst_name> .test_signed = 49; (width = 32, though should be 27 based on definition)
+ // defparam <inst_name> .test_unsigned = 40'd35; (width = 40, though should be 27 based on definition)
+ // defparam <inst_name> .test_signed_large = 40'd12; (width = 40)
+ //
+ // We therefore may lose the precision of the original verilog literal if
+ // it was written without its bitwidth specifier.
+
+ // Emit binary prefix for string.
+ res_str += "\"b";
+
+ // Emit bits.
+ for (int i = width - 1; i >= 0; i--)
+ {
+ log_assert(i < width);
+ switch (data.bits[i])
+ {
+ case State::S0: res_str += "0"; break;
+ case State::S1: res_str += "1"; break;
+ case State::Sx: res_str += "x"; break;
+ case State::Sz: res_str += "z"; break;
+ case State::Sa: res_str += "-"; break;
+ case State::Sm: res_str += "m"; break;
+ }
+ }
+
+ res_str += "\"";
+ }
+ }
+
+ return res_str;
+}
+
+std::string extmodule_name(RTLIL::Cell *cell, RTLIL::Module *mod_instance)
+{
+ // Since we are creating a custom extmodule for every cell that instantiates
+ // this blackbox, we need to create a custom name for it. We just use the
+ // name of the blackbox itself followed by the name of the cell.
+ const std::string cell_name = std::string(make_id(cell->name));
+ const std::string blackbox_name = std::string(make_id(mod_instance->name));
+ const std::string extmodule_name = blackbox_name + "_" + cell_name;
+ return extmodule_name;
+}
+
+/**
+ * Emits a parameterized extmodule. Instance parameters are obtained from
+ * ''cell'' as it represents the instantiation of the blackbox defined by
+ * ''mod_instance'' and therefore contains all its instance parameters.
+ */
+void emit_extmodule(RTLIL::Cell *cell, RTLIL::Module *mod_instance, std::ostream &f)
+{
+ const std::string indent = " ";
+
+ const std::string blackbox_name = std::string(make_id(mod_instance->name));
+ const std::string exported_name = extmodule_name(cell, mod_instance);
+
+ // We use the cell's fileinfo for this extmodule as its parameters come from
+ // the cell and not from the module itself (the module contains default
+ // parameters, not the instance-specific ones we're using to emit the
+ // extmodule).
+ const std::string extmoduleFileinfo = getFileinfo(cell);
+
+ // Emit extmodule header.
+ f << stringf(" extmodule %s: %s\n", exported_name.c_str(), extmoduleFileinfo.c_str());
+
+ // Emit extmodule ports.
+ for (auto wire : mod_instance->wires())
+ {
+ const auto wireName = make_id(wire->name);
+ const std::string wireFileinfo = getFileinfo(wire);
+
+ if (wire->port_input && wire->port_output)
+ {
+ log_error("Module port %s.%s is inout!\n", log_id(mod_instance), log_id(wire));
+ }
+
+ const std::string portDecl = stringf("%s%s %s: UInt<%d> %s\n",
+ indent.c_str(),
+ wire->port_input ? "input" : "output",
+ wireName,
+ wire->width,
+ wireFileinfo.c_str()
+ );
+
+ f << portDecl;
+ }
+
+ // Emit extmodule "defname" field. This is the name of the verilog blackbox
+ // that is used when verilog is emitted, so we use the name of mod_instance
+ // here.
+ f << stringf("%sdefname = %s\n", indent.c_str(), blackbox_name.c_str());
+
+ // Emit extmodule generic parameters.
+ for (const auto &p : cell->parameters)
+ {
+ const RTLIL::IdString p_id = p.first;
+ const RTLIL::Const p_value = p.second;
+
+ std::string param_name(p_id.c_str());
+ const std::string param_value = dump_const(p_value);
+
+ // Remove backslashes from parameters as these come from the internal RTLIL
+ // naming scheme, but should not exist in the emitted firrtl blackboxes.
+ // When firrtl is converted to verilog and given to downstream synthesis
+ // tools, these tools expect to find blackbox names and parameters as they
+ // were originally defined, i.e. without the extra RTLIL naming conventions.
+ param_name.erase(
+ std::remove(param_name.begin(), param_name.end(), '\\'),
+ param_name.end()
+ );
+
+ f << stringf("%sparameter %s = %s\n", indent.c_str(), param_name.c_str(), param_value.c_str());
+ }
+
+ f << "\n";
+}
+
+/**
+ * Emits extmodules for every instantiated blackbox in the design.
+ *
+ * RTLIL stores instance parameters at the cell's instantiation location.
+ * However, firrtl does not support module parameterization (everything is
+ * already elaborated). Firrtl instead supports external modules (extmodule),
+ * i.e. blackboxes that are defined by verilog and which have no body in
+ * firrtl itself other than the declaration of the blackboxes ports and
+ * parameters.
+ *
+ * Furthermore, firrtl does not support parameterization (even of extmodules)
+ * at a module's instantiation location and users must instead declare
+ * different extmodules with different instance parameters in the extmodule
+ * definition itself.
+ *
+ * This function goes through the design to identify all RTLIL blackboxes
+ * and emit parameterized extmodules with a unique name for each of them. The
+ * name that's given to the extmodule is
+ *
+ * <blackbox_name>_<instance_name>
+ *
+ * Beware that it is therefore necessary for users to replace "parameterized"
+ * instances in the RTLIL sense with these custom extmodules for the firrtl to
+ * be valid.
+ */
+void emit_elaborated_extmodules(RTLIL::Design *design, std::ostream &f)
+{
+ for (auto module : design->modules())
+ {
+ for (auto cell : module->cells())
+ {
+ // Is this cell a module instance?
+ bool cellIsModuleInstance = cell->type[0] != '$';
+
+ if (cellIsModuleInstance)
+ {
+ // Find the module corresponding to this instance.
+ auto modInstance = design->module(cell->type);
+ bool modIsBlackbox = modInstance->get_blackbox_attribute();
+
+ if (modIsBlackbox)
+ {
+ emit_extmodule(cell, modInstance, f);
+ }
+ }
+ }
+ }
+}
+
struct FirrtlWorker
{
Module *module;
@@ -328,8 +582,16 @@ struct FirrtlWorker
log_warning("No instance for %s.%s\n", cell_type.c_str(), cell_name.c_str());
return;
}
+
+ // If the instance is that of a blackbox, use the modified extmodule name
+ // that contains per-instance parameterizations. These instances were
+ // emitted earlier in the firrtl backend.
+ const std::string instanceName = instModule->get_blackbox_attribute() ?
+ extmodule_name(cell, instModule) :
+ instanceOf;
+
std::string cellFileinfo = getFileinfo(cell);
- wire_exprs.push_back(stringf("%s" "inst %s%s of %s %s", indent.c_str(), cell_name.c_str(), cell_name_comment.c_str(), instanceOf.c_str(), cellFileinfo.c_str()));
+ wire_exprs.push_back(stringf("%s" "inst %s%s of %s %s", indent.c_str(), cell_name.c_str(), cell_name_comment.c_str(), instanceName.c_str(), cellFileinfo.c_str()));
for (auto it = cell->connections().begin(); it != cell->connections().end(); ++it) {
if (it->second.size() > 0) {
@@ -392,33 +654,6 @@ struct FirrtlWorker
return result;
}
- void emit_extmodule()
- {
- std::string moduleFileinfo = getFileinfo(module);
- f << stringf(" extmodule %s: %s\n", make_id(module->name), moduleFileinfo.c_str());
- vector<std::string> port_decls;
-
- for (auto wire : module->wires())
- {
- const auto wireName = make_id(wire->name);
- std::string wireFileinfo = getFileinfo(wire);
-
- if (wire->port_input && wire->port_output)
- {
- log_error("Module port %s.%s is inout!\n", log_id(module), log_id(wire));
- }
- port_decls.push_back(stringf(" %s %s: UInt<%d> %s\n", wire->port_input ? "input" : "output",
- wireName, wire->width, wireFileinfo.c_str()));
- }
-
- for (auto &str : port_decls)
- {
- f << str;
- }
-
- f << stringf("\n");
- }
-
void emit_module()
{
std::string moduleFileinfo = getFileinfo(module);
@@ -440,12 +675,12 @@ struct FirrtlWorker
{
if (wire->port_input && wire->port_output)
log_error("Module port %s.%s is inout!\n", log_id(module), log_id(wire));
- port_decls.push_back(stringf(" %s %s: UInt<%d> %s\n", wire->port_input ? "input" : "output",
+ port_decls.push_back(stringf("%s%s %s: UInt<%d> %s\n", indent.c_str(), wire->port_input ? "input" : "output",
wireName, wire->width, wireFileinfo.c_str()));
}
else
{
- wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", wireName, wire->width, wireFileinfo.c_str()));
+ wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), wireName, wire->width, wireFileinfo.c_str()));
}
}
@@ -476,7 +711,7 @@ struct FirrtlWorker
if (cell->type.in(ID($not), ID($logic_not), ID($_NOT_), ID($neg), ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_bool), ID($reduce_xnor)))
{
string a_expr = make_expr(cell->getPort(ID::A));
- wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", y_id.c_str(), y_width, cellFileinfo.c_str()));
+ wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), y_width, cellFileinfo.c_str()));
if (a_signed) {
a_expr = "asSInt(" + a_expr + ")";
@@ -516,7 +751,7 @@ struct FirrtlWorker
if ((firrtl_is_signed && !always_uint))
expr = stringf("asUInt(%s)", expr.c_str());
- cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
+ cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
@@ -528,7 +763,7 @@ struct FirrtlWorker
string a_expr = make_expr(cell->getPort(ID::A));
string b_expr = make_expr(cell->getPort(ID::B));
std::string cellFileinfo = getFileinfo(cell);
- wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", y_id.c_str(), y_width, cellFileinfo.c_str()));
+ wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), y_width, cellFileinfo.c_str()));
if (a_signed) {
a_expr = "asSInt(" + a_expr + ")";
@@ -746,7 +981,7 @@ struct FirrtlWorker
if ((firrtl_is_signed && !always_uint))
expr = stringf("asUInt(%s)", expr.c_str());
- cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
+ cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
@@ -759,11 +994,11 @@ struct FirrtlWorker
string a_expr = make_expr(cell->getPort(ID::A));
string b_expr = make_expr(cell->getPort(ID::B));
string s_expr = make_expr(cell->getPort(ID::S));
- wire_decls.push_back(stringf(" wire %s: UInt<%d> %s\n", y_id.c_str(), width, cellFileinfo.c_str()));
+ wire_decls.push_back(stringf("%swire %s: UInt<%d> %s\n", indent.c_str(), y_id.c_str(), width, cellFileinfo.c_str()));
string expr = stringf("mux(%s, %s, %s)", s_expr.c_str(), b_expr.c_str(), a_expr.c_str());
- cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
+ cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
@@ -902,9 +1137,9 @@ struct FirrtlWorker
string expr = make_expr(cell->getPort(ID::D));
string clk_expr = "asClock(" + make_expr(cell->getPort(ID::CLK)) + ")";
- wire_decls.push_back(stringf(" reg %s: UInt<%d>, %s %s\n", y_id.c_str(), width, clk_expr.c_str(), cellFileinfo.c_str()));
+ wire_decls.push_back(stringf("%sreg %s: UInt<%d>, %s %s\n", indent.c_str(), y_id.c_str(), width, clk_expr.c_str(), cellFileinfo.c_str()));
- cell_exprs.push_back(stringf(" %s <= %s %s\n", y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
+ cell_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), y_id.c_str(), expr.c_str(), cellFileinfo.c_str()));
register_reverse_wire_map(y_id, cell->getPort(ID::Q));
continue;
@@ -923,7 +1158,7 @@ struct FirrtlWorker
string a_expr = make_expr(cell->getPort(ID::A));
// Get the initial bit selector
string b_expr = make_expr(cell->getPort(ID::B));
- wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
+ wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width));
if (cell->getParam(ID::B_SIGNED).as_bool()) {
// Use validif to constrain the selection (test the sign bit)
@@ -933,7 +1168,7 @@ struct FirrtlWorker
}
string expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_expr.c_str());
- cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
+ cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str()));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
@@ -945,7 +1180,7 @@ struct FirrtlWorker
string b_expr = make_expr(cell->getPort(ID::B));
auto b_string = b_expr.c_str();
string expr;
- wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
+ wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width));
if (cell->getParam(ID::B_SIGNED).as_bool()) {
// We generate a left or right shift based on the sign of b.
@@ -959,7 +1194,7 @@ struct FirrtlWorker
} else {
expr = stringf("dshr(%s, %s)", a_expr.c_str(), b_string);
}
- cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
+ cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str()));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
@@ -972,8 +1207,8 @@ struct FirrtlWorker
if (a_width < y_width) {
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
}
- wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
- cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), a_expr.c_str()));
+ wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width));
+ cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), a_expr.c_str()));
register_reverse_wire_map(y_id, cell->getPort(ID::Y));
continue;
}
@@ -986,8 +1221,8 @@ struct FirrtlWorker
int y_width = GetSize(conn.first);
string expr = make_expr(conn.second);
- wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
- cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
+ wire_decls.push_back(stringf("%swire %s: UInt<%d>\n", indent.c_str(), y_id.c_str(), y_width));
+ cell_exprs.push_back(stringf("%s%s <= %s\n", indent.c_str(), y_id.c_str(), expr.c_str()));
register_reverse_wire_map(y_id, conn.first);
}
@@ -1053,13 +1288,13 @@ struct FirrtlWorker
if (is_valid) {
if (make_unconn_id) {
- wire_decls.push_back(stringf(" wire %s: UInt<1> %s\n", unconn_id.c_str(), wireFileinfo.c_str()));
+ wire_decls.push_back(stringf("%swire %s: UInt<1> %s\n", indent.c_str(), unconn_id.c_str(), wireFileinfo.c_str()));
// `invalid` is a firrtl construction for simulation so we will not
// tag it with a @[fileinfo] tag as it doesn't directly correspond to
// a specific line of verilog code.
- wire_decls.push_back(stringf(" %s is invalid\n", unconn_id.c_str()));
+ wire_decls.push_back(stringf("%s%s is invalid\n", indent.c_str(), unconn_id.c_str()));
}
- wire_exprs.push_back(stringf(" %s <= %s %s\n", make_id(wire->name), expr.c_str(), wireFileinfo.c_str()));
+ wire_exprs.push_back(stringf("%s%s <= %s %s\n", indent.c_str(), make_id(wire->name), expr.c_str(), wireFileinfo.c_str()));
} else {
if (make_unconn_id) {
unconn_id.clear();
@@ -1067,7 +1302,7 @@ struct FirrtlWorker
// `invalid` is a firrtl construction for simulation so we will not
// tag it with a @[fileinfo] tag as it doesn't directly correspond to
// a specific line of verilog code.
- wire_decls.push_back(stringf(" %s is invalid\n", make_id(wire->name)));
+ wire_decls.push_back(stringf("%s%s is invalid\n", indent.c_str(), make_id(wire->name)));
}
}
@@ -1112,12 +1347,7 @@ struct FirrtlWorker
void run()
{
- // Blackboxes should be emitted as `extmodule`s in firrtl. Only ports are
- // emitted in such a case.
- if (module->get_blackbox_attribute())
- emit_extmodule();
- else
- emit_module();
+ emit_module();
}
};
@@ -1180,10 +1410,16 @@ struct FirrtlBackend : public Backend {
std::string circuitFileinfo = getFileinfo(top);
*f << stringf("circuit %s: %s\n", make_id(top->name), circuitFileinfo.c_str());
+ emit_elaborated_extmodules(design, *f);
+
+ // Emit non-blackbox modules.
for (auto module : design->modules())
{
- FirrtlWorker worker(module, *f, design);
- worker.run();
+ if (!module->get_blackbox_attribute())
+ {
+ FirrtlWorker worker(module, *f, design);
+ worker.run();
+ }
}
namecache.clear();
diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc
index 9523f4a52..165ce1ea4 100644
--- a/backends/verilog/verilog_backend.cc
+++ b/backends/verilog/verilog_backend.cc
@@ -35,7 +35,7 @@
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
-bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit, systemverilog;
+bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit, systemverilog, simple_lhs;
int auto_name_counter, auto_name_offset, auto_name_digits, extmem_counter;
std::map<RTLIL::IdString, int> auto_name_map;
std::set<RTLIL::IdString> reg_wires;
@@ -1546,11 +1546,23 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell)
void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right)
{
- f << stringf("%s" "assign ", indent.c_str());
- dump_sigspec(f, left);
- f << stringf(" = ");
- dump_sigspec(f, right);
- f << stringf(";\n");
+ if (simple_lhs) {
+ int offset = 0;
+ for (auto &chunk : left.chunks()) {
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, chunk);
+ f << stringf(" = ");
+ dump_sigspec(f, right.extract(offset, GetSize(chunk)));
+ f << stringf(";\n");
+ offset += GetSize(chunk);
+ }
+ } else {
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, left);
+ f << stringf(" = ");
+ dump_sigspec(f, right);
+ f << stringf(";\n");
+ }
}
void dump_proc_switch(std::ostream &f, std::string indent, RTLIL::SwitchRule *sw);
@@ -1861,6 +1873,9 @@ struct VerilogBackend : public Backend {
log(" deactivates this feature and instead will write string constants\n");
log(" as binary numbers.\n");
log("\n");
+ log(" -simple-lhs\n");
+ log(" Connection assignments with simple left hand side without concatenations.\n");
+ log("\n");
log(" -extmem\n");
log(" instead of initializing memories using assignments to individual\n");
log(" elements, use the '$readmemh' function to read initialization data\n");
@@ -1908,6 +1923,7 @@ struct VerilogBackend : public Backend {
defparam = false;
decimal = false;
siminit = false;
+ simple_lhs = false;
auto_prefix = "";
bool blackboxes = false;
@@ -1980,6 +1996,10 @@ struct VerilogBackend : public Backend {
selected = true;
continue;
}
+ if (arg == "-simple-lhs") {
+ simple_lhs = true;
+ continue;
+ }
if (arg == "-v") {
verbose = true;
continue;
diff --git a/frontends/rtlil/rtlil_lexer.l b/frontends/rtlil/rtlil_lexer.l
index 295455f53..beef220f6 100644
--- a/frontends/rtlil/rtlil_lexer.l
+++ b/frontends/rtlil/rtlil_lexer.l
@@ -86,7 +86,6 @@ USING_YOSYS_NAMESPACE
"\\"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; }
"$"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; }
-"."[0-9]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; }
[0-9]+'[01xzm-]* { rtlil_frontend_yylval.string = strdup(yytext); return TOK_VALUE; }
-?[0-9]+ {
diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc
index 31c77d39c..cf3bf1070 100644
--- a/frontends/verific/verific.cc
+++ b/frontends/verific/verific.cc
@@ -55,7 +55,7 @@ USING_YOSYS_NAMESPACE
# error "Only Symbiotic EDA flavored Verific is supported. Please contact office@symbioticeda.com for commercial support for Yosys+Verific."
#endif
-#if SYMBIOTIC_VERIFIC_API_VERSION < 20201001
+#if SYMBIOTIC_VERIFIC_API_VERSION < 20201101
# error "Please update your version of Symbiotic EDA flavored Verific."
#endif
diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc
index ea23139e2..752f7a7a8 100644
--- a/frontends/verilog/preproc.cc
+++ b/frontends/verilog/preproc.cc
@@ -321,7 +321,6 @@ struct define_body_t
define_map_t::define_map_t()
{
add("YOSYS", "1");
- add(formal_mode ? "FORMAL" : "SYNTHESIS", "1");
}
// We must define this destructor here (rather than relying on the default), because we need to
diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc
index 2e9c9b2e2..5319a45ad 100644
--- a/frontends/verilog/verilog_frontend.cc
+++ b/frontends/verilog/verilog_frontend.cc
@@ -446,6 +446,9 @@ struct VerilogFrontend : public Frontend {
}
break;
}
+
+ defines_map.add(formal_mode ? "FORMAL" : "SYNTHESIS", "1");
+
extra_args(f, filename, args, argidx);
log_header(design, "Executing Verilog-2005 frontend: %s\n", filename.c_str());
diff --git a/kernel/driver.cc b/kernel/driver.cc
index 57ed7b8b4..b55f02837 100644
--- a/kernel/driver.cc
+++ b/kernel/driver.cc
@@ -267,9 +267,11 @@ int main(int argc, char **argv)
printf("\n");
printf(" -s scriptfile\n");
printf(" execute the commands in the script file\n");
+#ifdef YOSYS_ENABLE_TCL
printf("\n");
printf(" -c tcl_scriptfile\n");
printf(" execute the commands in the tcl script file (see 'help tcl' for details)\n");
+#endif
printf("\n");
printf(" -p command\n");
printf(" execute the commands\n");
diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc
index a8b5362b3..36febb98a 100644
--- a/passes/cmds/check.cc
+++ b/passes/cmds/check.cc
@@ -35,30 +35,28 @@ struct CheckPass : public Pass {
log("\n");
log("This pass identifies the following problems in the current design:\n");
log("\n");
- log(" - combinatorial loops\n");
- log("\n");
- log(" - two or more conflicting drivers for one wire\n");
- log("\n");
- log(" - used wires that do not have a driver\n");
+ log(" - combinatorial loops\n");
+ log(" - two or more conflicting drivers for one wire\n");
+ log(" - used wires that do not have a driver\n");
log("\n");
log("Options:\n");
log("\n");
- log(" -noinit\n");
- log(" Also check for wires which have the 'init' attribute set.\n");
+ log(" -noinit\n");
+ log(" also check for wires which have the 'init' attribute set\n");
log("\n");
- log(" -initdrv\n");
- log(" Also check for wires that have the 'init' attribute set and are not\n");
- log(" driven by an FF cell type.\n");
+ log(" -initdrv\n");
+ log(" also check for wires that have the 'init' attribute set and are not\n");
+ log(" driven by an FF cell type\n");
log("\n");
- log(" -mapped\n");
- log(" Also check for internal cells that have not been mapped to cells of the\n");
- log(" target architecture.\n");
+ log(" -mapped\n");
+ log(" also check for internal cells that have not been mapped to cells of the\n");
+ log(" target architecture\n");
log("\n");
- log(" -allow-tbuf\n");
- log(" Modify the -mapped behavior to still allow $_TBUF_ cells.\n");
+ log(" -allow-tbuf\n");
+ log(" modify the -mapped behavior to still allow $_TBUF_ cells\n");
log("\n");
- log(" -assert\n");
- log(" Produce a runtime error if any problems are found in the current design.\n");
+ log(" -assert\n");
+ log(" produce a runtime error if any problems are found in the current design\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
@@ -100,10 +98,7 @@ struct CheckPass : public Pass {
for (auto module : design->selected_whole_modules_warn())
{
- if (module->has_processes_warn())
- continue;
-
- log("checking module %s..\n", log_id(module));
+ log("Checking module %s...\n", log_id(module));
SigMap sigmap(module);
dict<SigBit, vector<string>> wire_drivers;
@@ -111,6 +106,44 @@ struct CheckPass : public Pass {
pool<SigBit> used_wires;
TopoSort<string> topo;
+ for (auto &proc_it : module->processes)
+ {
+ std::vector<RTLIL::CaseRule*> all_cases = {&proc_it.second->root_case};
+ for (size_t i = 0; i < all_cases.size(); i++) {
+ for (auto action : all_cases[i]->actions) {
+ for (auto bit : sigmap(action.first))
+ if (bit.wire) {
+ wire_drivers[bit].push_back(
+ stringf("action %s <= %s (case rule) in process %s",
+ log_signal(action.first), log_signal(action.second), log_id(proc_it.first)));
+ }
+ for (auto bit : sigmap(action.second))
+ if (bit.wire) used_wires.insert(bit);
+ }
+ for (auto switch_ : all_cases[i]->switches) {
+ for (auto case_ : switch_->cases) {
+ all_cases.push_back(case_);
+ for (auto compare : case_->compare)
+ for (auto bit : sigmap(compare))
+ if (bit.wire) used_wires.insert(bit);
+ }
+ }
+ }
+ for (auto &sync : proc_it.second->syncs) {
+ for (auto bit : sigmap(sync->signal))
+ if (bit.wire) used_wires.insert(bit);
+ for (auto action : sync->actions) {
+ for (auto bit : sigmap(action.first))
+ if (bit.wire)
+ wire_drivers[bit].push_back(
+ stringf("action %s <= %s (sync rule) in process %s",
+ log_signal(action.first), log_signal(action.second), log_id(proc_it.first)));
+ for (auto bit : sigmap(action.second))
+ if (bit.wire) used_wires.insert(bit);
+ }
+ }
+ }
+
for (auto cell : module->cells())
{
if (mapped && cell->type.begins_with("$") && design->module(cell->type) == nullptr) {
@@ -216,7 +249,7 @@ struct CheckPass : public Pass {
}
}
- log("found and reported %d problems.\n", counter);
+ log("Found and reported %d problems.\n", counter);
if (assert_mode && counter > 0)
log_error("Found %d problems in 'check -assert'.\n", counter);
diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc
index 75f922dba..3ba66bd33 100644
--- a/passes/sat/sim.cc
+++ b/passes/sat/sim.cc
@@ -810,7 +810,9 @@ struct SimPass : public Pass {
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
if (args[argidx] == "-vcd" && argidx+1 < args.size()) {
- worker.vcdfile.open(args[++argidx].c_str());
+ std::string vcd_filename = args[++argidx];
+ rewrite_filename(vcd_filename);
+ worker.vcdfile.open(vcd_filename.c_str());
continue;
}
if (args[argidx] == "-n" && argidx+1 < args.size()) {
diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc
index 4d1e968ae..5bf0894da 100644
--- a/techlibs/gowin/synth_gowin.cc
+++ b/techlibs/gowin/synth_gowin.cc
@@ -44,6 +44,11 @@ struct SynthGowinPass : public ScriptPass
log(" write the design to the specified Verilog netlist file. writing of an\n");
log(" output file is omitted if this parameter is not specified.\n");
log("\n");
+ log(" -json <file>\n");
+ log(" write the design to the specified JSON netlist file. writing of an\n");
+ log(" output file is omitted if this parameter is not specified.\n");
+ log(" This disables features not yet supported by nexpnr-gowin.\n");
+ log("\n");
log(" -run <from_label>:<to_label>\n");
log(" only run the commands between the labels (see below). an empty\n");
log(" from label is synonymous to 'begin', and empty to label is\n");
@@ -70,6 +75,9 @@ struct SynthGowinPass : public ScriptPass
log(" -noiopads\n");
log(" do not emit IOB at top level ports\n");
log("\n");
+ log(" -noalu\n");
+ log(" do not use ALU cells\n");
+ log("\n");
log(" -abc9\n");
log(" use new ABC9 flow (EXPERIMENTAL)\n");
log("\n");
@@ -79,13 +87,14 @@ struct SynthGowinPass : public ScriptPass
log("\n");
}
- string top_opt, vout_file;
- bool retime, nobram, nolutram, flatten, nodffe, nowidelut, abc9, noiopads;
+ string top_opt, vout_file, json_file;
+ bool retime, nobram, nolutram, flatten, nodffe, nowidelut, abc9, noiopads, noalu;
void clear_flags() override
{
top_opt = "-auto-top";
vout_file = "";
+ json_file = "";
retime = false;
flatten = true;
nobram = false;
@@ -94,6 +103,7 @@ struct SynthGowinPass : public ScriptPass
nowidelut = false;
abc9 = false;
noiopads = false;
+ noalu = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
@@ -112,6 +122,14 @@ struct SynthGowinPass : public ScriptPass
vout_file = args[++argidx];
continue;
}
+ if (args[argidx] == "-json" && argidx+1 < args.size()) {
+ json_file = args[++argidx];
+ nobram = true;
+ nolutram = true;
+ nowidelut = true;
+ noalu = true;
+ continue;
+ }
if (args[argidx] == "-run" && argidx+1 < args.size()) {
size_t pos = args[argidx+1].find(':');
if (pos == std::string::npos)
@@ -144,6 +162,10 @@ struct SynthGowinPass : public ScriptPass
nowidelut = true;
continue;
}
+ if (args[argidx] == "-noalu") {
+ noalu = true;
+ continue;
+ }
if (args[argidx] == "-abc9") {
abc9 = true;
continue;
@@ -210,7 +232,11 @@ struct SynthGowinPass : public ScriptPass
if (check_label("map_gates"))
{
- run("techmap -map +/techmap.v -map +/gowin/arith_map.v");
+ if (noalu) {
+ run("techmap -map +/techmap.v");
+ } else {
+ run("techmap -map +/techmap.v -map +/gowin/arith_map.v");
+ }
run("opt -fast");
if (retime || help_mode)
run("abc -dff -D 1", "(only if -retime)");
@@ -270,6 +296,9 @@ struct SynthGowinPass : public ScriptPass
if (!vout_file.empty() || help_mode)
run(stringf("write_verilog -decimal -attr2comment -defparam -renameprefix gen %s",
help_mode ? "<file-name>" : vout_file.c_str()));
+ if (!json_file.empty() || help_mode)
+ run(stringf("write_json %s",
+ help_mode ? "<file-name>" : json_file.c_str()));
}
}
} SynthGowinPass;
diff --git a/tests/various/dynamic_part_select.ys b/tests/various/dynamic_part_select.ys
index abc1daad6..2dc061e89 100644
--- a/tests/various/dynamic_part_select.ys
+++ b/tests/various/dynamic_part_select.ys
@@ -21,18 +21,18 @@ read_verilog ./dynamic_part_select/multiple_blocking.v
proc
rename -top gold
design -stash gold
-
+
read_verilog ./dynamic_part_select/multiple_blocking_gate.v
proc
rename -top gate
design -stash gate
-
+
design -copy-from gold -as gold gold
design -copy-from gate -as gate gate
miter -equiv -make_assert -make_outcmp -flatten gold gate equiv
sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv
-
+
### Non-blocking to the same output register ###
design -reset
read_verilog ./dynamic_part_select/nonblocking.v
@@ -44,13 +44,13 @@ read_verilog ./dynamic_part_select/nonblocking_gate.v
proc
rename -top gate
design -stash gate
-
+
design -copy-from gold -as gold gold
design -copy-from gate -as gate gate
miter -equiv -make_assert -make_outcmp -flatten gold gate equiv
sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv
-
+
### For-loop select, one dynamic input
design -reset
read_verilog ./dynamic_part_select/forloop_select.v
@@ -62,13 +62,13 @@ read_verilog ./dynamic_part_select/forloop_select_gate.v
proc
rename -top gate
design -stash gate
-
+
design -copy-from gold -as gold gold
design -copy-from gate -as gate gate
miter -equiv -make_assert -make_outcmp -flatten gold gate equiv
sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv
-
+
#### Double loop (part-select, reset) ###
design -reset
read_verilog ./dynamic_part_select/reset_test.v
@@ -83,10 +83,10 @@ design -stash gate
design -copy-from gold -as gold gold
design -copy-from gate -as gate gate
-
+
miter -equiv -make_assert -make_outcmp -flatten gold gate equiv
sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv
-
+
### Reversed part-select case ###
design -reset
read_verilog ./dynamic_part_select/reversed.v
@@ -101,6 +101,62 @@ design -stash gate
design -copy-from gold -as gold gold
design -copy-from gate -as gate gate
-
+
+miter -equiv -make_assert -make_outcmp -flatten gold gate equiv
+sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv
+
+### Latches
+## Issue 1990
+design -reset
+read_verilog ./dynamic_part_select/latch_1990.v
+hierarchy -top latch_1990; prep; async2sync
+rename -top gold
+design -stash gold
+
+read_verilog ./dynamic_part_select/latch_1990_gate.v
+hierarchy -top latch_1990_gate; prep
+rename -top gate
+design -stash gate
+
+design -copy-from gold -as gold gold
+design -copy-from gate -as gate gate
+
+miter -equiv -make_assert -make_outcmp -flatten gold gate equiv
+sat -prove-asserts -show-public -verify -set-init-zero equiv
+
+###
+## Part select with obvious latch, expected to fail due comparison with old shift&mask AST transformation
+design -reset
+read_verilog ./dynamic_part_select/latch_002.v
+hierarchy -top latch_002; prep; async2sync
+rename -top gold
+design -stash gold
+
+read_verilog ./dynamic_part_select/latch_002_gate.v
+hierarchy -top latch_002_gate; prep; async2sync
+rename -top gate
+design -stash gate
+
+design -copy-from gold -as gold gold
+design -copy-from gate -as gate gate
+
+miter -equiv -make_assert -make_outcmp -flatten gold gate equiv
+sat -prove-asserts -seq 10 -show-public -falsify -set-init-zero equiv
+
+## Part select + latch, with no shift&mask
+design -reset
+read_verilog ./dynamic_part_select/latch_002.v
+hierarchy -top latch_002; prep; async2sync
+rename -top gold
+design -stash gold
+
+read_verilog ./dynamic_part_select/latch_002_gate_good.v
+hierarchy -top latch_002_gate; prep; async2sync
+rename -top gate
+design -stash gate
+
+design -copy-from gold -as gold gold
+design -copy-from gate -as gate gate
+
miter -equiv -make_assert -make_outcmp -flatten gold gate equiv
sat -prove-asserts -seq 10 -show-public -verify -set-init-zero equiv
diff --git a/tests/various/dynamic_part_select/forloop_select.v b/tests/various/dynamic_part_select/forloop_select.v
index 8260f3186..926fb3133 100644
--- a/tests/various/dynamic_part_select/forloop_select.v
+++ b/tests/various/dynamic_part_select/forloop_select.v
@@ -1,13 +1,14 @@
+`default_nettype none
module forloop_select #(parameter WIDTH=16, SELW=4, CTRLW=$clog2(WIDTH), DINW=2**SELW)
- (input clk,
- input [CTRLW-1:0] ctrl,
- input [DINW-1:0] din,
- input en,
+ (input wire clk,
+ input wire [CTRLW-1:0] ctrl,
+ input wire [DINW-1:0] din,
+ input wire en,
output reg [WIDTH-1:0] dout);
-
- reg [SELW:0] sel;
+
+ reg [SELW:0] sel;
localparam SLICE = WIDTH/(SELW**2);
-
+
always @(posedge clk)
begin
if (en) begin
@@ -16,4 +17,3 @@ module forloop_select #(parameter WIDTH=16, SELW=4, CTRLW=$clog2(WIDTH), DINW=2*
end
end
endmodule
-
diff --git a/tests/various/dynamic_part_select/forloop_select_gate.v b/tests/various/dynamic_part_select/forloop_select_gate.v
index 71ae88537..1a5fffdc7 100644
--- a/tests/various/dynamic_part_select/forloop_select_gate.v
+++ b/tests/various/dynamic_part_select/forloop_select_gate.v
@@ -1,8 +1,9 @@
+`default_nettype none
module forloop_select_gate (clk, ctrl, din, en, dout);
- input clk;
- input [3:0] ctrl;
- input [15:0] din;
- input en;
+ input wire clk;
+ input wire [3:0] ctrl;
+ input wire [15:0] din;
+ input wire en;
output reg [15:0] dout;
reg [4:0] sel;
always @(posedge clk)
diff --git a/tests/various/dynamic_part_select/latch_002.v b/tests/various/dynamic_part_select/latch_002.v
new file mode 100644
index 000000000..7617d6a72
--- /dev/null
+++ b/tests/various/dynamic_part_select/latch_002.v
@@ -0,0 +1,13 @@
+`default_nettype none
+module latch_002
+ (dword, sel, st, vect);
+ output reg [63:0] dword;
+ input wire [7:0] vect;
+ input wire [7:0] sel;
+ input wire st;
+
+ always @(*) begin
+ if (st)
+ dword[8*sel +:8] <= vect[7:0];
+ end
+endmodule // latch_002
diff --git a/tests/various/dynamic_part_select/latch_002_gate.v b/tests/various/dynamic_part_select/latch_002_gate.v
new file mode 100644
index 000000000..4acf129c6
--- /dev/null
+++ b/tests/various/dynamic_part_select/latch_002_gate.v
@@ -0,0 +1,18 @@
+`default_nettype none
+module latch_002_gate(dword, vect, sel, st);
+ output reg [63:0] dword;
+ input wire [7:0] vect;
+ input wire [7:0] sel;
+ input wire st;
+ reg [63:0] mask;
+ reg [63:0] data;
+ always @*
+ case (|(st))
+ 1'b 1:
+ begin
+ mask = (8'b 11111111)<<((((8)*(sel)))+(0));
+ data = ((8'b 11111111)&(vect[7:0]))<<((((8)*(sel)))+(0));
+ dword <= ((dword)&(~(mask)))|(data);
+ end
+ endcase
+endmodule
diff --git a/tests/various/dynamic_part_select/latch_002_gate_good.v b/tests/various/dynamic_part_select/latch_002_gate_good.v
new file mode 100644
index 000000000..809c74fc9
--- /dev/null
+++ b/tests/various/dynamic_part_select/latch_002_gate_good.v
@@ -0,0 +1,141 @@
+`default_nettype none
+module latch_002_gate (dword, vect, sel, st);
+ output reg [63:0] dword;
+ input wire [7:0] vect;
+ input wire [7:0] sel;
+ input st;
+ always @*
+ case (|(st))
+ 1'b 1:
+ case ((((8)*(sel)))+(0))
+ 0:
+ dword[7:0] <= vect[7:0];
+ 1:
+ dword[8:1] <= vect[7:0];
+ 2:
+ dword[9:2] <= vect[7:0];
+ 3:
+ dword[10:3] <= vect[7:0];
+ 4:
+ dword[11:4] <= vect[7:0];
+ 5:
+ dword[12:5] <= vect[7:0];
+ 6:
+ dword[13:6] <= vect[7:0];
+ 7:
+ dword[14:7] <= vect[7:0];
+ 8:
+ dword[15:8] <= vect[7:0];
+ 9:
+ dword[16:9] <= vect[7:0];
+ 10:
+ dword[17:10] <= vect[7:0];
+ 11:
+ dword[18:11] <= vect[7:0];
+ 12:
+ dword[19:12] <= vect[7:0];
+ 13:
+ dword[20:13] <= vect[7:0];
+ 14:
+ dword[21:14] <= vect[7:0];
+ 15:
+ dword[22:15] <= vect[7:0];
+ 16:
+ dword[23:16] <= vect[7:0];
+ 17:
+ dword[24:17] <= vect[7:0];
+ 18:
+ dword[25:18] <= vect[7:0];
+ 19:
+ dword[26:19] <= vect[7:0];
+ 20:
+ dword[27:20] <= vect[7:0];
+ 21:
+ dword[28:21] <= vect[7:0];
+ 22:
+ dword[29:22] <= vect[7:0];
+ 23:
+ dword[30:23] <= vect[7:0];
+ 24:
+ dword[31:24] <= vect[7:0];
+ 25:
+ dword[32:25] <= vect[7:0];
+ 26:
+ dword[33:26] <= vect[7:0];
+ 27:
+ dword[34:27] <= vect[7:0];
+ 28:
+ dword[35:28] <= vect[7:0];
+ 29:
+ dword[36:29] <= vect[7:0];
+ 30:
+ dword[37:30] <= vect[7:0];
+ 31:
+ dword[38:31] <= vect[7:0];
+ 32:
+ dword[39:32] <= vect[7:0];
+ 33:
+ dword[40:33] <= vect[7:0];
+ 34:
+ dword[41:34] <= vect[7:0];
+ 35:
+ dword[42:35] <= vect[7:0];
+ 36:
+ dword[43:36] <= vect[7:0];
+ 37:
+ dword[44:37] <= vect[7:0];
+ 38:
+ dword[45:38] <= vect[7:0];
+ 39:
+ dword[46:39] <= vect[7:0];
+ 40:
+ dword[47:40] <= vect[7:0];
+ 41:
+ dword[48:41] <= vect[7:0];
+ 42:
+ dword[49:42] <= vect[7:0];
+ 43:
+ dword[50:43] <= vect[7:0];
+ 44:
+ dword[51:44] <= vect[7:0];
+ 45:
+ dword[52:45] <= vect[7:0];
+ 46:
+ dword[53:46] <= vect[7:0];
+ 47:
+ dword[54:47] <= vect[7:0];
+ 48:
+ dword[55:48] <= vect[7:0];
+ 49:
+ dword[56:49] <= vect[7:0];
+ 50:
+ dword[57:50] <= vect[7:0];
+ 51:
+ dword[58:51] <= vect[7:0];
+ 52:
+ dword[59:52] <= vect[7:0];
+ 53:
+ dword[60:53] <= vect[7:0];
+ 54:
+ dword[61:54] <= vect[7:0];
+ 55:
+ dword[62:55] <= vect[7:0];
+ 56:
+ dword[63:56] <= vect[7:0];
+ 57:
+ dword[63:57] <= vect[7:0];
+ 58:
+ dword[63:58] <= vect[7:0];
+ 59:
+ dword[63:59] <= vect[7:0];
+ 60:
+ dword[63:60] <= vect[7:0];
+ 61:
+ dword[63:61] <= vect[7:0];
+ 62:
+ dword[63:62] <= vect[7:0];
+ 63:
+ dword[63:63] <= vect[7:0];
+ endcase
+ endcase
+endmodule
diff --git a/tests/various/dynamic_part_select/latch_1990.v b/tests/various/dynamic_part_select/latch_1990.v
new file mode 100644
index 000000000..864c05244
--- /dev/null
+++ b/tests/various/dynamic_part_select/latch_1990.v
@@ -0,0 +1,12 @@
+module latch_1990 #(
+ parameter BUG = 1
+) (
+ (* nowrshmsk = !BUG *)
+ output reg [1:0] x
+);
+ wire z = 0;
+ integer i;
+ always @*
+ for (i = 0; i < 2; i=i+1)
+ x[z^i] = z^i;
+endmodule
diff --git a/tests/various/dynamic_part_select/latch_1990_gate.v b/tests/various/dynamic_part_select/latch_1990_gate.v
new file mode 100644
index 000000000..a46183f23
--- /dev/null
+++ b/tests/various/dynamic_part_select/latch_1990_gate.v
@@ -0,0 +1,6 @@
+`default_nettype none
+module latch_1990_gate
+ (output wire [1:0] x);
+ assign x = 2'b10;
+endmodule // latch_1990_gate
+
diff --git a/tests/various/dynamic_part_select/multiple_blocking.v b/tests/various/dynamic_part_select/multiple_blocking.v
index 2858f7741..3bb249a76 100644
--- a/tests/various/dynamic_part_select/multiple_blocking.v
+++ b/tests/various/dynamic_part_select/multiple_blocking.v
@@ -1,8 +1,9 @@
+`default_nettype none
module multiple_blocking #(parameter WIDTH=32, SELW=1, CTRLW=$clog2(WIDTH), DINW=2**SELW)
- (input clk,
- input [CTRLW-1:0] ctrl,
- input [DINW-1:0] din,
- input [SELW-1:0] sel,
+ (input wire clk,
+ input wire [CTRLW-1:0] ctrl,
+ input wire [DINW-1:0] din,
+ input wire [SELW-1:0] sel,
output reg [WIDTH-1:0] dout);
localparam SLICE = WIDTH/(SELW**2);
diff --git a/tests/various/dynamic_part_select/multiple_blocking_gate.v b/tests/various/dynamic_part_select/multiple_blocking_gate.v
index 073b559dc..840918876 100644
--- a/tests/various/dynamic_part_select/multiple_blocking_gate.v
+++ b/tests/various/dynamic_part_select/multiple_blocking_gate.v
@@ -1,8 +1,9 @@
+`default_nettype none
module multiple_blocking_gate (clk, ctrl, din, sel, dout);
- input clk;
- input [4:0] ctrl;
- input [1:0] din;
- input [0:0] sel;
+ input wire clk;
+ input wire [4:0] ctrl;
+ input wire [1:0] din;
+ input wire [0:0] sel;
output reg [31:0] dout;
reg [5:0] a;
reg [0:0] b;
diff --git a/tests/various/dynamic_part_select/nonblocking.v b/tests/various/dynamic_part_select/nonblocking.v
index 0949b31a9..20f857cf9 100644
--- a/tests/various/dynamic_part_select/nonblocking.v
+++ b/tests/various/dynamic_part_select/nonblocking.v
@@ -1,8 +1,9 @@
+`default_nettype none
module nonblocking #(parameter WIDTH=32, SELW=1, CTRLW=$clog2(WIDTH), DINW=2**SELW)
- (input clk,
- input [CTRLW-1:0] ctrl,
- input [DINW-1:0] din,
- input [SELW-1:0] sel,
+ (input wire clk,
+ input wire [CTRLW-1:0] ctrl,
+ input wire [DINW-1:0] din,
+ input wire [SELW-1:0] sel,
output reg [WIDTH-1:0] dout);
localparam SLICE = WIDTH/(SELW**2);
diff --git a/tests/various/dynamic_part_select/nonblocking_gate.v b/tests/various/dynamic_part_select/nonblocking_gate.v
index ed1ee2776..212d44609 100644
--- a/tests/various/dynamic_part_select/nonblocking_gate.v
+++ b/tests/various/dynamic_part_select/nonblocking_gate.v
@@ -1,8 +1,9 @@
+`default_nettype none
module nonblocking_gate (clk, ctrl, din, sel, dout);
- input clk;
- input [4:0] ctrl;
- input [1:0] din;
- input [0:0] sel;
+ input wire clk;
+ input wire [4:0] ctrl;
+ input wire [1:0] din;
+ input wire [0:0] sel;
output reg [31:0] dout;
always @(posedge clk)
begin
diff --git a/tests/various/dynamic_part_select/original.v b/tests/various/dynamic_part_select/original.v
index f7dfed1a1..41310a215 100644
--- a/tests/various/dynamic_part_select/original.v
+++ b/tests/various/dynamic_part_select/original.v
@@ -1,8 +1,9 @@
+`default_nettype none
module original #(parameter WIDTH=32, SELW=1, CTRLW=$clog2(WIDTH), DINW=2**SELW)
- (input clk,
- input [CTRLW-1:0] ctrl,
- input [DINW-1:0] din,
- input [SELW-1:0] sel,
+ (input wire clk,
+ input wire [CTRLW-1:0] ctrl,
+ input wire [DINW-1:0] din,
+ input wire [SELW-1:0] sel,
output reg [WIDTH-1:0] dout);
localparam SLICE = WIDTH/(SELW**2);
always @(posedge clk)
diff --git a/tests/various/dynamic_part_select/original_gate.v b/tests/various/dynamic_part_select/original_gate.v
index 22093bf63..963b4228c 100644
--- a/tests/various/dynamic_part_select/original_gate.v
+++ b/tests/various/dynamic_part_select/original_gate.v
@@ -1,8 +1,9 @@
+`default_nettype none
module original_gate (clk, ctrl, din, sel, dout);
- input clk;
- input [4:0] ctrl;
- input [1:0] din;
- input [0:0] sel;
+ input wire clk;
+ input wire [4:0] ctrl;
+ input wire [1:0] din;
+ input wire [0:0] sel;
output reg [31:0] dout;
always @(posedge clk)
case (({(ctrl)*(sel)})+(0))
diff --git a/tests/various/dynamic_part_select/reset_test.v b/tests/various/dynamic_part_select/reset_test.v
index 29355aafb..1bb9379f2 100644
--- a/tests/various/dynamic_part_select/reset_test.v
+++ b/tests/various/dynamic_part_select/reset_test.v
@@ -1,8 +1,10 @@
+`default_nettype none
module reset_test #(parameter WIDTH=32, SELW=1, CTRLW=$clog2(WIDTH), DINW=2**SELW)
- (input clk,
- input [CTRLW-1:0] ctrl,
- input [DINW-1:0] din,
- input [SELW-1:0] sel,
+ (input wire clk,
+ input wire reset,
+ input wire [CTRLW-1:0] ctrl,
+ input wire [DINW-1:0] din,
+ input wire [SELW-1:0] sel,
output reg [WIDTH-1:0] dout);
reg [SELW:0] i;
@@ -16,8 +18,6 @@ module reset_test #(parameter WIDTH=32, SELW=1, CTRLW=$clog2(WIDTH), DINW=2**SE
dout[i*rval+:SLICE] <= 32'hDEAD;
end
end
- //else begin
dout[ctrl*sel+:SLICE] <= din;
- //end
end
endmodule
diff --git a/tests/various/dynamic_part_select/reset_test_gate.v b/tests/various/dynamic_part_select/reset_test_gate.v
index 96dff4135..4ae76c4f7 100644
--- a/tests/various/dynamic_part_select/reset_test_gate.v
+++ b/tests/various/dynamic_part_select/reset_test_gate.v
@@ -1,8 +1,10 @@
-module reset_test_gate (clk, ctrl, din, sel, dout);
- input clk;
- input [4:0] ctrl;
- input [1:0] din;
- input [0:0] sel;
+`default_nettype none
+module reset_test_gate (clk, reset, ctrl, din, sel, dout);
+ input wire clk;
+ input wire reset;
+ input wire [4:0] ctrl;
+ input wire [1:0] din;
+ input wire [0:0] sel;
output reg [31:0] dout;
reg [1:0] i;
wire [0:0] rval;
diff --git a/tests/various/dynamic_part_select/reversed.v b/tests/various/dynamic_part_select/reversed.v
index 8b114ac77..0268fa6bb 100644
--- a/tests/various/dynamic_part_select/reversed.v
+++ b/tests/various/dynamic_part_select/reversed.v
@@ -1,8 +1,9 @@
+`default_nettype none
module reversed #(parameter WIDTH=32, SELW=4, CTRLW=$clog2(WIDTH), DINW=2**SELW)
- (input clk,
- input [CTRLW-1:0] ctrl,
- input [DINW-1:0] din,
- input [SELW-1:0] sel,
+ (input wire clk,
+ input wire [CTRLW-1:0] ctrl,
+ input wire [DINW-1:0] din,
+ input wire [SELW-1:0] sel,
output reg [WIDTH-1:0] dout);
localparam SLICE = WIDTH/(SELW**2);
diff --git a/tests/various/dynamic_part_select/reversed_gate.v b/tests/various/dynamic_part_select/reversed_gate.v
index 9349d45ee..5ffdcb4d7 100644
--- a/tests/various/dynamic_part_select/reversed_gate.v
+++ b/tests/various/dynamic_part_select/reversed_gate.v
@@ -1,8 +1,9 @@
+`default_nettype none
module reversed_gate (clk, ctrl, din, sel, dout);
- input clk;
- input [4:0] ctrl;
- input [15:0] din;
- input [3:0] sel;
+ input wire clk;
+ input wire [4:0] ctrl;
+ input wire [15:0] din;
+ input wire [3:0] sel;
output reg [31:0] dout;
always @(posedge clk)
case ((({(32)-((ctrl)*(sel))})+(1))-(2))