diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index d327c13f397..86dd4cc69cd 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -1865,6 +1865,7 @@ class AstVar final : public AstNode { dtypeFrom(examplep); } ASTGEN_MEMBERS_AstVar; + void cloneRelink() override; void dump(std::ostream& str) const override; bool same(const AstNode* samep) const override; string name() const override VL_MT_STABLE VL_MT_SAFE { return m_name; } // * = Var name diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 5b717f51325..6da5d35475c 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -2168,6 +2168,9 @@ int AstVarRef::instrCount() const { // Otherwise as a load/store return widthInstrs() * (access().isReadOrRW() ? INSTR_COUNT_LD : 1); } +void AstVar::cloneRelink() { + if (m_sensIfacep && m_sensIfacep->clonep()) m_sensIfacep = m_sensIfacep->clonep(); +} void AstVar::dump(std::ostream& str) const { this->AstNode::dump(str); if (isSc()) str << " [SC]"; diff --git a/src/V3Sched.cpp b/src/V3Sched.cpp index ba23cfbcbc1..202c4fc54e9 100644 --- a/src/V3Sched.cpp +++ b/src/V3Sched.cpp @@ -834,8 +834,10 @@ AstNode* createInputCombLoop(AstNetlist* netlistp, AstCFunc* const initFuncp, const size_t dpiExportTriggerIndex = dpiExportTriggerVscp ? extraTriggers.allocate("DPI export trigger") : std::numeric_limits::max(); - const size_t firstVifTriggerIndex = dpiExportTriggerIndex + 1; - for (const auto& p : virtIfaceTriggers) extraTriggers.allocate(p.first->name()); + const size_t firstVifTriggerIndex = extraTriggers.size(); + for (const auto& p : virtIfaceTriggers) { + extraTriggers.allocate("virtual interface: " + p.first->name()); + } // Gather the relevant sensitivity expressions and create the trigger kit const auto& senTreeps = getSenTreesUsedBy({&logic}); @@ -1187,8 +1189,10 @@ void schedule(AstNetlist* netlistp) { const size_t dpiExportTriggerIndex = dpiExportTriggerVscp ? extraTriggers.allocate("DPI export trigger") : std::numeric_limits::max(); - const size_t firstVifTriggerIndex = dpiExportTriggerIndex + 1; - for (const auto& p : virtIfaceTriggers) extraTriggers.allocate(p.first->name()); + const size_t firstVifTriggerIndex = extraTriggers.size(); + for (const auto& p : virtIfaceTriggers) { + extraTriggers.allocate("virtual interface: " + p.first->name()); + } const auto& senTreeps = getSenTreesUsedBy({&logicRegions.m_pre, // &logicRegions.m_act, // diff --git a/src/V3SchedReplicate.cpp b/src/V3SchedReplicate.cpp index 9ef1fcdb0e9..7d72976d633 100644 --- a/src/V3SchedReplicate.cpp +++ b/src/V3SchedReplicate.cpp @@ -121,7 +121,8 @@ class SchedReplicateVarVertex final : public SchedReplicateVertex { : SchedReplicateVertex{graphp} , m_vscp{vscp} { // Top level inputs are - if (varp()->isPrimaryInish() || varp()->isSigUserRWPublic() || varp()->isWrittenByDpi()) { + if (varp()->isPrimaryInish() || varp()->isSigUserRWPublic() || varp()->isWrittenByDpi() + || varp()->sensIfacep()) { addDrivingRegions(INPUT); } // Currently we always execute suspendable processes at the beginning of diff --git a/test_regress/t/t_interface_virtual_sched_act.out b/test_regress/t/t_interface_virtual_sched_act.out new file mode 100644 index 00000000000..10090eb5708 --- /dev/null +++ b/test_regress/t/t_interface_virtual_sched_act.out @@ -0,0 +1,12 @@ +[0] data==0000 +[0] data==0000 +[10] data==0000 +[20] data==dead +[20] data==beef +[20] data==beef +[30] data==beef +[40] data==face +[40] data==cafe +[40] data==cafe +[50] data==cafe +*-* All Finished *-* diff --git a/test_regress/t/t_interface_virtual_trig.pl b/test_regress/t/t_interface_virtual_sched_act.pl similarity index 100% rename from test_regress/t/t_interface_virtual_trig.pl rename to test_regress/t/t_interface_virtual_sched_act.pl diff --git a/test_regress/t/t_interface_virtual_sched_act.v b/test_regress/t/t_interface_virtual_sched_act.v new file mode 100644 index 00000000000..46c4df4bb4e --- /dev/null +++ b/test_regress/t/t_interface_virtual_sched_act.v @@ -0,0 +1,40 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Antmicro Ltd. +// SPDX-License-Identifier: CC0-1.0 + +interface Bus; + logic [15:0] data; +endinterface + +module t ( + clk +); + input clk; + integer cyc = 0; + Bus intf(); + virtual Bus vif = intf; + logic [15:0] data; + + always @(posedge clk) begin + cyc <= cyc + 1; + end + + // Finish on negedge so that $finish is last + always @(negedge clk) + if (cyc >= 5) begin + $write("*-* All Finished *-*\n"); + $finish; + end + + always @(posedge clk or data) begin + if (cyc == 1) intf.data <= 'hdead; + if (cyc == 2) intf.data <= 'hbeef; + if (cyc == 3) intf.data <= 'hface; + if (cyc == 4) intf.data <= 'hcafe; + end + + assign data = vif.data; + always_comb $write("[%0t] data==%h\n", $time, data); +endmodule diff --git a/test_regress/t/t_interface_virtual_sched_ico.cpp b/test_regress/t/t_interface_virtual_sched_ico.cpp new file mode 100644 index 00000000000..aac1bebaad0 --- /dev/null +++ b/test_regress/t/t_interface_virtual_sched_ico.cpp @@ -0,0 +1,41 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2023 by Geza Lore. This program is free software; you can +// redistribute it and/or modify it under the terms of either the GNU +// Lesser General Public License Version 3 or the Perl Artistic License +// Version 2.0. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 +// +//************************************************************************* + +#include "verilated.h" + +#include "Vt_interface_virtual_sched_ico.h" +#include "Vt_interface_virtual_sched_ico__Syms.h" + +#include + +int main(int argc, char** argv) { + const std::unique_ptr contextp{new VerilatedContext}; + contextp->debug(0); + contextp->commandArgs(argc, argv); + srand48(5); + + const std::unique_ptr topp{new VM_PREFIX}; + topp->inc = 1; + topp->clk = false; + topp->eval(); + + while (!contextp->gotFinish() && contextp->time() < 100000) { + contextp->timeInc(5); + if (topp->clk) topp->inc += 1; + topp->clk = !topp->clk; + topp->eval(); + } + + if (!contextp->gotFinish()) { + vl_fatal(__FILE__, __LINE__, "main", "%Error: Timeout; never got a $finish"); + } + return 0; +} diff --git a/test_regress/t/t_interface_virtual_sched_ico.out b/test_regress/t/t_interface_virtual_sched_ico.out new file mode 100644 index 00000000000..6f751923352 --- /dev/null +++ b/test_regress/t/t_interface_virtual_sched_ico.out @@ -0,0 +1,25 @@ +[0] intf1.inc==0 +[0] vif2.inc==0 +[0] intf1.inc==1 +[0] vif2.inc==1 +[0] intf1.inc==1 +[0] vif2.inc==1 +[5] intf1.inc==1 +[5] vif2.inc==1 +[10] intf1.inc==2 +[10] vif2.inc==2 +[15] intf1.inc==2 +[15] vif2.inc==2 +[20] intf1.inc==3 +[20] vif2.inc==3 +[25] intf1.inc==3 +[25] vif2.inc==3 +[30] intf1.inc==4 +[30] vif2.inc==4 +[35] intf1.inc==4 +[35] vif2.inc==4 +[40] intf1.inc==5 +[40] vif2.inc==5 +[45] intf1.inc==5 +[45] vif2.inc==5 +*-* All Finished *-* diff --git a/test_regress/t/t_interface_virtual_sched_ico.pl b/test_regress/t/t_interface_virtual_sched_ico.pl new file mode 100755 index 00000000000..1f4f8b7caf9 --- /dev/null +++ b/test_regress/t/t_interface_virtual_sched_ico.pl @@ -0,0 +1,24 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2023 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt_all => 1); + +compile( + make_main => 0, + v_flags2 => ["--exe", "$Self->{t_dir}/$Self->{name}.cpp"], + ); + +execute( + check_finished => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_interface_virtual_sched_ico.v b/test_regress/t/t_interface_virtual_sched_ico.v new file mode 100644 index 00000000000..f3a85a29876 --- /dev/null +++ b/test_regress/t/t_interface_virtual_sched_ico.v @@ -0,0 +1,39 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2023 by Antmicro Ltd. +// SPDX-License-Identifier: CC0-1.0 + +interface If; + logic [31:0] inc; +endinterface + +module top ( + clk, + inc +); + + input clk; + input [31:0] inc; + int cyc = 0; + + If intf1(); + If intf2(); + virtual If vif1 = intf1; + virtual If vif2 = intf2; + + assign vif1.inc = inc; + assign intf2.inc = inc; + + always @(posedge clk) begin + cyc <= cyc + 1; + if (cyc >= 4) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + + always_comb $write("[%0t] intf1.inc==%0h\n", $time, intf1.inc); + always_comb $write("[%0t] vif2.inc==%0h\n", $time, vif2.inc); + +endmodule diff --git a/test_regress/t/t_interface_virtual_trig.out b/test_regress/t/t_interface_virtual_sched_nba.out similarity index 90% rename from test_regress/t/t_interface_virtual_trig.out rename to test_regress/t/t_interface_virtual_sched_nba.out index 74da89544a4..abde98039c6 100644 --- a/test_regress/t/t_interface_virtual_trig.out +++ b/test_regress/t/t_interface_virtual_sched_nba.out @@ -15,7 +15,7 @@ [50] intf2.data==beef [50] vif3.data==0000 [60] intf2.data==beef -[60] vif3.data==fafa +[60] vif3.data==face [70] intf2.data==beef -[70] vif3.data==bebe +[70] vif3.data==cafe *-* All Finished *-* diff --git a/test_regress/t/t_interface_virtual_sched_nba.pl b/test_regress/t/t_interface_virtual_sched_nba.pl new file mode 100755 index 00000000000..6247bd1265b --- /dev/null +++ b/test_regress/t/t_interface_virtual_sched_nba.pl @@ -0,0 +1,22 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_interface_virtual_sched_nba.v b/test_regress/t/t_interface_virtual_sched_nba.v new file mode 100644 index 00000000000..f40295830e1 --- /dev/null +++ b/test_regress/t/t_interface_virtual_sched_nba.v @@ -0,0 +1,61 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Antmicro Ltd. +// SPDX-License-Identifier: CC0-1.0 + +interface Bus1; + logic [15:0] data; +endinterface + +interface Bus2; + logic [15:0] data; +endinterface + +interface Bus3; + logic [15:0] data; +endinterface + +module t ( + clk +); + input clk; + integer cyc = 0; + Bus1 intf1(); + Bus2 intf2(); + Bus3 intf3(); + virtual Bus1 vif1 = intf1; + virtual Bus2 vif2 = intf2; + virtual Bus3 vif3 = intf3; + + logic [15:0] data; + assign vif2.data = data; + + always @(posedge clk) begin + cyc <= cyc + 1; + if (cyc == 1) begin + vif1.data = 'hdead; + end else if (cyc == 2) begin + data = vif1.data; + end else if (cyc == 3) begin + vif1.data = 'hbeef; + end else if (cyc == 4) begin + data = vif1.data; + end else if (cyc == 5) begin + intf3.data <= 'hface; + end else if (cyc == 6) begin + intf3.data <= 'hcafe; + end + end + + // Finish on negedge so that $finish is last + always @(negedge clk) + if (cyc >= 7) begin + $write("*-* All Finished *-*\n"); + $finish; + end + + always_comb $write("[%0t] intf1.data==%h\n", $time, intf1.data); + always_comb $write("[%0t] intf2.data==%h\n", $time, intf2.data); + always_comb $write("[%0t] vif3.data==%h\n", $time, vif3.data); +endmodule diff --git a/test_regress/t/t_interface_virtual_trig.v b/test_regress/t/t_interface_virtual_trig.v deleted file mode 100644 index 89149e03652..00000000000 --- a/test_regress/t/t_interface_virtual_trig.v +++ /dev/null @@ -1,59 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2023 by Antmicro Ltd. -// SPDX-License-Identifier: CC0-1.0 - -interface Bus1; - logic [15:0] data; -endinterface - -interface Bus2; - logic [15:0] data; -endinterface - -interface Bus3; - logic [15:0] data; -endinterface - -module t(clk); - input clk; - integer cyc = 0; - Bus1 intf1(); - Bus2 intf2(); - Bus3 intf3(); - virtual Bus1 vif1 = intf1; - virtual Bus2 vif2 = intf2; - virtual Bus3 vif3 = intf3; - - logic [15:0] data; - assign vif2.data = data; - - always @(posedge clk) begin - cyc <= cyc + 1; - if (cyc == 1) begin - vif1.data = 'hdead; - end else if (cyc == 2) begin - data = vif1.data; - end else if (cyc == 3) begin - vif1.data = 'hbeef; - end else if (cyc == 4) begin - data = vif1.data; - end else if (cyc == 5) begin - intf3.data <= 'hfafa; - end else if (cyc == 6) begin - intf3.data <= 'hbebe; - end - end - - // Finish on negedge so that $finish is last - always @(negedge clk) - if (cyc >= 7) begin - $write("*-* All Finished *-*\n"); - $finish; - end - - always_comb $write("[%0t] intf1.data==%h\n", $time, intf1.data); - always_comb $write("[%0t] intf2.data==%h\n", $time, intf2.data); - always_comb $write("[%0t] vif3.data==%h\n", $time, vif3.data); -endmodule