diff --git a/CHANGELOG b/CHANGELOG index b172988d5db..f42eaca27e1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,9 +2,23 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.39 .. Yosys 0.40-dev +Yosys 0.40 .. Yosys 0.41-dev -------------------------- +Yosys 0.39 .. Yosys 0.40 +-------------------------- + * New commands and options + - Added option "-vhdl2019" to "read" and "verific" pass. + + * Various + - Major documentation overhaul. + - Added port statistics to "stat" command. + - Added new formatting features to cxxrtl backend. + + * Verific support + - Added better support for VHDL constants import. + - Added support for VHDL 2009. + Yosys 0.38 .. Yosys 0.39 -------------------------- * New commands and options diff --git a/CODEOWNERS b/CODEOWNERS index 7d680e9f2e4..879bb8dee21 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -10,6 +10,7 @@ # PATH (can use glob) USERNAME(S) +CODEOWNERS @nakengelhardt passes/cmds/scratchpad.cc @nakengelhardt frontends/rpc/ @whitequark backends/cxxrtl/ @whitequark @@ -19,7 +20,7 @@ passes/opt/opt_lut.cc @whitequark passes/techmap/abc9*.cc @eddiehung @Ravenslofty backends/aiger/xaiger.cc @eddiehung docs/ @KrystalDelusion - +.github/workflows/*.yml @mmicko ## External Contributors # Only users with write permission to the repository get review diff --git a/Makefile b/Makefile index ca229ca4a52..87c19786d12 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,7 @@ LIBS += -lrt endif endif -YOSYS_VER := 0.39+149 +YOSYS_VER := 0.40+7 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -158,7 +158,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 0033808.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline a1bb025.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # @@ -629,6 +629,7 @@ $(eval $(call add_include_file,kernel/sigtools.h)) $(eval $(call add_include_file,kernel/timinginfo.h)) $(eval $(call add_include_file,kernel/utils.h)) $(eval $(call add_include_file,kernel/yosys.h)) +$(eval $(call add_include_file,kernel/yosys_common.h)) $(eval $(call add_include_file,kernel/yw.h)) $(eval $(call add_include_file,libs/ezsat/ezsat.h)) $(eval $(call add_include_file,libs/ezsat/ezminisat.h)) @@ -984,16 +985,27 @@ docs/gen_images: $(Q) $(MAKE) -C docs images DOCS_GUIDELINE_FILES := GettingStarted CodingStyle -docs/guidelines: - $(Q) mkdir -p docs/source/temp - $(Q) cp -f $(addprefix guidelines/,$(DOCS_GUIDELINE_FILES)) docs/source/temp - -# many of these will return an error which can be safely ignored, so we prefix -# the command with a '-' -DOCS_USAGE_PROGS := yosys yosys-config yosys-filterlib yosys-abc yosys-smtbmc yosys-witness -docs/usage: $(addprefix docs/source/temp/,$(DOCS_USAGE_PROGS)) -docs/source/temp/%: docs/guidelines - -$(Q) ./$(PROGRAM_PREFIX)$* --help > $@ 2>&1 +docs/guidelines docs/source/generated: + $(Q) mkdir -p docs/source/generated + $(Q) cp -f $(addprefix guidelines/,$(DOCS_GUIDELINE_FILES)) docs/source/generated + +# some commands return an error and print the usage text to stderr +define DOC_USAGE_STDERR +docs/source/generated/$(1): $(PROGRAM_PREFIX)$(1) docs/source/generated + -$(Q) ./$$< --help 2> $$@ +endef +DOCS_USAGE_STDERR := yosys-config yosys-filterlib yosys-abc +$(foreach usage,$(DOCS_USAGE_STDERR),$(eval $(call DOC_USAGE_STDERR,$(usage)))) + +# others print to stdout +define DOC_USAGE_STDOUT +docs/source/generated/$(1): $(PROGRAM_PREFIX)$(1) docs/source/generated + $(Q) ./$$< --help > $$@ +endef +DOCS_USAGE_STDOUT := yosys yosys-smtbmc yosys-witness +$(foreach usage,$(DOCS_USAGE_STDOUT),$(eval $(call DOC_USAGE_STDOUT,$(usage)))) + +docs/usage: $(addprefix docs/source/generated/,$(DOCS_USAGE_STDOUT) $(DOCS_USAGE_STDERR)) docs/reqs: $(Q) $(MAKE) -C docs reqs diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index a09ae984b3e..31bbc996ffa 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -2014,22 +2014,29 @@ void dump_sync_effect(std::ostream &f, std::string indent, const RTLIL::SigSpec void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { - if (simple_lhs) { + bool all_chunks_wires = true; + for (auto &chunk : left.chunks()) + if (chunk.is_wire() && reg_wires.count(chunk.wire->name)) + all_chunks_wires = false; + if (!simple_lhs && all_chunks_wires) { + f << stringf("%s" "assign ", indent.c_str()); + dump_sigspec(f, left); + f << stringf(" = "); + dump_sigspec(f, right); + f << stringf(";\n"); + } else { int offset = 0; for (auto &chunk : left.chunks()) { - f << stringf("%s" "assign ", indent.c_str()); + if (chunk.is_wire() && reg_wires.count(chunk.wire->name)) + f << stringf("%s" "always%s\n%s ", indent.c_str(), systemverilog ? "_comb" : " @*", indent.c_str()); + else + 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"); } } diff --git a/docs/.gitignore b/docs/.gitignore index d7bfd8e956a..65bbcdeaeb8 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,6 +1,6 @@ /build/ /source/cmd -/source/temp +/source/generated /source/_images/**/*.log /source/_images/**/*.aux /source/_images/**/*.pdf diff --git a/docs/Makefile b/docs/Makefile index a5b2fed6b7d..701157ee6c3 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -48,6 +48,7 @@ help: clean: clean-examples rm -rf $(BUILDDIR)/* rm -rf source/cmd util/__pycache__ + rm -rf source/generated $(MAKE) -C source/_images clean .PHONY: html diff --git a/docs/source/appendix/auxprogs.rst b/docs/source/appendix/auxprogs.rst index b6defbe802e..c239136b64e 100644 --- a/docs/source/appendix/auxprogs.rst +++ b/docs/source/appendix/auxprogs.rst @@ -11,7 +11,7 @@ The ``yosys-config`` tool (an auto-generated shell-script) can be used to query compiler options and other information needed for building loadable modules for Yosys. See :doc:`/yosys_internals/extending_yosys/extensions` for details. -.. literalinclude:: /temp/yosys-config +.. literalinclude:: /generated/yosys-config :start-at: Usage .. _sec:filterlib: @@ -25,7 +25,7 @@ The ``yosys-filterlib`` tool is a small utility that can be used to strip or extract information from a Liberty file. This can be useful for removing sensitive or proprietary information such as timing or other trade secrets. -.. literalinclude:: /temp/yosys-filterlib +.. literalinclude:: /generated/yosys-filterlib :start-at: Usage yosys-abc @@ -36,9 +36,8 @@ been accepted upstream. Not all versions of Yosys work with all versions of ABC. So Yosys comes with its own yosys-abc to avoid compatibility issues between the two. -.. literalinclude:: /temp/yosys-abc +.. literalinclude:: /generated/yosys-abc :start-at: usage - :end-before: UC Berkeley yosys-smtbmc ------------ @@ -46,7 +45,7 @@ yosys-smtbmc The ``yosys-smtbmc`` tool is a utility used by SBY for interacting with smt solvers. -.. literalinclude:: /temp/yosys-smtbmc +.. literalinclude:: /generated/yosys-smtbmc yosys-witness ------------- @@ -55,7 +54,7 @@ yosys-witness This is used in SBY and SCY for producing traces in a consistent format independent of the solver. -.. literalinclude:: /temp/yosys-witness +.. literalinclude:: /generated/yosys-witness :start-at: Usage .. note:: ``yosys-witness`` requires `click`_ Python package for use. diff --git a/docs/source/cmd_ref.rst b/docs/source/cmd_ref.rst index f0c4eaaf927..acf2d1d4141 100644 --- a/docs/source/cmd_ref.rst +++ b/docs/source/cmd_ref.rst @@ -4,7 +4,7 @@ Command line reference ================================================================================ -.. literalinclude:: /temp/yosys +.. literalinclude:: /generated/yosys :start-at: Usage .. toctree:: diff --git a/docs/source/code_examples/extensions/.gitignore b/docs/source/code_examples/extensions/.gitignore index ccdd6bd5c68..675a532eda6 100644 --- a/docs/source/code_examples/extensions/.gitignore +++ b/docs/source/code_examples/extensions/.gitignore @@ -1,2 +1,3 @@ my_cmd.so my_cmd.d +*.log diff --git a/docs/source/code_examples/extensions/Makefile b/docs/source/code_examples/extensions/Makefile index 288983ed356..8b5fa106af1 100644 --- a/docs/source/code_examples/extensions/Makefile +++ b/docs/source/code_examples/extensions/Makefile @@ -13,18 +13,18 @@ my_cmd.so: my_cmd.cc $(YOSYS)-config --exec --cxx $(subst $(DATDIR),../../../../share,$(CXXFLAGS)) --ldflags -o my_cmd.so -shared my_cmd.cc --ldlibs test0.log: my_cmd.so - $(YOSYS) -Ql test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' absval_ref.v + $(YOSYS) -QTl test0.log_new -m ./my_cmd.so -p 'my_cmd foo bar' -f verilog absval_ref.v mv test0.log_new test0.log test1.log: my_cmd.so - $(YOSYS) -Ql test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' absval_ref.v + $(YOSYS) -QTl test1.log_new -m ./my_cmd.so -p 'clean; test1; dump' -f verilog absval_ref.v mv test1.log_new test1.log test1.dot: my_cmd.so $(YOSYS) -m ./my_cmd.so -p 'test1; show -format dot -prefix test1' test2.log: my_cmd.so - $(YOSYS) -Ql test2.log_new -m ./my_cmd.so -p 'hierarchy -top test; test2' sigmap_test.v + $(YOSYS) -QTl test2.log_new -m ./my_cmd.so -p 'hierarchy -top test; test2' -f verilog sigmap_test.v mv test2.log_new test2.log .PHONY: clean diff --git a/docs/source/yosys_internals/formats/cell_library.rst b/docs/source/yosys_internals/formats/cell_library.rst index c80b0740255..2b8dc300154 100644 --- a/docs/source/yosys_internals/formats/cell_library.rst +++ b/docs/source/yosys_internals/formats/cell_library.rst @@ -619,6 +619,48 @@ Finite state machines Add a brief description of the ``$fsm`` cell type. +Coarse arithmetics +~~~~~~~~~~~~~~~~~~~~~ + +The ``$macc`` cell type represents a generalized multiply and accumulate operation. The cell is purely combinational. It outputs the result of summing up a sequence of products and other injected summands. + +.. code-block:: + + Y = 0 +- a0factor1 * a0factor2 +- a1factor1 * a1factor2 +- ... + + B[0] + B[1] + ... + +The A port consists of concatenated pairs of multiplier inputs ("factors"). +A zero length factor2 acts as a constant 1, turning factor1 into a simple summand. + +In this pseudocode, ``u(foo)`` means an unsigned int that's foo bits long. + +.. code-block:: + + struct A { + u(CONFIG.mul_info[0].factor1_len) a0factor1; + u(CONFIG.mul_info[0].factor2_len) a0factor2; + u(CONFIG.mul_info[1].factor1_len) a1factor1; + u(CONFIG.mul_info[1].factor2_len) a1factor2; + ... + }; + +The cell's ``CONFIG`` parameter determines the layout of cell port ``A``. +The CONFIG parameter carries the following information: + +.. code-block:: + + struct CONFIG { + u4 num_bits; + struct mul_info { + bool is_signed; + bool is_subtract; + u(num_bits) factor1_len; + u(num_bits) factor2_len; + }[num_ports]; + }; + +B is an array of concatenated 1-bit-wide unsigned integers to also be summed up. + Specify rules ~~~~~~~~~~~~~ @@ -1152,4 +1194,4 @@ file via ABC using the abc pass. .. todo:: Add information about ``$lut`` and ``$sop`` cells. -.. todo:: Add information about ``$alu``, ``$macc``, ``$fa``, and ``$lcu`` cells. +.. todo:: Add information about ``$alu``, ``$fa``, and ``$lcu`` cells. diff --git a/frontends/verific/Makefile.inc b/frontends/verific/Makefile.inc index c82428613af..df3ac8d2d43 100644 --- a/frontends/verific/Makefile.inc +++ b/frontends/verific/Makefile.inc @@ -14,6 +14,7 @@ ifneq ($(DISABLE_VERIFIC_VHDL),1) $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_1987/. share/verific.new/vhdl_vdbs_1987 $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_1993/. share/verific.new/vhdl_vdbs_1993 $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2008/. share/verific.new/vhdl_vdbs_2008 + $(Q) cp -r $(VERIFIC_DIR)/vhdl_packages/vdbs_2019/. share/verific.new/vhdl_vdbs_2019 endif $(Q) chmod -R a+rX share/verific.new $(Q) mv share/verific.new share/verific diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index faa0e1bcdd3..81e79f7497f 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -214,23 +214,120 @@ RTLIL::IdString VerificImporter::new_verific_id(Verific::DesignObj *obj) return s; } -// When used as attributes or parameter values Verific constants come already processed. -// - Real string values are already under quotes -// - Numeric values with specified width are always converted to binary -// - Rest of user defined values are handled as 32bit integers -// - There could be some internal values that are strings without quotes -// so we check if value is all digits or not -// -// Note: For signed values, verific uses 'sb and decimal values can -// also be negative. -static const RTLIL::Const verific_const(const char *value, bool allow_string = true, bool output_signed = false) +RTLIL::Const mkconst_str(const std::string &str) { - size_t found; + RTLIL::Const val; + std::vector data; + data.reserve(str.size() * 8); + for (size_t i = 0; i < str.size(); i++) { + unsigned char ch = str[str.size() - i - 1]; + for (int j = 0; j < 8; j++) { + data.push_back((ch & 1) ? State::S1 : State::S0); + ch = ch >> 1; + } + } + val.bits = data; + val.flags |= RTLIL::CONST_FLAG_STRING; + return val; +} + +static const RTLIL::Const extract_vhdl_boolean(std::string &val) +{ + if (val == "false") + return RTLIL::Const::from_string("0"); + if (val == "true") + return RTLIL::Const::from_string("1"); + log_error("Expecting VHDL boolean value.\n"); +} + +static const RTLIL::Const extract_vhdl_bit(std::string &val, std::string &typ) +{ + if (val.size()==3 && val[0]=='\'' && val.back()=='\'') + return RTLIL::Const::from_string(val.substr(1,val.size()-2)); + log_error("Error parsing VHDL %s.\n", typ.c_str()); +} + +static const RTLIL::Const extract_vhdl_bit_vector(std::string &val, std::string &typ) +{ + if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { + RTLIL::Const c = RTLIL::Const::from_string(val.substr(1,val.size()-2)); + if (typ == "signed") + c.flags |= RTLIL::CONST_FLAG_SIGNED; + return c; + } + log_error("Error parsing VHDL %s.\n", typ.c_str()); +} + +static const RTLIL::Const extract_vhdl_integer(std::string &val) +{ + char *end; + return RTLIL::Const((int)std::strtol(val.c_str(), &end, 10), 32); +} + +static const RTLIL::Const extract_vhdl_char(std::string &val) +{ + if (val.size()==3 && val[0]=='\"' && val.back()=='\"') + return RTLIL::Const((int)val[1], 32); + log_error("Error parsing VHDL character.\n"); +} + +static const RTLIL::Const extract_real_value(std::string &val) +{ + RTLIL::Const c = mkconst_str(val); + c.flags |= RTLIL::CONST_FLAG_REAL; + return c; +} + +static const RTLIL::Const extract_vhdl_string(std::string &val) +{ + if (!(val.size()>1 && val[0]=='\"' && val.back()=='\"')) + log_error("Error parsing VHDL string.\n"); + return RTLIL::Const(val.substr(1,val.size()-2)); +} + +static const RTLIL::Const extract_vhdl_const(const char *value, bool output_signed) +{ + RTLIL::Const c; char *end; int decimal; bool is_signed = false; + std::string val = std::string(value); + + if (val.size()>1 && val[0]=='\"' && val.back()=='\"') { + std::string data = val.substr(1,val.size()-2); + bool isBinary = std::all_of(data.begin(), data.end(), [](char c) {return c=='1' || c=='0'; }); + if (isBinary) + c = RTLIL::Const::from_string(data); + else + c = RTLIL::Const(data); + } else if (val.size()==3 && val[0]=='\'' && val.back()=='\'') { + c = RTLIL::Const::from_string(val.substr(1,val.size()-2)); + } else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) && + ((decimal = std::strtol(value, &end, 10)), !end[0])) { + is_signed = output_signed; + c = RTLIL::Const((int)decimal, 32); + } else if (val == "false") { + c = RTLIL::Const::from_string("0"); + } else if (val == "true") { + c = RTLIL::Const::from_string("1"); + } else { + c = mkconst_str(val); + log_warning("encoding value '%s' as string.\n", value); + } + if (is_signed) + c.flags |= RTLIL::CONST_FLAG_SIGNED; + return c; +} + +static const RTLIL::Const extract_verilog_const(const char *value, bool allow_string, bool output_signed) +{ RTLIL::Const c; + char *end; + int decimal; + bool is_signed = false; + size_t found; std::string val = std::string(value); + if (allow_string && val.size()>1 && val[0]=='\"' && val.back()=='\"') { c = RTLIL::Const(val.substr(1,val.size()-2)); } else if ((found = val.find("'sb")) != std::string::npos) { @@ -245,15 +342,56 @@ static const RTLIL::Const verific_const(const char *value, bool allow_string = t } else if (allow_string) { c = RTLIL::Const(val); } else { - log_error("expected numeric constant but found '%s'", value); + c = mkconst_str(val); + log_warning("encoding value '%s' as string.\n", value); } - if (is_signed) c.flags |= RTLIL::CONST_FLAG_SIGNED; - return c; } +// When used as attributes or parameter values Verific constants come already processed. +// - Real string values are already under quotes +// - Numeric values with specified width are always converted to binary +// - Rest of user defined values are handled as 32bit integers +// - There could be some internal values that are strings without quotes +// so we check if value is all digits or not +// +// Note: For signed values, verific uses 'sb and decimal values can +// also be negative. +static const RTLIL::Const verific_const(const char* type_name, const char *value, DesignObj *obj, bool allow_string = true, bool output_signed = false) +{ + std::string val = std::string(value); + // VHDL + if (obj->IsFromVhdl()) { + if (type_name) { + std::string typ = std::string(type_name); + transform(typ.begin(), typ.end(), typ.begin(), ::tolower); + if (typ == "integer" || typ == "natural" || typ=="positive") return extract_vhdl_integer(val); + else if (typ =="boolean") return extract_vhdl_boolean(val); + else if (typ == "bit" || typ =="std_logic" || typ == "std_ulogic") return extract_vhdl_bit(val,typ); + else if (typ == "character") return extract_vhdl_char(val); + else if (typ == "bit_vector" || typ == "std_logic_vector" || typ == "std_ulogic_vector" || + typ == "unsigned" || typ == "signed") return extract_vhdl_bit_vector(val,typ); + else if (typ == "real") return extract_real_value(val); + else if (typ == "string") return extract_vhdl_string(val); + else { + if (val.size()>1 && val[0]=='\"' && val.back()=='\"') + return RTLIL::Const(val.substr(1,val.size()-2)); + else if (val.size()==3 && val[0]=='\'' && val.back()=='\'') + return RTLIL::Const(val.substr(1,val.size()-2)); + else + return RTLIL::Const(val); + } + } else extract_vhdl_const(value, output_signed); + } + // SystemVerilog + if (type_name && strcmp(type_name, "real")==0) { + return extract_real_value(val); + } else + return extract_verilog_const(value, allow_string, output_signed); +} + static const std::string verific_unescape(const char *value) { std::string val = std::string(value); @@ -276,7 +414,7 @@ void VerificImporter::import_attributes(dict &att FOREACH_ATTRIBUTE(obj, mi, attr) { if (attr->Key()[0] == ' ' || attr->Value() == nullptr) continue; - attributes[RTLIL::escape_id(attr->Key())] = verific_const(attr->Value()); + attributes[RTLIL::escape_id(attr->Key())] = verific_const(nullptr, attr->Value(), obj); } if (nl) { @@ -298,7 +436,7 @@ void VerificImporter::import_attributes(dict &att const char *k, *v; FOREACH_MAP_ITEM(type_range->GetEnumIdMap(), mi, &k, &v) { if (nl->IsFromVerilog()) { - auto const value = verific_const(v, false); + auto const value = verific_const(type_name, v, nl, false); attributes.emplace(stringf("\\enum_value_%s", value.as_string().c_str()), RTLIL::escape_id(k)); } @@ -1292,6 +1430,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma } import_attributes(module->attributes, nl, nl); module->set_string_attribute(ID::hdlname, nl->CellBaseName()); + module->set_string_attribute(ID(library), nl->Owner()->Owner()->Name()); #ifdef VERIFIC_VHDL_SUPPORT if (nl->IsFromVhdl()) { NameSpace name_space(0); @@ -1304,7 +1443,8 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma MapIter mi; FOREACH_PARAMETER_OF_NETLIST(nl, mi, param_name, param_value) { module->avail_parameters(RTLIL::escape_id(param_name)); - module->parameter_default_values[RTLIL::escape_id(param_name)] = verific_const(param_value); + const TypeRange *tr = nl->GetTypeRange(param_name) ; + module->parameter_default_values[RTLIL::escape_id(param_name)] = verific_const(tr->GetTypeName(), param_value, nl); } SetIter si; @@ -2004,7 +2144,8 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma const char *param_value ; if (is_blackbox(inst->View())) { FOREACH_PARAMETER_OF_INST(inst, mi2, param_name, param_value) { - cell->setParam(RTLIL::escape_id(param_name), verific_const(param_value)); + const TypeRange *tr = inst->View()->GetTypeRange(param_name) ; + cell->setParam(RTLIL::escape_id(param_name), verific_const(tr->GetTypeName(), param_value, inst->View())); } } @@ -2699,7 +2840,7 @@ struct VerificPass : public Pass { log("\n"); log("\n"); #ifdef VERIFIC_VHDL_SUPPORT - log(" verific {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl} ..\n"); + log(" verific {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl2019|-vhdl} ..\n"); log("\n"); log("Load the specified VHDL files into Verific.\n"); log("\n"); @@ -3436,6 +3577,29 @@ struct VerificPass : public Pass { goto check_error; } + if (GetSize(args) > argidx && (args[argidx] == "-vhdl2019")) { + vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2019").c_str()); + bool flag_lib = false; + for (argidx++; argidx < GetSize(args); argidx++) { + if (args[argidx] == "-lib") { + flag_lib = true; + continue; + } + if (args[argidx].compare(0, 1, "-") == 0) { + cmd_error(args, argidx, "unknown option"); + goto check_error; + } + Map map(POINTER_HASH); + add_units_to_map(map, work, flag_lib); + std::string filename = frontent_rewrite(args, argidx, tmp_files); + if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2019)) + log_cmd_error("Reading `%s' in VHDL_2019 mode failed.\n", filename.c_str()); + set_units_to_blackbox(map, work, flag_lib); + } + verific_import_pending = true; + goto check_error; + } + if (GetSize(args) > argidx && (args[argidx] == "-vhdl2008" || args[argidx] == "-vhdl")) { vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2008").c_str()); bool flag_lib = false; @@ -3979,7 +4143,7 @@ struct ReadPass : public Pass { log("\n"); log("\n"); #ifdef VERIFIC_VHDL_SUPPORT - log(" read {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl} ..\n"); + log(" read {-vhdl87|-vhdl93|-vhdl2k|-vhdl2008|-vhdl2019|-vhdl} ..\n"); log("\n"); log("Load the specified VHDL files. (Requires Verific.)\n"); log("\n"); @@ -4083,7 +4247,7 @@ struct ReadPass : public Pass { } #ifdef VERIFIC_VHDL_SUPPORT - if (args[1] == "-vhdl87" || args[1] == "-vhdl93" || args[1] == "-vhdl2k" || args[1] == "-vhdl2008" || args[1] == "-vhdl") { + if (args[1] == "-vhdl87" || args[1] == "-vhdl93" || args[1] == "-vhdl2k" || args[1] == "-vhdl2008" || args[1] == "-vhdl2019" || args[1] == "-vhdl") { if (use_verific) { args[0] = "verific"; Pass::call(design, args); diff --git a/kernel/log.h b/kernel/log.h index e4f06c69d19..53aae58c6bc 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -17,11 +17,11 @@ * */ -#include "kernel/yosys.h" - #ifndef LOG_H #define LOG_H +#include "kernel/yosys_common.h" + #include #include @@ -449,4 +449,6 @@ void log_dump_args_worker(const char *p, T first, Args ... args) YOSYS_NAMESPACE_END +#include "kernel/yosys.h" + #endif diff --git a/kernel/register.h b/kernel/register.h index 08ce4b28787..25ea9f2321c 100644 --- a/kernel/register.h +++ b/kernel/register.h @@ -17,11 +17,12 @@ * */ -#include "kernel/yosys.h" - #ifndef REGISTER_H #define REGISTER_H +#include "kernel/yosys_common.h" +#include "kernel/yosys.h" + YOSYS_NAMESPACE_BEGIN struct Pass diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 40422dce56d..f9da2949508 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -17,11 +17,12 @@ * */ -#include "kernel/yosys.h" - #ifndef RTLIL_H #define RTLIL_H +#include "kernel/yosys_common.h" +#include "kernel/yosys.h" + YOSYS_NAMESPACE_BEGIN namespace RTLIL diff --git a/kernel/yosys.h b/kernel/yosys.h index 0a4641d1819..5922d9ab752 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -39,323 +39,7 @@ #ifndef YOSYS_H #define YOSYS_H -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WITH_PYTHON -#include -#endif - -#ifndef _YOSYS_ -# error It looks like you are trying to build Yosys without the config defines set. \ - When building Yosys with a custom make system, make sure you set all the \ - defines the Yosys Makefile would set for your build configuration. -#endif - -#ifdef YOSYS_ENABLE_TCL -# include -# ifdef YOSYS_MXE_HACKS -extern Tcl_Command Tcl_CreateCommand(Tcl_Interp *interp, const char *cmdName, Tcl_CmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); -extern Tcl_Interp *Tcl_CreateInterp(void); -extern void Tcl_Preserve(ClientData data); -extern void Tcl_Release(ClientData clientData); -extern int Tcl_InterpDeleted(Tcl_Interp *interp); -extern void Tcl_DeleteInterp(Tcl_Interp *interp); -extern int Tcl_Eval(Tcl_Interp *interp, const char *script); -extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName); -extern void Tcl_Finalize(void); -extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr); -extern const char *Tcl_GetStringResult(Tcl_Interp *interp); -extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length); -extern Tcl_Obj *Tcl_NewIntObj(int intValue); -extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]); -extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); -# endif -# undef CONST -# undef INLINE -#endif - -#ifdef _WIN32 -# undef NOMINMAX -# define NOMINMAX 1 -# undef YY_NO_UNISTD_H -# define YY_NO_UNISTD_H 1 - -# include -# include -# include - -# define strtok_r strtok_s -# define strdup _strdup -# define snprintf _snprintf -# define getcwd _getcwd -# define mkdir _mkdir -# define popen _popen -# define pclose _pclose - -# ifndef __MINGW32__ -# define PATH_MAX MAX_PATH -# define isatty _isatty -# define fileno _fileno -# endif - -// The following defines conflict with our identifiers: -# undef CONST -// `wingdi.h` defines a TRANSPARENT macro that conflicts with X(TRANSPARENT) entry in kernel/constids.inc -# undef TRANSPARENT -#endif - -#ifndef PATH_MAX -# define PATH_MAX 4096 -#endif - -#define YOSYS_NAMESPACE Yosys -#define PRIVATE_NAMESPACE_BEGIN namespace { -#define PRIVATE_NAMESPACE_END } -#define YOSYS_NAMESPACE_BEGIN namespace Yosys { -#define YOSYS_NAMESPACE_END } -#define YOSYS_NAMESPACE_PREFIX Yosys:: -#define USING_YOSYS_NAMESPACE using namespace Yosys; - -#if defined(__GNUC__) || defined(__clang__) -# define YS_ATTRIBUTE(...) __attribute__((__VA_ARGS__)) -#elif defined(_MSC_VER) -# define YS_ATTRIBUTE(...) -#else -# define YS_ATTRIBUTE(...) -#endif - -#if defined(__GNUC__) || defined(__clang__) -# define YS_MAYBE_UNUSED __attribute__((__unused__)) -#else -# define YS_MAYBE_UNUSED -#endif - -#if __cplusplus >= 201703L -# define YS_FALLTHROUGH [[fallthrough]]; -#elif defined(__clang__) -# define YS_FALLTHROUGH [[clang::fallthrough]]; -#elif defined(__GNUC__) -# define YS_FALLTHROUGH [[gnu::fallthrough]]; -#else -# define YS_FALLTHROUGH -#endif - -YOSYS_NAMESPACE_BEGIN - -// Note: All headers included in hashlib.h must be included -// outside of YOSYS_NAMESPACE before this or bad things will happen. -#ifdef HASHLIB_H -# undef HASHLIB_H -# include "kernel/hashlib.h" -#else -# include "kernel/hashlib.h" -# undef HASHLIB_H -#endif - -using std::vector; -using std::string; -using std::tuple; -using std::pair; - -using std::make_tuple; -using std::make_pair; -using std::get; -using std::min; -using std::max; - -// A primitive shared string implementation that does not -// move its .c_str() when the object is copied or moved. -struct shared_str { - std::shared_ptr content; - shared_str() { } - shared_str(string s) { content = std::shared_ptr(new string(s)); } - shared_str(const char *s) { content = std::shared_ptr(new string(s)); } - const char *c_str() const { return content->c_str(); } - const string &str() const { return *content; } - bool operator==(const shared_str &other) const { return *content == *other.content; } - unsigned int hash() const { return hashlib::hash_ops::hash(*content); } -}; - -using hashlib::mkhash; -using hashlib::mkhash_init; -using hashlib::mkhash_add; -using hashlib::mkhash_xorshift; -using hashlib::hash_ops; -using hashlib::hash_cstr_ops; -using hashlib::hash_ptr_ops; -using hashlib::hash_obj_ops; -using hashlib::dict; -using hashlib::idict; -using hashlib::pool; -using hashlib::mfp; - -namespace RTLIL { - struct IdString; - struct Const; - struct SigBit; - struct SigSpec; - struct Wire; - struct Cell; - struct Memory; - struct Process; - struct Module; - struct Design; - struct Monitor; - enum State : unsigned char; -} - -namespace AST { - struct AstNode; -} - -using RTLIL::IdString; -using RTLIL::Const; -using RTLIL::SigBit; -using RTLIL::SigSpec; -using RTLIL::Wire; -using RTLIL::Cell; -using RTLIL::Module; -using RTLIL::Design; - -namespace hashlib { - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; - template<> struct hash_ops : hash_obj_ops {}; -} - -void memhasher_on(); -void memhasher_off(); -void memhasher_do(); - -extern bool memhasher_active; -inline void memhasher() { if (memhasher_active) memhasher_do(); } - -void yosys_banner(); -int ceil_log2(int x) YS_ATTRIBUTE(const); - -inline std::string vstringf(const char *fmt, va_list ap) -{ - // For the common case of strings shorter than 128, save a heap - // allocation by using a stack allocated buffer. - const int kBufSize = 128; - char buf[kBufSize]; - buf[0] = '\0'; - va_list apc; - va_copy(apc, ap); - int n = vsnprintf(buf, kBufSize, fmt, apc); - va_end(apc); - if (n < kBufSize) - return std::string(buf); - - std::string string; - char *str = NULL; -#if defined(_WIN32 )|| defined(__CYGWIN__) - int sz = 2 * kBufSize, rc; - while (1) { - va_copy(apc, ap); - str = (char*)realloc(str, sz); - rc = vsnprintf(str, sz, fmt, apc); - va_end(apc); - if (rc >= 0 && rc < sz) - break; - sz *= 2; - } - if (str != NULL) { - string = str; - free(str); - } - return string; -#else - if (vasprintf(&str, fmt, ap) < 0) - str = NULL; - if (str != NULL) { - string = str; - free(str); - } - return string; -#endif -} - -std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); - -inline std::string stringf(const char *fmt, ...) -{ - std::string string; - va_list ap; - - va_start(ap, fmt); - string = vstringf(fmt, ap); - va_end(ap); - - return string; -} - -int readsome(std::istream &f, char *s, int n); -std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false); -std::vector split_tokens(const std::string &text, const char *sep = " \t\r\n"); -bool patmatch(const char *pattern, const char *string); -#if !defined(YOSYS_DISABLE_SPAWN) -int run_command(const std::string &command, std::function process_line = std::function()); -#endif -std::string get_base_tmpdir(); -std::string make_temp_file(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); -std::string make_temp_dir(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); -bool check_file_exists(std::string filename, bool is_exec = false); -bool check_directory_exists(const std::string& dirname); -bool is_absolute_path(std::string filename); -void remove_directory(std::string dirname); -bool create_directory(const std::string& dirname); -std::string escape_filename_spaces(const std::string& filename); - -template int GetSize(const T &obj) { return obj.size(); } -inline int GetSize(RTLIL::Wire *wire); - -extern int autoidx; -extern int yosys_xtrace; - -YOSYS_NAMESPACE_END +#include "kernel/yosys_common.h" #include "kernel/log.h" #include "kernel/rtlil.h" @@ -363,14 +47,6 @@ YOSYS_NAMESPACE_END YOSYS_NAMESPACE_BEGIN -using RTLIL::State; -using RTLIL::SigChunk; -using RTLIL::SigSig; - -namespace hashlib { - template<> struct hash_ops : hash_ops {}; -} - void yosys_setup(); #ifdef WITH_PYTHON @@ -385,26 +61,6 @@ Tcl_Interp *yosys_get_tcl_interp(); extern RTLIL::Design *yosys_design; -RTLIL::IdString new_id(std::string file, int line, std::string func); -RTLIL::IdString new_id_suffix(std::string file, int line, std::string func, std::string suffix); - -#define NEW_ID \ - YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) -#define NEW_ID_SUFFIX(suffix) \ - YOSYS_NAMESPACE_PREFIX new_id_suffix(__FILE__, __LINE__, __FUNCTION__, suffix) - -// Create a statically allocated IdString object, using for example ID::A or ID($add). -// -// Recipe for Converting old code that is using conversion of strings like ID::A and -// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for -// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary. -// -// sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' -// -#define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \ - static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })() -namespace ID = RTLIL::ID; - RTLIL::Design *yosys_get_design(); std::string proc_self_dirname(); std::string proc_share_dirname(); diff --git a/kernel/yosys_common.h b/kernel/yosys_common.h new file mode 100644 index 00000000000..9f1bc2f58d7 --- /dev/null +++ b/kernel/yosys_common.h @@ -0,0 +1,379 @@ +/* -*- c++ -*- + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef YOSYS_COMMON_H +#define YOSYS_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WITH_PYTHON +#include +#endif + +#ifndef _YOSYS_ +# error It looks like you are trying to build Yosys without the config defines set. \ + When building Yosys with a custom make system, make sure you set all the \ + defines the Yosys Makefile would set for your build configuration. +#endif + +#ifdef YOSYS_ENABLE_TCL +# include +# ifdef YOSYS_MXE_HACKS +extern Tcl_Command Tcl_CreateCommand(Tcl_Interp *interp, const char *cmdName, Tcl_CmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); +extern Tcl_Interp *Tcl_CreateInterp(void); +extern void Tcl_Preserve(ClientData data); +extern void Tcl_Release(ClientData clientData); +extern int Tcl_InterpDeleted(Tcl_Interp *interp); +extern void Tcl_DeleteInterp(Tcl_Interp *interp); +extern int Tcl_Eval(Tcl_Interp *interp, const char *script); +extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName); +extern void Tcl_Finalize(void); +extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr); +extern const char *Tcl_GetStringResult(Tcl_Interp *interp); +extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length); +extern Tcl_Obj *Tcl_NewIntObj(int intValue); +extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]); +extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); +# endif +# undef CONST +# undef INLINE +#endif + +#ifdef _WIN32 +# undef NOMINMAX +# define NOMINMAX 1 +# undef YY_NO_UNISTD_H +# define YY_NO_UNISTD_H 1 + +# include +# include +# include + +# define strtok_r strtok_s +# define strdup _strdup +# define snprintf _snprintf +# define getcwd _getcwd +# define mkdir _mkdir +# define popen _popen +# define pclose _pclose + +# ifndef __MINGW32__ +# define PATH_MAX MAX_PATH +# define isatty _isatty +# define fileno _fileno +# endif + +// The following defines conflict with our identifiers: +# undef CONST +// `wingdi.h` defines a TRANSPARENT macro that conflicts with X(TRANSPARENT) entry in kernel/constids.inc +# undef TRANSPARENT +#endif + +#ifndef PATH_MAX +# define PATH_MAX 4096 +#endif + + +#define YOSYS_NAMESPACE Yosys +#define PRIVATE_NAMESPACE_BEGIN namespace { +#define PRIVATE_NAMESPACE_END } +#define YOSYS_NAMESPACE_BEGIN namespace Yosys { +#define YOSYS_NAMESPACE_END } +#define YOSYS_NAMESPACE_PREFIX Yosys:: +#define USING_YOSYS_NAMESPACE using namespace Yosys; + +#if defined(__GNUC__) || defined(__clang__) +# define YS_ATTRIBUTE(...) __attribute__((__VA_ARGS__)) +#elif defined(_MSC_VER) +# define YS_ATTRIBUTE(...) +#else +# define YS_ATTRIBUTE(...) +#endif + +#if defined(__GNUC__) || defined(__clang__) +# define YS_MAYBE_UNUSED __attribute__((__unused__)) +#else +# define YS_MAYBE_UNUSED +#endif + +#if __cplusplus >= 201703L +# define YS_FALLTHROUGH [[fallthrough]]; +#elif defined(__clang__) +# define YS_FALLTHROUGH [[clang::fallthrough]]; +#elif defined(__GNUC__) +# define YS_FALLTHROUGH [[gnu::fallthrough]]; +#else +# define YS_FALLTHROUGH +#endif + + +YOSYS_NAMESPACE_BEGIN + +// Note: All headers included in hashlib.h must be included +// outside of YOSYS_NAMESPACE before this or bad things will happen. +#ifdef HASHLIB_H +# undef HASHLIB_H +# include "kernel/hashlib.h" +#else +# include "kernel/hashlib.h" +# undef HASHLIB_H +#endif + + +using std::vector; +using std::string; +using std::tuple; +using std::pair; + +using std::make_tuple; +using std::make_pair; +using std::get; +using std::min; +using std::max; + +// A primitive shared string implementation that does not +// move its .c_str() when the object is copied or moved. +struct shared_str { + std::shared_ptr content; + shared_str() { } + shared_str(string s) { content = std::shared_ptr(new string(s)); } + shared_str(const char *s) { content = std::shared_ptr(new string(s)); } + const char *c_str() const { return content->c_str(); } + const string &str() const { return *content; } + bool operator==(const shared_str &other) const { return *content == *other.content; } + unsigned int hash() const { return hashlib::hash_ops::hash(*content); } +}; + +using hashlib::mkhash; +using hashlib::mkhash_init; +using hashlib::mkhash_add; +using hashlib::mkhash_xorshift; +using hashlib::hash_ops; +using hashlib::hash_cstr_ops; +using hashlib::hash_ptr_ops; +using hashlib::hash_obj_ops; +using hashlib::dict; +using hashlib::idict; +using hashlib::pool; +using hashlib::mfp; + +namespace RTLIL { + struct IdString; + struct Const; + struct SigBit; + struct SigSpec; + struct Wire; + struct Cell; + struct Memory; + struct Process; + struct Module; + struct Design; + struct Monitor; + struct Selection; + struct SigChunk; + enum State : unsigned char; + + typedef std::pair SigSig; + + namespace ID {} +} + +namespace AST { + struct AstNode; +} + +using RTLIL::IdString; +using RTLIL::Const; +using RTLIL::SigBit; +using RTLIL::SigSpec; +using RTLIL::Wire; +using RTLIL::Cell; +using RTLIL::Module; +using RTLIL::Design; + +using RTLIL::State; +using RTLIL::SigChunk; +using RTLIL::SigSig; + +namespace hashlib { + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; + template<> struct hash_ops : hash_obj_ops {}; +} + +void memhasher_on(); +void memhasher_off(); +void memhasher_do(); + +extern bool memhasher_active; +inline void memhasher() { if (memhasher_active) memhasher_do(); } + +void yosys_banner(); +int ceil_log2(int x) YS_ATTRIBUTE(const); + +inline std::string vstringf(const char *fmt, va_list ap) +{ + // For the common case of strings shorter than 128, save a heap + // allocation by using a stack allocated buffer. + const int kBufSize = 128; + char buf[kBufSize]; + buf[0] = '\0'; + va_list apc; + va_copy(apc, ap); + int n = vsnprintf(buf, kBufSize, fmt, apc); + va_end(apc); + if (n < kBufSize) + return std::string(buf); + + std::string string; + char *str = NULL; +#if defined(_WIN32 )|| defined(__CYGWIN__) + int sz = 2 * kBufSize, rc; + while (1) { + va_copy(apc, ap); + str = (char*)realloc(str, sz); + rc = vsnprintf(str, sz, fmt, apc); + va_end(apc); + if (rc >= 0 && rc < sz) + break; + sz *= 2; + } + if (str != NULL) { + string = str; + free(str); + } + return string; +#else + if (vasprintf(&str, fmt, ap) < 0) + str = NULL; + if (str != NULL) { + string = str; + free(str); + } + return string; +#endif +} + +std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2)); + +inline std::string stringf(const char *fmt, ...) +{ + std::string string; + va_list ap; + + va_start(ap, fmt); + string = vstringf(fmt, ap); + va_end(ap); + + return string; +} + +int readsome(std::istream &f, char *s, int n); +std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false); +std::vector split_tokens(const std::string &text, const char *sep = " \t\r\n"); +bool patmatch(const char *pattern, const char *string); +#if !defined(YOSYS_DISABLE_SPAWN) +int run_command(const std::string &command, std::function process_line = std::function()); +#endif +std::string get_base_tmpdir(); +std::string make_temp_file(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); +std::string make_temp_dir(std::string template_str = get_base_tmpdir() + "/yosys_XXXXXX"); +bool check_file_exists(std::string filename, bool is_exec = false); +bool check_directory_exists(const std::string& dirname); +bool is_absolute_path(std::string filename); +void remove_directory(std::string dirname); +bool create_directory(const std::string& dirname); +std::string escape_filename_spaces(const std::string& filename); + +template int GetSize(const T &obj) { return obj.size(); } +inline int GetSize(RTLIL::Wire *wire); + +extern int autoidx; +extern int yosys_xtrace; + +RTLIL::IdString new_id(std::string file, int line, std::string func); +RTLIL::IdString new_id_suffix(std::string file, int line, std::string func, std::string suffix); + +#define NEW_ID \ + YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__) +#define NEW_ID_SUFFIX(suffix) \ + YOSYS_NAMESPACE_PREFIX new_id_suffix(__FILE__, __LINE__, __FUNCTION__, suffix) + +// Create a statically allocated IdString object, using for example ID::A or ID($add). +// +// Recipe for Converting old code that is using conversion of strings like ID::A and +// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for +// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary. +// +// sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' +// +#define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \ + static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })() +namespace ID = RTLIL::ID; + +namespace hashlib { + template<> struct hash_ops : hash_ops {}; +} + + +YOSYS_NAMESPACE_END + +#endif diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 85107b68f33..c2bb72f3bb3 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -36,7 +36,8 @@ struct cell_area_t { struct statdata_t { #define STAT_INT_MEMBERS X(num_wires) X(num_wire_bits) X(num_pub_wires) X(num_pub_wire_bits) \ - X(num_memories) X(num_memory_bits) X(num_cells) X(num_processes) + X(num_ports) X(num_port_bits) X(num_memories) X(num_memory_bits) X(num_cells) \ + X(num_processes) #define STAT_NUMERIC_MEMBERS STAT_INT_MEMBERS X(area) @@ -90,6 +91,11 @@ struct statdata_t for (auto wire : mod->selected_wires()) { + if (wire->port_input || wire->port_output) { + num_ports++; + num_port_bits += wire->width; + } + if (wire->name.isPublic()) { num_pub_wires++; num_pub_wire_bits += wire->width; @@ -239,6 +245,8 @@ struct statdata_t log(" Number of wire bits: %6u\n", num_wire_bits); log(" Number of public wires: %6u\n", num_pub_wires); log(" Number of public wire bits: %6u\n", num_pub_wire_bits); + log(" Number of ports: %6u\n", num_ports); + log(" Number of port bits: %6u\n", num_port_bits); log(" Number of memories: %6u\n", num_memories); log(" Number of memory bits: %6u\n", num_memory_bits); log(" Number of processes: %6u\n", num_processes); @@ -284,6 +292,8 @@ struct statdata_t log(" \"num_wire_bits\": %u,\n", num_wire_bits); log(" \"num_pub_wires\": %u,\n", num_pub_wires); log(" \"num_pub_wire_bits\": %u,\n", num_pub_wire_bits); + log(" \"num_ports\": %u,\n", num_ports); + log(" \"num_port_bits\": %u,\n", num_port_bits); log(" \"num_memories\": %u,\n", num_memories); log(" \"num_memory_bits\": %u,\n", num_memory_bits); log(" \"num_processes\": %u,\n", num_processes); @@ -494,6 +504,8 @@ struct StatPass : public Pass { design->scratchpad_set_int("stat.num_wire_bits", data.num_wire_bits); design->scratchpad_set_int("stat.num_pub_wires", data.num_pub_wires); design->scratchpad_set_int("stat.num_pub_wire_bits", data.num_pub_wire_bits); + design->scratchpad_set_int("stat.num_ports", data.num_ports); + design->scratchpad_set_int("stat.num_port_bits", data.num_port_bits); design->scratchpad_set_int("stat.num_memories", data.num_memories); design->scratchpad_set_int("stat.num_memory_bits", data.num_memory_bits); design->scratchpad_set_int("stat.num_processes", data.num_processes); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index cafc0aaf3e0..d1dd0fd882d 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -415,7 +415,7 @@ struct MemoryMapPass : public Pass { log(" to any of the values.\n"); log("\n"); log(" -iattr\n"); - log(" for -attr, ignore case of .\n"); + log(" for -attr, suppress case sensitivity in matching of .\n"); log("\n"); log(" -rom-only\n"); log(" only perform conversion for ROMs (memories with no write ports).\n"); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index b3e43c18ca7..ba39b9c8086 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -443,13 +443,6 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos if (!raw_used_signals.check_any(s1)) { // delete wires that aren't used by anything directly goto delete_this_wire; - } else - if (!used_signals.check_any(s2)) { - // this path shouldn't be possible: this wire is used directly (otherwise it would get cleaned up above), and indirectly - // used wires are a superset of those used directly - log_assert(false); - // delete wires that aren't used by anything indirectly, even though other wires may alias it - goto delete_this_wire; } if (0) diff --git a/passes/opt/opt_demorgan.cc b/passes/opt/opt_demorgan.cc index 1464c4177cd..4db3a810105 100644 --- a/passes/opt/opt_demorgan.cc +++ b/passes/opt/opt_demorgan.cc @@ -183,7 +183,7 @@ struct OptDemorganPass : public Pass { { log_header(design, "Executing OPT_DEMORGAN pass (push inverters through $reduce_* cells).\n"); - int argidx = 0; + int argidx = 1; extra_args(args, argidx, design); unsigned int cells_changed = 0; diff --git a/passes/sat/formalff.cc b/passes/sat/formalff.cc index 264a9fb3be0..0eadb69e0eb 100644 --- a/passes/sat/formalff.cc +++ b/passes/sat/formalff.cc @@ -237,7 +237,7 @@ struct InitValWorker return true; if (ff.has_ce && initconst(ff.sig_ce.as_bit()) == (ff.pol_ce ? State::S0 : State::S1)) continue; - if (ff.has_srst && initconst(ff.sig_ce.as_bit()) == (ff.pol_srst ? State::S1 : State::S0)) + if (ff.has_srst && initconst(ff.sig_srst.as_bit()) == (ff.pol_srst ? State::S1 : State::S0)) continue; return true; diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index 6b377855e3e..fa5c2a825de 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -35,3 +35,4 @@ $(eval $(call add_share_file,share,techlibs/common/abc9_map.v)) $(eval $(call add_share_file,share,techlibs/common/abc9_unmap.v)) $(eval $(call add_share_file,share,techlibs/common/cmp2lcu.v)) $(eval $(call add_share_file,share,techlibs/common/cmp2softlogic.v)) +$(eval $(call add_share_file,share/choices,techlibs/common/choices/kogge-stone.v)) diff --git a/techlibs/common/choices/kogge-stone.v b/techlibs/common/choices/kogge-stone.v new file mode 100644 index 00000000000..ad2e2b16954 --- /dev/null +++ b/techlibs/common/choices/kogge-stone.v @@ -0,0 +1,54 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2024 Martin PoviĊĦer + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +(* techmap_celltype = "$lcu" *) +module _80_lcu_kogge_stone (P, G, CI, CO); + parameter WIDTH = 2; + + (* force_downto *) + input [WIDTH-1:0] P, G; + input CI; + + (* force_downto *) + output [WIDTH-1:0] CO; + + integer i, j; + (* force_downto *) + reg [WIDTH-1:0] p, g; + + wire [1023:0] _TECHMAP_DO_ = "proc; opt -fast"; + + always @* begin + p = P; + g = G; + + // in almost all cases CI will be constant zero + g[0] = g[0] | (p[0] & CI); + + for (i = 0; i < $clog2(WIDTH); i = i + 1) begin + // iterate in reverse so we don't confuse a result from this stage and the previous + for (j = WIDTH - 1; j >= 2**i; j = j - 1) begin + g[j] = g[j] | p[j] & g[j - 2**i]; + p[j] = p[j] & p[j - 2**i]; + end + end + end + + assign CO = g; +endmodule diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 489281f26a0..7dc03da6d2d 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -902,18 +902,34 @@ endgenerate endmodule // -------------------------------------------------------- - +// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| +//- +//- $macc (A, B, Y) +//- +//- Multiply and accumulate. +//- A building block for summing any number of negated and unnegated signals +//- and arithmetic products of pairs of signals. Cell port A concatenates pairs +//- of signals to be multiplied together. When the second signal in a pair is zero +//- length, a constant 1 is used instead as the second factor. Cell port B +//- concatenates 1-bit-wide signals to also be summed, such as "carry in" in adders. +//- Typically created by the `alumacc` pass, which transforms $add and $mul +//- into $macc cells. module \$macc (A, B, Y); parameter A_WIDTH = 0; parameter B_WIDTH = 0; parameter Y_WIDTH = 0; +// CONFIG determines the layout of A, as explained below parameter CONFIG = 4'b0000; parameter CONFIG_WIDTH = 4; -input [A_WIDTH-1:0] A; -input [B_WIDTH-1:0] B; -output reg [Y_WIDTH-1:0] Y; +// In the terms used for this cell, there's mixed meanings for the term "port". To disambiguate: +// A cell port is for example the A input (it is constructed in C++ as cell->setPort(ID::A, ...)) +// Multiplier ports are pairs of multiplier inputs ("factors"). +// If the second signal in such a pair is zero length, no multiplication is necessary, and the first signal is just added to the sum. +input [A_WIDTH-1:0] A; // Cell port A is the concatenation of all arithmetic ports +input [B_WIDTH-1:0] B; // Cell port B is the concatenation of single-bit unsigned signals to be also added to the sum +output reg [Y_WIDTH-1:0] Y; // Output sum // Xilinx XSIM does not like $clog2() below.. function integer my_clog2; @@ -929,10 +945,42 @@ function integer my_clog2; end endfunction +// Bits that a factor's length field in CONFIG per factor in cell port A localparam integer num_bits = CONFIG[3:0] > 0 ? CONFIG[3:0] : 1; +// Number of multiplier ports localparam integer num_ports = (CONFIG_WIDTH-4) / (2 + 2*num_bits); +// Minium bit width of an induction variable to iterate over all bits of cell port A localparam integer num_abits = my_clog2(A_WIDTH) > 0 ? my_clog2(A_WIDTH) : 1; +// In this pseudocode, u(foo) means an unsigned int that's foo bits long. +// The CONFIG parameter carries the following information: +// struct CONFIG { +// u4 num_bits; +// struct port_field { +// bool is_signed; +// bool is_subtract; +// u(num_bits) factor1_len; +// u(num_bits) factor2_len; +// }[num_ports]; +// }; + +// The A cell port carries the following information: +// struct A { +// u(CONFIG.port_field[0].factor1_len) port0factor1; +// u(CONFIG.port_field[0].factor2_len) port0factor2; +// u(CONFIG.port_field[1].factor1_len) port1factor1; +// u(CONFIG.port_field[1].factor2_len) port1factor2; +// ... +// }; +// and log(sizeof(A)) is num_abits. +// No factor1 may have a zero length. +// A factor2 having a zero length implies factor2 is replaced with a constant 1. + +// Additionally, B is an array of 1-bit-wide unsigned integers to also be summed up. +// Finally, we have: +// Y = port0factor1 * port0factor2 + port1factor1 * port1factor2 + ... +// * B[0] + B[1] + ... + function [2*num_ports*num_abits-1:0] get_port_offsets; input [CONFIG_WIDTH-1:0] cfg; integer i, cursor; diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 7fb8173b069..68b276588b5 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -207,7 +207,7 @@ module _90_fa (A, B, C, X, Y); endmodule (* techmap_celltype = "$lcu" *) -module _90_lcu (P, G, CI, CO); +module _90_lcu_brent_kung (P, G, CI, CO); parameter WIDTH = 2; (* force_downto *) diff --git a/techlibs/efinix/cells_sim.v b/techlibs/efinix/cells_sim.v index 22c7bc776da..26e45464613 100644 --- a/techlibs/efinix/cells_sim.v +++ b/techlibs/efinix/cells_sim.v @@ -113,7 +113,31 @@ module EFX_GBUFCE( endmodule -module EFX_RAM_5K( +module EFX_RAM_5K +# ( + parameter READ_WIDTH = 20, + parameter WRITE_WIDTH = 20, + localparam READ_ADDR_WIDTH = + (READ_WIDTH == 16) ? 8 : // 256x16 + (READ_WIDTH == 8) ? 9 : // 512x8 + (READ_WIDTH == 4) ? 10 : // 1024x4 + (READ_WIDTH == 2) ? 11 : // 2048x2 + (READ_WIDTH == 1) ? 12 : // 4096x1 + (READ_WIDTH == 20) ? 8 : // 256x20 + (READ_WIDTH == 10) ? 9 : // 512x10 + (READ_WIDTH == 5) ? 10 : -1, // 1024x5 + + localparam WRITE_ADDR_WIDTH = + (WRITE_WIDTH == 16) ? 8 : // 256x16 + (WRITE_WIDTH == 8) ? 9 : // 512x8 + (WRITE_WIDTH == 4) ? 10 : // 1024x4 + (WRITE_WIDTH == 2) ? 11 : // 2048x2 + (WRITE_WIDTH == 1) ? 12 : // 4096x1 + (WRITE_WIDTH == 20) ? 8 : // 256x20 + (WRITE_WIDTH == 10) ? 9 : // 512x10 + (WRITE_WIDTH == 5) ? 10 : -1 // 1024x5 +) +( input [WRITE_WIDTH-1:0] WDATA, input [WRITE_ADDR_WIDTH-1:0] WADDR, input WE, @@ -126,8 +150,6 @@ module EFX_RAM_5K( (* clkbuf_sink *) input RCLK ); - parameter READ_WIDTH = 20; - parameter WRITE_WIDTH = 20; parameter OUTPUT_REG = 1'b0; parameter RCLK_POLARITY = 1'b1; parameter RE_POLARITY = 1'b1; @@ -155,25 +177,4 @@ module EFX_RAM_5K( parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - - localparam READ_ADDR_WIDTH = - (READ_WIDTH == 16) ? 8 : // 256x16 - (READ_WIDTH == 8) ? 9 : // 512x8 - (READ_WIDTH == 4) ? 10 : // 1024x4 - (READ_WIDTH == 2) ? 11 : // 2048x2 - (READ_WIDTH == 1) ? 12 : // 4096x1 - (READ_WIDTH == 20) ? 8 : // 256x20 - (READ_WIDTH == 10) ? 9 : // 512x10 - (READ_WIDTH == 5) ? 10 : -1; // 1024x5 - - localparam WRITE_ADDR_WIDTH = - (WRITE_WIDTH == 16) ? 8 : // 256x16 - (WRITE_WIDTH == 8) ? 9 : // 512x8 - (WRITE_WIDTH == 4) ? 10 : // 1024x4 - (WRITE_WIDTH == 2) ? 11 : // 2048x2 - (WRITE_WIDTH == 1) ? 12 : // 4096x1 - (WRITE_WIDTH == 20) ? 8 : // 256x20 - (WRITE_WIDTH == 10) ? 9 : // 512x10 - (WRITE_WIDTH == 5) ? 10 : -1; // 1024x5 - endmodule diff --git a/tests/arch/quicklogic/.gitignore b/tests/arch/quicklogic/.gitignore index 9a71dca69b0..ae20ed34262 100644 --- a/tests/arch/quicklogic/.gitignore +++ b/tests/arch/quicklogic/.gitignore @@ -1,4 +1,4 @@ *.log -/run-test.mk +run-test.mk +*_synth.v +*_testbench diff --git a/tests/arch/run-test.sh b/tests/arch/run-test.sh index a14b795090d..68f925b34d9 100755 --- a/tests/arch/run-test.sh +++ b/tests/arch/run-test.sh @@ -16,7 +16,7 @@ for arch in ../../techlibs/*; do done else echo -n "Test $path ->" - iverilog -t null -I$arch $path + iverilog -t null -I$arch -g2005-sv $path echo " ok" fi done diff --git a/tests/memlib/memlib_9b1B.v b/tests/memlib/memlib_9b1B.v index 55545ebd4db..9a8246c9f19 100644 --- a/tests/memlib/memlib_9b1B.v +++ b/tests/memlib/memlib_9b1B.v @@ -1,4 +1,14 @@ -module RAM_9b1B ( +module RAM_9b1B +#( + parameter INIT = 0, + parameter OPTION_INIT = "UNDEFINED", + parameter PORT_R_WIDTH = 9, + parameter PORT_W_WIDTH = 9, + parameter PORT_R_CLK_POL = 0, + parameter PORT_W_CLK_POL = 0, + parameter PORT_W_WR_EN_WIDTH = 1 +) +( input PORT_R_CLK, input [6:0] PORT_R_ADDR, output reg [PORT_R_WIDTH-1:0] PORT_R_RD_DATA, @@ -8,14 +18,6 @@ module RAM_9b1B ( input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA ); -parameter INIT = 0; -parameter OPTION_INIT = "UNDEFINED"; -parameter PORT_R_WIDTH = 9; -parameter PORT_W_WIDTH = 9; -parameter PORT_R_CLK_POL = 0; -parameter PORT_W_CLK_POL = 0; -parameter PORT_W_WR_EN_WIDTH = 1; - reg [8:0] mem [0:15]; integer i; diff --git a/tests/memlib/memlib_wren.v b/tests/memlib/memlib_wren.v index b9433d42e66..c687184bdca 100644 --- a/tests/memlib/memlib_wren.v +++ b/tests/memlib/memlib_wren.v @@ -1,4 +1,11 @@ -module RAM_WREN ( +module RAM_WREN #( + parameter ABITS=4, + parameter WIDTH=8, + parameter PORT_A_WR_EN_WIDTH=1, + parameter PORT_A_WR_BE_WIDTH=0, + parameter OPTION_BYTESIZE=WIDTH, + parameter WB=OPTION_BYTESIZE +)( input PORT_A_CLK, input [ABITS-1:0] PORT_A_ADDR, input [WIDTH-1:0] PORT_A_WR_DATA, @@ -7,13 +14,6 @@ module RAM_WREN ( input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE ); -parameter ABITS=4; -parameter WIDTH=8; -parameter PORT_A_WR_EN_WIDTH=1; -parameter PORT_A_WR_BE_WIDTH=0; -parameter OPTION_BYTESIZE=WIDTH; -parameter WB=OPTION_BYTESIZE; - reg [WIDTH-1:0] mem [0:2**ABITS-1]; integer i; diff --git a/tests/memories/issue00335.v b/tests/memories/issue00335.v index f3b6e5dfe28..305339dd959 100644 --- a/tests/memories/issue00335.v +++ b/tests/memories/issue00335.v @@ -2,13 +2,15 @@ // expect-rd-ports 1 // expect-rd-clk \clk -module ram2 (input clk, +module ram2 #( + parameter SIZE = 5 // Address size + ) (input clk, input sel, input we, input [SIZE-1:0] adr, input [63:0] dat_i, output reg [63:0] dat_o); - parameter SIZE = 5; // Address size + reg [63:0] mem [0:(1 << SIZE)-1]; integer i; diff --git a/tests/simple/.gitignore b/tests/simple/.gitignore index 073f46157e1..5daaadbd734 100644 --- a/tests/simple/.gitignore +++ b/tests/simple/.gitignore @@ -1,2 +1,3 @@ *.log *.out +*.err diff --git a/tests/techmap/kogge-stone.ys b/tests/techmap/kogge-stone.ys new file mode 100644 index 00000000000..fc3637f10b0 --- /dev/null +++ b/tests/techmap/kogge-stone.ys @@ -0,0 +1 @@ +test_cell -s 1711533949 -n 10 -map +/techmap.v -map +/choices/kogge-stone.v $lcu diff --git a/tests/verilog/.gitignore b/tests/verilog/.gitignore index 96ebe20ba26..cfd72076e4e 100644 --- a/tests/verilog/.gitignore +++ b/tests/verilog/.gitignore @@ -1,6 +1,10 @@ /*.log /*.out +/*.err /run-test.mk /const_arst.v /const_sr.v /doubleslash.v +/roundtrip_proc_1.v +/roundtrip_proc_2.v +/assign_to_reg.v diff --git a/tests/verilog/assign_to_reg.ys b/tests/verilog/assign_to_reg.ys new file mode 100644 index 00000000000..80080e9f372 --- /dev/null +++ b/tests/verilog/assign_to_reg.ys @@ -0,0 +1,22 @@ +# https://github.com/yosyshq/yosys/issues/2035 + +read_ilang <