diff --git a/README.md b/README.md index 02495c71a..32ecd8205 100644 --- a/README.md +++ b/README.md @@ -266,6 +266,16 @@ The command ``prep`` provides a good default word-level synthesis script, as used in SMT-based formal verification. +Additional information +====================== + +The ``read_verilog`` command, used by default when calling ``read`` with Verilog +source input, does not perform syntax checking. You should instead lint your +source with another tool such as +[Verilator](https://www.veripool.org/verilator/) first, e.g. by calling +``verilator --lint-only``. + + Unsupported Verilog-2005 Features ================================= diff --git a/backends/json/json.cc b/backends/json/json.cc index 2f442c494..287c01ead 100644 --- a/backends/json/json.cc +++ b/backends/json/json.cc @@ -353,6 +353,9 @@ struct JsonBackend : public Backend { log(" emit 32-bit or smaller fully-defined parameter values directly\n"); log(" as JSON numbers (for compatibility with old parsers)\n"); log("\n"); + log(" -selected\n"); + log(" output only select module\n"); + log("\n"); log("\n"); log("The general syntax of the JSON output created by this command is as follows:\n"); log("\n"); @@ -597,6 +600,7 @@ struct JsonBackend : public Backend { { bool aig_mode = false; bool compat_int_mode = false; + bool use_selection = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -609,13 +613,17 @@ struct JsonBackend : public Backend { compat_int_mode = true; continue; } + if (args[argidx] == "-selected") { + use_selection = true; + continue; + } break; } extra_args(f, filename, args, argidx); log_header(design, "Executing JSON backend.\n"); - JsonWriter json_writer(*f, false, aig_mode, compat_int_mode); + JsonWriter json_writer(*f, use_selection, aig_mode, compat_int_mode); json_writer.write_design(design); } } JsonBackend; diff --git a/docs/source/code_examples/fifo/fifo.v b/docs/source/code_examples/fifo/fifo.v index 769dfafd4..86f292406 100644 --- a/docs/source/code_examples/fifo/fifo.v +++ b/docs/source/code_examples/fifo/fifo.v @@ -5,7 +5,7 @@ module addr_gen ) ( input en, clk, rst, output reg [AWIDTH-1:0] addr ); - initial addr <= 0; + initial addr = 0; // async reset // increment address when enabled @@ -13,7 +13,7 @@ module addr_gen if (rst) addr <= 0; else if (en) begin - if (addr == MAX_DATA-1) + if ({'0, addr} == MAX_DATA-1) addr <= 0; else addr <= addr + 1; @@ -57,7 +57,7 @@ module fifo ); // status signals - initial count <= 0; + initial count = 0; always @(posedge clk or posedge rst) begin if (rst) diff --git a/docs/source/getting_started/example_synth.rst b/docs/source/getting_started/example_synth.rst index f8530b45b..189eaddfa 100644 --- a/docs/source/getting_started/example_synth.rst +++ b/docs/source/getting_started/example_synth.rst @@ -30,6 +30,14 @@ First, let's quickly look at the design we'll be synthesizing: .. todo:: fifo.v description +While the open source `read_verilog` frontend generally does a pretty good job +at processing valid Verilog input, it does not provide very good error handling +or reporting. Using an external tool such as `verilator`_ before running Yosys +is highly recommended. We can quickly check the Verilog syntax of our design by +calling ``verilator --lint-only fifo.v``. + +.. _verilator: https://www.veripool.org/verilator/ + Loading the design ~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 7261d8edb..376c8043b 100644 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -69,9 +69,14 @@ Things you can't do - Check out `nextpnr`_ for that +- Rely on built-in syntax checking + + - Use an external tool like `verilator`_ instead + .. todo:: nextpnr for FPGAs, consider mentioning openlane, vpr, coriolis .. _nextpnr: https://github.com/YosysHQ/nextpnr +.. _verilator: https://www.veripool.org/verilator/ The Yosys family ---------------- diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index 5667fd4ab..90b01a0c8 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -462,6 +462,9 @@ struct LibertyFrontend : public Frontend { log(" -ignore_miss_data_latch\n"); log(" ignore latches with missing data and/or enable pins\n"); log("\n"); + log(" -ignore_buses\n"); + log(" ignore cells with bus interfaces (wide ports)\n"); + log("\n"); log(" -setattr \n"); log(" set the specified attribute (to the value 1) on all loaded modules\n"); log("\n"); @@ -478,6 +481,7 @@ struct LibertyFrontend : public Frontend { bool flag_ignore_miss_func = false; bool flag_ignore_miss_dir = false; bool flag_ignore_miss_data_latch = false; + bool flag_ignore_buses = false; bool flag_unit_delay = false; std::vector attributes; @@ -514,6 +518,10 @@ struct LibertyFrontend : public Frontend { flag_ignore_miss_data_latch = true; continue; } + if (arg == "-ignore_buses") { + flag_ignore_buses = true; + continue; + } if (arg == "-setattr" && argidx+1 < args.size()) { attributes.push_back(RTLIL::escape_id(args[++argidx])); continue; @@ -546,27 +554,13 @@ struct LibertyFrontend : public Frontend { if (cell->id != "cell" || cell->args.size() != 1) continue; - std::string cell_name = RTLIL::escape_id(cell->args.at(0)); - - if (design->has(cell_name)) { - Module *existing_mod = design->module(cell_name); - if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute(ID::blackbox)) { - log_error("Re-definition of cell/module %s!\n", log_id(cell_name)); - } else if (flag_nooverwrite) { - log("Ignoring re-definition of module %s.\n", log_id(cell_name)); - continue; - } else { - log("Replacing existing%s module %s.\n", existing_mod->get_bool_attribute(ID::blackbox) ? " blackbox" : "", log_id(cell_name)); - design->remove(existing_mod); - } - } - // log("Processing cell type %s.\n", RTLIL::unescape_id(cell_name).c_str()); std::map> type_map = global_type_map; parse_type_map(type_map, cell); RTLIL::Module *module = new RTLIL::Module; + std::string cell_name = RTLIL::escape_id(cell->args.at(0)); module->name = cell_name; if (leakage_power_unit != "") module->attributes["\\leakage_power_unit"] = leakage_power_unit; @@ -577,6 +571,10 @@ struct LibertyFrontend : public Frontend { if (flag_wb) module->set_bool_attribute(ID::whitebox); + const LibertyAst *area = cell->find("area"); + if (area) + module->attributes[ID::area] = area->value; + for (auto &attr : attributes) module->attributes[attr] = 1; @@ -607,6 +605,12 @@ struct LibertyFrontend : public Frontend { if (node->id == "bus" && node->args.size() == 1) { + if (flag_ignore_buses) { + log("Ignoring cell %s with a bus interface %s.\n", log_id(module->name), node->args.at(0).c_str()); + delete module; + goto skip_cell; + } + if (!flag_lib) log_error("Error in cell %s: bus interfaces are only supported in -lib mode.\n", log_id(cell_name)); @@ -720,6 +724,10 @@ struct LibertyFrontend : public Frontend { RTLIL::Wire *wire = module->wires_.at(RTLIL::escape_id(node->args.at(0))); log_assert(wire); + const LibertyAst *capacitance = node->find("capacitance"); + if (capacitance) + wire->attributes[ID::capacitance] = capacitance->value; + if (dir && dir->value == "inout") { wire->port_input = true; wire->port_output = true; @@ -797,6 +805,20 @@ struct LibertyFrontend : public Frontend { } } + if (design->has(cell_name)) { + Module *existing_mod = design->module(cell_name); + if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute(ID::blackbox)) { + log_error("Re-definition of cell/module %s!\n", log_id(cell_name)); + } else if (flag_nooverwrite) { + log("Ignoring re-definition of module %s.\n", log_id(cell_name)); + delete module; + goto skip_cell; + } else { + log("Replacing existing%s module %s.\n", existing_mod->get_bool_attribute(ID::blackbox) ? " blackbox" : "", log_id(cell_name)); + design->remove(existing_mod); + } + } + module->fixup_ports(); design->add(module); cell_count++; diff --git a/kernel/constids.inc b/kernel/constids.inc index d1bbb8eda..d68e2dfe6 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -274,3 +274,5 @@ X(X) X(xprop_decoder) X(Y) X(Y_WIDTH) +X(area) +X(capacitance) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 2650042ff..2c0e3af60 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1857,9 +1857,9 @@ namespace { param_bits(ID::RD_COLLISION_X_MASK, max(1, param(ID::RD_PORTS) * param(ID::WR_PORTS))); param_bits(ID::RD_WIDE_CONTINUATION, max(1, param(ID::RD_PORTS))); param_bits(ID::RD_CE_OVER_SRST, max(1, param(ID::RD_PORTS))); - param_bits(ID::RD_ARST_VALUE, param(ID::RD_PORTS) * param(ID::WIDTH)); - param_bits(ID::RD_SRST_VALUE, param(ID::RD_PORTS) * param(ID::WIDTH)); - param_bits(ID::RD_INIT_VALUE, param(ID::RD_PORTS) * param(ID::WIDTH)); + param_bits(ID::RD_ARST_VALUE, max(1, param(ID::RD_PORTS) * param(ID::WIDTH))); + param_bits(ID::RD_SRST_VALUE, max(1, param(ID::RD_PORTS) * param(ID::WIDTH))); + param_bits(ID::RD_INIT_VALUE, max(1, param(ID::RD_PORTS) * param(ID::WIDTH))); param_bits(ID::WR_CLK_ENABLE, max(1, param(ID::WR_PORTS))); param_bits(ID::WR_CLK_POLARITY, max(1, param(ID::WR_PORTS))); param_bits(ID::WR_WIDE_CONTINUATION, max(1, param(ID::WR_PORTS))); diff --git a/tests/liberty/.gitignore b/tests/liberty/.gitignore index 8763aaac5..2ee56e9d1 100644 --- a/tests/liberty/.gitignore +++ b/tests/liberty/.gitignore @@ -1,3 +1,3 @@ *.log -*.filtered +/*.filtered *.verilogsim diff --git a/tests/liberty/foundry_data/.gitignore b/tests/liberty/foundry_data/.gitignore new file mode 100644 index 000000000..3b97f2a3e --- /dev/null +++ b/tests/liberty/foundry_data/.gitignore @@ -0,0 +1,2 @@ +*.lib +*.lib.filtered diff --git a/tests/liberty/foundry_data/RM_IHPSG13_1P_64x64_c2_bm_bist_typ_1p20V_25C.lib.filtered.gz b/tests/liberty/foundry_data/RM_IHPSG13_1P_64x64_c2_bm_bist_typ_1p20V_25C.lib.filtered.gz new file mode 100644 index 000000000..826d77060 Binary files /dev/null and b/tests/liberty/foundry_data/RM_IHPSG13_1P_64x64_c2_bm_bist_typ_1p20V_25C.lib.filtered.gz differ diff --git a/tests/liberty/foundry_data/rules.txt b/tests/liberty/foundry_data/rules.txt new file mode 100644 index 000000000..1e739f552 --- /dev/null +++ b/tests/liberty/foundry_data/rules.txt @@ -0,0 +1,16 @@ +-wire_load +-wire_load_selection +-default_wire_load +-default_wire_load_area +-default_wire_load_capacitance +-default_wire_load_mode +-default_wire_load_resistance +-default_cell_leakage_power +-default_wire_load_selection +-default_leakage_power_density +-lu_table_template +-power_lut_template +-leakage_power +-cell_leakage_power +-leakage_power +-internal_power diff --git a/tests/liberty/foundry_data/sg13g2_stdcell_typ_1p20V_25C.lib.filtered.gz b/tests/liberty/foundry_data/sg13g2_stdcell_typ_1p20V_25C.lib.filtered.gz new file mode 100644 index 000000000..81c100e43 Binary files /dev/null and b/tests/liberty/foundry_data/sg13g2_stdcell_typ_1p20V_25C.lib.filtered.gz differ diff --git a/tests/liberty/options_test.ys b/tests/liberty/options_test.ys new file mode 100644 index 000000000..54957950e --- /dev/null +++ b/tests/liberty/options_test.ys @@ -0,0 +1,23 @@ +# Test memory macro gets ignored due to -ignore_buses +read_verilog -noblackbox <Y arc on nand2_1 exists +select -assert-any =sg13g2_nand2_1/i:A %co1:+$specify2[SRC] =sg13g2_nand2_1/o:Y %co1:+$specify2[DST] %i + +# D->Q arc on sdfbbp_1 doesn't +select -assert-none =sg13g2_sdfbbp_1/i:D %co1:+$specify2[SRC] =sg13g2_nand2_1/o:Q %co1:+$specify2[DST] %i diff --git a/tests/liberty/unit_delay.ys b/tests/liberty/unit_delay.ys deleted file mode 100644 index 8dd409183..000000000 --- a/tests/liberty/unit_delay.ys +++ /dev/null @@ -1,3 +0,0 @@ -# Nothing gets imported: the file lacks timing data -read_liberty -wb -unit_delay normal.lib -select -assert-none =*/t:$specify* diff --git a/tests/memories/nordports.ys b/tests/memories/nordports.ys new file mode 100644 index 000000000..d3694e64a --- /dev/null +++ b/tests/memories/nordports.ys @@ -0,0 +1,9 @@ +# check memory_collect doesn't produce invalid RTLIL on a memory w/o read ports +read_rtlil <