aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--backends/cxxrtl/cxxrtl.h16
-rw-r--r--backends/cxxrtl/cxxrtl_backend.cc22
-rw-r--r--backends/cxxrtl/cxxrtl_vcd.h4
-rw-r--r--backends/spice/spice.cc22
-rw-r--r--frontends/ast/dpicall.cc17
-rw-r--r--frontends/ast/simplify.cc3
-rw-r--r--frontends/verific/verific.cc36
-rw-r--r--frontends/verilog/preproc.cc1
-rw-r--r--frontends/verilog/verilog_parser.y96
-rw-r--r--passes/opt/opt_share.cc4
-rw-r--r--passes/techmap/abc.cc37
-rw-r--r--techlibs/xilinx/cells_sim.v80
-rw-r--r--techlibs/xilinx/xilinx_dffopt.cc6
-rw-r--r--tests/arch/xilinx/mux.ys3
-rw-r--r--tests/arch/xilinx/xilinx_dffopt.ys46
-rw-r--r--tests/opt/opt_share_bug2538.ys20
-rw-r--r--tests/simple/macro_arg_spaces.sv28
-rw-r--r--tests/svtypes/typedef_struct_port.sv111
-rw-r--r--tests/svtypes/typedef_struct_port.ys6
-rw-r--r--tests/various/.gitignore1
-rw-r--r--tests/various/rand_const.sv8
-rw-r--r--tests/various/rand_const.ys1
-rw-r--r--tests/verilog/wire_and_var.sv33
-rw-r--r--tests/verilog/wire_and_var.ys9
25 files changed, 510 insertions, 102 deletions
diff --git a/Makefile b/Makefile
index 8602a3f3c..e4a228b81 100644
--- a/Makefile
+++ b/Makefile
@@ -126,7 +126,7 @@ LDFLAGS += -rdynamic
LDLIBS += -lrt
endif
-YOSYS_VER := 0.9+3833
+YOSYS_VER := 0.9+3871
GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN)
OBJS = kernel/version_$(GIT_REV).o
diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h
index 0a6bcb849..0e55c46c2 100644
--- a/backends/cxxrtl/cxxrtl.h
+++ b/backends/cxxrtl/cxxrtl.h
@@ -1217,49 +1217,49 @@ value<BitsY> xnor_ss(const value<BitsA> &a, const value<BitsB> &b) {
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> shl_uu(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template zcast<BitsY>().template shl(b);
+ return a.template zcast<BitsY>().shl(b);
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> shl_su(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template scast<BitsY>().template shl(b);
+ return a.template scast<BitsY>().shl(b);
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> sshl_uu(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template zcast<BitsY>().template shl(b);
+ return a.template zcast<BitsY>().shl(b);
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> sshl_su(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template scast<BitsY>().template shl(b);
+ return a.template scast<BitsY>().shl(b);
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> shr_uu(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template shr(b).template zcast<BitsY>();
+ return a.shr(b).template zcast<BitsY>();
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> shr_su(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template shr(b).template scast<BitsY>();
+ return a.shr(b).template scast<BitsY>();
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> sshr_uu(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template shr(b).template zcast<BitsY>();
+ return a.shr(b).template zcast<BitsY>();
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
CXXRTL_ALWAYS_INLINE
value<BitsY> sshr_su(const value<BitsA> &a, const value<BitsB> &b) {
- return a.template sshr(b).template scast<BitsY>();
+ return a.sshr(b).template scast<BitsY>();
}
template<size_t BitsY, size_t BitsA, size_t BitsB>
diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc
index 861b484f4..39046bd78 100644
--- a/backends/cxxrtl/cxxrtl_backend.cc
+++ b/backends/cxxrtl/cxxrtl_backend.cc
@@ -601,6 +601,12 @@ struct WireType {
bool is_exact() const { return type == ALIAS || type == CONST; }
};
+// Tests for a SigSpec that is a valid clock input, clocks have to have a backing wire and be a single bit
+// using this instead of sig.is_wire() solves issues when the clock is a slice instead of a full wire
+bool is_valid_clock(const RTLIL::SigSpec& sig) {
+ return sig.is_chunk() && sig.is_bit() && sig[0].wire;
+}
+
struct CxxrtlWorker {
bool split_intf = false;
std::string intf_filename;
@@ -1110,7 +1116,8 @@ struct CxxrtlWorker {
// Flip-flops
} else if (is_ff_cell(cell->type)) {
log_assert(!for_debug);
- if (cell->hasPort(ID::CLK) && cell->getPort(ID::CLK).is_wire()) {
+ // Clocks might be slices of larger signals but should only ever be single bit
+ if (cell->hasPort(ID::CLK) && is_valid_clock(cell->getPort(ID::CLK))) {
// Edge-sensitive logic
RTLIL::SigBit clk_bit = cell->getPort(ID::CLK)[0];
clk_bit = sigmaps[clk_bit.wire->module](clk_bit);
@@ -2266,7 +2273,7 @@ struct CxxrtlWorker {
void register_edge_signal(SigMap &sigmap, RTLIL::SigSpec signal, RTLIL::SyncType type)
{
signal = sigmap(signal);
- log_assert(signal.is_wire() && signal.is_bit());
+ log_assert(is_valid_clock(signal));
log_assert(type == RTLIL::STp || type == RTLIL::STn || type == RTLIL::STe);
RTLIL::SigBit sigbit = signal[0];
@@ -2274,7 +2281,8 @@ struct CxxrtlWorker {
edge_types[sigbit] = type;
else if (edge_types[sigbit] != type)
edge_types[sigbit] = RTLIL::STe;
- edge_wires.insert(signal.as_wire());
+ // Cannot use as_wire because signal might not be a full wire, instead extract the wire from the sigbit
+ edge_wires.insert(sigbit.wire);
}
void analyze_design(RTLIL::Design *design)
@@ -2355,14 +2363,14 @@ struct CxxrtlWorker {
// Various DFF cells are treated like posedge/negedge processes, see above for details.
if (cell->type.in(ID($dff), ID($dffe), ID($adff), ID($adffe), ID($dffsr), ID($dffsre), ID($sdff), ID($sdffe), ID($sdffce))) {
- if (sigmap(cell->getPort(ID::CLK)).is_wire())
+ if (is_valid_clock(cell->getPort(ID::CLK)))
register_edge_signal(sigmap, cell->getPort(ID::CLK),
cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn);
}
// Similar for memory port cells.
if (cell->type.in(ID($memrd), ID($memwr))) {
if (cell->getParam(ID::CLK_ENABLE).as_bool()) {
- if (sigmap(cell->getPort(ID::CLK)).is_wire())
+ if (is_valid_clock(cell->getPort(ID::CLK)))
register_edge_signal(sigmap, cell->getPort(ID::CLK),
cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn);
}
@@ -2372,7 +2380,7 @@ struct CxxrtlWorker {
if (cell->type == ID($memwr))
writable_memories.insert(module->memories[cell->getParam(ID::MEMID).decode_string()]);
// Collect groups of memory write ports in the same domain.
- if (cell->type == ID($memwr) && cell->getParam(ID::CLK_ENABLE).as_bool() && cell->getPort(ID::CLK).is_wire()) {
+ if (cell->type == ID($memwr) && cell->getParam(ID::CLK_ENABLE).as_bool() && is_valid_clock(cell->getPort(ID::CLK))) {
RTLIL::SigBit clk_bit = sigmap(cell->getPort(ID::CLK))[0];
const RTLIL::Memory *memory = module->memories[cell->getParam(ID::MEMID).decode_string()];
memwr_per_domain[{clk_bit, memory}].insert(cell);
@@ -2384,7 +2392,7 @@ struct CxxrtlWorker {
}
for (auto cell : module->cells()) {
// Collect groups of memory write ports read by every transparent read port.
- if (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool() && cell->getPort(ID::CLK).is_wire() &&
+ if (cell->type == ID($memrd) && cell->getParam(ID::CLK_ENABLE).as_bool() && is_valid_clock(cell->getPort(ID::CLK)) &&
cell->getParam(ID::TRANSPARENT).as_bool()) {
RTLIL::SigBit clk_bit = sigmap(cell->getPort(ID::CLK))[0];
const RTLIL::Memory *memory = module->memories[cell->getParam(ID::MEMID).decode_string()];
diff --git a/backends/cxxrtl/cxxrtl_vcd.h b/backends/cxxrtl/cxxrtl_vcd.h
index 6ee98b428..3f40a8d12 100644
--- a/backends/cxxrtl/cxxrtl_vcd.h
+++ b/backends/cxxrtl/cxxrtl_vcd.h
@@ -228,13 +228,13 @@ public:
}
void add(const debug_items &items) {
- this->template add(items, [](const std::string &, const debug_item &) {
+ this->add(items, [](const std::string &, const debug_item &) {
return true;
});
}
void add_without_memories(const debug_items &items) {
- this->template add(items, [](const std::string &, const debug_item &item) {
+ this->add(items, [](const std::string &, const debug_item &item) {
return item.type != debug_item::MEMORY;
});
}
diff --git a/backends/spice/spice.cc b/backends/spice/spice.cc
index aa20f106a..ca5c680c9 100644
--- a/backends/spice/spice.cc
+++ b/backends/spice/spice.cc
@@ -64,7 +64,7 @@ static void print_spice_net(std::ostream &f, RTLIL::SigBit s, std::string &neg,
}
}
-static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &ncpf, bool big_endian, bool use_inames)
+static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::Design *design, std::string &neg, std::string &pos, std::string &buf, std::string &ncpf, bool big_endian, bool use_inames)
{
SigMap sigmap(module);
idict<IdString, 1> inums;
@@ -121,10 +121,10 @@ static void print_spice_module(std::ostream &f, RTLIL::Module *module, RTLIL::De
for (auto &conn : module->connections())
for (int i = 0; i < conn.first.size(); i++) {
- f << stringf("V%d", conn_counter++);
- print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
+ f << (buf == "DC" ? stringf("V%d", conn_counter++) : stringf("X%d", cell_counter++));
print_spice_net(f, conn.second.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
- f << stringf(" DC 0\n");
+ print_spice_net(f, conn.first.extract(i, 1), neg, pos, ncpf, nc_counter, use_inames, inums);
+ f << (buf == "DC" ? " DC 0\n" : stringf(" %s\n", buf.c_str()));
}
}
@@ -148,6 +148,10 @@ struct SpiceBackend : public Backend {
log(" -pos net_name\n");
log(" set the net name for constant 1 (default: Vdd)\n");
log("\n");
+ log(" -buf DC|subckt_name\n");
+ log(" set the name for jumper element (default: DC)\n");
+ log(" (used to connect different nets)\n");
+ log("\n");
log(" -nc_prefix\n");
log(" prefix for not-connected nets (default: _NC)\n");
log("\n");
@@ -164,7 +168,7 @@ struct SpiceBackend : public Backend {
std::string top_module_name;
RTLIL::Module *top_module = NULL;
bool big_endian = false, use_inames = false;
- std::string neg = "Vss", pos = "Vdd", ncpf = "_NC";
+ std::string neg = "Vss", pos = "Vdd", ncpf = "_NC", buf = "DC";
log_header(design, "Executing SPICE backend.\n");
@@ -187,6 +191,10 @@ struct SpiceBackend : public Backend {
pos = args[++argidx];
continue;
}
+ if (args[argidx] == "-buf" && argidx+1 < args.size()) {
+ buf = args[++argidx];
+ continue;
+ }
if (args[argidx] == "-nc_prefix" && argidx+1 < args.size()) {
ncpf = args[++argidx];
continue;
@@ -241,14 +249,14 @@ struct SpiceBackend : public Backend {
*f << stringf(" %s", spice_id2str(wire->name).c_str());
}
*f << stringf("\n");
- print_spice_module(*f, module, design, neg, pos, ncpf, big_endian, use_inames);
+ print_spice_module(*f, module, design, neg, pos, buf, ncpf, big_endian, use_inames);
*f << stringf(".ENDS %s\n\n", spice_id2str(module->name).c_str());
}
if (!top_module_name.empty()) {
if (top_module == NULL)
log_error("Can't find top module `%s'!\n", top_module_name.c_str());
- print_spice_module(*f, top_module, design, neg, pos, ncpf, big_endian, use_inames);
+ print_spice_module(*f, top_module, design, neg, pos, buf, ncpf, big_endian, use_inames);
*f << stringf("\n");
}
diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc
index e241142d3..948c9083c 100644
--- a/frontends/ast/dpicall.cc
+++ b/frontends/ast/dpicall.cc
@@ -67,7 +67,7 @@ static ffi_fptr resolve_fn (std::string symbol_name)
AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, const std::vector<std::string> &argtypes, const std::vector<AstNode*> &args)
{
AST::AstNode *newNode = nullptr;
- union { double f64; float f32; int32_t i32; } value_store [args.size() + 1];
+ union { double f64; float f32; int32_t i32; void *ptr; } value_store [args.size() + 1];
ffi_type *types [args.size() + 1];
void *values [args.size() + 1];
ffi_cif cif;
@@ -92,6 +92,11 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname,
value_store[i].i32 = args[i]->asInt(args[i]->is_signed);
values[i] = &value_store[i].i32;
types[i] = &ffi_type_sint32;
+ } else if (argtypes[i] == "chandle") {
+ log(" arg %d (%s): %llx\n", i, argtypes[i].c_str(), (unsigned long long)args[i]->asInt(false));
+ value_store[i].ptr = (void *)args[i]->asInt(args[i]->is_signed);
+ values[i] = &value_store[i].ptr;
+ types[i] = &ffi_type_pointer;
} else {
log_error("invalid argtype '%s' for argument %d.\n", argtypes[i].c_str(), i);
}
@@ -106,6 +111,9 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname,
} else if (rtype == "real") {
types[args.size()] = &ffi_type_double;
values[args.size()] = &value_store[args.size()].f64;
+ } else if (rtype == "chandle") {
+ types[args.size()] = &ffi_type_pointer;
+ values[args.size()] = &value_store[args.size()].ptr;
} else {
log_error("invalid rtype '%s'.\n", rtype.c_str());
}
@@ -123,6 +131,13 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname,
newNode = new AstNode(AST_REALVALUE);
newNode->realvalue = value_store[args.size()].f32;
log(" return realvalue: %g\n", newNode->asReal(true));
+ } else if (rtype == "chandle") {
+ uint64_t rawval = (uint64_t)value_store[args.size()].ptr;
+ std::vector<RTLIL::State> bits(64);
+ for (int i = 0; i < 64; i++)
+ bits.at(i) = (rawval & (1ULL << i)) ? RTLIL::State::S1 : RTLIL::State::S0;
+ newNode = AstNode::mkconst_bits(bits, false);
+ log(" return chandle: %llx\n", (unsigned long long)newNode->asInt(false));
} else {
newNode = AstNode::mkconst_int(value_store[args.size()].i32, false);
log(" return integer: %lld\n", (long long)newNode->asInt(true));
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index d4242f1e7..fc2976c83 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -1330,6 +1330,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (template_node->type == AST_STRUCT || template_node->type == AST_UNION) {
// replace with wire representing the packed structure
newNode = make_packed_struct(template_node, str);
+ // add original input/output attribute to resolved wire
+ newNode->is_input = this->is_input;
+ newNode->is_output = this->is_output;
current_scope[str] = this;
goto apply_newNode;
}
diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc
index cf3bf1070..614124a29 100644
--- a/frontends/verific/verific.cc
+++ b/frontends/verific/verific.cc
@@ -51,12 +51,12 @@ USING_YOSYS_NAMESPACE
#include "VeriLibrary.h"
#include "VeriExtensions.h"
-#ifndef SYMBIOTIC_VERIFIC_API_VERSION
-# error "Only Symbiotic EDA flavored Verific is supported. Please contact office@symbioticeda.com for commercial support for Yosys+Verific."
+#ifndef YOSYSHQ_VERIFIC_API_VERSION
+# error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific."
#endif
-#if SYMBIOTIC_VERIFIC_API_VERSION < 20201101
-# error "Please update your version of Symbiotic EDA flavored Verific."
+#if YOSYSHQ_VERIFIC_API_VERSION < 20201201
+# error "Please update your version of YosysHQ flavored Verific."
#endif
#ifdef __clang__
@@ -1471,7 +1471,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
continue;
}
- if (inst->Type() == PRIM_SEDA_INITSTATE)
+ if (inst->Type() == PRIM_YOSYSHQ_INITSTATE)
{
SigBit initstate = module->Initstate(new_verific_id(inst));
SigBit sig_o = net_map_at(inst->GetOutput());
@@ -2199,7 +2199,7 @@ struct VerificPass : public Pass {
log("\n");
log(" verific -app <application>..\n");
log("\n");
- log("Execute SEDA formal application on loaded Verilog files.\n");
+ log("Execute YosysHQ formal application on loaded Verilog files.\n");
log("\n");
log("Application options:\n");
log("\n");
@@ -2250,11 +2250,11 @@ struct VerificPass : public Pass {
log(" WARNING: Templates only available in commercial build.\n");
log("\n");
#endif
- log("Use Symbiotic EDA Suite if you need Yosys+Verifc.\n");
- log("https://www.symbioticeda.com/seda-suite\n");
+ log("Use YosysHQ Tabby CAD Suite if you need Yosys+Verific.\n");
+ log("https://www.yosyshq.com/\n");
log("\n");
- log("Contact office@symbioticeda.com for free evaluation\n");
- log("binaries of Symbiotic EDA Suite.\n");
+ log("Contact office@yosyshq.com for free evaluation\n");
+ log("binaries of YosysHQ Tabby CAD Suite.\n");
log("\n");
}
#ifdef YOSYS_ENABLE_VERIFIC
@@ -2265,11 +2265,11 @@ struct VerificPass : public Pass {
if (check_noverific_env())
log_cmd_error("This version of Yosys is built without Verific support.\n"
"\n"
- "Use Symbiotic EDA Suite if you need Yosys+Verifc.\n"
- "https://www.symbioticeda.com/seda-suite\n"
+ "Use YosysHQ Tabby CAD Suite if you need Yosys+Verific.\n"
+ "https://www.yosyshq.com/\n"
"\n"
- "Contact office@symbioticeda.com for free evaluation\n"
- "binaries of Symbiotic EDA Suite.\n");
+ "Contact office@yosyshq.com for free evaluation\n"
+ "binaries of YosysHQ Tabby CAD Suite.\n");
log_header(design, "Executing VERIFIC (loading SystemVerilog and VHDL designs using Verific).\n");
@@ -2926,11 +2926,11 @@ struct VerificPass : public Pass {
void execute(std::vector<std::string>, RTLIL::Design *) override {
log_cmd_error("This version of Yosys is built without Verific support.\n"
"\n"
- "Use Symbiotic EDA Suite if you need Yosys+Verifc.\n"
- "https://www.symbioticeda.com/seda-suite\n"
+ "Use YosysHQ Tabby CAD Suite if you need Yosys+Verific.\n"
+ "https://www.yosyshq.com/\n"
"\n"
- "Contact office@symbioticeda.com for free evaluation\n"
- "binaries of Symbiotic EDA Suite.\n");
+ "Contact office@yosyshq.com for free evaluation\n"
+ "binaries of YosysHQ Tabby CAD Suite.\n");
}
#endif
} VerificPass;
diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc
index 752f7a7a8..5a2804a41 100644
--- a/frontends/verilog/preproc.cc
+++ b/frontends/verilog/preproc.cc
@@ -392,7 +392,6 @@ static bool read_argument(std::string &dest)
{
std::vector<char> openers;
for (;;) {
- skip_spaces();
std::string tok = next_token(true);
if (tok == ")") {
if (openers.empty())
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 6c4b06d7f..8bd58d24c 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -282,7 +282,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
%token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
-%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
+%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type
%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number
%type <string> type_name
%type <ast> opt_enum_init enum_type struct_type non_wire_data_type
@@ -619,26 +619,19 @@ non_opt_delay:
delay:
non_opt_delay | %empty;
-wire_type:
- {
- astbuf3 = new AstNode(AST_WIRE);
- current_wire_rand = false;
- current_wire_const = false;
- } wire_type_token_list {
- $$ = astbuf3;
- SET_RULE_LOC(@$, @2, @$);
- };
+io_wire_type:
+ { astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; }
+ wire_type_token_io wire_type_const_rand opt_wire_type_token wire_type_signedness
+ { $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); };
-wire_type_token_list:
- wire_type_token |
- wire_type_token_list wire_type_token |
- wire_type_token_io |
- hierarchical_type_id {
- astbuf3->is_custom_type = true;
- astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
- astbuf3->children.back()->str = *$1;
- delete $1;
- };
+non_io_wire_type:
+ { astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; }
+ wire_type_const_rand wire_type_token wire_type_signedness
+ { $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); };
+
+wire_type:
+ io_wire_type |
+ non_io_wire_type;
wire_type_token_io:
TOK_INPUT {
@@ -652,8 +645,32 @@ wire_type_token_io:
astbuf3->is_output = true;
};
+wire_type_signedness:
+ TOK_SIGNED { astbuf3->is_signed = true; } |
+ TOK_UNSIGNED { astbuf3->is_signed = false; } |
+ %empty;
+
+wire_type_const_rand:
+ TOK_RAND TOK_CONST {
+ current_wire_rand = true;
+ current_wire_const = true;
+ } |
+ TOK_CONST {
+ current_wire_const = true;
+ } |
+ TOK_RAND {
+ current_wire_rand = true;
+ } |
+ %empty;
+
+opt_wire_type_token:
+ wire_type_token | %empty;
+
wire_type_token:
- TOK_WIRE {
+ hierarchical_type_id {
+ astbuf3->is_custom_type = true;
+ astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
+ astbuf3->children.back()->str = *$1;
} |
TOK_WOR {
astbuf3->is_wor = true;
@@ -661,20 +678,27 @@ wire_type_token:
TOK_WAND {
astbuf3->is_wand = true;
} |
+ // wires
+ TOK_WIRE {
+ } |
+ TOK_WIRE logic_type {
+ } |
+ // regs
TOK_REG {
astbuf3->is_reg = true;
} |
- TOK_LOGIC {
- astbuf3->is_logic = true;
+ TOK_VAR TOK_REG {
+ astbuf3->is_reg = true;
} |
+ // logics
TOK_VAR {
astbuf3->is_logic = true;
} |
- TOK_INTEGER {
- astbuf3->is_reg = true;
- astbuf3->range_left = 31;
- astbuf3->range_right = 0;
- astbuf3->is_signed = true;
+ TOK_VAR logic_type {
+ astbuf3->is_logic = true;
+ } |
+ logic_type {
+ astbuf3->is_logic = true;
} |
TOK_GENVAR {
astbuf3->type = AST_GENVAR;
@@ -682,15 +706,15 @@ wire_type_token:
astbuf3->is_signed = true;
astbuf3->range_left = 31;
astbuf3->range_right = 0;
+ };
+
+logic_type:
+ TOK_LOGIC {
} |
- TOK_SIGNED {
+ TOK_INTEGER {
+ astbuf3->range_left = 31;
+ astbuf3->range_right = 0;
astbuf3->is_signed = true;
- } |
- TOK_RAND {
- current_wire_rand = true;
- } |
- TOK_CONST {
- current_wire_const = true;
};
non_opt_range:
@@ -1803,7 +1827,7 @@ type_name: TOK_ID // first time seen
;
typedef_decl:
- TOK_TYPEDEF wire_type range type_name range_or_multirange ';' {
+ TOK_TYPEDEF non_io_wire_type range type_name range_or_multirange ';' {
astbuf1 = $2;
astbuf2 = checkRange(astbuf1, $3);
if (astbuf2)
diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc
index 53296699c..62a478673 100644
--- a/passes/opt/opt_share.cc
+++ b/passes/opt/opt_share.cc
@@ -244,8 +244,8 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
}
if (shared_op->type.in(ID($alu))) {
- shared_op->setPort(ID::X, module->addWire(NEW_ID, GetSize(new_sig_out)));
- shared_op->setPort(ID::CO, module->addWire(NEW_ID, GetSize(new_sig_out)));
+ shared_op->setPort(ID::X, module->addWire(NEW_ID, GetSize(new_out)));
+ shared_op->setPort(ID::CO, module->addWire(NEW_ID, GetSize(new_out)));
}
bool is_fine = shared_op->type.in(FINE_BITWISE_OPS);
diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc
index 192e39372..1169e3da0 100644
--- a/passes/techmap/abc.cc
+++ b/passes/techmap/abc.cc
@@ -54,6 +54,7 @@
#include <cerrno>
#include <sstream>
#include <climits>
+#include <vector>
#ifndef _WIN32
# include <unistd.h>
@@ -654,7 +655,7 @@ struct abc_output_filter
};
void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::string script_file, std::string exe_file,
- std::string liberty_file, std::string constr_file, bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str,
+ std::vector<std::string> &liberty_files, std::string constr_file, bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str,
bool keepff, std::string delay_target, std::string sop_inputs, std::string sop_products, std::string lutin_shared, bool fast_mode,
const std::vector<RTLIL::Cell*> &cells, bool show_tempdir, bool sop_mode, bool abc_dress)
{
@@ -709,8 +710,8 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
std::string abc_script = stringf("read_blif %s/input.blif; ", tempdir_name.c_str());
- if (!liberty_file.empty()) {
- abc_script += stringf("read_lib -w %s; ", liberty_file.c_str());
+ if (!liberty_files.empty()) {
+ for (std::string liberty_file : liberty_files) abc_script += stringf("read_lib -w %s; ", liberty_file.c_str());
if (!constr_file.empty())
abc_script += stringf("read_constr -v %s; ", constr_file.c_str());
} else
@@ -738,7 +739,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
abc_script += fast_mode ? ABC_FAST_COMMAND_LUT : ABC_COMMAND_LUT;
if (all_luts_cost_same && !fast_mode)
abc_script += "; lutpack {S}";
- } else if (!liberty_file.empty())
+ } else if (!liberty_files.empty())
abc_script += constr_file.empty() ? (fast_mode ? ABC_FAST_COMMAND_LIB : ABC_COMMAND_LIB) : (fast_mode ? ABC_FAST_COMMAND_CTR : ABC_COMMAND_CTR);
else if (sop_mode)
abc_script += fast_mode ? ABC_FAST_COMMAND_SOP : ABC_COMMAND_SOP;
@@ -1019,7 +1020,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
if (ifs.fail())
log_error("Can't open ABC output file `%s'.\n", buffer.c_str());
- bool builtin_lib = liberty_file.empty();
+ bool builtin_lib = liberty_files.empty();
RTLIL::Design *mapped_design = new RTLIL::Design;
parse_blif(mapped_design, ifs, builtin_lib ? ID(DFF) : ID(_dff_), false, sop_mode);
@@ -1471,7 +1472,8 @@ struct AbcPass : public Pass {
po_map.clear();
std::string exe_file = yosys_abc_executable;
- std::string script_file, liberty_file, constr_file, clk_str;
+ std::string script_file, default_liberty_file, constr_file, clk_str;
+ std::vector<std::string> liberty_files;
std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1";
bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true;
bool show_tempdir = false, sop_mode = false;
@@ -1489,7 +1491,7 @@ struct AbcPass : public Pass {
std::string lut_arg, luts_arg, g_arg;
exe_file = design->scratchpad_get_string("abc.exe", exe_file /* inherit default value if not set */);
script_file = design->scratchpad_get_string("abc.script", script_file);
- liberty_file = design->scratchpad_get_string("abc.liberty", liberty_file);
+ default_liberty_file = design->scratchpad_get_string("abc.liberty", default_liberty_file);
constr_file = design->scratchpad_get_string("abc.constr", constr_file);
if (design->scratchpad.count("abc.D")) {
delay_target = "-D " + design->scratchpad_get_string("abc.D");
@@ -1551,7 +1553,7 @@ struct AbcPass : public Pass {
continue;
}
if (arg == "-liberty" && argidx+1 < args.size()) {
- liberty_file = args[++argidx];
+ liberty_files.push_back(args[++argidx]);
continue;
}
if (arg == "-constr" && argidx+1 < args.size()) {
@@ -1643,12 +1645,16 @@ struct AbcPass : public Pass {
}
extra_args(args, argidx, design);
+ if (liberty_files.empty() && !default_liberty_file.empty()) liberty_files.push_back(default_liberty_file);
+
rewrite_filename(script_file);
if (!script_file.empty() && !is_absolute_path(script_file) && script_file[0] != '+')
script_file = std::string(pwd) + "/" + script_file;
- rewrite_filename(liberty_file);
- if (!liberty_file.empty() && !is_absolute_path(liberty_file))
- liberty_file = std::string(pwd) + "/" + liberty_file;
+ for (int i = 0; i < GetSize(liberty_files); i++) {
+ rewrite_filename(liberty_files[i]);
+ if (!liberty_files[i].empty() && !is_absolute_path(liberty_files[i]))
+ liberty_files[i] = std::string(pwd) + "/" + liberty_files[i];
+ }
rewrite_filename(constr_file);
if (!constr_file.empty() && !is_absolute_path(constr_file))
constr_file = std::string(pwd) + "/" + constr_file;
@@ -1794,6 +1800,7 @@ struct AbcPass : public Pass {
gate_list.push_back("OAI4");
gate_list.push_back("MUX");
gate_list.push_back("NMUX");
+ goto ok_alias;
}
if (g_arg_from_cmd)
cmd_error(args, g_argidx, stringf("Unsupported gate type: %s", g.c_str()));
@@ -1811,9 +1818,9 @@ struct AbcPass : public Pass {
}
}
- if (!lut_costs.empty() && !liberty_file.empty())
+ if (!lut_costs.empty() && !liberty_files.empty())
log_cmd_error("Got -lut and -liberty! These two options are exclusive.\n");
- if (!constr_file.empty() && liberty_file.empty())
+ if (!constr_file.empty() && liberty_files.empty())
log_cmd_error("Got -constr but no -liberty!\n");
if (enabled_gates.empty()) {
@@ -1844,7 +1851,7 @@ struct AbcPass : public Pass {
initvals.set(&assign_map, mod);
if (!dff_mode || !clk_str.empty()) {
- abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff,
+ abc_module(design, mod, script_file, exe_file, liberty_files, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff,
delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, abc_dress);
continue;
}
@@ -1989,7 +1996,7 @@ struct AbcPass : public Pass {
clk_sig = assign_map(std::get<1>(it.first));
en_polarity = std::get<2>(it.first);
en_sig = assign_map(std::get<3>(it.first));
- abc_module(design, mod, script_file, exe_file, liberty_file, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$",
+ abc_module(design, mod, script_file, exe_file, liberty_files, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$",
keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, abc_dress);
assign_map.set(mod);
}
diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v
index adaf7aee1..a079f1c95 100644
--- a/techlibs/xilinx/cells_sim.v
+++ b/techlibs/xilinx/cells_sim.v
@@ -633,6 +633,41 @@ module FDRSE (
Q <= d;
endmodule
+module FDRSE_1 (
+ output reg Q,
+ (* clkbuf_sink *)
+ (* invertible_pin = "IS_C_INVERTED" *)
+ input C,
+ (* invertible_pin = "IS_CE_INVERTED" *)
+ input CE,
+ (* invertible_pin = "IS_D_INVERTED" *)
+ input D,
+ (* invertible_pin = "IS_R_INVERTED" *)
+ input R,
+ (* invertible_pin = "IS_S_INVERTED" *)
+ input S
+);
+ parameter [0:0] INIT = 1'b0;
+ parameter [0:0] IS_C_INVERTED = 1'b0;
+ parameter [0:0] IS_CE_INVERTED = 1'b0;
+ parameter [0:0] IS_D_INVERTED = 1'b0;
+ parameter [0:0] IS_R_INVERTED = 1'b0;
+ parameter [0:0] IS_S_INVERTED = 1'b0;
+ initial Q <= INIT;
+ wire c = C ^ IS_C_INVERTED;
+ wire ce = CE ^ IS_CE_INVERTED;
+ wire d = D ^ IS_D_INVERTED;
+ wire r = R ^ IS_R_INVERTED;
+ wire s = S ^ IS_S_INVERTED;
+ always @(negedge c)
+ if (r)
+ Q <= 0;
+ else if (s)
+ Q <= 1;
+ else if (ce)
+ Q <= d;
+endmodule
+
(* abc9_box, lib_whitebox *)
module FDCE (
output reg Q,
@@ -837,6 +872,51 @@ module FDCPE (
assign Q = qs ? qp : qc;
endmodule
+module FDCPE_1 (
+ output wire Q,
+ (* clkbuf_sink *)
+ (* invertible_pin = "IS_C_INVERTED" *)
+ input C,
+ input CE,
+ (* invertible_pin = "IS_CLR_INVERTED" *)
+ input CLR,
+ input D,
+ (* invertible_pin = "IS_PRE_INVERTED" *)
+ input PRE
+);
+ parameter [0:0] INIT = 1'b0;
+ parameter [0:0] IS_C_INVERTED = 1'b0;
+ parameter [0:0] IS_CLR_INVERTED = 1'b0;
+ parameter [0:0] IS_PRE_INVERTED = 1'b0;
+ wire c = C ^ IS_C_INVERTED;
+ wire clr = CLR ^ IS_CLR_INVERTED;
+ wire pre = PRE ^ IS_PRE_INVERTED;
+ // Hacky model to avoid simulation-synthesis mismatches.
+ reg qc, qp, qs;
+ initial qc = INIT;
+ initial qp = INIT;
+ initial qs = 0;
+ always @(negedge c, posedge clr) begin
+ if (clr)
+ qc <= 0;
+ else if (CE)
+ qc <= D;
+ end
+ always @(negedge c, posedge pre) begin
+ if (pre)
+ qp <= 1;
+ else if (CE)
+ qp <= D;
+ end
+ always @* begin
+ if (clr)
+ qs <= 0;
+ else if (pre)
+ qs <= 1;
+ end
+ assign Q = qs ? qp : qc;
+endmodule
+
module LDCE (
output reg Q,
(* invertible_pin = "IS_CLR_INVERTED" *)
diff --git a/techlibs/xilinx/xilinx_dffopt.cc b/techlibs/xilinx/xilinx_dffopt.cc
index 365f505fb..598f1b216 100644
--- a/techlibs/xilinx/xilinx_dffopt.cc
+++ b/techlibs/xilinx/xilinx_dffopt.cc
@@ -209,7 +209,7 @@ lut_sigin_done:
continue;
LutData lut_d = it_D->second.first;
Cell *cell_d = it_D->second.second;
- if (cell->getParam(ID(IS_D_INVERTED)).as_bool()) {
+ if (cell->hasParam(ID(IS_D_INVERTED)) && cell->getParam(ID(IS_D_INVERTED)).as_bool()) {
// Flip all bits in the LUT.
for (int i = 0; i < GetSize(lut_d.first); i++)
lut_d.first.bits[i] = (lut_d.first.bits[i] == State::S1) ? State::S0 : State::S1;
@@ -249,7 +249,7 @@ lut_sigin_done:
if (has_s) {
SigBit sig_S = sigmap(cell->getPort(ID::S));
LutData lut_s = LutData(Const(2, 2), {sig_S});
- bool inv_s = cell->getParam(ID(IS_S_INVERTED)).as_bool();
+ bool inv_s = cell->hasParam(ID(IS_S_INVERTED)) && cell->getParam(ID(IS_S_INVERTED)).as_bool();
auto it_S = bit_to_lut.find(sig_S);
if (it_S != bit_to_lut.end())
lut_s = it_S->second.first;
@@ -271,7 +271,7 @@ lut_sigin_done:
if (has_r) {
SigBit sig_R = sigmap(cell->getPort(ID::R));
LutData lut_r = LutData(Const(2, 2), {sig_R});
- bool inv_r = cell->getParam(ID(IS_R_INVERTED)).as_bool();
+ bool inv_r = cell->hasParam(ID(IS_R_INVERTED)) && cell->getParam(ID(IS_R_INVERTED)).as_bool();
auto it_R = bit_to_lut.find(sig_R);
if (it_R != bit_to_lut.end())
lut_r = it_R->second.first;
diff --git a/tests/arch/xilinx/mux.ys b/tests/arch/xilinx/mux.ys
index 1b2788448..c2a23de6d 100644
--- a/tests/arch/xilinx/mux.ys
+++ b/tests/arch/xilinx/mux.ys
@@ -40,10 +40,11 @@ proc
equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux16 # Constrain all select calls below inside the top module
+select -assert-max 2 t:LUT3
select -assert-max 2 t:LUT4
select -assert-min 4 t:LUT6
select -assert-max 7 t:LUT6
select -assert-max 2 t:MUXF7
dump
-select -assert-none t:LUT6 t:LUT4 t:MUXF7 %% t:* %D
+select -assert-none t:LUT6 t:LUT4 t:LUT3 t:MUXF7 %% t:* %D
diff --git a/tests/arch/xilinx/xilinx_dffopt.ys b/tests/arch/xilinx/xilinx_dffopt.ys
index 2c729832e..c09699411 100644
--- a/tests/arch/xilinx/xilinx_dffopt.ys
+++ b/tests/arch/xilinx/xilinx_dffopt.ys
@@ -223,3 +223,49 @@ select -assert-count 1 t:LUT2
select -assert-none t:FDRSE t:LUT4 t:LUT2 %% t:* %D
design -reset
+
+
+read_verilog << EOT
+
+// FDSE_1, mergeable CE and S, but CE only not worth it.
+
+module t0 (...);
+input wire clk;
+input wire [7:0] i;
+output wire [7:0] o;
+
+wire [7:0] tmp ;
+
+LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0]));
+LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1]));
+
+FDSE_1 ff (.D(tmp[0]), .CE(i[7]), .S(tmp[1]), .Q(o[0]));
+
+endmodule
+
+EOT
+
+read_verilog -lib +/xilinx/cells_sim.v
+design -save t0
+
+equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt
+design -load postopt
+clean
+
+cd t0
+select -assert-count 1 t:FDSE_1
+select -assert-count 1 t:LUT5
+select -assert-none t:FDSE_1 t:LUT5 %% t:* %D
+
+design -load t0
+
+equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt -lut4
+design -load postopt
+clean
+
+cd t0
+select -assert-count 1 t:FDSE_1
+select -assert-count 2 t:LUT2
+select -assert-none t:FDSE_1 t:LUT2 %% t:* %D
+
+design -reset
diff --git a/tests/opt/opt_share_bug2538.ys b/tests/opt/opt_share_bug2538.ys
new file mode 100644
index 000000000..7261c6695
--- /dev/null
+++ b/tests/opt/opt_share_bug2538.ys
@@ -0,0 +1,20 @@
+read_verilog <<EOT
+
+module top(...);
+
+input [3:0] A;
+input S;
+output [1:0] Y;
+
+wire [3:0] A1 = A + 1;
+wire [3:0] A2 = A + 2;
+assign Y = S ? A1[3:2] : A2[3:2];
+
+endmodule
+
+EOT
+
+proc
+alumacc
+equiv_opt -assert opt_share
+
diff --git a/tests/simple/macro_arg_spaces.sv b/tests/simple/macro_arg_spaces.sv
new file mode 100644
index 000000000..75c4cd136
--- /dev/null
+++ b/tests/simple/macro_arg_spaces.sv
@@ -0,0 +1,28 @@
+module top(
+ input wire [31:0] i,
+ output wire [31:0] x, y, z
+);
+
+`define BAR(a) a
+`define FOO(a = function automatic [31:0] f) a
+
+`BAR(function automatic [31:0] a);
+ input [31:0] i;
+ a = i * 2;
+endfunction
+
+`FOO();
+ input [31:0] i;
+ f = i * 3;
+endfunction
+
+`FOO(function automatic [31:0] b);
+ input [31:0] i;
+ b = i * 5;
+endfunction
+
+assign x = a(i);
+assign y = f(i);
+assign z = b(i);
+
+endmodule
diff --git a/tests/svtypes/typedef_struct_port.sv b/tests/svtypes/typedef_struct_port.sv
new file mode 100644
index 000000000..ecc03bee8
--- /dev/null
+++ b/tests/svtypes/typedef_struct_port.sv
@@ -0,0 +1,111 @@
+package p;
+
+typedef struct packed {
+ byte a;
+ byte b;
+} p_t;
+
+typedef logic [31:0] l_t;
+
+endpackage
+
+module foo1(
+ input p::p_t p,
+ output p::p_t o
+);
+ assign o = p;
+endmodule
+
+module foo2(p, o);
+ input p::p_t p;
+ output p::p_t o;
+ assign o = p;
+endmodule
+
+module foo3(input p::l_t p, input p::l_t o);
+ assign o = p;
+endmodule
+
+module foo4(input logic [15:0] p, input logic [15:0] o);
+ assign o = p;
+endmodule
+
+module test_parser(a,b,c,d,e,f,g,h,i);
+input [7:0] a; // no explicit net declaration - net is unsigned
+input [7:0] b;
+input signed [7:0] c;
+input signed [7:0] d; // no explicit net declaration - net is signed
+output [7:0] e; // no explicit net declaration - net is unsigned
+output [7:0] f;
+output signed [7:0] g;
+output signed [7:0] h; // no explicit net declaration - net is signed
+output unsigned [7:0] i;
+wire signed [7:0] b; // port b inherits signed attribute from net decl.
+wire [7:0] c; // net c inherits signed attribute from port
+logic signed [7:0] f;// port f inherits signed attribute from logic decl.
+logic [7:0] g; // logic g inherits signed attribute from port
+
+ assign a = 8'b10001111;
+ assign b = 8'b10001111;
+ assign c = 8'b10001111;
+ assign d = 8'b10001111;
+ assign e = 8'b10001111;
+ assign f = 8'b10001111;
+ assign g = 8'b10001111;
+ assign h = 8'b10001111;
+ assign i = 8'b10001111;
+ always_comb begin
+ assert($unsigned(143) == a);
+ assert($signed(-113) == b);
+ assert($signed(-113) == c);
+ assert($signed(-113) == d);
+ assert($unsigned(143) == e);
+ assert($unsigned(143) == f);
+ assert($signed(-113) == g);
+ assert($signed(-113) == h);
+ assert($unsigned(143) == i);
+ end
+endmodule
+
+module top;
+ p::p_t ps;
+ assign ps.a = 8'hAA;
+ assign ps.b = 8'h55;
+ foo1 foo(.p(ps));
+
+ p::p_t body;
+ assign body.a = 8'hBB;
+ assign body.b = 8'h66;
+ foo2 foo_b(.p(body));
+
+ typedef p::l_t local_alias;
+
+ local_alias l_s;
+ assign l_s = 32'hAAAAAAAA;
+ foo3 foo_l(.p(l_s));
+
+ typedef logic [15:0] sl_t;
+
+ sl_t sl_s;
+ assign sl_s = 16'hBBBB;
+ foo4 foo_sl(.p(sl_s));
+
+ typedef sl_t local_alias_st;
+
+ local_alias_st lsl_s;
+ assign lsl_s = 16'hCCCC;
+ foo4 foo_lsl(.p(lsl_s));
+
+ const logic j = 1'b1;
+
+ always_comb begin
+ assert(8'hAA == ps.a);
+ assert(8'h55 == ps.b);
+ assert(8'hBB == body.a);
+ assert(8'h66 == body.b);
+ assert(32'hAAAAAAAA == l_s);
+ assert(16'hBBBB == sl_s);
+ assert(16'hCCCC == lsl_s);
+ assert(1'b1 == j);
+ end
+endmodule
diff --git a/tests/svtypes/typedef_struct_port.ys b/tests/svtypes/typedef_struct_port.ys
new file mode 100644
index 000000000..5b75c3105
--- /dev/null
+++ b/tests/svtypes/typedef_struct_port.ys
@@ -0,0 +1,6 @@
+read_verilog -sv typedef_struct_port.sv
+hierarchy; proc; opt
+select -module top
+sat -verify -seq 1 -tempinduct -prove-asserts -show-all
+select -module test_parser
+sat -verify -seq 1 -tempinduct -prove-asserts -show-all
diff --git a/tests/various/.gitignore b/tests/various/.gitignore
index 12d4e5048..2bb6c7179 100644
--- a/tests/various/.gitignore
+++ b/tests/various/.gitignore
@@ -4,3 +4,4 @@
/write_gzip.v.gz
/run-test.mk
/plugin.so
+/plugin.so.dSYM
diff --git a/tests/various/rand_const.sv b/tests/various/rand_const.sv
new file mode 100644
index 000000000..be00812c0
--- /dev/null
+++ b/tests/various/rand_const.sv
@@ -0,0 +1,8 @@
+module top;
+ rand const reg rx;
+ const reg ry;
+ rand reg rz;
+ rand const integer ix;
+ const integer iy;
+ rand integer iz;
+endmodule
diff --git a/tests/various/rand_const.ys b/tests/various/rand_const.ys
new file mode 100644
index 000000000..74e43c7cc
--- /dev/null
+++ b/tests/various/rand_const.ys
@@ -0,0 +1 @@
+read_verilog -sv rand_const.sv
diff --git a/tests/verilog/wire_and_var.sv b/tests/verilog/wire_and_var.sv
new file mode 100644
index 000000000..79c7c04c6
--- /dev/null
+++ b/tests/verilog/wire_and_var.sv
@@ -0,0 +1,33 @@
+`define TEST(kwd) \
+ kwd kwd``_1; \
+ kwd kwd``_2; \
+ initial kwd``_1 = 1; \
+ assign kwd``_2 = 1;
+
+`define TEST_VAR(kwd) \
+ var kwd var_``kwd``_1; \
+ var kwd var_``kwd``_2; \
+ initial var_``kwd``_1 = 1; \
+ assign var_``kwd``_2 = 1;
+
+`define TEST_WIRE(kwd) \
+ wire kwd wire_``kwd``_1; \
+ wire kwd wire_``kwd``_2; \
+ initial wire_``kwd``_1 = 1; \
+ assign wire_``kwd``_2 = 1;
+
+module top;
+
+`TEST(wire) // wire assigned in a block
+`TEST(reg) // reg assigned in a continuous assignment
+`TEST(logic)
+`TEST(integer)
+
+`TEST_VAR(reg) // reg assigned in a continuous assignment
+`TEST_VAR(logic)
+`TEST_VAR(integer)
+
+`TEST_WIRE(logic) // wire assigned in a block
+`TEST_WIRE(integer) // wire assigned in a block
+
+endmodule
diff --git a/tests/verilog/wire_and_var.ys b/tests/verilog/wire_and_var.ys
new file mode 100644
index 000000000..9359a9d55
--- /dev/null
+++ b/tests/verilog/wire_and_var.ys
@@ -0,0 +1,9 @@
+logger -expect warning "wire '\\wire_1' is assigned in a block" 1
+logger -expect warning "reg '\\reg_2' is assigned in a continuous assignment" 1
+
+logger -expect warning "reg '\\var_reg_2' is assigned in a continuous assignment" 1
+
+logger -expect warning "wire '\\wire_logic_1' is assigned in a block" 1
+logger -expect warning "wire '\\wire_integer_1' is assigned in a block" 1
+
+read_verilog -sv wire_and_var.sv