Skip to content

Commit

Permalink
Support generated classes (verilator#5665).
Browse files Browse the repository at this point in the history
  • Loading branch information
wsnyder committed Jan 5, 2025
1 parent 78d6ec8 commit b6a400e
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 1 deletion.
1 change: 1 addition & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Verilator 5.033 devel

**Minor:**

* Support generated classes (#5665). [Shou-Li Hsu]
* Fix error message when call task as a function (#3089). [Matthew Ballance]
* Fix V3Simulate constant reuse (#5709). [Geza Lore]
* Fix man pages what-is section (#5710). [Ahmed El-Mahmoudy]
Expand Down
12 changes: 12 additions & 0 deletions src/V3Begin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,18 @@ class BeginVisitor final : public VNVisitor {
void visit(AstNodeModule* nodep) override {
VL_RESTORER(m_modp);
m_modp = nodep;
// Rename it (e.g. class under a generate)
if (m_unnamedScope != "") {
nodep->name(dot(m_unnamedScope, nodep->name()));
UINFO(8, " rename to " << nodep->name() << endl);
m_statep->userMarkChanged(nodep);
}
VL_RESTORER(m_displayScope);
VL_RESTORER(m_namedScope);
VL_RESTORER(m_unnamedScope);
m_displayScope = "";
m_namedScope = "";
m_unnamedScope = "";
iterateChildren(nodep);
}
void visit(AstNodeFTask* nodep) override {
Expand Down
3 changes: 2 additions & 1 deletion test_regress/t/t_EXAMPLE.v
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
// SPDX-License-Identifier: CC0-1.0

`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0x exp=%0x (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0x exp=%0x (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
`define checks(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);

module t(/*AUTOARG*/
// Inputs
Expand Down
18 changes: 18 additions & 0 deletions test_regress/t/t_gen_class.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 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

import vltest_bootstrap

test.scenarios('simulator')

test.compile(verilator_flags2=['--binary'])

test.execute()

test.passes()
67 changes: 67 additions & 0 deletions test_regress/t/t_gen_class.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0

`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0x exp=%0x (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
`define checks(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);

module Child;
int ch_value;
endmodule

module Parent;
for (genvar i = 0; i < 10; i++) begin : gen_child
Child child();
end
endmodule

module t;
Parent parent();

virtual class ChildAgentBase;
pure virtual task preload(int value);
pure virtual function string name();
endclass

ChildAgentBase child_agents[10];

for (genvar i = 0; i < 10; i++) begin : gfor
class ChildAgent extends ChildAgentBase;
task automatic preload(int value);
parent.gen_child[i].child.ch_value = value;
endtask
function string name();
return $sformatf("%m");
endfunction
endclass

ChildAgent agent = new();

initial child_agents[i] = agent;
end

task automatic preload_children;
for (int i = 0; i < 10; i++) begin
child_agents[i].preload(i);
end
endtask

string s;

initial begin
#1; // Ensure all class instances are initialized
preload_children();
`checkh(parent.gen_child[3].child.ch_value, 3);
`checkh(parent.gen_child[8].child.ch_value, 8);
`ifdef VERILATOR
// Some legal examples "t.gfor[4].\ChildAgent::name", "t.gfor[4].ChildAgent.name"
`checks(child_agents[4].name(), "t.gfor[4].ChildAgent.name");
`endif
$write("*-* All Finished *-*\n");
$finish;
end

endmodule

0 comments on commit b6a400e

Please sign in to comment.