From 4372cf690d829755279a6a5778023e5e0a4493b2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 1 Jun 2018 13:25:42 +0200 Subject: [PATCH] Add (* gclk *) attribute support Signed-off-by: Clifford Wolf --- README.md | 4 +++- frontends/ast/genrtlil.cc | 9 +++++++++ frontends/verific/verific.cc | 10 ++++++++++ frontends/verific/verific.h | 1 + 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 704948e2d..c02691d94 100644 --- a/README.md +++ b/README.md @@ -418,7 +418,9 @@ Non-standard or SystemVerilog features for formal verification supported in any clocked block. - The syntax ``@($global_clock)`` can be used to create FFs that have no - explicit clock input ($ff cells). + explicit clock input ($ff cells). The same can be achieved by using + ``@(posedge )`` or ``@(negedge )`` when ```` + is marked with the ``(* gclk *)`` Verilog attribute. Supported features from SystemVerilog diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 57ba9668d..40cbbc2a3 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -223,12 +223,18 @@ struct AST_INTERNAL::ProcessGenerator bool found_global_syncs = false; bool found_anyedge_syncs = false; for (auto child : always->children) + { + if ((child->type == AST_POSEDGE || child->type == AST_NEGEDGE) && GetSize(child->children) == 1 && child->children.at(0)->type == AST_IDENTIFIER && + child->children.at(0)->id2ast && child->children.at(0)->id2ast->type == AST_WIRE && child->children.at(0)->id2ast->get_bool_attribute("\\gclk")) { + found_global_syncs = true; + } if (child->type == AST_EDGE) { if (GetSize(child->children) == 1 && child->children.at(0)->type == AST_IDENTIFIER && child->children.at(0)->str == "\\$global_clock") found_global_syncs = true; else found_anyedge_syncs = true; } + } if (found_anyedge_syncs) { if (found_global_syncs) @@ -242,6 +248,9 @@ struct AST_INTERNAL::ProcessGenerator bool found_clocked_sync = false; for (auto child : always->children) if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE) { + if (GetSize(child->children) == 1 && child->children.at(0)->type == AST_IDENTIFIER && child->children.at(0)->id2ast && + child->children.at(0)->id2ast->type == AST_WIRE && child->children.at(0)->id2ast->get_bool_attribute("\\gclk")) + continue; found_clocked_sync = true; if (found_global_syncs || found_anyedge_syncs) log_error("Found non-synthesizable event list at %s:%d!\n", always->filename.c_str(), always->linenum); diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 12f2fdd7f..f67337754 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1470,6 +1470,10 @@ VerificClocking::VerificClocking(VerificImporter *importer, Net *net, bool sva_a clock_net = net; clock_sig = importer->net_map_at(clock_net); + + const char *gclk_attr = clock_net->GetAttValue("gclk"); + if (gclk_attr != nullptr && (!strcmp(gclk_attr, "1") || !strcmp(gclk_attr, "'1'"))) + gclk = true; } Cell *VerificClocking::addDff(IdString name, SigSpec sig_d, SigSpec sig_q, Const init_value) @@ -1492,15 +1496,20 @@ Cell *VerificClocking::addDff(IdString name, SigSpec sig_d, SigSpec sig_q, Const sig_d = module->Mux(NEW_ID, sig_q, sig_d, enable_sig); if (disable_sig != State::S0) { + log_assert(gclk == false); log_assert(GetSize(sig_q) == GetSize(init_value)); return module->addAdff(name, clock_sig, disable_sig, sig_d, sig_q, init_value, posedge); } + if (gclk) + return module->addFf(name, sig_d, sig_q); + return module->addDff(name, clock_sig, sig_d, sig_q, posedge); } Cell *VerificClocking::addAdff(IdString name, RTLIL::SigSpec sig_arst, SigSpec sig_d, SigSpec sig_q, Const arst_value) { + log_assert(gclk == false); log_assert(disable_sig == State::S0); if (enable_sig != State::S1) @@ -1511,6 +1520,7 @@ Cell *VerificClocking::addAdff(IdString name, RTLIL::SigSpec sig_arst, SigSpec s Cell *VerificClocking::addDffsr(IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, SigSpec sig_d, SigSpec sig_q) { + log_assert(gclk == false); log_assert(disable_sig == State::S0); if (enable_sig != State::S1) diff --git a/frontends/verific/verific.h b/frontends/verific/verific.h index 714b7c82a..86a743ea1 100644 --- a/frontends/verific/verific.h +++ b/frontends/verific/verific.h @@ -40,6 +40,7 @@ struct VerificClocking { SigBit enable_sig = State::S1; SigBit disable_sig = State::S0; bool posedge = true; + bool gclk = false; VerificClocking() { } VerificClocking(VerificImporter *importer, Verific::Net *net, bool sva_at_only = false); -- 2.30.2