From 96f64f4788ca64adde55421a6abadefd182d9a1a Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 3 May 2022 13:22:18 +0200 Subject: [PATCH] verific: Fix conditions of SVAs with explicit clocks within procedures For SVAs that have an explicit clock and are contained in a procedure which conditionally executes the assertion, verific expresses this using a mux with one input connected to constant 1 and the other output connected to an SVA_AT. The existing code only handled the case where the first input is connected to 1. This patch also handles the other case. --- frontends/verific/verific.cc | 8 ++++++-- frontends/verific/verific.h | 1 + frontends/verific/verificsva.cc | 12 +++++++++--- tests/sva/nested_clk_else.sv | 11 +++++++++++ 4 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 tests/sva/nested_clk_else.sv diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index d19d837ff..4eb66851d 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1873,15 +1873,19 @@ VerificClocking::VerificClocking(VerificImporter *importer, Net *net, bool sva_a if (inst_mux == nullptr || inst_mux->Type() != PRIM_MUX) break; - if (!inst_mux->GetInput1()->IsPwr()) + bool pwr1 = inst_mux->GetInput1()->IsPwr(); + bool pwr2 = inst_mux->GetInput2()->IsPwr(); + + if (!pwr1 && !pwr2) break; - Net *sva_net = inst_mux->GetInput2(); + Net *sva_net = pwr1 ? inst_mux->GetInput2() : inst_mux->GetInput1(); if (!verific_is_sva_net(importer, sva_net)) break; body_net = sva_net; cond_net = inst_mux->GetControl(); + cond_pol = pwr1; } while (0); clock_net = net; diff --git a/frontends/verific/verific.h b/frontends/verific/verific.h index 416b26396..695c04f3b 100644 --- a/frontends/verific/verific.h +++ b/frontends/verific/verific.h @@ -44,6 +44,7 @@ struct VerificClocking { SigBit disable_sig = State::S0; bool posedge = true; bool gclk = false; + bool cond_pol = true; VerificClocking() { } VerificClocking(VerificImporter *importer, Verific::Net *net, bool sva_at_only = false); diff --git a/frontends/verific/verificsva.cc b/frontends/verific/verificsva.cc index 1bbdcf016..12bac2a3d 100644 --- a/frontends/verific/verificsva.cc +++ b/frontends/verific/verificsva.cc @@ -1522,10 +1522,13 @@ struct VerificSvaImporter if (inst == nullptr) return false; - if (clocking.cond_net != nullptr) + if (clocking.cond_net != nullptr) { trig = importer->net_map_at(clocking.cond_net); - else + if (!clocking.cond_pol) + trig = module->Not(NEW_ID, trig); + } else { trig = State::S1; + } if (inst->Type() == PRIM_SVA_S_EVENTUALLY || inst->Type() == PRIM_SVA_EVENTUALLY) { @@ -1587,8 +1590,11 @@ struct VerificSvaImporter SigBit trig = State::S1; - if (clocking.cond_net != nullptr) + if (clocking.cond_net != nullptr) { trig = importer->net_map_at(clocking.cond_net); + if (!clocking.cond_pol) + trig = module->Not(NEW_ID, trig); + } if (inst == nullptr) { diff --git a/tests/sva/nested_clk_else.sv b/tests/sva/nested_clk_else.sv new file mode 100644 index 000000000..4421cb36a --- /dev/null +++ b/tests/sva/nested_clk_else.sv @@ -0,0 +1,11 @@ +module top (input clk, a, b); + always @(posedge clk) begin + if (a); + else assume property (@(posedge clk) b); + end + +`ifndef FAIL + assume property (@(posedge clk) !a); +`endif + assert property (@(posedge clk) b); +endmodule