mirror of https://github.com/YosysHQ/yosys.git
Add (* gclk *) attribute support
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
f273291dfe
commit
4372cf690d
|
@ -418,7 +418,9 @@ Non-standard or SystemVerilog features for formal verification
|
||||||
supported in any clocked block.
|
supported in any clocked block.
|
||||||
|
|
||||||
- The syntax ``@($global_clock)`` can be used to create FFs that have no
|
- 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 <netname>)`` or ``@(negedge <netname>)`` when ``<netname>``
|
||||||
|
is marked with the ``(* gclk *)`` Verilog attribute.
|
||||||
|
|
||||||
|
|
||||||
Supported features from SystemVerilog
|
Supported features from SystemVerilog
|
||||||
|
|
|
@ -223,12 +223,18 @@ struct AST_INTERNAL::ProcessGenerator
|
||||||
bool found_global_syncs = false;
|
bool found_global_syncs = false;
|
||||||
bool found_anyedge_syncs = false;
|
bool found_anyedge_syncs = false;
|
||||||
for (auto child : always->children)
|
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 (child->type == AST_EDGE) {
|
||||||
if (GetSize(child->children) == 1 && child->children.at(0)->type == AST_IDENTIFIER && child->children.at(0)->str == "\\$global_clock")
|
if (GetSize(child->children) == 1 && child->children.at(0)->type == AST_IDENTIFIER && child->children.at(0)->str == "\\$global_clock")
|
||||||
found_global_syncs = true;
|
found_global_syncs = true;
|
||||||
else
|
else
|
||||||
found_anyedge_syncs = true;
|
found_anyedge_syncs = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (found_anyedge_syncs) {
|
if (found_anyedge_syncs) {
|
||||||
if (found_global_syncs)
|
if (found_global_syncs)
|
||||||
|
@ -242,6 +248,9 @@ struct AST_INTERNAL::ProcessGenerator
|
||||||
bool found_clocked_sync = false;
|
bool found_clocked_sync = false;
|
||||||
for (auto child : always->children)
|
for (auto child : always->children)
|
||||||
if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE) {
|
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;
|
found_clocked_sync = true;
|
||||||
if (found_global_syncs || found_anyedge_syncs)
|
if (found_global_syncs || found_anyedge_syncs)
|
||||||
log_error("Found non-synthesizable event list at %s:%d!\n", always->filename.c_str(), always->linenum);
|
log_error("Found non-synthesizable event list at %s:%d!\n", always->filename.c_str(), always->linenum);
|
||||||
|
|
|
@ -1470,6 +1470,10 @@ VerificClocking::VerificClocking(VerificImporter *importer, Net *net, bool sva_a
|
||||||
|
|
||||||
clock_net = net;
|
clock_net = net;
|
||||||
clock_sig = importer->net_map_at(clock_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)
|
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);
|
sig_d = module->Mux(NEW_ID, sig_q, sig_d, enable_sig);
|
||||||
|
|
||||||
if (disable_sig != State::S0) {
|
if (disable_sig != State::S0) {
|
||||||
|
log_assert(gclk == false);
|
||||||
log_assert(GetSize(sig_q) == GetSize(init_value));
|
log_assert(GetSize(sig_q) == GetSize(init_value));
|
||||||
return module->addAdff(name, clock_sig, disable_sig, sig_d, sig_q, init_value, posedge);
|
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);
|
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)
|
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);
|
log_assert(disable_sig == State::S0);
|
||||||
|
|
||||||
if (enable_sig != State::S1)
|
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)
|
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);
|
log_assert(disable_sig == State::S0);
|
||||||
|
|
||||||
if (enable_sig != State::S1)
|
if (enable_sig != State::S1)
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct VerificClocking {
|
||||||
SigBit enable_sig = State::S1;
|
SigBit enable_sig = State::S1;
|
||||||
SigBit disable_sig = State::S0;
|
SigBit disable_sig = State::S0;
|
||||||
bool posedge = true;
|
bool posedge = true;
|
||||||
|
bool gclk = false;
|
||||||
|
|
||||||
VerificClocking() { }
|
VerificClocking() { }
|
||||||
VerificClocking(VerificImporter *importer, Verific::Net *net, bool sva_at_only = false);
|
VerificClocking(VerificImporter *importer, Verific::Net *net, bool sva_at_only = false);
|
||||||
|
|
Loading…
Reference in New Issue