diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | frontends/ast/ast.cc | 4 | ||||
-rw-r--r-- | frontends/verific/verific.cc | 2 | ||||
-rw-r--r-- | frontends/verilog/preproc.cc | 6 | ||||
-rw-r--r-- | passes/cmds/scc.cc | 77 | ||||
-rw-r--r-- | passes/techmap/abc9.cc | 2 | ||||
-rw-r--r-- | passes/techmap/flatten.cc | 2 | ||||
-rw-r--r-- | tests/simple/const_branch_finish.v | 3 | ||||
-rw-r--r-- | tests/simple/generate.v | 8 | ||||
-rw-r--r-- | tests/simple/macro_arg_surrounding_spaces.v | 20 |
10 files changed, 95 insertions, 31 deletions
@@ -126,7 +126,7 @@ LDFLAGS += -rdynamic LDLIBS += -lrt endif -YOSYS_VER := 0.9+3871 +YOSYS_VER := 0.9+3885 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/frontends/ast/ast.cc b/frontends/ast/ast.cc index 1c0a8b34d..dc47420af 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -548,9 +548,9 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const break; case AST_CASE: - if (!children.empty() && children[0]->type == AST_CONDX) + if (children.size() > 1 && children[1]->type == AST_CONDX) fprintf(f, "%s" "casex (", indent.c_str()); - else if (!children.empty() && children[0]->type == AST_CONDZ) + else if (children.size() > 1 && children[1]->type == AST_CONDZ) fprintf(f, "%s" "casez (", indent.c_str()); else fprintf(f, "%s" "case (", indent.c_str()); diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 614124a29..81e14ac41 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -55,7 +55,7 @@ USING_YOSYS_NAMESPACE # error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific." #endif -#if YOSYSHQ_VERIFIC_API_VERSION < 20201201 +#if YOSYSHQ_VERIFIC_API_VERSION < 20210101 # error "Please update your version of YosysHQ flavored Verific." #endif diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 5a2804a41..c451c4c20 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -390,12 +390,16 @@ static void input_file(std::istream &f, std::string filename) // the argument list); false if we finished with ','. static bool read_argument(std::string &dest) { + skip_spaces(); std::vector<char> openers; for (;;) { std::string tok = next_token(true); if (tok == ")") { - if (openers.empty()) + if (openers.empty()) { + while (dest.size() && (dest.back() == ' ' || dest.back() == '\t')) + dest = dest.substr(0, dest.size() - 1); return true; + } if (openers.back() != '(') log_error("Mismatched brackets in macro argument: %c and %c.\n", openers.back(), tok[0]); diff --git a/passes/cmds/scc.cc b/passes/cmds/scc.cc index 8e7f3f990..7aa9a484f 100644 --- a/passes/cmds/scc.cc +++ b/passes/cmds/scc.cc @@ -37,7 +37,7 @@ struct SccWorker RTLIL::Design *design; RTLIL::Module *module; SigMap sigmap; - CellTypes ct; + CellTypes ct, specifyCells; std::set<RTLIL::Cell*> workQueue; std::map<RTLIL::Cell*, std::set<RTLIL::Cell*>> cellToNextCell; @@ -100,7 +100,7 @@ struct SccWorker } } - SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool nofeedbackMode, bool allCellTypes, int maxDepth) : + SccWorker(RTLIL::Design *design, RTLIL::Module *module, bool nofeedbackMode, bool allCellTypes, bool specifyMode, int maxDepth) : design(design), module(module), sigmap(module) { if (module->processes.size() > 0) { @@ -115,6 +115,18 @@ struct SccWorker ct.setup_stdcells(); } + // Discover boxes with specify rules in them, for special handling. + if (specifyMode) { + for (auto mod : design->modules()) + if (mod->get_blackbox_attribute(false)) + for (auto cell : mod->cells()) + if (cell->type == ID($specify2)) + { + specifyCells.setup_module(mod); + break; + } + } + SigPool selectedSignals; SigSet<RTLIL::Cell*> sigToNextCells; @@ -129,29 +141,52 @@ struct SccWorker if (!design->selected(module, cell)) continue; - if (!allCellTypes && !ct.cell_known(cell->type)) + if (!allCellTypes && !ct.cell_known(cell->type) && !specifyCells.cell_known(cell->type)) continue; workQueue.insert(cell); RTLIL::SigSpec inputSignals, outputSignals; - for (auto &conn : cell->connections()) - { - bool isInput = true, isOutput = true; + if (specifyCells.cell_known(cell->type)) { + // Use specify rules of the type `(X => Y) = NN` to look for asynchronous paths in boxes. + for (auto subcell : design->module(cell->type)->cells()) + { + if (subcell->type != ID($specify2)) + continue; - if (ct.cell_known(cell->type)) { - isInput = ct.cell_input(cell->type, conn.first); - isOutput = ct.cell_output(cell->type, conn.first); + for (auto bit : subcell->getPort(ID::SRC)) + { + if (!bit.wire || !cell->hasPort(bit.wire->name)) + continue; + inputSignals.append(sigmap(cell->getPort(bit.wire->name))); + } + + for (auto bit : subcell->getPort(ID::DST)) + { + if (!bit.wire || !cell->hasPort(bit.wire->name)) + continue; + outputSignals.append(sigmap(cell->getPort(bit.wire->name))); + } } + } else { + for (auto &conn : cell->connections()) + { + bool isInput = true, isOutput = true; + + if (ct.cell_known(cell->type)) { + isInput = ct.cell_input(cell->type, conn.first); + isOutput = ct.cell_output(cell->type, conn.first); + } - RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second)); - sig.sort_and_unify(); + RTLIL::SigSpec sig = selectedSignals.extract(sigmap(conn.second)); + sig.sort_and_unify(); - if (isInput) - inputSignals.append(sig); - if (isOutput) - outputSignals.append(sig); + if (isInput) + inputSignals.append(sig); + if (isOutput) + outputSignals.append(sig); + } } inputSignals.sort_and_unify(); @@ -228,7 +263,7 @@ struct SccPass : public Pass { log("design.\n"); log("\n"); log(" -expect <num>\n"); - log(" expect to find exactly <num> SSCs. A different number of SSCs will\n"); + log(" expect to find exactly <num> SCCs. A different number of SCCs will\n"); log(" produce an error.\n"); log("\n"); log(" -max_depth <num>\n"); @@ -254,6 +289,9 @@ struct SccPass : public Pass { log(" replace the current selection with a selection of all cells and wires\n"); log(" that are part of a found logic loop\n"); log("\n"); + log(" -specify\n"); + log(" examine specify rules to detect logic loops in whitebox/blackbox cells\n"); + log("\n"); } void execute(std::vector<std::string> args, RTLIL::Design *design) override { @@ -261,6 +299,7 @@ struct SccPass : public Pass { bool allCellTypes = false; bool selectMode = false; bool nofeedbackMode = false; + bool specifyMode = false; int maxDepth = -1; int expect = -1; @@ -293,6 +332,10 @@ struct SccPass : public Pass { selectMode = true; continue; } + if (args[argidx] == "-specify") { + specifyMode = true; + continue; + } break; } int origSelectPos = design->selection_stack.size() - 1; @@ -303,7 +346,7 @@ struct SccPass : public Pass { for (auto mod : design->selected_modules()) { - SccWorker worker(design, mod, nofeedbackMode, allCellTypes, maxDepth); + SccWorker worker(design, mod, nofeedbackMode, allCellTypes, specifyMode, maxDepth); if (!setAttr.empty()) { diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 7d017ac40..56bb15495 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -339,7 +339,7 @@ struct Abc9Pass : public ScriptPass if (check_label("pre")) { run("read_verilog -icells -lib -specify +/abc9_model.v"); - run("scc -set_attr abc9_scc_id {}"); + run("scc -specify -set_attr abc9_scc_id {}"); if (help_mode) run("abc9_ops -mark_scc -prep_delays -prep_xaiger [-dff]", "(option for -dff)"); else diff --git a/passes/techmap/flatten.cc b/passes/techmap/flatten.cc index ec5f83fb0..f35b7ff60 100644 --- a/passes/techmap/flatten.cc +++ b/passes/techmap/flatten.cc @@ -211,7 +211,7 @@ struct FlattenWorker log_assert(new_conn.first.size() == new_conn.second.size()); if (sigmap(new_conn.first).has_const()) - log_error("Mismatch in directionality for cell port %s.%s.%s: %s <= %s\n", + log_error("Cell port %s.%s.%s is driving constant bits: %s <= %s\n", log_id(module), log_id(cell), log_id(port_it.first), log_signal(new_conn.first), log_signal(new_conn.second)); module->connect(new_conn); diff --git a/tests/simple/const_branch_finish.v b/tests/simple/const_branch_finish.v index 8166688e6..f585be87a 100644 --- a/tests/simple/const_branch_finish.v +++ b/tests/simple/const_branch_finish.v @@ -21,9 +21,6 @@ module top; end end generate - begin : unconditional_block - initial `CONSTANT_CHECK - end if (WIDTH == 32) begin : conditional_block initial `CONSTANT_CHECK end diff --git a/tests/simple/generate.v b/tests/simple/generate.v index ac4dd81a8..445c88ba8 100644 --- a/tests/simple/generate.v +++ b/tests/simple/generate.v @@ -167,7 +167,7 @@ module gen_test7; reg [2:0] out2; wire [2:0] out3; generate - begin : cond + if (1) begin : cond reg [2:0] sub_out1; reg [2:0] sub_out2; wire [2:0] sub_out3; @@ -215,9 +215,9 @@ module gen_test8; wire [1:0] x = 2'b11; generate - begin : A + if (1) begin : A wire [1:0] x; - begin : B + if (1) begin : B wire [1:0] x = 2'b00; `ASSERT(x == 0) `ASSERT(A.x == 2) @@ -228,7 +228,7 @@ module gen_test8; `ASSERT(gen_test8.A.C.x == 1) `ASSERT(gen_test8.A.B.x == 0) end - begin : C + if (1) begin : C wire [1:0] x = 2'b01; `ASSERT(x == 1) `ASSERT(A.x == 2) diff --git a/tests/simple/macro_arg_surrounding_spaces.v b/tests/simple/macro_arg_surrounding_spaces.v new file mode 100644 index 000000000..3dbb5ea01 --- /dev/null +++ b/tests/simple/macro_arg_surrounding_spaces.v @@ -0,0 +1,20 @@ +module top( + IDENT_V_, + IDENT_W_, + IDENT_X_, + IDENT_Y_, + IDENT_Z_, + IDENT_A_, + IDENT_B_, + IDENT_C_ +); + `define MACRO(dummy, x) IDENT_``x``_ + output wire IDENT_V_; + output wire `MACRO(_,W); + output wire `MACRO(_, X); + output wire `MACRO(_,Y ); + output wire `MACRO(_, Z ); + output wire `MACRO(_, A); + output wire `MACRO(_,B ); + output wire `MACRO(_, C ); +endmodule |