aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--backends/firrtl/firrtl.cc3
-rw-r--r--backends/jny/jny.cc5
-rw-r--r--backends/json/json.cc5
-rw-r--r--backends/rtlil/rtlil_backend.cc5
-rw-r--r--frontends/ast/ast.cc3
-rw-r--r--frontends/ast/simplify.cc3
-rw-r--r--frontends/liberty/liberty.cc4
-rw-r--r--frontends/verific/verific.cc10
-rw-r--r--frontends/verific/verificsva.cc4
-rw-r--r--kernel/fstdata.cc2
-rw-r--r--kernel/log.cc1
-rw-r--r--kernel/register.cc7
-rw-r--r--kernel/yosys.cc4
-rw-r--r--passes/cmds/bugpoint.cc1
-rw-r--r--passes/cmds/design.cc5
-rw-r--r--passes/cmds/show.cc1
-rw-r--r--passes/cmds/splitcells.cc172
-rw-r--r--passes/opt/opt_ffinv.cc3
-rw-r--r--passes/proc/proc_dff.cc2
-rw-r--r--techlibs/gowin/cells_sim.v47
21 files changed, 210 insertions, 79 deletions
diff --git a/Makefile b/Makefile
index 9a579d6de..dbaf9e2b0 100644
--- a/Makefile
+++ b/Makefile
@@ -141,7 +141,7 @@ LDLIBS += -lrt
endif
endif
-YOSYS_VER := 0.25+8
+YOSYS_VER := 0.25+60
# Note: We arrange for .gitcommit to contain the (short) commit hash in
# tarballs generated with git-archive(1) using .gitattributes. The git repo
diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc
index e483117d1..d68c52563 100644
--- a/backends/firrtl/firrtl.cc
+++ b/backends/firrtl/firrtl.cc
@@ -1238,6 +1238,9 @@ struct FirrtlBackend : public Backend {
if (top == nullptr)
top = last;
+ if (!top)
+ log_cmd_error("There is no top module in this design!\n");
+
std::string circuitFileinfo = getFileinfo(top);
*f << stringf("circuit %s: %s\n", make_id(top->name), circuitFileinfo.c_str());
diff --git a/backends/jny/jny.cc b/backends/jny/jny.cc
index 2b8d51b76..0be11a52c 100644
--- a/backends/jny/jny.cc
+++ b/backends/jny/jny.cc
@@ -546,8 +546,9 @@ struct JnyPass : public Pass {
std::ostream *f;
std::stringstream buf;
+ bool empty = filename.empty();
- if (!filename.empty()) {
+ if (!empty) {
rewrite_filename(filename);
std::ofstream *ff = new std::ofstream;
ff->open(filename.c_str(), std::ofstream::trunc);
@@ -565,7 +566,7 @@ struct JnyPass : public Pass {
JnyWriter jny_writer(*f, false, connections, attributes, properties);
jny_writer.write_metadata(design, 0, invk.str());
- if (!filename.empty()) {
+ if (!empty) {
delete f;
} else {
log("%s", buf.str().c_str());
diff --git a/backends/json/json.cc b/backends/json/json.cc
index 1ff0a6c66..fd2c922fd 100644
--- a/backends/json/json.cc
+++ b/backends/json/json.cc
@@ -666,8 +666,9 @@ struct JsonPass : public Pass {
std::ostream *f;
std::stringstream buf;
+ bool empty = filename.empty();
- if (!filename.empty()) {
+ if (!empty) {
rewrite_filename(filename);
std::ofstream *ff = new std::ofstream;
ff->open(filename.c_str(), std::ofstream::trunc);
@@ -683,7 +684,7 @@ struct JsonPass : public Pass {
JsonWriter json_writer(*f, true, aig_mode, compat_int_mode);
json_writer.write_design(design);
- if (!filename.empty()) {
+ if (!empty) {
delete f;
} else {
log("%s", buf.str().c_str());
diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc
index b5163aefe..7c7e26a93 100644
--- a/backends/rtlil/rtlil_backend.cc
+++ b/backends/rtlil/rtlil_backend.cc
@@ -530,8 +530,9 @@ struct DumpPass : public Pass {
std::ostream *f;
std::stringstream buf;
+ bool empty = filename.empty();
- if (!filename.empty()) {
+ if (!empty) {
rewrite_filename(filename);
std::ofstream *ff = new std::ofstream;
ff->open(filename.c_str(), append ? std::ofstream::app : std::ofstream::trunc);
@@ -546,7 +547,7 @@ struct DumpPass : public Pass {
RTLIL_BACKEND::dump_design(*f, design, true, flag_m, flag_n);
- if (!filename.empty()) {
+ if (!empty) {
delete f;
} else {
log("%s", buf.str().c_str());
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 6097f02f5..982943d1b 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -1649,7 +1649,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr
AstNode *new_ast = NULL;
std::string modname = derive_common(design, parameters, &new_ast, quiet);
- if (!design->has(modname)) {
+ if (!design->has(modname) && new_ast) {
new_ast->str = modname;
process_module(design, new_ast, false, NULL, quiet);
design->module(modname)->check();
@@ -1699,6 +1699,7 @@ std::string AST::derived_module_name(std::string stripped_name, const std::vecto
std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> &parameters, AstNode **new_ast_out, bool quiet)
{
std::string stripped_name = name.str();
+ (*new_ast_out) = nullptr;
if (stripped_name.compare(0, 9, "$abstract") == 0)
stripped_name = stripped_name.substr(9);
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index da7933d2f..71a26983b 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -4705,8 +4705,7 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg
children_flags |= AstNode::MEM2REG_FL_ASYNC;
proc_flags_p = new dict<AstNode*, uint32_t>;
}
-
- if (type == AST_INITIAL) {
+ else if (type == AST_INITIAL) {
children_flags |= AstNode::MEM2REG_FL_INIT;
proc_flags_p = new dict<AstNode*, uint32_t>;
}
diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc
index 188ef2e04..cadbcaee6 100644
--- a/frontends/liberty/liberty.cc
+++ b/frontends/liberty/liberty.cc
@@ -500,8 +500,6 @@ struct LibertyFrontend : public Frontend {
bool flag_ignore_miss_data_latch = false;
std::vector<std::string> attributes;
- log_header(design, "Executing Liberty frontend.\n");
-
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++) {
std::string arg = args[argidx];
@@ -546,6 +544,8 @@ struct LibertyFrontend : public Frontend {
if (flag_wb && flag_lib)
log_error("-wb and -lib cannot be specified together!\n");
+ log_header(design, "Executing Liberty frontend: %s\n", filename.c_str());
+
LibertyParser parser(*f);
int cell_count = 0;
diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc
index a93d79c80..8898c4597 100644
--- a/frontends/verific/verific.cc
+++ b/frontends/verific/verific.cc
@@ -2317,8 +2317,8 @@ std::string verific_import(Design *design, const std::map<std::string,std::strin
const char *lib_name = (prefix) ? prefix->GetName() : 0 ;
if (!Strings::compare("work", lib_name)) lib = veri_file::GetLibrary(lib_name, 1) ;
}
- veri_module = (lib && module_name) ? lib->GetModule(module_name->GetName(), 1) : 0;
- top = veri_module->GetName();
+ if (lib && module_name)
+ top = lib->GetModule(module_name->GetName(), 1)->GetName();
}
}
@@ -2344,6 +2344,7 @@ std::string verific_import(Design *design, const std::map<std::string,std::strin
int i;
FOREACH_ARRAY_ITEM(netlists, i, nl) {
+ if (!nl) continue;
if (!top.empty() && nl->CellBaseName() != top)
continue;
nl->AddAtt(new Att(" \\top", NULL));
@@ -3297,8 +3298,8 @@ struct VerificPass : public Pass {
const char *lib_name = (prefix) ? prefix->GetName() : 0 ;
if (!Strings::compare("work", lib_name)) lib = veri_file::GetLibrary(lib_name, 1) ;
}
- veri_module = (lib && module_name) ? lib->GetModule(module_name->GetName(), 1) : 0;
- top_mod_names.insert(veri_module->GetName());
+ if (lib && module_name)
+ top_mod_names.insert(lib->GetModule(module_name->GetName(), 1)->GetName());
}
} else {
log("Adding Verilog module '%s' to elaboration queue.\n", name);
@@ -3333,6 +3334,7 @@ struct VerificPass : public Pass {
int i;
FOREACH_ARRAY_ITEM(netlists, i, nl) {
+ if (!nl) continue;
if (!top_mod_names.count(nl->CellBaseName()))
continue;
nl->AddAtt(new Att(" \\top", NULL));
diff --git a/frontends/verific/verificsva.cc b/frontends/verific/verificsva.cc
index 12bac2a3d..986a98643 100644
--- a/frontends/verific/verificsva.cc
+++ b/frontends/verific/verificsva.cc
@@ -1777,7 +1777,7 @@ struct VerificSvaImporter
if (mode_assert) c = module->addLive(root_name, sig_a_q, sig_en_q);
if (mode_assume) c = module->addFair(root_name, sig_a_q, sig_en_q);
- importer->import_attributes(c->attributes, root);
+ if (c) importer->import_attributes(c->attributes, root);
return;
}
@@ -1822,7 +1822,7 @@ struct VerificSvaImporter
if (mode_assume) c = module->addAssume(root_name, sig_a_q, sig_en_q);
if (mode_cover) c = module->addCover(root_name, sig_a_q, sig_en_q);
- importer->import_attributes(c->attributes, root);
+ if (c) importer->import_attributes(c->attributes, root);
}
}
catch (ParserErrorException)
diff --git a/kernel/fstdata.cc b/kernel/fstdata.cc
index 1b8043f9a..65ae3426c 100644
--- a/kernel/fstdata.cc
+++ b/kernel/fstdata.cc
@@ -197,7 +197,7 @@ static void reconstruct_clb_attimes(void *user_data, uint64_t pnt_time, fstHandl
void FstData::reconstruct_callback_attimes(uint64_t pnt_time, fstHandle pnt_facidx, const unsigned char *pnt_value, uint32_t /* plen */)
{
- if (pnt_time > end_time) return;
+ if (pnt_time > end_time || !pnt_value) return;
// if we are past the timestamp
bool is_clock = false;
if (!all_samples) {
diff --git a/kernel/log.cc b/kernel/log.cc
index 0092871f0..75a1ffb45 100644
--- a/kernel/log.cc
+++ b/kernel/log.cc
@@ -707,6 +707,7 @@ void log_check_expected()
if (item.second.current_count == item.second.expected_count) {
log_warn_regexes.clear();
log("Expected error pattern '%s' found !!!\n", item.first.c_str());
+ yosys_shutdown();
#ifdef EMSCRIPTEN
throw 0;
#elif defined(_MSC_VER)
diff --git a/kernel/register.cc b/kernel/register.cc
index 0e4d503be..9ffb17c1a 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -531,10 +531,11 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s
std::ifstream *ff = new std::ifstream;
ff->open(filename.c_str(), bin_input ? std::ifstream::binary : std::ifstream::in);
yosys_input_files.insert(filename);
- if (ff->fail())
+ if (ff->fail()) {
delete ff;
- else
- f = ff;
+ ff = nullptr;
+ }
+ f = ff;
if (f != NULL) {
// Check for gzip magic
unsigned char magic[3];
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index 333faae6a..bd8dded4b 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -469,8 +469,8 @@ std::string make_temp_dir(std::string template_str)
# endif
char *p = strdup(template_str.c_str());
- p = mkdtemp(p);
- log_assert(p != NULL);
+ char *res = mkdtemp(p);
+ log_assert(res != NULL);
template_str = p;
free(p);
diff --git a/passes/cmds/bugpoint.cc b/passes/cmds/bugpoint.cc
index e666023fa..c398afffa 100644
--- a/passes/cmds/bugpoint.cc
+++ b/passes/cmds/bugpoint.cc
@@ -393,6 +393,7 @@ struct BugpointPass : public Pass {
}
}
}
+ delete design_copy;
return nullptr;
}
diff --git a/passes/cmds/design.cc b/passes/cmds/design.cc
index 169f7cc4a..168d38563 100644
--- a/passes/cmds/design.cc
+++ b/passes/cmds/design.cc
@@ -118,6 +118,9 @@ struct DesignPass : public Pass {
std::string save_name, load_name, as_name, delete_name;
std::vector<RTLIL::Module*> copy_src_modules;
+ if (!design)
+ log_cmd_error("No default design.\n");
+
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
@@ -280,7 +283,7 @@ struct DesignPass : public Pass {
done[mod->name] = prefix;
}
- while (!queue.empty())
+ while (!queue.empty() && copy_from_design)
{
pool<Module*> old_queue;
old_queue.swap(queue);
diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc
index b186e5db2..a7c77f96f 100644
--- a/passes/cmds/show.cc
+++ b/passes/cmds/show.cc
@@ -296,7 +296,6 @@ struct ShowWorker
code += stringf("x%d [ shape=record, style=rounded, label=\"%s\" ];\n", idx, label_string.c_str());
if (!port.empty()) {
currentColor = xorshift32(currentColor);
- log_warning("WIDTHLABEL %s %d\n", log_signal(sig), GetSize(sig));
if (driver)
code += stringf("%s:e -> x%d:w [arrowhead=odiamond, arrowtail=odiamond, dir=both, %s, %s];\n", port.c_str(), idx, nextColor(sig).c_str(), widthLabel(sig.size()).c_str());
else
diff --git a/passes/cmds/splitcells.cc b/passes/cmds/splitcells.cc
index de6df6142..82ed49074 100644
--- a/passes/cmds/splitcells.cc
+++ b/passes/cmds/splitcells.cc
@@ -68,70 +68,132 @@ struct SplitcellsWorker
int split(Cell *cell, const std::string &format)
{
- if (!cell->type.in("$and", "$mux", "$not", "$or", "$pmux", "$xnor", "$xor")) return 0;
+ if (cell->type.in("$and", "$mux", "$not", "$or", "$pmux", "$xnor", "$xor"))
+ {
+ SigSpec outsig = sigmap(cell->getPort(ID::Y));
+ if (GetSize(outsig) <= 1) return 0;
+
+ std::vector<int> slices;
+ slices.push_back(0);
+
+ int width = GetSize(outsig);
+ width = std::min(width, GetSize(cell->getPort(ID::A)));
+ if (cell->hasPort(ID::B))
+ width = std::min(width, GetSize(cell->getPort(ID::B)));
+
+ for (int i = 1; i < width; i++) {
+ auto &last_users = bit_users_db[outsig[slices.back()]];
+ auto &this_users = bit_users_db[outsig[i]];
+ if (last_users != this_users) slices.push_back(i);
+ }
+ if (GetSize(slices) <= 1) return 0;
+ slices.push_back(GetSize(outsig));
+
+ log("Splitting %s cell %s/%s into %d slices:\n", log_id(cell->type), log_id(module), log_id(cell), GetSize(slices)-1);
+ for (int i = 1; i < GetSize(slices); i++)
+ {
+ int slice_msb = slices[i]-1;
+ int slice_lsb = slices[i-1];
- SigSpec outsig = sigmap(cell->getPort(ID::Y));
- if (GetSize(outsig) <= 1) return 0;
+ IdString slice_name = module->uniquify(cell->name.str() + (slice_msb == slice_lsb ?
+ stringf("%c%d%c", format[0], slice_lsb, format[1]) :
+ stringf("%c%d%c%d%c", format[0], slice_msb, format[2], slice_lsb, format[1])));
+
+ Cell *slice = module->addCell(slice_name, cell);
+
+ auto slice_signal = [&](SigSpec old_sig) -> SigSpec {
+ SigSpec new_sig;
+ for (int i = 0; i < GetSize(old_sig); i += GetSize(outsig)) {
+ int offset = i+slice_lsb;
+ int length = std::min(GetSize(old_sig)-offset, slice_msb-slice_lsb+1);
+ new_sig.append(old_sig.extract(offset, length));
+ }
+ return new_sig;
+ };
+
+ slice->setPort(ID::A, slice_signal(slice->getPort(ID::A)));
+ if (slice->hasParam(ID::A_WIDTH))
+ slice->setParam(ID::A_WIDTH, GetSize(slice->getPort(ID::A)));
+
+ if (slice->hasPort(ID::B)) {
+ slice->setPort(ID::B, slice_signal(slice->getPort(ID::B)));
+ if (slice->hasParam(ID::B_WIDTH))
+ slice->setParam(ID::B_WIDTH, GetSize(slice->getPort(ID::B)));
+ }
- std::vector<int> slices;
- slices.push_back(0);
+ slice->setPort(ID::Y, slice_signal(slice->getPort(ID::Y)));
+ if (slice->hasParam(ID::Y_WIDTH))
+ slice->setParam(ID::Y_WIDTH, GetSize(slice->getPort(ID::Y)));
+ if (slice->hasParam(ID::WIDTH))
+ slice->setParam(ID::WIDTH, GetSize(slice->getPort(ID::Y)));
- int width = GetSize(outsig);
- width = std::min(width, GetSize(cell->getPort(ID::A)));
- if (cell->hasPort(ID::B))
- width = std::min(width, GetSize(cell->getPort(ID::B)));
+ log(" slice %d: %s => %s\n", i, log_id(slice_name), log_signal(slice->getPort(ID::Y)));
+ }
- for (int i = 1; i < width; i++) {
- auto &last_users = bit_users_db[outsig[slices.back()]];
- auto &this_users = bit_users_db[outsig[i]];
- if (last_users != this_users) slices.push_back(i);
+ module->remove(cell);
+ return GetSize(slices)-1;
}
- if (GetSize(slices) <= 1) return 0;
- slices.push_back(GetSize(outsig));
- log("Splitting %s cell %s/%s into %d slices:\n", log_id(cell->type), log_id(module), log_id(cell), GetSize(slices)-1);
- for (int i = 1; i < GetSize(slices); i++)
+ if (cell->type.in("$ff", "$dff", "$dffe", "$dffsr", "$dffsre", "$adff", "$adffe", "$aldffe",
+ "$sdff", "$sdffce", "$sdffe", "$dlatch", "$dlatchsr", "$adlatch"))
{
- int slice_msb = slices[i]-1;
- int slice_lsb = slices[i-1];
+ auto splitports = {ID::D, ID::Q, ID::AD, ID::SET, ID::CLR};
+ auto splitparams = {ID::ARST_VALUE, ID::SRST_VALUE};
+
+ SigSpec outsig = sigmap(cell->getPort(ID::Q));
+ if (GetSize(outsig) <= 1) return 0;
+ int width = GetSize(outsig);
+
+ std::vector<int> slices;
+ slices.push_back(0);
+
+ for (int i = 1; i < width; i++) {
+ auto &last_users = bit_users_db[outsig[slices.back()]];
+ auto &this_users = bit_users_db[outsig[i]];
+ if (last_users != this_users) slices.push_back(i);
+ }
+
+ if (GetSize(slices) <= 1) return 0;
+ slices.push_back(GetSize(outsig));
- IdString slice_name = module->uniquify(cell->name.str() + (slice_msb == slice_lsb ?
- stringf("%c%d%c", format[0], slice_lsb, format[1]) :
- stringf("%c%d%c%d%c", format[0], slice_msb, format[2], slice_lsb, format[1])));
+ log("Splitting %s cell %s/%s into %d slices:\n", log_id(cell->type), log_id(module), log_id(cell), GetSize(slices)-1);
+ for (int i = 1; i < GetSize(slices); i++)
+ {
+ int slice_msb = slices[i]-1;
+ int slice_lsb = slices[i-1];
- Cell *slice = module->addCell(slice_name, cell);
+ IdString slice_name = module->uniquify(cell->name.str() + (slice_msb == slice_lsb ?
+ stringf("%c%d%c", format[0], slice_lsb, format[1]) :
+ stringf("%c%d%c%d%c", format[0], slice_msb, format[2], slice_lsb, format[1])));
- auto slice_signal = [&](SigSpec old_sig) -> SigSpec {
- SigSpec new_sig;
- for (int i = 0; i < GetSize(old_sig); i += GetSize(outsig)) {
- int offset = i+slice_lsb;
- int length = std::min(GetSize(old_sig)-offset, slice_msb-slice_lsb+1);
- new_sig.append(old_sig.extract(offset, length));
+ Cell *slice = module->addCell(slice_name, cell);
+
+ for (IdString portname : splitports) {
+ if (slice->hasPort(portname)) {
+ SigSpec sig = slice->getPort(portname);
+ sig = sig.extract(slice_lsb, slice_msb-slice_lsb+1);
+ slice->setPort(portname, sig);
+ }
}
- return new_sig;
- };
- slice->setPort(ID::A, slice_signal(slice->getPort(ID::A)));
- if (slice->hasParam(ID::A_WIDTH))
- slice->setParam(ID::A_WIDTH, GetSize(slice->getPort(ID::A)));
+ for (IdString paramname : splitparams) {
+ if (slice->hasParam(paramname)) {
+ Const val = slice->getParam(paramname);
+ val = val.extract(slice_lsb, slice_msb-slice_lsb+1);
+ slice->setParam(paramname, val);
+ }
+ }
- if (slice->hasPort(ID::B)) {
- slice->setPort(ID::B, slice_signal(slice->getPort(ID::B)));
- if (slice->hasParam(ID::B_WIDTH))
- slice->setParam(ID::B_WIDTH, GetSize(slice->getPort(ID::B)));
- }
+ slice->setParam(ID::WIDTH, GetSize(slice->getPort(ID::Q)));
- slice->setPort(ID::Y, slice_signal(slice->getPort(ID::Y)));
- if (slice->hasParam(ID::Y_WIDTH))
- slice->setParam(ID::Y_WIDTH, GetSize(slice->getPort(ID::Y)));
- if (slice->hasParam(ID::WIDTH))
- slice->setParam(ID::WIDTH, GetSize(slice->getPort(ID::Y)));
+ log(" slice %d: %s => %s\n", i, log_id(slice_name), log_signal(slice->getPort(ID::Q)));
+ }
- log(" slice %d: %s => %s\n", i, log_id(slice_name), log_signal(slice->getPort(ID::Y)));
+ module->remove(cell);
+ return GetSize(slices)-1;
}
- module->remove(cell);
- return GetSize(slices)-1;
+ return 0;
}
};
@@ -179,14 +241,20 @@ struct SplitcellsPass : public Pass {
for (auto module : design->selected_modules())
{
- SplitcellsWorker worker(module);
int count_split_pre = 0;
int count_split_post = 0;
- for (auto cell : module->selected_cells()) {
- int n = worker.split(cell, format);
- count_split_pre += (n != 0);
- count_split_post += n;
+ while (1) {
+ SplitcellsWorker worker(module);
+ bool did_something = false;
+ for (auto cell : module->selected_cells()) {
+ int n = worker.split(cell, format);
+ did_something |= (n != 0);
+ count_split_pre += (n != 0);
+ count_split_post += n;
+ }
+ if (!did_something)
+ break;
}
if (count_split_pre)
diff --git a/passes/opt/opt_ffinv.cc b/passes/opt/opt_ffinv.cc
index 5d989dafd..3f7b4bc4a 100644
--- a/passes/opt/opt_ffinv.cc
+++ b/passes/opt/opt_ffinv.cc
@@ -64,6 +64,7 @@ struct OptFfInvWorker
log_assert(d_inv == nullptr);
d_inv = port.cell;
}
+ if (!d_inv) return false;
if (index.query_is_output(ff.sig_q))
return false;
@@ -140,6 +141,7 @@ struct OptFfInvWorker
log_assert(d_lut == nullptr);
d_lut = port.cell;
}
+ if (!d_lut) return false;
if (index.query_is_output(ff.sig_q))
return false;
@@ -167,6 +169,7 @@ struct OptFfInvWorker
log_assert(q_inv == nullptr);
q_inv = port.cell;
}
+ if (!q_inv) return false;
ff.flip_rst_bits({0});
ff.sig_q = q_inv->getPort(ID::Y);
diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc
index 234671df5..fd56786f2 100644
--- a/passes/proc/proc_dff.cc
+++ b/passes/proc/proc_dff.cc
@@ -302,7 +302,7 @@ void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce)
ce.assign_map.apply(rstval);
ce.assign_map.apply(sig);
- if (rstval == sig) {
+ if (rstval == sig && sync_level) {
if (sync_level->type == RTLIL::SyncType::ST1)
insig = mod->Mux(NEW_ID, insig, sig, sync_level->signal);
else
diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v
index 736aa0707..ab8207ef1 100644
--- a/techlibs/gowin/cells_sim.v
+++ b/techlibs/gowin/cells_sim.v
@@ -1553,6 +1553,53 @@ parameter DEVICE = "GW1N-1"; // "GW1N-1", "GW1N-4", "GW1N-9", "GW1NR-4",
endmodule
(* blackbox *)
+module PLLVR (CLKOUT, CLKOUTP, CLKOUTD, CLKOUTD3, LOCK, CLKIN, CLKFB, FBDSEL, IDSEL, ODSEL, DUTYDA, PSDA, FDLY, RESET, RESET_P, VREN);
+input CLKIN;
+input CLKFB;
+input RESET;
+input RESET_P;
+input [5:0] FBDSEL;
+input [5:0] IDSEL;
+input [5:0] ODSEL;
+input [3:0] PSDA,FDLY;
+input [3:0] DUTYDA;
+input VREN;
+
+output CLKOUT;
+output LOCK;
+output CLKOUTP;
+output CLKOUTD;
+output CLKOUTD3;
+
+parameter FCLKIN = "100.0"; // frequency of CLKIN
+parameter DYN_IDIV_SEL= "false"; // true:IDSEL, false:IDIV_SEL
+parameter IDIV_SEL = 0; // 0:1, 1:2 ... 63:64
+parameter DYN_FBDIV_SEL= "false"; // true:FBDSEL, false:FBDIV_SEL
+parameter FBDIV_SEL = 0; // 0:1, 1:2 ... 63:64
+parameter DYN_ODIV_SEL= "false"; // true:ODSEL, false:ODIV_SEL
+parameter ODIV_SEL = 8; // 2/4/8/16/32/48/64/80/96/112/128
+
+parameter PSDA_SEL= "0000";
+parameter DYN_DA_EN = "false"; // true:PSDA or DUTYDA or FDA, false: DA_SEL
+parameter DUTYDA_SEL= "1000";
+
+parameter CLKOUT_FT_DIR = 1'b1; // CLKOUT fine tuning direction. 1'b1 only
+parameter CLKOUTP_FT_DIR = 1'b1; // 1'b1 only
+parameter CLKOUT_DLY_STEP = 0; // 0, 1, 2, 4
+parameter CLKOUTP_DLY_STEP = 0; // 0, 1, 2
+
+parameter CLKFB_SEL = "internal"; // "internal", "external"
+parameter CLKOUT_BYPASS = "false"; // "true", "false"
+parameter CLKOUTP_BYPASS = "false"; // "true", "false"
+parameter CLKOUTD_BYPASS = "false"; // "true", "false"
+parameter DYN_SDIV_SEL = 2; // 2~128, only even numbers
+parameter CLKOUTD_SRC = "CLKOUT"; // CLKOUT, CLKOUTP
+parameter CLKOUTD3_SRC = "CLKOUT"; // CLKOUT, CLKOUTP
+parameter DEVICE = "GW1NS-4"; // "GW1NS-4", "GW1NS-4C", "GW1NSR-4", "GW1NSR-4C", "GW1NSER-4C"
+
+endmodule
+
+(* blackbox *)
module OSC(OSCOUT);
output OSCOUT;