diff options
Diffstat (limited to 'passes')
-rw-r--r-- | passes/hierarchy/hierarchy.cc | 23 | ||||
-rw-r--r-- | passes/memory/memory_map.cc | 20 | ||||
-rw-r--r-- | passes/sat/async2sync.cc | 3 |
3 files changed, 36 insertions, 10 deletions
diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index d40d6e59f..d27fddf1c 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -439,7 +439,8 @@ void check_cell_connections(const RTLIL::Module &module, RTLIL::Cell &cell, RTLI } } -bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, std::vector<std::string> &libdirs) +bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check, bool flag_simcheck, bool flag_smtcheck, + std::vector<std::string> &libdirs) { bool did_something = false; std::map<RTLIL::Cell*, std::pair<int, int>> array_cells; @@ -477,7 +478,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check RTLIL::Module *mod = design->module(cell->type); if (!mod) { - mod = get_module(*design, *cell, *module, flag_check || flag_simcheck, libdirs); + mod = get_module(*design, *cell, *module, flag_check || flag_simcheck || flag_smtcheck, libdirs); // If we still don't have a module, treat the cell as a black box and skip // it. Otherwise, we either loaded or derived something so should set the @@ -495,11 +496,11 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check // interfaces. if_expander.visit_connections(*cell, *mod); - if (flag_check || flag_simcheck) + if (flag_check || flag_simcheck || flag_smtcheck) check_cell_connections(*module, *cell, *mod); if (mod->get_blackbox_attribute()) { - if (flag_simcheck) + if (flag_simcheck || (flag_smtcheck && !mod->get_bool_attribute(ID::smtlib2_module))) log_error("Module `%s' referenced in module `%s' in cell `%s' is a blackbox/whitebox module.\n", cell->type.c_str(), module->name.c_str(), cell->name.c_str()); continue; @@ -737,6 +738,9 @@ struct HierarchyPass : public Pass { log(" like -check, but also throw an error if blackbox modules are\n"); log(" instantiated, and throw an error if the design has no top module.\n"); log("\n"); + log(" -smtcheck\n"); + log(" like -simcheck, but allow smtlib2_module modules.\n"); + log("\n"); log(" -purge_lib\n"); log(" by default the hierarchy command will not remove library (blackbox)\n"); log(" modules. use this option to also remove unused blackbox modules.\n"); @@ -803,6 +807,7 @@ struct HierarchyPass : public Pass { bool flag_check = false; bool flag_simcheck = false; + bool flag_smtcheck = false; bool purge_lib = false; RTLIL::Module *top_mod = NULL; std::string load_top_mod; @@ -821,7 +826,7 @@ struct HierarchyPass : public Pass { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-generate" && !flag_check && !flag_simcheck && !top_mod) { + if (args[argidx] == "-generate" && !flag_check && !flag_simcheck && !flag_smtcheck && !top_mod) { generate_mode = true; log("Entering generate mode.\n"); while (++argidx < args.size()) { @@ -868,6 +873,10 @@ struct HierarchyPass : public Pass { flag_simcheck = true; continue; } + if (args[argidx] == "-smtcheck") { + flag_smtcheck = true; + continue; + } if (args[argidx] == "-purge_lib") { purge_lib = true; continue; @@ -1013,7 +1022,7 @@ struct HierarchyPass : public Pass { } } - if (flag_simcheck && top_mod == nullptr) + if ((flag_simcheck || flag_smtcheck) && top_mod == nullptr) log_error("Design has no top module.\n"); if (top_mod != NULL) { @@ -1039,7 +1048,7 @@ struct HierarchyPass : public Pass { } for (auto module : used_modules) { - if (expand_module(design, module, flag_check, flag_simcheck, libdirs)) + if (expand_module(design, module, flag_check, flag_simcheck, flag_smtcheck, libdirs)) did_something = true; } diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index ccfb8c94f..fd5b1f1ad 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -31,6 +31,7 @@ struct MemoryMapWorker { bool attr_icase = false; bool rom_only = false; + bool keepdc = false; dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes; RTLIL::Design *design; @@ -190,14 +191,15 @@ struct MemoryMapWorker { int addr = i + mem.start_offset; int idx = addr & ((1 << abits) - 1); + SigSpec w_init = init_data.extract(i*mem.width, mem.width); if (static_cells_map.count(addr) > 0) { data_reg_out[idx] = static_cells_map[addr]; count_static++; } - else if (mem.wr_ports.empty()) + else if (mem.wr_ports.empty() && (!keepdc || w_init.is_fully_def())) { - data_reg_out[idx] = init_data.extract(i*mem.width, mem.width); + data_reg_out[idx] = w_init; } else { @@ -220,13 +222,15 @@ struct MemoryMapWorker w_out_name = genid(mem.memid, "", addr, "$q"); RTLIL::Wire *w_out = module->addWire(w_out_name, mem.width); - SigSpec w_init = init_data.extract(i*mem.width, mem.width); if (!w_init.is_fully_undef()) w_out->attributes[ID::init] = w_init.as_const(); data_reg_out[idx] = w_out; c->setPort(ID::Q, w_out); + + if (mem.wr_ports.empty()) + module->connect(RTLIL::SigSig(w_in, w_out)); } } @@ -380,11 +384,15 @@ struct MemoryMapPass : public Pass { log(" -rom-only\n"); log(" only perform conversion for ROMs (memories with no write ports).\n"); log("\n"); + log(" -keepdc\n"); + log(" when mapping ROMs, keep x-bits shared across read ports.\n"); + log("\n"); } void execute(std::vector<std::string> args, RTLIL::Design *design) override { bool attr_icase = false; bool rom_only = false; + bool keepdc = false; dict<RTLIL::IdString, std::vector<RTLIL::Const>> attributes; log_header(design, "Executing MEMORY_MAP pass (converting memories to logic and flip-flops).\n"); @@ -426,6 +434,11 @@ struct MemoryMapPass : public Pass { rom_only = true; continue; } + if (args[argidx] == "-keepdc") + { + keepdc = true; + continue; + } break; } extra_args(args, argidx, design); @@ -435,6 +448,7 @@ struct MemoryMapPass : public Pass { worker.attr_icase = attr_icase; worker.attributes = attributes; worker.rom_only = rom_only; + worker.keepdc = keepdc; worker.run(); } } diff --git a/passes/sat/async2sync.cc b/passes/sat/async2sync.cc index 46c76eba9..6fdf470b1 100644 --- a/passes/sat/async2sync.cc +++ b/passes/sat/async2sync.cc @@ -75,6 +75,9 @@ struct Async2syncPass : public Pass { if (ff.has_gclk) continue; + if (ff.has_clk && ff.sig_clk.is_fully_const()) + ff.has_ce = ff.has_clk = ff.has_srst = false; + if (ff.has_clk) { if (ff.has_sr) { |